[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 6 16:12:31 PST 2021


jinlin created this revision.
jinlin added a project: LLVM.
Herald added a subscriber: hiraditya.
jinlin requested review of this revision.
Herald added a subscriber: llvm-commits.

The order of global variables is generated in the order of recursively materializing variables if the global variable has the attribute of hasLocalLinkage or hasLinkOnceLinkage during the module merging. In practice, it is often the exact reverse of source order. This new order may cause performance regression.

The change is to preserve the original lexical order of the global variables in the above case.


Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D94202

Files:
  llvm/lib/Linker/IRMover.cpp
  llvm/lib/Linker/LinkModules.cpp


Index: llvm/lib/Linker/LinkModules.cpp
===================================================================
--- llvm/lib/Linker/LinkModules.cpp
+++ llvm/lib/Linker/LinkModules.cpp
@@ -369,9 +369,7 @@
     GV.setUnnamedAddr(UnnamedAddr);
   }
 
-  if (!DGV && !shouldOverrideFromSrc() &&
-      (GV.hasLocalLinkage() || GV.hasLinkOnceLinkage() ||
-       GV.hasAvailableExternallyLinkage()))
+  if (!DGV && !shouldOverrideFromSrc() && GV.hasAvailableExternallyLinkage())
     return false;
 
   if (GV.isDeclaration())
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,67 @@
       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;
+    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.315016.patch
Type: text/x-patch
Size: 3280 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20210107/f7d303c9/attachment.bin>


More information about the llvm-commits mailing list