mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2024-12-13 04:30:23 +00:00
Reapply r112091 and r111922, support for metadata linking, with a
fix: add a flag to MapValue and friends which indicates whether any module-level mappings are being made. In the common case of inlining, no module-level mappings are needed, so MapValue doesn't need to examine non-function-local metadata, which can be very expensive in the case of a large module with really deep metadata (e.g. a large C++ program compiled with -g). This flag is a little awkward; perhaps eventually it can be moved into the ClonedCodeInfo class. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@112190 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
837bccd052
commit
6cb8c23db1
@ -121,8 +121,12 @@ Loop *CloneLoop(Loop *L, LPPassManager *LPM, LoopInfo *LI,
|
||||
/// the function from their old to new values. The final argument captures
|
||||
/// information about the cloned code if non-null.
|
||||
///
|
||||
/// If ModuleLevelChanges is false, VMap contains no non-identity GlobalValue
|
||||
/// mappings.
|
||||
///
|
||||
Function *CloneFunction(const Function *F,
|
||||
ValueMap<const Value*, Value*> &VMap,
|
||||
bool ModuleLevelChanges,
|
||||
ClonedCodeInfo *CodeInfo = 0);
|
||||
|
||||
/// CloneFunction - Version of the function that doesn't need the VMap.
|
||||
@ -133,13 +137,17 @@ inline Function *CloneFunction(const Function *F, ClonedCodeInfo *CodeInfo = 0){
|
||||
}
|
||||
|
||||
/// Clone OldFunc into NewFunc, transforming the old arguments into references
|
||||
/// to ArgMap values. Note that if NewFunc already has basic blocks, the ones
|
||||
/// to VMap values. Note that if NewFunc already has basic blocks, the ones
|
||||
/// cloned into it will be added to the end of the function. This function
|
||||
/// fills in a list of return instructions, and can optionally append the
|
||||
/// specified suffix to all values cloned.
|
||||
///
|
||||
/// If ModuleLevelChanges is false, VMap contains no non-identity GlobalValue
|
||||
/// mappings.
|
||||
///
|
||||
void CloneFunctionInto(Function *NewFunc, const Function *OldFunc,
|
||||
ValueMap<const Value*, Value*> &VMap,
|
||||
bool ModuleLevelChanges,
|
||||
SmallVectorImpl<ReturnInst*> &Returns,
|
||||
const char *NameSuffix = "",
|
||||
ClonedCodeInfo *CodeInfo = 0);
|
||||
@ -151,8 +159,13 @@ void CloneFunctionInto(Function *NewFunc, const Function *OldFunc,
|
||||
/// constant arguments cause a significant amount of code in the callee to be
|
||||
/// dead. Since this doesn't produce an exactly copy of the input, it can't be
|
||||
/// used for things like CloneFunction or CloneModule.
|
||||
///
|
||||
/// If ModuleLevelChanges is false, VMap contains no non-identity GlobalValue
|
||||
/// mappings.
|
||||
///
|
||||
void CloneAndPruneFunctionInto(Function *NewFunc, const Function *OldFunc,
|
||||
ValueMap<const Value*, Value*> &VMap,
|
||||
bool ModuleLevelChanges,
|
||||
SmallVectorImpl<ReturnInst*> &Returns,
|
||||
const char *NameSuffix = "",
|
||||
ClonedCodeInfo *CodeInfo = 0,
|
||||
|
@ -22,8 +22,10 @@ namespace llvm {
|
||||
class Instruction;
|
||||
typedef ValueMap<const Value *, Value *> ValueToValueMapTy;
|
||||
|
||||
Value *MapValue(const Value *V, ValueToValueMapTy &VM);
|
||||
void RemapInstruction(Instruction *I, ValueToValueMapTy &VM);
|
||||
Value *MapValue(const Value *V, ValueToValueMapTy &VM,
|
||||
bool ModuleLevelChanges);
|
||||
void RemapInstruction(Instruction *I, ValueToValueMapTy &VM,
|
||||
bool ModuleLevelChanges);
|
||||
} // End llvm namespace
|
||||
|
||||
#endif
|
||||
|
@ -460,7 +460,8 @@ static void LinkNamedMDNodes(Module *Dest, Module *Src,
|
||||
// Add Src elements into Dest node.
|
||||
for (unsigned i = 0, e = SrcNMD->getNumOperands(); i != e; ++i)
|
||||
DestNMD->addOperand(cast<MDNode>(MapValue(SrcNMD->getOperand(i),
|
||||
ValueMap)));
|
||||
ValueMap,
|
||||
true)));
|
||||
}
|
||||
}
|
||||
|
||||
@ -823,7 +824,7 @@ static bool LinkGlobalInits(Module *Dest, const Module *Src,
|
||||
if (SGV->hasInitializer()) { // Only process initialized GV's
|
||||
// Figure out what the initializer looks like in the dest module...
|
||||
Constant *SInit =
|
||||
cast<Constant>(MapValue(SGV->getInitializer(), ValueMap));
|
||||
cast<Constant>(MapValue(SGV->getInitializer(), ValueMap, true));
|
||||
// Grab destination global variable or alias.
|
||||
GlobalValue *DGV = cast<GlobalValue>(ValueMap[SGV]->stripPointerCasts());
|
||||
|
||||
@ -1005,12 +1006,30 @@ static bool LinkFunctionBody(Function *Dest, Function *Src,
|
||||
// the Source function as operands. Loop through all of the operands of the
|
||||
// functions and patch them up to point to the local versions...
|
||||
//
|
||||
// This is the same as RemapInstruction, except that it avoids remapping
|
||||
// instruction and basic block operands.
|
||||
//
|
||||
for (Function::iterator BB = Dest->begin(), BE = Dest->end(); BB != BE; ++BB)
|
||||
for (BasicBlock::iterator I = BB->begin(), E = BB->end(); I != E; ++I)
|
||||
for (BasicBlock::iterator I = BB->begin(), E = BB->end(); I != E; ++I) {
|
||||
// Remap operands.
|
||||
for (Instruction::op_iterator OI = I->op_begin(), OE = I->op_end();
|
||||
OI != OE; ++OI)
|
||||
if (!isa<Instruction>(*OI) && !isa<BasicBlock>(*OI))
|
||||
*OI = MapValue(*OI, ValueMap);
|
||||
*OI = MapValue(*OI, ValueMap, true);
|
||||
|
||||
// Remap attached metadata.
|
||||
SmallVector<std::pair<unsigned, MDNode *>, 4> MDs;
|
||||
I->getAllMetadata(MDs);
|
||||
for (SmallVectorImpl<std::pair<unsigned, MDNode *> >::iterator
|
||||
MI = MDs.begin(), ME = MDs.end(); MI != ME; ++MI) {
|
||||
Value *Old = MI->second;
|
||||
if (!isa<Instruction>(Old) && !isa<BasicBlock>(Old)) {
|
||||
Value *New = MapValue(Old, ValueMap, true);
|
||||
if (New != Old)
|
||||
I->setMetadata(MI->first, cast<MDNode>(New));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// There is no need to map the arguments anymore.
|
||||
for (Function::arg_iterator I = Src->arg_begin(), E = Src->arg_end();
|
||||
|
@ -256,7 +256,7 @@ PIC16Cloner::cloneFunction(Function *OrgF) {
|
||||
CloneAutos(OrgF);
|
||||
|
||||
// Now create the clone.
|
||||
ClonedF = CloneFunction(OrgF, VMap);
|
||||
ClonedF = CloneFunction(OrgF, VMap, /*ModuleLevelChanges=*/false);
|
||||
|
||||
// The new function should be for interrupt line. Therefore should have
|
||||
// the name suffixed with IL and section attribute marked with IL.
|
||||
|
@ -68,7 +68,8 @@ Function* PartialInliner::unswitchFunction(Function* F) {
|
||||
|
||||
// Clone the function, so that we can hack away on it.
|
||||
ValueMap<const Value*, Value*> VMap;
|
||||
Function* duplicateFunction = CloneFunction(F, VMap);
|
||||
Function* duplicateFunction = CloneFunction(F, VMap,
|
||||
/*ModuleLevelChanges=*/false);
|
||||
duplicateFunction->setLinkage(GlobalValue::InternalLinkage);
|
||||
F->getParent()->getFunctionList().push_back(duplicateFunction);
|
||||
BasicBlock* newEntryBlock = cast<BasicBlock>(VMap[entryBlock]);
|
||||
|
@ -74,7 +74,8 @@ SpecializeFunction(Function* F,
|
||||
deleted[arg->getArgNo()] = arg;
|
||||
}
|
||||
|
||||
Function* NF = CloneFunction(F, replacements);
|
||||
Function* NF = CloneFunction(F, replacements,
|
||||
/*ModuleLevelChanges=*/false);
|
||||
NF->setLinkage(GlobalValue::InternalLinkage);
|
||||
F->getParent()->getFunctionList().push_back(NF);
|
||||
|
||||
|
@ -69,10 +69,11 @@ BasicBlock *llvm::CloneBasicBlock(const BasicBlock *BB,
|
||||
}
|
||||
|
||||
// Clone OldFunc into NewFunc, transforming the old arguments into references to
|
||||
// ArgMap values.
|
||||
// VMap values.
|
||||
//
|
||||
void llvm::CloneFunctionInto(Function *NewFunc, const Function *OldFunc,
|
||||
ValueToValueMapTy &VMap,
|
||||
bool ModuleLevelChanges,
|
||||
SmallVectorImpl<ReturnInst*> &Returns,
|
||||
const char *NameSuffix, ClonedCodeInfo *CodeInfo) {
|
||||
assert(NameSuffix && "NameSuffix cannot be null!");
|
||||
@ -126,7 +127,7 @@ void llvm::CloneFunctionInto(Function *NewFunc, const Function *OldFunc,
|
||||
BE = NewFunc->end(); BB != BE; ++BB)
|
||||
// Loop over all instructions, fixing each one as we find it...
|
||||
for (BasicBlock::iterator II = BB->begin(); II != BB->end(); ++II)
|
||||
RemapInstruction(II, VMap);
|
||||
RemapInstruction(II, VMap, ModuleLevelChanges);
|
||||
}
|
||||
|
||||
/// CloneFunction - Return a copy of the specified function, but without
|
||||
@ -139,6 +140,7 @@ void llvm::CloneFunctionInto(Function *NewFunc, const Function *OldFunc,
|
||||
///
|
||||
Function *llvm::CloneFunction(const Function *F,
|
||||
ValueToValueMapTy &VMap,
|
||||
bool ModuleLevelChanges,
|
||||
ClonedCodeInfo *CodeInfo) {
|
||||
std::vector<const Type*> ArgTypes;
|
||||
|
||||
@ -167,7 +169,7 @@ Function *llvm::CloneFunction(const Function *F,
|
||||
}
|
||||
|
||||
SmallVector<ReturnInst*, 8> Returns; // Ignore returns cloned.
|
||||
CloneFunctionInto(NewF, F, VMap, Returns, "", CodeInfo);
|
||||
CloneFunctionInto(NewF, F, VMap, ModuleLevelChanges, Returns, "", CodeInfo);
|
||||
return NewF;
|
||||
}
|
||||
|
||||
@ -180,6 +182,7 @@ namespace {
|
||||
Function *NewFunc;
|
||||
const Function *OldFunc;
|
||||
ValueToValueMapTy &VMap;
|
||||
bool ModuleLevelChanges;
|
||||
SmallVectorImpl<ReturnInst*> &Returns;
|
||||
const char *NameSuffix;
|
||||
ClonedCodeInfo *CodeInfo;
|
||||
@ -187,12 +190,14 @@ namespace {
|
||||
public:
|
||||
PruningFunctionCloner(Function *newFunc, const Function *oldFunc,
|
||||
ValueToValueMapTy &valueMap,
|
||||
bool moduleLevelChanges,
|
||||
SmallVectorImpl<ReturnInst*> &returns,
|
||||
const char *nameSuffix,
|
||||
ClonedCodeInfo *codeInfo,
|
||||
const TargetData *td)
|
||||
: NewFunc(newFunc), OldFunc(oldFunc), VMap(valueMap), Returns(returns),
|
||||
NameSuffix(nameSuffix), CodeInfo(codeInfo), TD(td) {
|
||||
: NewFunc(newFunc), OldFunc(oldFunc),
|
||||
VMap(valueMap), ModuleLevelChanges(moduleLevelChanges),
|
||||
Returns(returns), NameSuffix(nameSuffix), CodeInfo(codeInfo), TD(td) {
|
||||
}
|
||||
|
||||
/// CloneBlock - The specified block is found to be reachable, clone it and
|
||||
@ -313,7 +318,7 @@ ConstantFoldMappedInstruction(const Instruction *I) {
|
||||
SmallVector<Constant*, 8> Ops;
|
||||
for (unsigned i = 0, e = I->getNumOperands(); i != e; ++i)
|
||||
if (Constant *Op = dyn_cast_or_null<Constant>(MapValue(I->getOperand(i),
|
||||
VMap)))
|
||||
VMap, ModuleLevelChanges)))
|
||||
Ops.push_back(Op);
|
||||
else
|
||||
return 0; // All operands not constant!
|
||||
@ -355,6 +360,7 @@ UpdateInlinedAtInfo(const DebugLoc &InsnDL, const DebugLoc &TheCallDL,
|
||||
/// used for things like CloneFunction or CloneModule.
|
||||
void llvm::CloneAndPruneFunctionInto(Function *NewFunc, const Function *OldFunc,
|
||||
ValueToValueMapTy &VMap,
|
||||
bool ModuleLevelChanges,
|
||||
SmallVectorImpl<ReturnInst*> &Returns,
|
||||
const char *NameSuffix,
|
||||
ClonedCodeInfo *CodeInfo,
|
||||
@ -368,8 +374,8 @@ void llvm::CloneAndPruneFunctionInto(Function *NewFunc, const Function *OldFunc,
|
||||
assert(VMap.count(II) && "No mapping from source argument specified!");
|
||||
#endif
|
||||
|
||||
PruningFunctionCloner PFC(NewFunc, OldFunc, VMap, Returns,
|
||||
NameSuffix, CodeInfo, TD);
|
||||
PruningFunctionCloner PFC(NewFunc, OldFunc, VMap, ModuleLevelChanges,
|
||||
Returns, NameSuffix, CodeInfo, TD);
|
||||
|
||||
// Clone the entry block, and anything recursively reachable from it.
|
||||
std::vector<const BasicBlock*> CloneWorklist;
|
||||
@ -449,7 +455,7 @@ void llvm::CloneAndPruneFunctionInto(Function *NewFunc, const Function *OldFunc,
|
||||
I->setDebugLoc(DebugLoc());
|
||||
}
|
||||
}
|
||||
RemapInstruction(I, VMap);
|
||||
RemapInstruction(I, VMap, ModuleLevelChanges);
|
||||
}
|
||||
}
|
||||
|
||||
@ -471,7 +477,7 @@ void llvm::CloneAndPruneFunctionInto(Function *NewFunc, const Function *OldFunc,
|
||||
if (BasicBlock *MappedBlock =
|
||||
cast_or_null<BasicBlock>(VMap[PN->getIncomingBlock(pred)])) {
|
||||
Value *InVal = MapValue(PN->getIncomingValue(pred),
|
||||
VMap);
|
||||
VMap, ModuleLevelChanges);
|
||||
assert(InVal && "Unknown input value?");
|
||||
PN->setIncomingValue(pred, InVal);
|
||||
PN->setIncomingBlock(pred, MappedBlock);
|
||||
|
@ -89,7 +89,8 @@ Module *llvm::CloneModule(const Module *M,
|
||||
GlobalVariable *GV = cast<GlobalVariable>(VMap[I]);
|
||||
if (I->hasInitializer())
|
||||
GV->setInitializer(cast<Constant>(MapValue(I->getInitializer(),
|
||||
VMap)));
|
||||
VMap,
|
||||
true)));
|
||||
GV->setLinkage(I->getLinkage());
|
||||
GV->setThreadLocal(I->isThreadLocal());
|
||||
GV->setConstant(I->isConstant());
|
||||
@ -108,7 +109,7 @@ Module *llvm::CloneModule(const Module *M,
|
||||
}
|
||||
|
||||
SmallVector<ReturnInst*, 8> Returns; // Ignore returns cloned.
|
||||
CloneFunctionInto(F, I, VMap, Returns);
|
||||
CloneFunctionInto(F, I, VMap, /*ModuleLevelChanges=*/true, Returns);
|
||||
}
|
||||
|
||||
F->setLinkage(I->getLinkage());
|
||||
@ -120,7 +121,7 @@ Module *llvm::CloneModule(const Module *M,
|
||||
GlobalAlias *GA = cast<GlobalAlias>(VMap[I]);
|
||||
GA->setLinkage(I->getLinkage());
|
||||
if (const Constant* C = I->getAliasee())
|
||||
GA->setAliasee(cast<Constant>(MapValue(C, VMap)));
|
||||
GA->setAliasee(cast<Constant>(MapValue(C, VMap, true)));
|
||||
}
|
||||
|
||||
// And named metadata....
|
||||
@ -129,23 +130,8 @@ Module *llvm::CloneModule(const Module *M,
|
||||
const NamedMDNode &NMD = *I;
|
||||
NamedMDNode *NewNMD = New->getOrInsertNamedMetadata(NMD.getName());
|
||||
for (unsigned i = 0, e = NMD.getNumOperands(); i != e; ++i)
|
||||
NewNMD->addOperand(cast<MDNode>(MapValue(NMD.getOperand(i), VMap)));
|
||||
NewNMD->addOperand(cast<MDNode>(MapValue(NMD.getOperand(i), VMap, true)));
|
||||
}
|
||||
|
||||
// Update metadata attach with instructions.
|
||||
for (Module::iterator MI = New->begin(), ME = New->end(); MI != ME; ++MI)
|
||||
for (Function::iterator FI = MI->begin(), FE = MI->end();
|
||||
FI != FE; ++FI)
|
||||
for (BasicBlock::iterator BI = FI->begin(), BE = FI->end();
|
||||
BI != BE; ++BI) {
|
||||
SmallVector<std::pair<unsigned, MDNode *>, 4 > MDs;
|
||||
BI->getAllMetadata(MDs);
|
||||
for (SmallVector<std::pair<unsigned, MDNode *>, 4>::iterator
|
||||
MDI = MDs.begin(), MDE = MDs.end(); MDI != MDE; ++MDI) {
|
||||
Value *MappedValue = MapValue(MDI->second, VMap);
|
||||
if (MDI->second != MappedValue && MappedValue)
|
||||
BI->setMetadata(MDI->first, cast<MDNode>(MappedValue));
|
||||
}
|
||||
}
|
||||
return New;
|
||||
}
|
||||
|
@ -365,7 +365,8 @@ bool llvm::InlineFunction(CallSite CS, InlineFunctionInfo &IFI) {
|
||||
// have no dead or constant instructions leftover after inlining occurs
|
||||
// (which can happen, e.g., because an argument was constant), but we'll be
|
||||
// happy with whatever the cloner can do.
|
||||
CloneAndPruneFunctionInto(Caller, CalledFunc, VMap, Returns, ".i",
|
||||
CloneAndPruneFunctionInto(Caller, CalledFunc, VMap,
|
||||
/*ModuleLevelChanges=*/false, Returns, ".i",
|
||||
&InlinedFunctionInfo, IFI.TD, TheCall);
|
||||
|
||||
// Remember the first block that is newly cloned over.
|
||||
|
@ -20,28 +20,51 @@
|
||||
#include "llvm/ADT/SmallVector.h"
|
||||
using namespace llvm;
|
||||
|
||||
Value *llvm::MapValue(const Value *V, ValueToValueMapTy &VM) {
|
||||
Value *llvm::MapValue(const Value *V, ValueToValueMapTy &VM,
|
||||
bool ModuleLevelChanges) {
|
||||
Value *&VMSlot = VM[V];
|
||||
if (VMSlot) return VMSlot; // Does it exist in the map yet?
|
||||
|
||||
// NOTE: VMSlot can be invalidated by any reference to VM, which can grow the
|
||||
// DenseMap. This includes any recursive calls to MapValue.
|
||||
|
||||
// Global values and non-function-local metadata do not need to be seeded into
|
||||
// the VM if they are using the identity mapping.
|
||||
// Global values do not need to be seeded into the VM if they
|
||||
// are using the identity mapping.
|
||||
if (isa<GlobalValue>(V) || isa<InlineAsm>(V) || isa<MDString>(V) ||
|
||||
(isa<MDNode>(V) && !cast<MDNode>(V)->isFunctionLocal()))
|
||||
(isa<MDNode>(V) && !cast<MDNode>(V)->isFunctionLocal() &&
|
||||
!ModuleLevelChanges))
|
||||
return VMSlot = const_cast<Value*>(V);
|
||||
|
||||
if (const MDNode *MD = dyn_cast<MDNode>(V)) {
|
||||
SmallVector<Value*, 4> Elts;
|
||||
for (unsigned i = 0, e = MD->getNumOperands(); i != e; ++i)
|
||||
Elts.push_back(MD->getOperand(i) ? MapValue(MD->getOperand(i), VM) : 0);
|
||||
return VM[V] = MDNode::get(V->getContext(), Elts.data(), Elts.size());
|
||||
// Start by assuming that we'll use the identity mapping.
|
||||
VMSlot = const_cast<Value*>(V);
|
||||
|
||||
// Check all operands to see if any need to be remapped.
|
||||
for (unsigned i = 0, e = MD->getNumOperands(); i != e; ++i) {
|
||||
Value *OP = MD->getOperand(i);
|
||||
if (!OP || MapValue(OP, VM, ModuleLevelChanges) == OP) continue;
|
||||
|
||||
// Ok, at least one operand needs remapping.
|
||||
MDNode *Dummy = MDNode::getTemporary(V->getContext(), 0, 0);
|
||||
VM[V] = Dummy;
|
||||
SmallVector<Value*, 4> Elts;
|
||||
Elts.reserve(MD->getNumOperands());
|
||||
for (i = 0; i != e; ++i)
|
||||
Elts.push_back(MD->getOperand(i) ?
|
||||
MapValue(MD->getOperand(i), VM, ModuleLevelChanges) : 0);
|
||||
MDNode *NewMD = MDNode::get(V->getContext(), Elts.data(), Elts.size());
|
||||
Dummy->replaceAllUsesWith(NewMD);
|
||||
MDNode::deleteTemporary(Dummy);
|
||||
return VM[V] = NewMD;
|
||||
}
|
||||
|
||||
// No operands needed remapping; keep the identity map.
|
||||
return const_cast<Value*>(V);
|
||||
}
|
||||
|
||||
Constant *C = const_cast<Constant*>(dyn_cast<Constant>(V));
|
||||
if (C == 0) return 0;
|
||||
if (C == 0)
|
||||
return 0;
|
||||
|
||||
if (isa<ConstantInt>(C) || isa<ConstantFP>(C) ||
|
||||
isa<ConstantPointerNull>(C) || isa<ConstantAggregateZero>(C) ||
|
||||
@ -51,7 +74,7 @@ Value *llvm::MapValue(const Value *V, ValueToValueMapTy &VM) {
|
||||
if (ConstantArray *CA = dyn_cast<ConstantArray>(C)) {
|
||||
for (User::op_iterator b = CA->op_begin(), i = b, e = CA->op_end();
|
||||
i != e; ++i) {
|
||||
Value *MV = MapValue(*i, VM);
|
||||
Value *MV = MapValue(*i, VM, ModuleLevelChanges);
|
||||
if (MV != *i) {
|
||||
// This array must contain a reference to a global, make a new array
|
||||
// and return it.
|
||||
@ -62,7 +85,8 @@ Value *llvm::MapValue(const Value *V, ValueToValueMapTy &VM) {
|
||||
Values.push_back(cast<Constant>(*j));
|
||||
Values.push_back(cast<Constant>(MV));
|
||||
for (++i; i != e; ++i)
|
||||
Values.push_back(cast<Constant>(MapValue(*i, VM)));
|
||||
Values.push_back(cast<Constant>(MapValue(*i, VM,
|
||||
ModuleLevelChanges)));
|
||||
return VM[V] = ConstantArray::get(CA->getType(), Values);
|
||||
}
|
||||
}
|
||||
@ -72,7 +96,7 @@ Value *llvm::MapValue(const Value *V, ValueToValueMapTy &VM) {
|
||||
if (ConstantStruct *CS = dyn_cast<ConstantStruct>(C)) {
|
||||
for (User::op_iterator b = CS->op_begin(), i = b, e = CS->op_end();
|
||||
i != e; ++i) {
|
||||
Value *MV = MapValue(*i, VM);
|
||||
Value *MV = MapValue(*i, VM, ModuleLevelChanges);
|
||||
if (MV != *i) {
|
||||
// This struct must contain a reference to a global, make a new struct
|
||||
// and return it.
|
||||
@ -83,7 +107,8 @@ Value *llvm::MapValue(const Value *V, ValueToValueMapTy &VM) {
|
||||
Values.push_back(cast<Constant>(*j));
|
||||
Values.push_back(cast<Constant>(MV));
|
||||
for (++i; i != e; ++i)
|
||||
Values.push_back(cast<Constant>(MapValue(*i, VM)));
|
||||
Values.push_back(cast<Constant>(MapValue(*i, VM,
|
||||
ModuleLevelChanges)));
|
||||
return VM[V] = ConstantStruct::get(CS->getType(), Values);
|
||||
}
|
||||
}
|
||||
@ -93,14 +118,14 @@ Value *llvm::MapValue(const Value *V, ValueToValueMapTy &VM) {
|
||||
if (ConstantExpr *CE = dyn_cast<ConstantExpr>(C)) {
|
||||
std::vector<Constant*> Ops;
|
||||
for (User::op_iterator i = CE->op_begin(), e = CE->op_end(); i != e; ++i)
|
||||
Ops.push_back(cast<Constant>(MapValue(*i, VM)));
|
||||
Ops.push_back(cast<Constant>(MapValue(*i, VM, ModuleLevelChanges)));
|
||||
return VM[V] = CE->getWithOperands(Ops);
|
||||
}
|
||||
|
||||
if (ConstantVector *CV = dyn_cast<ConstantVector>(C)) {
|
||||
for (User::op_iterator b = CV->op_begin(), i = b, e = CV->op_end();
|
||||
i != e; ++i) {
|
||||
Value *MV = MapValue(*i, VM);
|
||||
Value *MV = MapValue(*i, VM, ModuleLevelChanges);
|
||||
if (MV != *i) {
|
||||
// This vector value must contain a reference to a global, make a new
|
||||
// vector constant and return it.
|
||||
@ -111,7 +136,8 @@ Value *llvm::MapValue(const Value *V, ValueToValueMapTy &VM) {
|
||||
Values.push_back(cast<Constant>(*j));
|
||||
Values.push_back(cast<Constant>(MV));
|
||||
for (++i; i != e; ++i)
|
||||
Values.push_back(cast<Constant>(MapValue(*i, VM)));
|
||||
Values.push_back(cast<Constant>(MapValue(*i, VM,
|
||||
ModuleLevelChanges)));
|
||||
return VM[V] = ConstantVector::get(Values);
|
||||
}
|
||||
}
|
||||
@ -119,19 +145,33 @@ Value *llvm::MapValue(const Value *V, ValueToValueMapTy &VM) {
|
||||
}
|
||||
|
||||
BlockAddress *BA = cast<BlockAddress>(C);
|
||||
Function *F = cast<Function>(MapValue(BA->getFunction(), VM));
|
||||
BasicBlock *BB = cast_or_null<BasicBlock>(MapValue(BA->getBasicBlock(),VM));
|
||||
Function *F = cast<Function>(MapValue(BA->getFunction(), VM,
|
||||
ModuleLevelChanges));
|
||||
BasicBlock *BB = cast_or_null<BasicBlock>(MapValue(BA->getBasicBlock(),VM,
|
||||
ModuleLevelChanges));
|
||||
return VM[V] = BlockAddress::get(F, BB ? BB : BA->getBasicBlock());
|
||||
}
|
||||
|
||||
/// RemapInstruction - Convert the instruction operands from referencing the
|
||||
/// current values into those specified by VMap.
|
||||
///
|
||||
void llvm::RemapInstruction(Instruction *I, ValueToValueMapTy &VMap) {
|
||||
void llvm::RemapInstruction(Instruction *I, ValueToValueMapTy &VMap,
|
||||
bool ModuleLevelChanges) {
|
||||
// Remap operands.
|
||||
for (User::op_iterator op = I->op_begin(), E = I->op_end(); op != E; ++op) {
|
||||
Value *V = MapValue(*op, VMap);
|
||||
Value *V = MapValue(*op, VMap, ModuleLevelChanges);
|
||||
assert(V && "Referenced value not in value map!");
|
||||
*op = V;
|
||||
}
|
||||
}
|
||||
|
||||
// Remap attached metadata.
|
||||
SmallVector<std::pair<unsigned, MDNode *>, 4> MDs;
|
||||
I->getAllMetadata(MDs);
|
||||
for (SmallVectorImpl<std::pair<unsigned, MDNode *> >::iterator
|
||||
MI = MDs.begin(), ME = MDs.end(); MI != ME; ++MI) {
|
||||
Value *Old = MI->second;
|
||||
Value *New = MapValue(Old, VMap, ModuleLevelChanges);
|
||||
if (New != Old)
|
||||
I->setMetadata(MI->first, cast<MDNode>(New));
|
||||
}
|
||||
}
|
||||
|
15
test/Linker/metadata-a.ll
Normal file
15
test/Linker/metadata-a.ll
Normal file
@ -0,0 +1,15 @@
|
||||
; RUN: llvm-link %s %p/metadata-b.ll -S -o - | FileCheck %s
|
||||
|
||||
; CHECK: define void @foo(i32 %a)
|
||||
; CHECK: ret void, !attach !0, !also !{i32 %a}
|
||||
; CHECK: define void @goo(i32 %b)
|
||||
; CHECK: ret void, !attach !1, !and !{i32 %b}
|
||||
; CHECK: !0 = metadata !{i32 524334, void (i32)* @foo}
|
||||
; CHECK: !1 = metadata !{i32 524334, void (i32)* @goo}
|
||||
|
||||
define void @foo(i32 %a) nounwind {
|
||||
entry:
|
||||
ret void, !attach !0, !also !{ i32 %a }
|
||||
}
|
||||
|
||||
!0 = metadata !{i32 524334, void (i32)* @foo}
|
9
test/Linker/metadata-b.ll
Normal file
9
test/Linker/metadata-b.ll
Normal file
@ -0,0 +1,9 @@
|
||||
; This file is for use with metadata-a.ll
|
||||
; RUN: true
|
||||
|
||||
define void @goo(i32 %b) nounwind {
|
||||
entry:
|
||||
ret void, !attach !0, !and !{ i32 %b }
|
||||
}
|
||||
|
||||
!0 = metadata !{i32 524334, void (i32)* @goo}
|
Loading…
Reference in New Issue
Block a user