By popular demand, link up types by name if they are isomorphic and one is an
authorChris Lattner <sabre@nondot.org>
Fri, 16 Dec 2011 08:36:07 +0000 (08:36 +0000)
committerChris Lattner <sabre@nondot.org>
Fri, 16 Dec 2011 08:36:07 +0000 (08:36 +0000)
autorenamed version of the other.   This makes the IR easier to read, because
we don't end up with random renamed versions of the types after LTO'ing a large app.

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

lib/Linker/LinkModules.cpp
test/Linker/link-type-names.ll [new file with mode: 0644]

index ab099bbfaf8926a36f324839957da711a2f32c02..c53b2067a29799c3e322f7f64639ac04b2baa5cf 100644 (file)
@@ -543,6 +543,31 @@ void ModuleLinker::computeTypeMapping() {
       TypeMap.addTypeMapping(DGV->getType(), I->getType());
   }
   
+  // Incorporate types by name, scanning all the types in the source module.
+  // At this point, the destination module may have a type "%foo = { i32 }" for
+  // example.  When the source module got loaded into the same LLVMContext, if
+  // it had the same type, it would have been renamed to "%foo.42 = { i32 }".
+  // Though it isn't required for correctness, attempt to link these up to clean
+  // up the IR.
+  std::vector<StructType*> SrcStructTypes;
+  SrcM->findUsedStructTypes(SrcStructTypes);
+  
+  for (unsigned i = 0, e = SrcStructTypes.size(); i != e; ++i) {
+    StructType *ST = SrcStructTypes[i];
+    if (!ST->hasName()) continue;
+    
+    // Check to see if there is a dot in the name followed by a digit.
+    size_t DotPos = ST->getName().rfind('.');
+    if (DotPos == 0 || DotPos == StringRef::npos ||
+        ST->getName().back() == '.' || !isdigit(ST->getName()[DotPos+1]))
+      continue;
+    
+    // Check to see if the destination module has a struct with the prefix name.
+    if (StructType *DST = DstM->getTypeByName(ST->getName().substr(0, DotPos)))
+      TypeMap.addTypeMapping(DST, ST);
+  }
+  
+  
   // Don't bother incorporating aliases, they aren't generally typed well.
   
   // Now that we have discovered all of the type equivalences, get a body for
diff --git a/test/Linker/link-type-names.ll b/test/Linker/link-type-names.ll
new file mode 100644 (file)
index 0000000..b54c9db
--- /dev/null
@@ -0,0 +1,9 @@
+; RUN: echo "%X = type { i32 } @G2 = global %X { i32 4 }" > %t.ll
+; RUN: llvm-link %s %t.ll -S | FileCheck %s
+
+%X = type { i32 }
+@G = global %X { i32 4 }
+
+
+; CHECK: @G = global %X { i32 4 }
+; CHECK: @G2 = global %X { i32 4 }