#include "llvm/Transforms/Utils/Linker.h"
#include "llvm/Module.h"
-#include "llvm/Function.h"
-#include "llvm/BasicBlock.h"
-#include "llvm/GlobalVariable.h"
#include "llvm/SymbolTable.h"
#include "llvm/DerivedTypes.h"
#include "llvm/iOther.h"
#include "llvm/Constants.h"
-#include "llvm/Argument.h"
-#include <iostream>
using std::cerr;
using std::string;
using std::map;
// 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()))
+ if (!isa<DerivedType>(CPV->getType()) && !isa<ConstantExpr>(CPV))
return const_cast<Constant*>(CPV); // Simple constants stay identical...
Constant *Result = 0;
if (const ConstantArray *CPA = dyn_cast<ConstantArray>(CPV)) {
const std::vector<Use> &Ops = CPA->getValues();
std::vector<Constant*> Operands(Ops.size());
- for (unsigned i = 0; i < Ops.size(); ++i)
+ for (unsigned i = 0, e = Ops.size(); i != e; ++i)
Operands[i] =
cast<Constant>(RemapOperand(Ops[i], LocalMap, GlobalMap));
Result = ConstantArray::get(cast<ArrayType>(CPA->getType()), Operands);
dyn_cast<ConstantPointerRef>(CPV)) {
Value *V = RemapOperand(CPR->getValue(), LocalMap, GlobalMap);
Result = ConstantPointerRef::get(cast<GlobalValue>(V));
+ } else if (const ConstantExpr *CE = dyn_cast<ConstantExpr>(CPV)) {
+ if (CE->getOpcode() == Instruction::GetElementPtr) {
+ Value *Ptr = RemapOperand(CE->getOperand(0), LocalMap, GlobalMap);
+ std::vector<Constant*> Indices;
+ Indices.reserve(CE->getNumOperands()-1);
+ for (unsigned i = 1, e = CE->getNumOperands(); i != e; ++i)
+ Indices.push_back(cast<Constant>(RemapOperand(CE->getOperand(i),
+ LocalMap, GlobalMap)));
+
+ Result = ConstantExpr::getGetElementPtr(cast<Constant>(Ptr), Indices);
+ } else if (CE->getNumOperands() == 1) {
+ // Cast instruction
+ assert(CE->getOpcode() == Instruction::Cast);
+ Value *V = RemapOperand(CE->getOperand(0), LocalMap, GlobalMap);
+ Result = ConstantExpr::getCast(cast<Constant>(V), CE->getType());
+ } else if (CE->getNumOperands() == 2) {
+ // Binary operator...
+ Value *V1 = RemapOperand(CE->getOperand(0), LocalMap, GlobalMap);
+ Value *V2 = RemapOperand(CE->getOperand(1), LocalMap, GlobalMap);
+
+ Result = ConstantExpr::get(CE->getOpcode(), cast<Constant>(V1),
+ cast<Constant>(V2));
+ } else {
+ assert(0 && "Unknown constant expr type!");
+ }
+
} else {
assert(0 && "Unknown type of derived type constant value!");
}
// Cache the mapping in our local map structure...
- LocalMap.insert(std::make_pair(In, const_cast<Constant*>(CPV)));
+ LocalMap.insert(std::make_pair(In, Result));
return Result;
}
PrintMap(*GlobalMap);
}
- cerr << "Couldn't remap value: " << (void*)In << " ";
- In->dump();
- cerr << "\n";
+ cerr << "Couldn't remap value: " << (void*)In << " " << *In << "\n";
assert(0 && "Couldn't remap value!");
return 0;
}
// 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, string *ErrorMsg = 0) {
+bool LinkModules(Module *Dest, const Module *Src, string *ErrorMsg) {
// LinkTypes - Go through the symbol table of the Src module and see if any
// types are named in the src module that are not named in the Dst module.
// initializers
if (LinkGlobals(Dest, Src, ValueMap, ErrorMsg)) return true;
- // Update the initializers in the Dest module now that all globals that may
- // be referenced are in Dest.
- //
- if (LinkGlobalInits(Dest, Src, ValueMap, ErrorMsg)) return true;
-
// Link the functions together between the two modules, without doing function
// bodies... this just adds external function prototypes to the Dest
// function... We do this so that when we begin processing function bodies,
//
if (LinkFunctionProtos(Dest, Src, ValueMap, ErrorMsg)) return true;
+ // Update the initializers in the Dest module now that all globals that may
+ // be referenced are in Dest.
+ //
+ if (LinkGlobalInits(Dest, Src, ValueMap, ErrorMsg)) return true;
+
// Link in the function bodies that are defined in the source module into the
// DestModule. This consists basically of copying the function over and
// fixing up references to values.