//===----------------------------------------------------------------------===//
#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...
const SymbolTable *SrcST = &Src->getSymbolTable();
// Look for a type plane for Type's...
- SymbolTable::const_iterator PI = SrcST->find(Type::TypeTy);
- if (PI == SrcST->end()) return false; // No named types, do nothing.
+ SymbolTable::type_const_iterator TI = SrcST->type_begin();
+ SymbolTable::type_const_iterator TE = SrcST->type_end();
+ if (TI == TE) return false; // No named types, do nothing.
// Some types cannot be resolved immediately because they depend on other
// types being resolved to each other first. This contains a list of types we
// are waiting to recheck.
std::vector<std::string> DelayedTypesToResolve;
- const SymbolTable::VarMap &VM = PI->second;
- for (SymbolTable::type_const_iterator I = VM.begin(), E = VM.end();
- I != E; ++I) {
- const std::string &Name = I->first;
- Type *RHS = cast<Type>(I->second);
+ for ( ; TI != TE; ++TI ) {
+ const std::string &Name = TI->first;
+ Type *RHS = TI->second;
// Check to see if this type name is already in the dest module...
- Type *Entry = cast_or_null<Type>(DestST->lookup(Type::TypeTy, Name));
+ Type *Entry = DestST->lookupType(Name);
if (ResolveTypes(Entry, RHS, DestST, Name)) {
// They look different, save the types 'till later to resolve.
// Try direct resolution by name...
for (unsigned i = 0; i != DelayedTypesToResolve.size(); ++i) {
const std::string &Name = DelayedTypesToResolve[i];
- Type *T1 = cast<Type>(VM.find(Name)->second);
- Type *T2 = cast<Type>(DestST->lookup(Type::TypeTy, Name));
+ Type *T1 = SrcST->lookupType(Name);
+ Type *T2 = DestST->lookupType(Name);
if (!ResolveTypes(T2, T1, DestST, Name)) {
// We are making progress!
DelayedTypesToResolve.erase(DelayedTypesToResolve.begin()+i);
// two types: { int* } and { opaque* }
for (unsigned i = 0, e = DelayedTypesToResolve.size(); i != e; ++i) {
const std::string &Name = DelayedTypesToResolve[i];
- PATypeHolder T1(cast<Type>(VM.find(Name)->second));
- PATypeHolder T2(cast<Type>(DestST->lookup(Type::TypeTy, Name)));
+ PATypeHolder T1(SrcST->lookupType(Name));
+ PATypeHolder T2(DestST->lookupType(Name));
if (!RecursiveResolveTypes(T2, T1, DestST, Name)) {
// We are making progress!
if (DelayedTypesToResolve.size() == OldSize) {
const std::string &Name = DelayedTypesToResolve.back();
- const Type *T1 = cast<Type>(VM.find(Name)->second);
- const Type *T2 = cast<Type>(DestST->lookup(Type::TypeTy, Name));
+ const Type *T1 = SrcST->lookupType(Name);
+ const Type *T2 = DestST->lookupType(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();
// 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;
assert(CE->getOpcode() == Instruction::Cast);
Value *V = RemapOperand(CE->getOperand(0), LocalMap, GlobalMap);
Result = ConstantExpr::getCast(cast<Constant>(V), CE->getType());
- } else if (CE->getOpcode() == Instruction::Shl ||
- CE->getOpcode() == Instruction::Shr) { // Shift
+ } else if (CE->getNumOperands() == 3) {
+ // Select instruction
+ assert(CE->getOpcode() == Instruction::Select);
Value *V1 = RemapOperand(CE->getOperand(0), LocalMap, GlobalMap);
Value *V2 = RemapOperand(CE->getOperand(1), LocalMap, GlobalMap);
- Result = ConstantExpr::getShift(CE->getOpcode(), cast<Constant>(V1),
- cast<Constant>(V2));
+ Value *V3 = RemapOperand(CE->getOperand(2), LocalMap, GlobalMap);
+ Result = ConstantExpr::getSelect(cast<Constant>(V1), cast<Constant>(V2),
+ cast<Constant>(V3));
} else if (CE->getNumOperands() == 2) {
// Binary operator...
Value *V1 = RemapOperand(CE->getOperand(0), LocalMap, GlobalMap);
// It doesn't exist exactly, scan through all of the type planes in the symbol
// table, checking each of them for a type-compatible version.
//
- for (SymbolTable::iterator I = ST->begin(), E = ST->end(); I != E; ++I)
- if (I->first != Type::TypeTy) {
- SymbolTable::VarMap &VM = I->second;
+ for (SymbolTable::plane_iterator PI = ST->plane_begin(), PE = ST->plane_end();
+ PI != PE; ++PI) {
+ SymbolTable::ValueMap &VM = PI->second;
- // Does this type plane contain an entry with the specified name?
- SymbolTable::type_iterator TI = VM.find(Name);
- if (TI != VM.end()) {
+ // Does this type plane contain an entry with the specified name?
+ SymbolTable::value_iterator VI = VM.find(Name);
+ if (VI != VM.end()) {
//
// Ensure that this type if placed correctly into the symbol table.
//
- assert(TI->second->getType() == I->first && "Type conflict!");
+ assert(VI->second->getType() == PI->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;
+ Value *ValPtr = VI->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, ""))
+ if (!RecursiveResolveTypes(Ty, PI->first, ST, ""))
return cast<GlobalValue>(ValPtr);
}
}
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 '" +
} 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 {
// 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();
// 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)
return false;
}
+// vim: sw=2