Move machine code rewriter and spiller outside the register
[oota-llvm.git] / lib / Linker / LinkModules.cpp
index 7bab1af8c5269eb810f1841d953266d3ce30fee3..529fb7714893841f231833524c1d6a8e51972b22 100644 (file)
 //===----------------------------------------------------------------------===//
 
 #include "llvm/Transforms/Utils/Linker.h"
+#include "llvm/Constants.h"
+#include "llvm/DerivedTypes.h"
 #include "llvm/Module.h"
 #include "llvm/SymbolTable.h"
-#include "llvm/DerivedTypes.h"
 #include "llvm/iOther.h"
-#include "llvm/Constants.h"
+#include "llvm/Assembly/Writer.h"
+using namespace llvm;
 
 // Error - Simple wrapper function to conditionally assign to E and return true.
 // This just makes error return conditions a little bit simpler...
@@ -31,8 +33,23 @@ static inline bool Error(std::string *E, const std::string &Message) {
   return true;
 }
 
-// ResolveTypes - Attempt to link the two specified types together.  Return true
-// if there is an error and they cannot yet be linked.
+//
+// Function: ResolveTypes()
+//
+// Description:
+//  Attempt to link the two specified types together.
+//
+// Inputs:
+//  DestTy - The type to which we wish to resolve.
+//  SrcTy  - The original type which we want to resolve.
+//  Name   - The name of the type.
+//
+// Outputs:
+//  DestST - The symbol table in which the new type should be placed.
+//
+// Return value:
+//  true  - There is an error and the types cannot yet be linked.
+//  false - No errors.
 //
 static bool ResolveTypes(const Type *DestTy, const Type *SrcTy,
                          SymbolTable *DestST, const std::string &Name) {
@@ -222,7 +239,11 @@ static bool LinkTypes(Module *Dest, const Module *Src, std::string *Err) {
         const Type *T1 = cast<Type>(VM.find(Name)->second);
         const Type *T2 = cast<Type>(DestST->lookup(Type::TypeTy, Name));
         std::cerr << "WARNING: Type conflict between types named '" << Name
-                  <<  "'.\n    Src='" << *T1 << "'.\n   Dest='" << *T2 << "'\n";
+                  <<  "'.\n    Src='";
+        WriteTypeSymbolic(std::cerr, T1, Src);
+        std::cerr << "'.\n   Dest='";
+        WriteTypeSymbolic(std::cerr, T2, Dest);
+        std::cerr << "'\n";
 
         // Remove the symbol name from the destination.
         DelayedTypesToResolve.pop_back();
@@ -263,7 +284,8 @@ static Value *RemapOperand(const Value *In,
 
   // Check to see if it's a constant that we are interesting in transforming...
   if (const Constant *CPV = dyn_cast<Constant>(In)) {
-    if (!isa<DerivedType>(CPV->getType()) && !isa<ConstantExpr>(CPV))
+    if ((!isa<DerivedType>(CPV->getType()) && !isa<ConstantExpr>(CPV)) ||
+        isa<ConstantAggregateZero>(CPV))
       return const_cast<Constant*>(CPV);   // Simple constants stay identical...
 
     Constant *Result = 0;
@@ -309,7 +331,7 @@ static Value *RemapOperand(const Value *In,
         Value *V2 = RemapOperand(CE->getOperand(1), LocalMap, GlobalMap);
 
         Result = ConstantExpr::get(CE->getOpcode(), cast<Constant>(V1),
-                                   cast<Constant>(V2));        
+                                   cast<Constant>(V2));
       } else {
         assert(0 && "Unknown constant expr type!");
       }
@@ -356,13 +378,27 @@ static GlobalValue *FindGlobalNamed(const std::string &Name, const Type *Ty,
   for (SymbolTable::iterator I = ST->begin(), E = ST->end(); I != E; ++I)
     if (I->first != Type::TypeTy) {
       SymbolTable::VarMap &VM = I->second;
+
       // Does this type plane contain an entry with the specified name?
       SymbolTable::type_iterator TI = VM.find(Name);
       if (TI != VM.end()) {
+        //
+        // Ensure that this type if placed correctly into the symbol table.
+        //
+        assert(TI->second->getType() == I->first && "Type conflict!");
+
+        //
+        // Save a reference to the new type.  Resolving the type can modify the
+        // symbol table, invalidating the TI variable.
+        //
+        Value *ValPtr = TI->second;
+
+        //
         // Determine whether we can fold the two types together, resolving them.
         // If so, we can use this value.
+        //
         if (!RecursiveResolveTypes(Ty, I->first, ST, ""))
-          return cast<GlobalValue>(TI->second);
+          return cast<GlobalValue>(ValPtr);
       }
     }
   return 0;  // Otherwise, nothing could be found.
@@ -530,7 +566,6 @@ static bool LinkGlobalInits(Module *Dest, const Module *Src,
 
       GlobalVariable *DGV = cast<GlobalVariable>(ValueMap[SGV]);    
       if (DGV->hasInitializer()) {
-        assert(SGV->getLinkage() == DGV->getLinkage());
         if (SGV->hasExternalLinkage()) {
           if (DGV->getInitializer() != SInit)
             return Error(Err, "Global Variable Collision on '" + 
@@ -539,6 +574,9 @@ static bool LinkGlobalInits(Module *Dest, const Module *Src,
         } else if (DGV->hasLinkOnceLinkage() || DGV->hasWeakLinkage()) {
           // Nothing is required, mapped values will take the new global
           // automatically.
+        } else if (SGV->hasLinkOnceLinkage() || SGV->hasWeakLinkage()) {
+          // Nothing is required, mapped values will take the new global
+          // automatically.
         } else if (DGV->hasAppendingLinkage()) {
           assert(0 && "Appending linkage unimplemented!");
         } else {
@@ -761,12 +799,24 @@ static bool LinkAppendingVars(Module *M,
 
       // Merge the initializer...
       Inits.reserve(NewSize);
-      ConstantArray *I = cast<ConstantArray>(G1->getInitializer());
-      for (unsigned i = 0, e = T1->getNumElements(); i != e; ++i)
-        Inits.push_back(cast<Constant>(I->getValues()[i]));
-      I = cast<ConstantArray>(G2->getInitializer());
-      for (unsigned i = 0, e = T2->getNumElements(); i != e; ++i)
-        Inits.push_back(cast<Constant>(I->getValues()[i]));
+      if (ConstantArray *I = dyn_cast<ConstantArray>(G1->getInitializer())) {
+        for (unsigned i = 0, e = T1->getNumElements(); i != e; ++i)
+          Inits.push_back(cast<Constant>(I->getValues()[i]));
+      } else {
+        assert(isa<ConstantAggregateZero>(G1->getInitializer()));
+        Constant *CV = Constant::getNullValue(T1->getElementType());
+        for (unsigned i = 0, e = T1->getNumElements(); i != e; ++i)
+          Inits.push_back(CV);
+      }
+      if (ConstantArray *I = dyn_cast<ConstantArray>(G2->getInitializer())) {
+        for (unsigned i = 0, e = T2->getNumElements(); i != e; ++i)
+          Inits.push_back(cast<Constant>(I->getValues()[i]));
+      } else {
+        assert(isa<ConstantAggregateZero>(G2->getInitializer()));
+        Constant *CV = Constant::getNullValue(T2->getElementType());
+        for (unsigned i = 0, e = T2->getNumElements(); i != e; ++i)
+          Inits.push_back(CV);
+      }
       NG->setInitializer(ConstantArray::get(NewType, Inits));
       Inits.clear();
 
@@ -800,7 +850,7 @@ static bool LinkAppendingVars(Module *M,
 // the problem.  Upon failure, the Dest module could be in a modified state, and
 // shouldn't be relied on to be consistent.
 //
-bool LinkModules(Module *Dest, const Module *Src, std::string *ErrorMsg) {
+bool llvm::LinkModules(Module *Dest, const Module *Src, std::string *ErrorMsg) {
   if (Dest->getEndianness() == Module::AnyEndianness)
     Dest->setEndianness(Src->getEndianness());
   if (Dest->getPointerSize() == Module::AnyPointerSize)