[clang] b8f9459 - [CodeGen] Keep track info of lazy-emitted symbols in ModuleBuilder

Jun Zhang via cfe-commits cfe-commits at lists.llvm.org
Thu Jun 9 08:13:01 PDT 2022


Author: Jun Zhang
Date: 2022-06-09T23:12:21+08:00
New Revision: b8f9459715815fa055b3e1c5f970c616797dfcfb

URL: https://github.com/llvm/llvm-project/commit/b8f9459715815fa055b3e1c5f970c616797dfcfb
DIFF: https://github.com/llvm/llvm-project/commit/b8f9459715815fa055b3e1c5f970c616797dfcfb.diff

LOG: [CodeGen] Keep track info of lazy-emitted symbols in ModuleBuilder

The intent of this patch is to selectively carry some states over to
the Builder so we won't lose the information of the previous symbols.

This used to be several downstream patches of Cling, it aims to fix
errors in Clang Interpreter when trying to use inline functions.
Before this patch:

clang-repl> inline int foo() { return 42;}
clang-repl> int x = foo();

JIT session error: Symbols not found: [ _Z3foov ]
error: Failed to materialize symbols:
{ (main, { x, $.incr_module_1.__inits.0, __orc_init_func.incr_module_1 }) }

Co-authored-by: Axel Naumann <Axel.Naumann at cern.ch>
Signed-off-by: Jun Zhang <jun at junz.org>

Differential Revision: https://reviews.llvm.org/D126781

Added: 
    

Modified: 
    clang/lib/CodeGen/CodeGenModule.h
    clang/lib/CodeGen/ModuleBuilder.cpp
    clang/test/Interpreter/execute.cpp

Removed: 
    


################################################################################
diff  --git a/clang/lib/CodeGen/CodeGenModule.h b/clang/lib/CodeGen/CodeGenModule.h
index 0ac476dd6dbcc..b7c180f1c8859 100644
--- a/clang/lib/CodeGen/CodeGenModule.h
+++ b/clang/lib/CodeGen/CodeGenModule.h
@@ -1477,6 +1477,31 @@ class CodeGenModule : public CodeGenTypeCache {
   void printPostfixForExternalizedDecl(llvm::raw_ostream &OS,
                                        const Decl *D) const;
 
+  /// Move some lazily-emitted states to the NewBuilder. This is especially
+  /// essential for the incremental parsing environment like Clang Interpreter,
+  /// because we'll lose all important information after each repl.
+  void moveLazyEmissionStates(CodeGenModule *NewBuilder) {
+    assert(DeferredDeclsToEmit.empty() &&
+           "Should have emitted all decls deferred to emit.");
+    assert(NewBuilder->DeferredDecls.empty() &&
+           "Newly created module should not have deferred decls");
+    NewBuilder->DeferredDecls = std::move(DeferredDecls);
+
+    assert(NewBuilder->DeferredVTables.empty() &&
+           "Newly created module should not have deferred vtables");
+    NewBuilder->DeferredVTables = std::move(DeferredVTables);
+
+    assert(NewBuilder->MangledDeclNames.empty() &&
+           "Newly created module should not have mangled decl names");
+    assert(NewBuilder->Manglings.empty() &&
+           "Newly created module should not have manglings");
+    NewBuilder->Manglings = std::move(Manglings);
+
+    assert(WeakRefReferences.empty() &&
+           "Not all WeakRefRefs have been applied");
+    NewBuilder->TBAA = std::move(TBAA);
+  }
+
 private:
   llvm::Constant *GetOrCreateLLVMFunction(
       StringRef MangledName, llvm::Type *Ty, GlobalDecl D, bool ForVTable,

diff  --git a/clang/lib/CodeGen/ModuleBuilder.cpp b/clang/lib/CodeGen/ModuleBuilder.cpp
index 50b7fd8eb993c..8e97a298ce7fa 100644
--- a/clang/lib/CodeGen/ModuleBuilder.cpp
+++ b/clang/lib/CodeGen/ModuleBuilder.cpp
@@ -134,7 +134,14 @@ namespace {
                               llvm::LLVMContext &C) {
       assert(!M && "Replacing existing Module?");
       M.reset(new llvm::Module(ExpandModuleName(ModuleName, CodeGenOpts), C));
+
+      std::unique_ptr<CodeGenModule> OldBuilder = std::move(Builder);
+
       Initialize(*Ctx);
+
+      if (OldBuilder)
+        OldBuilder->moveLazyEmissionStates(Builder.get());
+
       return M.get();
     }
 

diff  --git a/clang/test/Interpreter/execute.cpp b/clang/test/Interpreter/execute.cpp
index 298046c068c37..61e68990acf96 100644
--- a/clang/test/Interpreter/execute.cpp
+++ b/clang/test/Interpreter/execute.cpp
@@ -13,4 +13,8 @@ struct S { float f = 1.0; S *m = nullptr;} s;
 
 auto r2 = printf("S[f=%f, m=0x%llx]\n", s.f, reinterpret_cast<unsigned long long>(s.m));
 // CHECK-NEXT: S[f=1.000000, m=0x0]
+
+inline int foo() { return 42; }
+int r3 = foo();
+
 quit


        


More information about the cfe-commits mailing list