OSDN Git Service

Cloning: Copy comdats when cloning globals.
authorPeter Collingbourne <peter@pcc.me.uk>
Wed, 18 Jan 2017 20:02:31 +0000 (20:02 +0000)
committerPeter Collingbourne <peter@pcc.me.uk>
Wed, 18 Jan 2017 20:02:31 +0000 (20:02 +0000)
Differential Revision: https://reviews.llvm.org/D28838

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@292430 91177308-0d34-0410-b5e6-96231b3b80d8

lib/Transforms/Utils/CloneModule.cpp
unittests/Transforms/Utils/Cloning.cpp

index 7ebeb61..4e9d672 100644 (file)
 #include "llvm-c/Core.h"
 using namespace llvm;
 
+static void copyComdat(GlobalObject *Dst, const GlobalObject *Src) {
+  const Comdat *SC = Src->getComdat();
+  if (!SC)
+    return;
+  Comdat *DC = Dst->getParent()->getOrInsertComdat(SC->getName());
+  DC->setSelectionKind(SC->getSelectionKind());
+  Dst->setComdat(DC);
+}
+
 /// This is not as easy as it might seem because we have to worry about making
 /// copies of global variables and functions, and making their (initializers and
 /// references, respectively) refer to the right globals.
@@ -124,6 +133,8 @@ std::unique_ptr<Module> llvm::CloneModule(
     I->getAllMetadata(MDs);
     for (auto MD : MDs)
       GV->addMetadata(MD.first, *MapMetadata(MD.second, VMap));
+
+    copyComdat(GV, &*I);
   }
 
   // Similarly, copy over function bodies now...
@@ -153,6 +164,8 @@ std::unique_ptr<Module> llvm::CloneModule(
 
     if (I.hasPersonalityFn())
       F->setPersonalityFn(MapValue(I.getPersonalityFn(), VMap));
+
+    copyComdat(F, &I);
   }
 
   // And aliases
index 216bd32..634aa9e 100644 (file)
@@ -405,10 +405,14 @@ protected:
   void SetupModule() { OldM = new Module("", C); }
 
   void CreateOldModule() {
+    auto *CD = OldM->getOrInsertComdat("comdat");
+    CD->setSelectionKind(Comdat::ExactMatch);
+
     auto GV = new GlobalVariable(
         *OldM, Type::getInt32Ty(C), false, GlobalValue::ExternalLinkage,
         ConstantInt::get(Type::getInt32Ty(C), 1), "gv");
     GV->addMetadata(LLVMContext::MD_type, *MDNode::get(C, {}));
+    GV->setComdat(CD);
 
     DIBuilder DBuilder(*OldM);
     IRBuilder<> IBuilder(C);
@@ -419,6 +423,7 @@ protected:
     auto *F =
         Function::Create(FuncType, GlobalValue::PrivateLinkage, "f", OldM);
     F->setPersonalityFn(PersFn);
+    F->setComdat(CD);
 
     // Create debug info
     auto *File = DBuilder.createFile("filename.c", "/file/dir/");
@@ -472,4 +477,15 @@ TEST_F(CloneModule, GlobalMetadata) {
   GlobalVariable *NewGV = NewM->getGlobalVariable("gv");
   EXPECT_NE(nullptr, NewGV->getMetadata(LLVMContext::MD_type));
 }
+
+TEST_F(CloneModule, Comdat) {
+  GlobalVariable *NewGV = NewM->getGlobalVariable("gv");
+  auto *CD = NewGV->getComdat();
+  ASSERT_NE(nullptr, CD);
+  EXPECT_EQ("comdat", CD->getName());
+  EXPECT_EQ(Comdat::ExactMatch, CD->getSelectionKind());
+
+  Function *NewF = NewM->getFunction("f");
+  EXPECT_EQ(CD, NewF->getComdat());
+}
 }