[PATCH] D94202: Preserve the lexical order of global variables during llvm-link merge

Jin Lin via Phabricator via llvm-commits llvm-commits at lists.llvm.org
Wed Jan 13 22:38:16 PST 2021


jinlin updated this revision to Diff 316570.

Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D94202/new/

https://reviews.llvm.org/D94202

Files:
  llvm/lib/Linker/IRMover.cpp


Index: llvm/lib/Linker/IRMover.cpp
===================================================================
--- llvm/lib/Linker/IRMover.cpp
+++ llvm/lib/Linker/IRMover.cpp
@@ -1443,6 +1443,8 @@
   computeTypeMapping();
 
   std::reverse(Worklist.begin(), Worklist.end());
+  SmallVector<std::pair<Constant *, GlobalVariable *>, 16> MappedConstants;
+
   while (!Worklist.empty()) {
     GlobalValue *GV = Worklist.back();
     Worklist.pop_back();
@@ -1453,12 +1455,70 @@
       continue;
 
     assert(!GV->isDeclaration());
-    Mapper.mapValue(*GV);
+
+    // Set the initializer of global variable to be empty so that
+    // the global varaibles in the initializer won't be generated.
+    Constant *InitCnst = nullptr;
+    StringRef Name = GV->getName();
+    if (Name != "llvm.global_ctors" && Name != "llvm.global_dtors") {
+      if (auto *V = dyn_cast<GlobalVariable>(GV)) {
+        if (V->hasInitializer()) {
+          InitCnst = V->getInitializer();
+          if (InitCnst != Constant::getNullValue(V->getValueType()))
+            V->setInitializer(Constant::getNullValue(V->getValueType()));
+          else
+            InitCnst = nullptr;
+        }
+      }
+    }
+
+    // Record the mapping between the old initializer and new
+    // global variable.
+    auto NewV = Mapper.mapValue(*GV);
+    if (InitCnst) {
+      assert(NewV);
+      NewV = NewV->stripPointerCastsAndAliases();
+      auto *NewGV = dyn_cast<GlobalVariable>(NewV);
+      assert(NewGV);
+      MappedConstants.push_back({InitCnst, NewGV});
+    }
+
     if (FoundError)
       return std::move(*FoundError);
     flushRAUWWorklist();
   }
 
+  // Generate the new iniitializer based on the
+  // mapping btween the old initializer and the
+  // new global variable. By this way, the original
+  // lexical order can be preserved.
+  for (auto &MC : MappedConstants) {
+    auto OldCnst = dyn_cast<Value>(MC.first);
+    auto NewCnst = Mapper.mapValue(*OldCnst);
+    Constant *C = dyn_cast<Constant>(NewCnst);
+    assert(C);
+    if (MC.second->getInitializer() !=
+        Constant::getNullValue(MC.second->getValueType())) {
+      SmallVector<Constant *, 16> NewElements;
+      getArrayElements(MC.second->getInitializer(), NewElements);
+
+      SmallVector<Constant *, 16> OldElements;
+      getArrayElements(C, OldElements);
+
+      unsigned Size = OldElements.size();
+      while (Size > 0) {
+        NewElements.pop_back();
+        Size--;
+      }
+      NewElements.append(OldElements.begin(), OldElements.end());
+      ArrayType *ATyp =
+          dyn_cast<ArrayType>(MC.second->getType()->getElementType());
+      assert(ATyp);
+      C = ConstantArray::get(ATyp, NewElements);
+    }
+    MC.second->setInitializer(C);
+  }
+
   // Note that we are done linking global value bodies. This prevents
   // metadata linking from creating new references.
   DoneLinkingBodies = true;


-------------- next part --------------
A non-text attachment was scrubbed...
Name: D94202.316570.patch
Type: text/x-patch
Size: 2892 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20210114/59fea987/attachment.bin>


More information about the llvm-commits mailing list