[llvm-branch-commits] [llvm-branch] r134397 - in /llvm/branches/type-system-rewrite: lib/Linker/LinkModules.cpp test/Linker/testlink1.ll test/Linker/testlink2.ll

Chris Lattner sabre at nondot.org
Mon Jul 4 15:34:25 PDT 2011


Author: lattner
Date: Mon Jul  4 17:34:24 2011
New Revision: 134397

URL: http://llvm.org/viewvc/llvm-project?rev=134397&view=rev
Log:
implement support for mapping struct bodies from the source module into the 
dest module.

Modified:
    llvm/branches/type-system-rewrite/lib/Linker/LinkModules.cpp
    llvm/branches/type-system-rewrite/test/Linker/testlink1.ll
    llvm/branches/type-system-rewrite/test/Linker/testlink2.ll

Modified: llvm/branches/type-system-rewrite/lib/Linker/LinkModules.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/branches/type-system-rewrite/lib/Linker/LinkModules.cpp?rev=134397&r1=134396&r2=134397&view=diff
==============================================================================
--- llvm/branches/type-system-rewrite/lib/Linker/LinkModules.cpp (original)
+++ llvm/branches/type-system-rewrite/lib/Linker/LinkModules.cpp Mon Jul  4 17:34:24 2011
@@ -29,6 +29,10 @@
   /// MappedTypes - This is a mapping from a source type to a destination type
   /// to use.
   DenseMap<Type*, Type*> MappedTypes;
+
+  /// DefinitionsToResolve - This is a list of non-opaque structs in the source
+  /// module that are mapped to an opaque struct in the destination module.
+  std::vector<StructType*> DefinitionsToResolve;
 public:
   
   /// addTypeMapping - Indicate that the specified type in the destination
@@ -38,6 +42,10 @@
   /// "extern float x") this returns true.
   bool addTypeMapping(Type *DstTy, Type *SrcTy);
 
+  /// linkDefinedTypeBodies - Produce a body for an opaque type in the dest
+  /// module from a type definition in the source module.
+  void linkDefinedTypeBodies();
+  
   /// get - Return the mapped type to use for the specified input type from the
   /// source module.
   Type *get(Type *T);
@@ -79,8 +87,14 @@
     // If the destination type is opaque, then it should be resolved to the
     // input type.  If the source type is opaque, then it gets whatever the
     // destination type is.
-    if (DstST->isOpaque() || SrcST->isOpaque())
+    if (SrcST->isOpaque())
       break;
+    // If the type is opaque in the dest module but not the src module, then we
+    // should get the new type definition from the src module.
+    if (DstST->isOpaque()) { 
+      DefinitionsToResolve.push_back(SrcST);
+      break;
+    }
     
     if (DstST->getNumContainedTypes() != SrcST->getNumContainedTypes() ||
         DstST->isPacked() != SrcST->isPacked())
@@ -147,6 +161,33 @@
   return false;
 }
 
+/// linkDefinedTypeBodies - Produce a body for an opaque type in the dest
+/// module from a type definition in the source module.
+void TypeMapTy::linkDefinedTypeBodies() {
+  SmallVector<Type*, 16> Elements;
+  
+  for (unsigned i = 0, e = DefinitionsToResolve.size(); i != e; ++i) {
+    StructType *SrcSTy = DefinitionsToResolve[i];
+    StructType *DstSTy = cast<StructType>(MappedTypes[SrcSTy]);
+    
+    // TypeMap is a many-to-one mapping, if there were multiple types that
+    // provide a body for DstSTy then previous iterations of this loop may have
+    // already handled it.  Just ignore this case.
+    if (!DstSTy->isOpaque()) continue;
+    assert(!SrcSTy->isOpaque() && "Not resolving a definition?");
+    
+    // Map the body of the source type over to a new body for the dest type.
+    Elements.resize(SrcSTy->getNumElements());
+    for (unsigned i = 0, e = Elements.size(); i != e; ++i)
+      Elements[i] = get(SrcSTy->getElementType(i));
+    
+    DstSTy->setBody(Elements, SrcSTy->isPacked());
+  }
+  
+  DefinitionsToResolve.clear();
+}
+
+
 /// get - Return the mapped type to use for the specified input type from the
 /// source module.
 Type *TypeMapTy::get(Type *Ty) {
@@ -430,6 +471,10 @@
   }
   
   // 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
+  // any 'opaque' types in the dest module that are now resolved. 
+  TypeMap.linkDefinedTypeBodies();
 }
 
 /// linkGlobalProto - Loop through the global variables in the src module and

Modified: llvm/branches/type-system-rewrite/test/Linker/testlink1.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/branches/type-system-rewrite/test/Linker/testlink1.ll?rev=134397&r1=134396&r2=134397&view=diff
==============================================================================
--- llvm/branches/type-system-rewrite/test/Linker/testlink1.ll (original)
+++ llvm/branches/type-system-rewrite/test/Linker/testlink1.ll Mon Jul  4 17:34:24 2011
@@ -2,11 +2,24 @@
 ; RUN: llvm-as < %p/testlink2.ll > %t2.bc
 ; RUN: llvm-link %t.bc %t2.bc -S | FileCheck %s
 
+; CHECK: %Ty2 = type { %Ty1* }
+; CHECK: %Ty1 = type { %Ty2* }
+%Ty1 = type opaque
+%Ty2 = type { %Ty1* }
+
 ; CHECK: %intlist = type { %intlist*, i32 }
 %intlist = type { %intlist*, i32 }
 
 ; The uses of intlist in the other file should be remapped.
-; CHECK-NOT: {{%intlist.[0-9]}}
+; XXHECK-NOT: {{%intlist.[0-9]}}
+
+%Struct1 = type opaque
+ at S1GV = external global %Struct1*
+
+
+ at GVTy1 = external global %Ty1*
+ at GVTy2 = global %Ty2* null
+
 
 ; This should stay the same
 ; CHECK: @MyIntList = global %intlist { %intlist* null, i32 17 }

Modified: llvm/branches/type-system-rewrite/test/Linker/testlink2.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/branches/type-system-rewrite/test/Linker/testlink2.ll?rev=134397&r1=134396&r2=134397&view=diff
==============================================================================
--- llvm/branches/type-system-rewrite/test/Linker/testlink2.ll (original)
+++ llvm/branches/type-system-rewrite/test/Linker/testlink2.ll Mon Jul  4 17:34:24 2011
@@ -4,6 +4,14 @@
 
 %intlist = type { %intlist*, i32 }
 
+
+%Ty1 = type { %Ty2* }
+%Ty2 = type opaque
+
+ at GVTy1 = global %Ty1* null
+ at GVTy2 = external global %Ty2*
+
+
 @MyVar = global i32 4
 @MyIntList = external global %intlist
 @AConst = constant i32 1234
@@ -18,6 +26,10 @@
 @MyVarPtr = linkonce global { i32* } { i32* @MyVar }
 @0 = constant i32 412
 
+; Provides definition of Struct1 and of S1GV.
+%Struct1 = type { i32 }
+ at S1GV = global %Struct1* null
+
 define i32 @foo(i32 %blah) {
   store i32 %blah, i32* @MyVar
   %idx = getelementptr %intlist* @MyIntList, i64 0, i32 1





More information about the llvm-branch-commits mailing list