From 6cb8c23db1c3becdce6dfbf1b7f1677faca4251e Mon Sep 17 00:00:00 2001 From: Dan Gohman Date: Thu, 26 Aug 2010 15:41:53 +0000 Subject: [PATCH] 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 --- include/llvm/Transforms/Utils/Cloning.h | 15 +++- include/llvm/Transforms/Utils/ValueMapper.h | 6 +- lib/Linker/LinkModules.cpp | 27 ++++++- lib/Target/PIC16/PIC16Passes/PIC16Cloner.cpp | 2 +- lib/Transforms/IPO/PartialInlining.cpp | 3 +- lib/Transforms/IPO/PartialSpecialization.cpp | 3 +- lib/Transforms/Utils/CloneFunction.cpp | 26 ++++--- lib/Transforms/Utils/CloneModule.cpp | 24 ++---- lib/Transforms/Utils/InlineFunction.cpp | 3 +- lib/Transforms/Utils/ValueMapper.cpp | 82 +++++++++++++++----- test/Linker/metadata-a.ll | 15 ++++ test/Linker/metadata-b.ll | 9 +++ 12 files changed, 154 insertions(+), 61 deletions(-) create mode 100644 test/Linker/metadata-a.ll create mode 100644 test/Linker/metadata-b.ll diff --git a/include/llvm/Transforms/Utils/Cloning.h b/include/llvm/Transforms/Utils/Cloning.h index 1ca4981ccbb..62bf92aced4 100644 --- a/include/llvm/Transforms/Utils/Cloning.h +++ b/include/llvm/Transforms/Utils/Cloning.h @@ -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 &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 &VMap, + bool ModuleLevelChanges, SmallVectorImpl &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 &VMap, + bool ModuleLevelChanges, SmallVectorImpl &Returns, const char *NameSuffix = "", ClonedCodeInfo *CodeInfo = 0, diff --git a/include/llvm/Transforms/Utils/ValueMapper.h b/include/llvm/Transforms/Utils/ValueMapper.h index b219e8e59d1..5274112897b 100644 --- a/include/llvm/Transforms/Utils/ValueMapper.h +++ b/include/llvm/Transforms/Utils/ValueMapper.h @@ -22,8 +22,10 @@ namespace llvm { class Instruction; typedef ValueMap 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 diff --git a/lib/Linker/LinkModules.cpp b/lib/Linker/LinkModules.cpp index 89f4cdc2296..19d22475f65 100644 --- a/lib/Linker/LinkModules.cpp +++ b/lib/Linker/LinkModules.cpp @@ -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(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(MapValue(SGV->getInitializer(), ValueMap)); + cast(MapValue(SGV->getInitializer(), ValueMap, true)); // Grab destination global variable or alias. GlobalValue *DGV = cast(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(*OI) && !isa(*OI)) - *OI = MapValue(*OI, ValueMap); + *OI = MapValue(*OI, ValueMap, true); + + // Remap attached metadata. + SmallVector, 4> MDs; + I->getAllMetadata(MDs); + for (SmallVectorImpl >::iterator + MI = MDs.begin(), ME = MDs.end(); MI != ME; ++MI) { + Value *Old = MI->second; + if (!isa(Old) && !isa(Old)) { + Value *New = MapValue(Old, ValueMap, true); + if (New != Old) + I->setMetadata(MI->first, cast(New)); + } + } + } // There is no need to map the arguments anymore. for (Function::arg_iterator I = Src->arg_begin(), E = Src->arg_end(); diff --git a/lib/Target/PIC16/PIC16Passes/PIC16Cloner.cpp b/lib/Target/PIC16/PIC16Passes/PIC16Cloner.cpp index 27f1cf572ae..56f02115709 100644 --- a/lib/Target/PIC16/PIC16Passes/PIC16Cloner.cpp +++ b/lib/Target/PIC16/PIC16Passes/PIC16Cloner.cpp @@ -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. diff --git a/lib/Transforms/IPO/PartialInlining.cpp b/lib/Transforms/IPO/PartialInlining.cpp index eba7b3ae4d1..432f7c53a67 100644 --- a/lib/Transforms/IPO/PartialInlining.cpp +++ b/lib/Transforms/IPO/PartialInlining.cpp @@ -68,7 +68,8 @@ Function* PartialInliner::unswitchFunction(Function* F) { // Clone the function, so that we can hack away on it. ValueMap 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(VMap[entryBlock]); diff --git a/lib/Transforms/IPO/PartialSpecialization.cpp b/lib/Transforms/IPO/PartialSpecialization.cpp index 17245c7acd3..4a99a411ab3 100644 --- a/lib/Transforms/IPO/PartialSpecialization.cpp +++ b/lib/Transforms/IPO/PartialSpecialization.cpp @@ -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); diff --git a/lib/Transforms/Utils/CloneFunction.cpp b/lib/Transforms/Utils/CloneFunction.cpp index c5c62bfd241..f43186edae4 100644 --- a/lib/Transforms/Utils/CloneFunction.cpp +++ b/lib/Transforms/Utils/CloneFunction.cpp @@ -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 &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 ArgTypes; @@ -167,7 +169,7 @@ Function *llvm::CloneFunction(const Function *F, } SmallVector 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 &Returns; const char *NameSuffix; ClonedCodeInfo *CodeInfo; @@ -187,12 +190,14 @@ namespace { public: PruningFunctionCloner(Function *newFunc, const Function *oldFunc, ValueToValueMapTy &valueMap, + bool moduleLevelChanges, SmallVectorImpl &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 Ops; for (unsigned i = 0, e = I->getNumOperands(); i != e; ++i) if (Constant *Op = dyn_cast_or_null(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 &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 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(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); diff --git a/lib/Transforms/Utils/CloneModule.cpp b/lib/Transforms/Utils/CloneModule.cpp index 25083adb7ce..b347bf597f8 100644 --- a/lib/Transforms/Utils/CloneModule.cpp +++ b/lib/Transforms/Utils/CloneModule.cpp @@ -89,7 +89,8 @@ Module *llvm::CloneModule(const Module *M, GlobalVariable *GV = cast(VMap[I]); if (I->hasInitializer()) GV->setInitializer(cast(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 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(VMap[I]); GA->setLinkage(I->getLinkage()); if (const Constant* C = I->getAliasee()) - GA->setAliasee(cast(MapValue(C, VMap))); + GA->setAliasee(cast(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(MapValue(NMD.getOperand(i), VMap))); + NewNMD->addOperand(cast(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, 4 > MDs; - BI->getAllMetadata(MDs); - for (SmallVector, 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(MappedValue)); - } - } return New; } diff --git a/lib/Transforms/Utils/InlineFunction.cpp b/lib/Transforms/Utils/InlineFunction.cpp index b7677b5a3c3..88979e862df 100644 --- a/lib/Transforms/Utils/InlineFunction.cpp +++ b/lib/Transforms/Utils/InlineFunction.cpp @@ -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. diff --git a/lib/Transforms/Utils/ValueMapper.cpp b/lib/Transforms/Utils/ValueMapper.cpp index 20e7f79b87d..fc4bde77d4f 100644 --- a/lib/Transforms/Utils/ValueMapper.cpp +++ b/lib/Transforms/Utils/ValueMapper.cpp @@ -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(V) || isa(V) || isa(V) || - (isa(V) && !cast(V)->isFunctionLocal())) + (isa(V) && !cast(V)->isFunctionLocal() && + !ModuleLevelChanges)) return VMSlot = const_cast(V); if (const MDNode *MD = dyn_cast(V)) { - SmallVector 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(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 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(V); } Constant *C = const_cast(dyn_cast(V)); - if (C == 0) return 0; + if (C == 0) + return 0; if (isa(C) || isa(C) || isa(C) || isa(C) || @@ -51,7 +74,7 @@ Value *llvm::MapValue(const Value *V, ValueToValueMapTy &VM) { if (ConstantArray *CA = dyn_cast(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(*j)); Values.push_back(cast(MV)); for (++i; i != e; ++i) - Values.push_back(cast(MapValue(*i, VM))); + Values.push_back(cast(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(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(*j)); Values.push_back(cast(MV)); for (++i; i != e; ++i) - Values.push_back(cast(MapValue(*i, VM))); + Values.push_back(cast(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(C)) { std::vector Ops; for (User::op_iterator i = CE->op_begin(), e = CE->op_end(); i != e; ++i) - Ops.push_back(cast(MapValue(*i, VM))); + Ops.push_back(cast(MapValue(*i, VM, ModuleLevelChanges))); return VM[V] = CE->getWithOperands(Ops); } if (ConstantVector *CV = dyn_cast(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(*j)); Values.push_back(cast(MV)); for (++i; i != e; ++i) - Values.push_back(cast(MapValue(*i, VM))); + Values.push_back(cast(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(C); - Function *F = cast(MapValue(BA->getFunction(), VM)); - BasicBlock *BB = cast_or_null(MapValue(BA->getBasicBlock(),VM)); + Function *F = cast(MapValue(BA->getFunction(), VM, + ModuleLevelChanges)); + BasicBlock *BB = cast_or_null(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, 4> MDs; + I->getAllMetadata(MDs); + for (SmallVectorImpl >::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(New)); + } +} diff --git a/test/Linker/metadata-a.ll b/test/Linker/metadata-a.ll new file mode 100644 index 00000000000..5a9d2e40b94 --- /dev/null +++ b/test/Linker/metadata-a.ll @@ -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} diff --git a/test/Linker/metadata-b.ll b/test/Linker/metadata-b.ll new file mode 100644 index 00000000000..ef0270af075 --- /dev/null +++ b/test/Linker/metadata-b.ll @@ -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} -- 2.34.1