From b5fa5fcecc97168a72c9533c84cf297c018b957c Mon Sep 17 00:00:00 2001 From: Chris Lattner Date: Sat, 8 Jan 2011 08:15:20 +0000 Subject: [PATCH] Revamp the ValueMapper interfaces in a couple ways: 1. Take a flags argument instead of a bool. This makes it more clear to the reader what it is used for. 2. Add a flag that says that "remapping a value not in the map is ok". 3. Reimplement MapValue to share a bunch of code and be a lot more efficient. For lookup failures, don't drop null values into the map. 4. Using the new flag a bunch of code can vaporize in LinkModules and LoopUnswitch, kill it. No functionality change. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@123058 91177308-0d34-0410-b5e6-96231b3b80d8 --- include/llvm/Transforms/Utils/ValueMapper.h | 23 ++- lib/Linker/LinkModules.cpp | 35 +--- lib/Transforms/Scalar/LoopRotation.cpp | 2 +- lib/Transforms/Scalar/LoopUnswitch.cpp | 15 +- lib/Transforms/Utils/CloneFunction.cpp | 22 +-- lib/Transforms/Utils/CloneModule.cpp | 8 +- lib/Transforms/Utils/ValueMapper.cpp | 169 ++++++++------------ 7 files changed, 108 insertions(+), 166 deletions(-) diff --git a/include/llvm/Transforms/Utils/ValueMapper.h b/include/llvm/Transforms/Utils/ValueMapper.h index dd320a3fb4c..d612213a871 100644 --- a/include/llvm/Transforms/Utils/ValueMapper.h +++ b/include/llvm/Transforms/Utils/ValueMapper.h @@ -22,10 +22,29 @@ namespace llvm { class Instruction; typedef ValueMap > ValueToValueMapTy; + /// RemapFlags - These are flags that the value mapping APIs allow. + enum RemapFlags { + RF_None = 0, + + /// RF_NoModuleLevelChanges - If this flag is set, the remapper knows that + /// only local values within a function (such as an instruction or argument) + /// are mapped, not global values like functions and global metadata. + RF_NoModuleLevelChanges = 1, + + /// RF_IgnoreMissingEntries - If this flag is set, the remapper ignores + /// entries that are not in the value map. If it is unset, it aborts if an + /// operand is asked to be remapped which doesn't exist in the mapping. + RF_IgnoreMissingEntries = 2 + }; + + static inline RemapFlags operator|(RemapFlags LHS, RemapFlags RHS) { + return RemapFlags(unsigned(LHS)|unsigned(RHS)); + } + Value *MapValue(const Value *V, ValueToValueMapTy &VM, - bool ModuleLevelChanges); + RemapFlags Flags = RF_None); void RemapInstruction(Instruction *I, ValueToValueMapTy &VM, - bool ModuleLevelChanges); + RemapFlags Flags = RF_None); } // End llvm namespace #endif diff --git a/lib/Linker/LinkModules.cpp b/lib/Linker/LinkModules.cpp index d99e0a06b67..3b3d3a46bc2 100644 --- a/lib/Linker/LinkModules.cpp +++ b/lib/Linker/LinkModules.cpp @@ -451,8 +451,7 @@ 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, - true))); + ValueMap))); } } @@ -814,9 +813,9 @@ static bool LinkGlobalInits(Module *Dest, const Module *Src, const GlobalVariable *SGV = I; if (SGV->hasInitializer()) { // Only process initialized GV's - // Figure out what the initializer looks like in the dest module... + // Figure out what the initializer looks like in the dest module. Constant *SInit = - cast(MapValue(SGV->getInitializer(), ValueMap, true)); + cast(MapValue(SGV->getInitializer(), ValueMap)); // Grab destination global variable or alias. GlobalValue *DGV = cast(ValueMap[SGV]->stripPointerCasts()); @@ -996,32 +995,10 @@ static bool LinkFunctionBody(Function *Dest, Function *Src, // At this point, all of the instructions and values of the function are now // copied over. The only problem is that they are still referencing values in // 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. - // + // functions and patch them up to point to the local versions. for (Function::iterator BB = Dest->begin(), BE = Dest->end(); BB != BE; ++BB) - 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, 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)); - } - } - } + for (BasicBlock::iterator I = BB->begin(), E = BB->end(); I != E; ++I) + RemapInstruction(I, ValueMap, RF_IgnoreMissingEntries); // 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/Transforms/Scalar/LoopRotation.cpp b/lib/Transforms/Scalar/LoopRotation.cpp index ba1a27983bc..4ca422e6209 100644 --- a/lib/Transforms/Scalar/LoopRotation.cpp +++ b/lib/Transforms/Scalar/LoopRotation.cpp @@ -22,7 +22,6 @@ #include "llvm/Transforms/Utils/BasicBlockUtils.h" #include "llvm/Transforms/Utils/SSAUpdater.h" #include "llvm/Transforms/Utils/ValueMapper.h" -#include "llvm/Support/CommandLine.h" #include "llvm/Support/Debug.h" #include "llvm/ADT/Statistic.h" using namespace llvm; @@ -205,6 +204,7 @@ bool LoopRotate::rotateLoop(Loop *Lp, LPPassManager &LPM) { // Otherwise, create a duplicate of the instruction. Instruction *C = Inst->clone(); + C->setName(Inst->getName()); C->insertBefore(LoopEntryBranch); ValueMap[Inst] = C; diff --git a/lib/Transforms/Scalar/LoopUnswitch.cpp b/lib/Transforms/Scalar/LoopUnswitch.cpp index 20d7019c218..0fc416d6746 100644 --- a/lib/Transforms/Scalar/LoopUnswitch.cpp +++ b/lib/Transforms/Scalar/LoopUnswitch.cpp @@ -457,19 +457,6 @@ bool LoopUnswitch::UnswitchIfProfitable(Value *LoopCond, Constant *Val) { return true; } -// RemapInstruction - Convert the instruction operands from referencing the -// current values into those specified by VMap. -// -static inline void RemapInstruction(Instruction *I, - ValueToValueMapTy &VMap) { - for (unsigned op = 0, E = I->getNumOperands(); op != E; ++op) { - Value *Op = I->getOperand(op); - ValueToValueMapTy::iterator It = VMap.find(Op); - if (It != VMap.end()) Op = It->second; - I->setOperand(op, Op); - } -} - /// CloneLoop - Recursively clone the specified loop and all of its children, /// mapping the blocks with the specified map. static Loop *CloneLoop(Loop *L, Loop *PL, ValueToValueMapTy &VM, @@ -664,7 +651,7 @@ void LoopUnswitch::UnswitchNontrivialCondition(Value *LIC, Constant *Val, for (unsigned i = 0, e = NewBlocks.size(); i != e; ++i) for (BasicBlock::iterator I = NewBlocks[i]->begin(), E = NewBlocks[i]->end(); I != E; ++I) - RemapInstruction(I, VMap); + RemapInstruction(I, VMap,RF_NoModuleLevelChanges|RF_IgnoreMissingEntries); // Rewrite the original preheader to select between versions of the loop. BranchInst *OldBR = cast(loopPreheader->getTerminator()); diff --git a/lib/Transforms/Utils/CloneFunction.cpp b/lib/Transforms/Utils/CloneFunction.cpp index 80da08611dc..d967ceb9685 100644 --- a/lib/Transforms/Utils/CloneFunction.cpp +++ b/lib/Transforms/Utils/CloneFunction.cpp @@ -112,8 +112,7 @@ void llvm::CloneFunctionInto(Function *NewFunc, const Function *OldFunc, const BasicBlock &BB = *BI; // Create a new basic block and copy instructions into it! - BasicBlock *CBB = CloneBasicBlock(&BB, VMap, NameSuffix, NewFunc, - CodeInfo); + BasicBlock *CBB = CloneBasicBlock(&BB, VMap, NameSuffix, NewFunc, CodeInfo); VMap[&BB] = CBB; // Add basic block mapping. if (ReturnInst *RI = dyn_cast(CBB->getTerminator())) @@ -122,12 +121,12 @@ void llvm::CloneFunctionInto(Function *NewFunc, const Function *OldFunc, // Loop over all of the instructions in the function, fixing up operand // references as we go. This uses VMap to do all the hard work. - // for (Function::iterator BB = cast(VMap[OldFunc->begin()]), 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, ModuleLevelChanges); + RemapInstruction(II, VMap, + ModuleLevelChanges ? RF_None : RF_NoModuleLevelChanges); } /// CloneFunction - Return a copy of the specified function, but without @@ -138,8 +137,7 @@ void llvm::CloneFunctionInto(Function *NewFunc, const Function *OldFunc, /// updated to include mappings from all of the instructions and basicblocks in /// the function from their old to new values. /// -Function *llvm::CloneFunction(const Function *F, - ValueToValueMapTy &VMap, +Function *llvm::CloneFunction(const Function *F, ValueToValueMapTy &VMap, bool ModuleLevelChanges, ClonedCodeInfo *CodeInfo) { std::vector ArgTypes; @@ -322,7 +320,8 @@ 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, ModuleLevelChanges))) + VMap, + ModuleLevelChanges ? RF_None : RF_NoModuleLevelChanges))) Ops.push_back(Op); else return 0; // All operands not constant! @@ -460,7 +459,8 @@ void llvm::CloneAndPruneFunctionInto(Function *NewFunc, const Function *OldFunc, I->setDebugLoc(DebugLoc()); } } - RemapInstruction(I, VMap, ModuleLevelChanges); + RemapInstruction(I, VMap, + ModuleLevelChanges ? RF_None : RF_NoModuleLevelChanges); } } @@ -480,10 +480,10 @@ void llvm::CloneAndPruneFunctionInto(Function *NewFunc, const Function *OldFunc, PHINode *PN = cast(VMap[OPN]); for (unsigned pred = 0, e = NumPreds; pred != e; ++pred) { Value *V = VMap[PN->getIncomingBlock(pred)]; - if (BasicBlock *MappedBlock = - cast_or_null(V)) { + if (BasicBlock *MappedBlock = cast_or_null(V)) { Value *InVal = MapValue(PN->getIncomingValue(pred), - VMap, ModuleLevelChanges); + VMap, + ModuleLevelChanges ? RF_None : RF_NoModuleLevelChanges); 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 b347bf597f8..1046c38ec01 100644 --- a/lib/Transforms/Utils/CloneModule.cpp +++ b/lib/Transforms/Utils/CloneModule.cpp @@ -89,8 +89,7 @@ Module *llvm::CloneModule(const Module *M, GlobalVariable *GV = cast(VMap[I]); if (I->hasInitializer()) GV->setInitializer(cast(MapValue(I->getInitializer(), - VMap, - true))); + VMap, RF_None))); GV->setLinkage(I->getLinkage()); GV->setThreadLocal(I->isThreadLocal()); GV->setConstant(I->isConstant()); @@ -121,7 +120,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, true))); + GA->setAliasee(cast(MapValue(C, VMap, RF_None))); } // And named metadata.... @@ -130,7 +129,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, true))); + NewNMD->addOperand(cast(MapValue(NMD.getOperand(i), VMap, + RF_None))); } return New; diff --git a/lib/Transforms/Utils/ValueMapper.cpp b/lib/Transforms/Utils/ValueMapper.cpp index 9455e532b0e..132c3920397 100644 --- a/lib/Transforms/Utils/ValueMapper.cpp +++ b/lib/Transforms/Utils/ValueMapper.cpp @@ -21,147 +21,106 @@ using namespace llvm; Value *llvm::MapValue(const Value *V, ValueToValueMapTy &VM, - bool ModuleLevelChanges) { - TrackingVH &VMSlot = VM[V]; - if (VMSlot) return VMSlot; // Does it exist in the map yet? + RemapFlags Flags) { + ValueToValueMapTy::iterator I = VM.find(V); + + // If the value already exists in the map, use it. + if (I != VM.end() && I->second) return I->second; - // NOTE: VMSlot can be invalidated by any reference to VM, which can grow the - // DenseMap. This includes any recursive calls to MapValue. - // 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() && - !ModuleLevelChanges)) - return VMSlot = const_cast(V); + if (isa(V) || isa(V) || isa(V)) + return VM[V] = const_cast(V); if (const MDNode *MD = dyn_cast(V)) { - // Start by assuming that we'll use the identity mapping. - VMSlot = const_cast(V); - + // If this is a module-level metadata and we know that nothing at the module + // level is changing, then use an identity mapping. + if (!MD->isFunctionLocal() && (Flags & RF_NoModuleLevelChanges)) + return VM[V] = 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; + if (OP == 0 || MapValue(OP, VM, Flags) == OP) continue; - // Ok, at least one operand needs remapping. + // Ok, at least one operand needs remapping. Create a dummy node in case + // we have a metadata cycle. 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); + for (i = 0; i != e; ++i) { + Value *Op = MD->getOperand(i); + Elts.push_back(Op ? MapValue(Op, VM, Flags) : 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); + // No operands needed remapping. Use an identity mapping. + return VM[V] = const_cast(V); } + // Okay, this either must be a constant (which may or may not be mappable) or + // is something that is not in the mapping table. Constant *C = const_cast(dyn_cast(V)); if (C == 0) return 0; - if (isa(C) || isa(C) || - isa(C) || isa(C) || - isa(C)) - return VMSlot = C; // Primitive constants map directly - - 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, ModuleLevelChanges); - if (MV != *i) { - // This array must contain a reference to a global, make a new array - // and return it. - // - std::vector Values; - Values.reserve(CA->getNumOperands()); - for (User::op_iterator j = b; j != i; ++j) - Values.push_back(cast(*j)); - Values.push_back(cast(MV)); - for (++i; i != e; ++i) - Values.push_back(cast(MapValue(*i, VM, - ModuleLevelChanges))); - return VM[V] = ConstantArray::get(CA->getType(), Values); - } - } - return VM[V] = C; + if (BlockAddress *BA = dyn_cast(C)) { + Function *F = cast(MapValue(BA->getFunction(), VM, Flags)); + BasicBlock *BB = cast_or_null(MapValue(BA->getBasicBlock(), VM, + Flags)); + return VM[V] = BlockAddress::get(F, BB ? BB : BA->getBasicBlock()); } - 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, ModuleLevelChanges); - if (MV != *i) { - // This struct must contain a reference to a global, make a new struct - // and return it. - // - std::vector Values; - Values.reserve(CS->getNumOperands()); - for (User::op_iterator j = b; j != i; ++j) - Values.push_back(cast(*j)); - Values.push_back(cast(MV)); - for (++i; i != e; ++i) - Values.push_back(cast(MapValue(*i, VM, - ModuleLevelChanges))); - return VM[V] = ConstantStruct::get(CS->getType(), Values); - } - } - return VM[V] = C; - } - - if (ConstantExpr *CE = dyn_cast(C)) { + for (unsigned i = 0, e = C->getNumOperands(); i != e; ++i) { + Value *Op = C->getOperand(i); + Value *Mapped = MapValue(Op, VM, Flags); + if (Mapped == C) continue; + + // Okay, the operands don't all match. We've already processed some or all + // of the operands, set them up now. 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, 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, ModuleLevelChanges); - if (MV != *i) { - // This vector value must contain a reference to a global, make a new - // vector constant and return it. - // - std::vector Values; - Values.reserve(CV->getNumOperands()); - for (User::op_iterator j = b; j != i; ++j) - Values.push_back(cast(*j)); - Values.push_back(cast(MV)); - for (++i; i != e; ++i) - Values.push_back(cast(MapValue(*i, VM, - ModuleLevelChanges))); - return VM[V] = ConstantVector::get(Values); - } - } - return VM[V] = C; + Ops.reserve(C->getNumOperands()); + for (unsigned j = 0; j != i; ++j) + Ops.push_back(cast(C->getOperand(i))); + Ops.push_back(cast(Mapped)); + + // Map the rest of the operands that aren't processed yet. + for (++i; i != e; ++i) + Ops.push_back(cast(MapValue(C->getOperand(i), VM, Flags))); + + if (ConstantExpr *CE = dyn_cast(C)) + return VM[V] = CE->getWithOperands(Ops); + if (ConstantArray *CA = dyn_cast(C)) + return VM[V] = ConstantArray::get(CA->getType(), Ops); + if (ConstantStruct *CS = dyn_cast(C)) + return VM[V] = ConstantStruct::get(CS->getType(), Ops); + assert(isa(C) && "Unknown mapped constant type"); + return VM[V] = ConstantVector::get(Ops); } - - BlockAddress *BA = cast(C); - 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()); + + // If we reach here, all of the operands of the constant match. + return VM[V] = C; } /// RemapInstruction - Convert the instruction operands from referencing the /// current values into those specified by VMap. /// void llvm::RemapInstruction(Instruction *I, ValueToValueMapTy &VMap, - bool ModuleLevelChanges) { + RemapFlags Flags) { // Remap operands. for (User::op_iterator op = I->op_begin(), E = I->op_end(); op != E; ++op) { - Value *V = MapValue(*op, VMap, ModuleLevelChanges); - assert(V && "Referenced value not in value map!"); - *op = V; + Value *V = MapValue(*op, VMap, Flags); + // If we aren't ignoring missing entries, assert that something happened. + if (V != 0) + *op = V; + else + assert((Flags & RF_IgnoreMissingEntries) && + "Referenced value not in value map!"); } // Remap attached metadata. @@ -170,7 +129,7 @@ void llvm::RemapInstruction(Instruction *I, ValueToValueMapTy &VMap, for (SmallVectorImpl >::iterator MI = MDs.begin(), ME = MDs.end(); MI != ME; ++MI) { Value *Old = MI->second; - Value *New = MapValue(Old, VMap, ModuleLevelChanges); + Value *New = MapValue(Old, VMap, Flags); if (New != Old) I->setMetadata(MI->first, cast(New)); } -- 2.34.1