mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2025-05-13 17:38:39 +00:00
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
This commit is contained in:
parent
6ccb365293
commit
b5fa5fcecc
@ -22,10 +22,29 @@ namespace llvm {
|
|||||||
class Instruction;
|
class Instruction;
|
||||||
typedef ValueMap<const Value *, TrackingVH<Value> > ValueToValueMapTy;
|
typedef ValueMap<const Value *, TrackingVH<Value> > 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,
|
Value *MapValue(const Value *V, ValueToValueMapTy &VM,
|
||||||
bool ModuleLevelChanges);
|
RemapFlags Flags = RF_None);
|
||||||
void RemapInstruction(Instruction *I, ValueToValueMapTy &VM,
|
void RemapInstruction(Instruction *I, ValueToValueMapTy &VM,
|
||||||
bool ModuleLevelChanges);
|
RemapFlags Flags = RF_None);
|
||||||
} // End llvm namespace
|
} // End llvm namespace
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@ -451,8 +451,7 @@ static void LinkNamedMDNodes(Module *Dest, Module *Src,
|
|||||||
// Add Src elements into Dest node.
|
// Add Src elements into Dest node.
|
||||||
for (unsigned i = 0, e = SrcNMD->getNumOperands(); i != e; ++i)
|
for (unsigned i = 0, e = SrcNMD->getNumOperands(); i != e; ++i)
|
||||||
DestNMD->addOperand(cast<MDNode>(MapValue(SrcNMD->getOperand(i),
|
DestNMD->addOperand(cast<MDNode>(MapValue(SrcNMD->getOperand(i),
|
||||||
ValueMap,
|
ValueMap)));
|
||||||
true)));
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -814,9 +813,9 @@ static bool LinkGlobalInits(Module *Dest, const Module *Src,
|
|||||||
const GlobalVariable *SGV = I;
|
const GlobalVariable *SGV = I;
|
||||||
|
|
||||||
if (SGV->hasInitializer()) { // Only process initialized GV's
|
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 =
|
Constant *SInit =
|
||||||
cast<Constant>(MapValue(SGV->getInitializer(), ValueMap, true));
|
cast<Constant>(MapValue(SGV->getInitializer(), ValueMap));
|
||||||
// Grab destination global variable or alias.
|
// Grab destination global variable or alias.
|
||||||
GlobalValue *DGV = cast<GlobalValue>(ValueMap[SGV]->stripPointerCasts());
|
GlobalValue *DGV = cast<GlobalValue>(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
|
// 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
|
// 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
|
// the Source function as operands. Loop through all of the operands of the
|
||||||
// functions and patch them up to point to the local versions...
|
// 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 (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.
|
RemapInstruction(I, ValueMap, RF_IgnoreMissingEntries);
|
||||||
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, 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.
|
// There is no need to map the arguments anymore.
|
||||||
for (Function::arg_iterator I = Src->arg_begin(), E = Src->arg_end();
|
for (Function::arg_iterator I = Src->arg_begin(), E = Src->arg_end();
|
||||||
|
@ -22,7 +22,6 @@
|
|||||||
#include "llvm/Transforms/Utils/BasicBlockUtils.h"
|
#include "llvm/Transforms/Utils/BasicBlockUtils.h"
|
||||||
#include "llvm/Transforms/Utils/SSAUpdater.h"
|
#include "llvm/Transforms/Utils/SSAUpdater.h"
|
||||||
#include "llvm/Transforms/Utils/ValueMapper.h"
|
#include "llvm/Transforms/Utils/ValueMapper.h"
|
||||||
#include "llvm/Support/CommandLine.h"
|
|
||||||
#include "llvm/Support/Debug.h"
|
#include "llvm/Support/Debug.h"
|
||||||
#include "llvm/ADT/Statistic.h"
|
#include "llvm/ADT/Statistic.h"
|
||||||
using namespace llvm;
|
using namespace llvm;
|
||||||
@ -205,6 +204,7 @@ bool LoopRotate::rotateLoop(Loop *Lp, LPPassManager &LPM) {
|
|||||||
|
|
||||||
// Otherwise, create a duplicate of the instruction.
|
// Otherwise, create a duplicate of the instruction.
|
||||||
Instruction *C = Inst->clone();
|
Instruction *C = Inst->clone();
|
||||||
|
|
||||||
C->setName(Inst->getName());
|
C->setName(Inst->getName());
|
||||||
C->insertBefore(LoopEntryBranch);
|
C->insertBefore(LoopEntryBranch);
|
||||||
ValueMap[Inst] = C;
|
ValueMap[Inst] = C;
|
||||||
|
@ -457,19 +457,6 @@ bool LoopUnswitch::UnswitchIfProfitable(Value *LoopCond, Constant *Val) {
|
|||||||
return true;
|
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,
|
/// CloneLoop - Recursively clone the specified loop and all of its children,
|
||||||
/// mapping the blocks with the specified map.
|
/// mapping the blocks with the specified map.
|
||||||
static Loop *CloneLoop(Loop *L, Loop *PL, ValueToValueMapTy &VM,
|
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 (unsigned i = 0, e = NewBlocks.size(); i != e; ++i)
|
||||||
for (BasicBlock::iterator I = NewBlocks[i]->begin(),
|
for (BasicBlock::iterator I = NewBlocks[i]->begin(),
|
||||||
E = NewBlocks[i]->end(); I != E; ++I)
|
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.
|
// Rewrite the original preheader to select between versions of the loop.
|
||||||
BranchInst *OldBR = cast<BranchInst>(loopPreheader->getTerminator());
|
BranchInst *OldBR = cast<BranchInst>(loopPreheader->getTerminator());
|
||||||
|
@ -112,8 +112,7 @@ void llvm::CloneFunctionInto(Function *NewFunc, const Function *OldFunc,
|
|||||||
const BasicBlock &BB = *BI;
|
const BasicBlock &BB = *BI;
|
||||||
|
|
||||||
// Create a new basic block and copy instructions into it!
|
// Create a new basic block and copy instructions into it!
|
||||||
BasicBlock *CBB = CloneBasicBlock(&BB, VMap, NameSuffix, NewFunc,
|
BasicBlock *CBB = CloneBasicBlock(&BB, VMap, NameSuffix, NewFunc, CodeInfo);
|
||||||
CodeInfo);
|
|
||||||
VMap[&BB] = CBB; // Add basic block mapping.
|
VMap[&BB] = CBB; // Add basic block mapping.
|
||||||
|
|
||||||
if (ReturnInst *RI = dyn_cast<ReturnInst>(CBB->getTerminator()))
|
if (ReturnInst *RI = dyn_cast<ReturnInst>(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
|
// 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.
|
// references as we go. This uses VMap to do all the hard work.
|
||||||
//
|
|
||||||
for (Function::iterator BB = cast<BasicBlock>(VMap[OldFunc->begin()]),
|
for (Function::iterator BB = cast<BasicBlock>(VMap[OldFunc->begin()]),
|
||||||
BE = NewFunc->end(); BB != BE; ++BB)
|
BE = NewFunc->end(); BB != BE; ++BB)
|
||||||
// Loop over all instructions, fixing each one as we find it...
|
// Loop over all instructions, fixing each one as we find it...
|
||||||
for (BasicBlock::iterator II = BB->begin(); II != BB->end(); ++II)
|
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
|
/// 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
|
/// updated to include mappings from all of the instructions and basicblocks in
|
||||||
/// the function from their old to new values.
|
/// the function from their old to new values.
|
||||||
///
|
///
|
||||||
Function *llvm::CloneFunction(const Function *F,
|
Function *llvm::CloneFunction(const Function *F, ValueToValueMapTy &VMap,
|
||||||
ValueToValueMapTy &VMap,
|
|
||||||
bool ModuleLevelChanges,
|
bool ModuleLevelChanges,
|
||||||
ClonedCodeInfo *CodeInfo) {
|
ClonedCodeInfo *CodeInfo) {
|
||||||
std::vector<const Type*> ArgTypes;
|
std::vector<const Type*> ArgTypes;
|
||||||
@ -322,7 +320,8 @@ ConstantFoldMappedInstruction(const Instruction *I) {
|
|||||||
SmallVector<Constant*, 8> Ops;
|
SmallVector<Constant*, 8> Ops;
|
||||||
for (unsigned i = 0, e = I->getNumOperands(); i != e; ++i)
|
for (unsigned i = 0, e = I->getNumOperands(); i != e; ++i)
|
||||||
if (Constant *Op = dyn_cast_or_null<Constant>(MapValue(I->getOperand(i),
|
if (Constant *Op = dyn_cast_or_null<Constant>(MapValue(I->getOperand(i),
|
||||||
VMap, ModuleLevelChanges)))
|
VMap,
|
||||||
|
ModuleLevelChanges ? RF_None : RF_NoModuleLevelChanges)))
|
||||||
Ops.push_back(Op);
|
Ops.push_back(Op);
|
||||||
else
|
else
|
||||||
return 0; // All operands not constant!
|
return 0; // All operands not constant!
|
||||||
@ -460,7 +459,8 @@ void llvm::CloneAndPruneFunctionInto(Function *NewFunc, const Function *OldFunc,
|
|||||||
I->setDebugLoc(DebugLoc());
|
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<PHINode>(VMap[OPN]);
|
PHINode *PN = cast<PHINode>(VMap[OPN]);
|
||||||
for (unsigned pred = 0, e = NumPreds; pred != e; ++pred) {
|
for (unsigned pred = 0, e = NumPreds; pred != e; ++pred) {
|
||||||
Value *V = VMap[PN->getIncomingBlock(pred)];
|
Value *V = VMap[PN->getIncomingBlock(pred)];
|
||||||
if (BasicBlock *MappedBlock =
|
if (BasicBlock *MappedBlock = cast_or_null<BasicBlock>(V)) {
|
||||||
cast_or_null<BasicBlock>(V)) {
|
|
||||||
Value *InVal = MapValue(PN->getIncomingValue(pred),
|
Value *InVal = MapValue(PN->getIncomingValue(pred),
|
||||||
VMap, ModuleLevelChanges);
|
VMap,
|
||||||
|
ModuleLevelChanges ? RF_None : RF_NoModuleLevelChanges);
|
||||||
assert(InVal && "Unknown input value?");
|
assert(InVal && "Unknown input value?");
|
||||||
PN->setIncomingValue(pred, InVal);
|
PN->setIncomingValue(pred, InVal);
|
||||||
PN->setIncomingBlock(pred, MappedBlock);
|
PN->setIncomingBlock(pred, MappedBlock);
|
||||||
|
@ -89,8 +89,7 @@ Module *llvm::CloneModule(const Module *M,
|
|||||||
GlobalVariable *GV = cast<GlobalVariable>(VMap[I]);
|
GlobalVariable *GV = cast<GlobalVariable>(VMap[I]);
|
||||||
if (I->hasInitializer())
|
if (I->hasInitializer())
|
||||||
GV->setInitializer(cast<Constant>(MapValue(I->getInitializer(),
|
GV->setInitializer(cast<Constant>(MapValue(I->getInitializer(),
|
||||||
VMap,
|
VMap, RF_None)));
|
||||||
true)));
|
|
||||||
GV->setLinkage(I->getLinkage());
|
GV->setLinkage(I->getLinkage());
|
||||||
GV->setThreadLocal(I->isThreadLocal());
|
GV->setThreadLocal(I->isThreadLocal());
|
||||||
GV->setConstant(I->isConstant());
|
GV->setConstant(I->isConstant());
|
||||||
@ -121,7 +120,7 @@ Module *llvm::CloneModule(const Module *M,
|
|||||||
GlobalAlias *GA = cast<GlobalAlias>(VMap[I]);
|
GlobalAlias *GA = cast<GlobalAlias>(VMap[I]);
|
||||||
GA->setLinkage(I->getLinkage());
|
GA->setLinkage(I->getLinkage());
|
||||||
if (const Constant* C = I->getAliasee())
|
if (const Constant* C = I->getAliasee())
|
||||||
GA->setAliasee(cast<Constant>(MapValue(C, VMap, true)));
|
GA->setAliasee(cast<Constant>(MapValue(C, VMap, RF_None)));
|
||||||
}
|
}
|
||||||
|
|
||||||
// And named metadata....
|
// And named metadata....
|
||||||
@ -130,7 +129,8 @@ Module *llvm::CloneModule(const Module *M,
|
|||||||
const NamedMDNode &NMD = *I;
|
const NamedMDNode &NMD = *I;
|
||||||
NamedMDNode *NewNMD = New->getOrInsertNamedMetadata(NMD.getName());
|
NamedMDNode *NewNMD = New->getOrInsertNamedMetadata(NMD.getName());
|
||||||
for (unsigned i = 0, e = NMD.getNumOperands(); i != e; ++i)
|
for (unsigned i = 0, e = NMD.getNumOperands(); i != e; ++i)
|
||||||
NewNMD->addOperand(cast<MDNode>(MapValue(NMD.getOperand(i), VMap, true)));
|
NewNMD->addOperand(cast<MDNode>(MapValue(NMD.getOperand(i), VMap,
|
||||||
|
RF_None)));
|
||||||
}
|
}
|
||||||
|
|
||||||
return New;
|
return New;
|
||||||
|
@ -21,147 +21,106 @@
|
|||||||
using namespace llvm;
|
using namespace llvm;
|
||||||
|
|
||||||
Value *llvm::MapValue(const Value *V, ValueToValueMapTy &VM,
|
Value *llvm::MapValue(const Value *V, ValueToValueMapTy &VM,
|
||||||
bool ModuleLevelChanges) {
|
RemapFlags Flags) {
|
||||||
TrackingVH<Value> &VMSlot = VM[V];
|
ValueToValueMapTy::iterator I = VM.find(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
|
// If the value already exists in the map, use it.
|
||||||
// DenseMap. This includes any recursive calls to MapValue.
|
if (I != VM.end() && I->second) return I->second;
|
||||||
|
|
||||||
// Global values do not need to be seeded into the VM if they
|
// Global values do not need to be seeded into the VM if they
|
||||||
// are using the identity mapping.
|
// are using the identity mapping.
|
||||||
if (isa<GlobalValue>(V) || isa<InlineAsm>(V) || isa<MDString>(V) ||
|
if (isa<GlobalValue>(V) || isa<InlineAsm>(V) || isa<MDString>(V))
|
||||||
(isa<MDNode>(V) && !cast<MDNode>(V)->isFunctionLocal() &&
|
return VM[V] = const_cast<Value*>(V);
|
||||||
!ModuleLevelChanges))
|
|
||||||
return VMSlot = const_cast<Value*>(V);
|
|
||||||
|
|
||||||
if (const MDNode *MD = dyn_cast<MDNode>(V)) {
|
if (const MDNode *MD = dyn_cast<MDNode>(V)) {
|
||||||
// Start by assuming that we'll use the identity mapping.
|
// If this is a module-level metadata and we know that nothing at the module
|
||||||
VMSlot = const_cast<Value*>(V);
|
// level is changing, then use an identity mapping.
|
||||||
|
if (!MD->isFunctionLocal() && (Flags & RF_NoModuleLevelChanges))
|
||||||
|
return VM[V] = const_cast<Value*>(V);
|
||||||
|
|
||||||
// Check all operands to see if any need to be remapped.
|
// Check all operands to see if any need to be remapped.
|
||||||
for (unsigned i = 0, e = MD->getNumOperands(); i != e; ++i) {
|
for (unsigned i = 0, e = MD->getNumOperands(); i != e; ++i) {
|
||||||
Value *OP = MD->getOperand(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);
|
MDNode *Dummy = MDNode::getTemporary(V->getContext(), 0, 0);
|
||||||
VM[V] = Dummy;
|
VM[V] = Dummy;
|
||||||
SmallVector<Value*, 4> Elts;
|
SmallVector<Value*, 4> Elts;
|
||||||
Elts.reserve(MD->getNumOperands());
|
Elts.reserve(MD->getNumOperands());
|
||||||
for (i = 0; i != e; ++i)
|
for (i = 0; i != e; ++i) {
|
||||||
Elts.push_back(MD->getOperand(i) ?
|
Value *Op = MD->getOperand(i);
|
||||||
MapValue(MD->getOperand(i), VM, ModuleLevelChanges) : 0);
|
Elts.push_back(Op ? MapValue(Op, VM, Flags) : 0);
|
||||||
|
}
|
||||||
MDNode *NewMD = MDNode::get(V->getContext(), Elts.data(), Elts.size());
|
MDNode *NewMD = MDNode::get(V->getContext(), Elts.data(), Elts.size());
|
||||||
Dummy->replaceAllUsesWith(NewMD);
|
Dummy->replaceAllUsesWith(NewMD);
|
||||||
MDNode::deleteTemporary(Dummy);
|
MDNode::deleteTemporary(Dummy);
|
||||||
return VM[V] = NewMD;
|
return VM[V] = NewMD;
|
||||||
}
|
}
|
||||||
|
|
||||||
// No operands needed remapping; keep the identity map.
|
// No operands needed remapping. Use an identity mapping.
|
||||||
return const_cast<Value*>(V);
|
return VM[V] = const_cast<Value*>(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<Constant*>(dyn_cast<Constant>(V));
|
Constant *C = const_cast<Constant*>(dyn_cast<Constant>(V));
|
||||||
if (C == 0)
|
if (C == 0)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
if (isa<ConstantInt>(C) || isa<ConstantFP>(C) ||
|
if (BlockAddress *BA = dyn_cast<BlockAddress>(C)) {
|
||||||
isa<ConstantPointerNull>(C) || isa<ConstantAggregateZero>(C) ||
|
Function *F = cast<Function>(MapValue(BA->getFunction(), VM, Flags));
|
||||||
isa<UndefValue>(C))
|
|
||||||
return VMSlot = C; // Primitive constants map directly
|
|
||||||
|
|
||||||
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, ModuleLevelChanges);
|
|
||||||
if (MV != *i) {
|
|
||||||
// This array must contain a reference to a global, make a new array
|
|
||||||
// and return it.
|
|
||||||
//
|
|
||||||
std::vector<Constant*> Values;
|
|
||||||
Values.reserve(CA->getNumOperands());
|
|
||||||
for (User::op_iterator j = b; j != i; ++j)
|
|
||||||
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,
|
|
||||||
ModuleLevelChanges)));
|
|
||||||
return VM[V] = ConstantArray::get(CA->getType(), Values);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return VM[V] = C;
|
|
||||||
}
|
|
||||||
|
|
||||||
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, ModuleLevelChanges);
|
|
||||||
if (MV != *i) {
|
|
||||||
// This struct must contain a reference to a global, make a new struct
|
|
||||||
// and return it.
|
|
||||||
//
|
|
||||||
std::vector<Constant*> Values;
|
|
||||||
Values.reserve(CS->getNumOperands());
|
|
||||||
for (User::op_iterator j = b; j != i; ++j)
|
|
||||||
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,
|
|
||||||
ModuleLevelChanges)));
|
|
||||||
return VM[V] = ConstantStruct::get(CS->getType(), Values);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return VM[V] = C;
|
|
||||||
}
|
|
||||||
|
|
||||||
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, 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, ModuleLevelChanges);
|
|
||||||
if (MV != *i) {
|
|
||||||
// This vector value must contain a reference to a global, make a new
|
|
||||||
// vector constant and return it.
|
|
||||||
//
|
|
||||||
std::vector<Constant*> Values;
|
|
||||||
Values.reserve(CV->getNumOperands());
|
|
||||||
for (User::op_iterator j = b; j != i; ++j)
|
|
||||||
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,
|
|
||||||
ModuleLevelChanges)));
|
|
||||||
return VM[V] = ConstantVector::get(Values);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return VM[V] = C;
|
|
||||||
}
|
|
||||||
|
|
||||||
BlockAddress *BA = cast<BlockAddress>(C);
|
|
||||||
Function *F = cast<Function>(MapValue(BA->getFunction(), VM,
|
|
||||||
ModuleLevelChanges));
|
|
||||||
BasicBlock *BB = cast_or_null<BasicBlock>(MapValue(BA->getBasicBlock(), VM,
|
BasicBlock *BB = cast_or_null<BasicBlock>(MapValue(BA->getBasicBlock(), VM,
|
||||||
ModuleLevelChanges));
|
Flags));
|
||||||
return VM[V] = BlockAddress::get(F, BB ? BB : BA->getBasicBlock());
|
return VM[V] = BlockAddress::get(F, BB ? BB : BA->getBasicBlock());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
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<Constant*> Ops;
|
||||||
|
Ops.reserve(C->getNumOperands());
|
||||||
|
for (unsigned j = 0; j != i; ++j)
|
||||||
|
Ops.push_back(cast<Constant>(C->getOperand(i)));
|
||||||
|
Ops.push_back(cast<Constant>(Mapped));
|
||||||
|
|
||||||
|
// Map the rest of the operands that aren't processed yet.
|
||||||
|
for (++i; i != e; ++i)
|
||||||
|
Ops.push_back(cast<Constant>(MapValue(C->getOperand(i), VM, Flags)));
|
||||||
|
|
||||||
|
if (ConstantExpr *CE = dyn_cast<ConstantExpr>(C))
|
||||||
|
return VM[V] = CE->getWithOperands(Ops);
|
||||||
|
if (ConstantArray *CA = dyn_cast<ConstantArray>(C))
|
||||||
|
return VM[V] = ConstantArray::get(CA->getType(), Ops);
|
||||||
|
if (ConstantStruct *CS = dyn_cast<ConstantStruct>(C))
|
||||||
|
return VM[V] = ConstantStruct::get(CS->getType(), Ops);
|
||||||
|
assert(isa<ConstantVector>(C) && "Unknown mapped constant type");
|
||||||
|
return VM[V] = ConstantVector::get(Ops);
|
||||||
|
}
|
||||||
|
|
||||||
|
// If we reach here, all of the operands of the constant match.
|
||||||
|
return VM[V] = C;
|
||||||
|
}
|
||||||
|
|
||||||
/// RemapInstruction - Convert the instruction operands from referencing the
|
/// RemapInstruction - Convert the instruction operands from referencing the
|
||||||
/// current values into those specified by VMap.
|
/// current values into those specified by VMap.
|
||||||
///
|
///
|
||||||
void llvm::RemapInstruction(Instruction *I, ValueToValueMapTy &VMap,
|
void llvm::RemapInstruction(Instruction *I, ValueToValueMapTy &VMap,
|
||||||
bool ModuleLevelChanges) {
|
RemapFlags Flags) {
|
||||||
// Remap operands.
|
// Remap operands.
|
||||||
for (User::op_iterator op = I->op_begin(), E = I->op_end(); op != E; ++op) {
|
for (User::op_iterator op = I->op_begin(), E = I->op_end(); op != E; ++op) {
|
||||||
Value *V = MapValue(*op, VMap, ModuleLevelChanges);
|
Value *V = MapValue(*op, VMap, Flags);
|
||||||
assert(V && "Referenced value not in value map!");
|
// If we aren't ignoring missing entries, assert that something happened.
|
||||||
|
if (V != 0)
|
||||||
*op = V;
|
*op = V;
|
||||||
|
else
|
||||||
|
assert((Flags & RF_IgnoreMissingEntries) &&
|
||||||
|
"Referenced value not in value map!");
|
||||||
}
|
}
|
||||||
|
|
||||||
// Remap attached metadata.
|
// Remap attached metadata.
|
||||||
@ -170,7 +129,7 @@ void llvm::RemapInstruction(Instruction *I, ValueToValueMapTy &VMap,
|
|||||||
for (SmallVectorImpl<std::pair<unsigned, MDNode *> >::iterator
|
for (SmallVectorImpl<std::pair<unsigned, MDNode *> >::iterator
|
||||||
MI = MDs.begin(), ME = MDs.end(); MI != ME; ++MI) {
|
MI = MDs.begin(), ME = MDs.end(); MI != ME; ++MI) {
|
||||||
Value *Old = MI->second;
|
Value *Old = MI->second;
|
||||||
Value *New = MapValue(Old, VMap, ModuleLevelChanges);
|
Value *New = MapValue(Old, VMap, Flags);
|
||||||
if (New != Old)
|
if (New != Old)
|
||||||
I->setMetadata(MI->first, cast<MDNode>(New));
|
I->setMetadata(MI->first, cast<MDNode>(New));
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user