#include "llvm/Transforms/Utils/ValueMapper.h"
#include "llvm/IR/Constants.h"
#include "llvm/IR/Function.h"
#include "llvm/IR/InlineAsm.h"
#include "llvm/IR/Instructions.h"
#include "llvm/IR/Metadata.h"
using namespace llvm;
void ValueMapTypeRemapper::anchor() {}
Value *llvm::MapValue(const Value *V, ValueToValueMapTy &VM, RemapFlags Flags,
ValueMapTypeRemapper *TypeMapper) {
ValueToValueMapTy::iterator I = VM.find(V);
if (I != VM.end() && I->second) return I->second;
if (isa<GlobalValue>(V) || isa<MDString>(V))
return VM[V] = const_cast<Value*>(V);
if (const InlineAsm *IA = dyn_cast<InlineAsm>(V)) {
FunctionType *NewTy = IA->getFunctionType();
if (TypeMapper) {
NewTy = cast<FunctionType>(TypeMapper->remapType(NewTy));
if (NewTy != IA->getFunctionType())
V = InlineAsm::get(NewTy, IA->getAsmString(), IA->getConstraintString(),
IA->hasSideEffects(), IA->isAlignStack());
}
return VM[V] = const_cast<Value*>(V);
}
if (const MDNode *MD = dyn_cast<MDNode>(V)) {
if (!MD->isFunctionLocal() && (Flags & RF_NoModuleLevelChanges))
return VM[V] = const_cast<Value*>(V);
MDNode *Dummy = MDNode::getTemporary(V->getContext(), ArrayRef<Value*>());
VM[V] = Dummy;
for (unsigned i = 0, e = MD->getNumOperands(); i != e; ++i) {
Value *OP = MD->getOperand(i);
if (OP == 0) continue;
Value *Mapped_OP = MapValue(OP, VM, Flags, TypeMapper);
if (Mapped_OP == OP ||
(Mapped_OP == 0 && (Flags & RF_IgnoreMissingEntries)))
continue;
SmallVector<Value*, 4> Elts;
Elts.reserve(MD->getNumOperands());
for (i = 0; i != e; ++i) {
Value *Op = MD->getOperand(i);
if (Op == 0)
Elts.push_back(0);
else {
Value *Mapped_Op = MapValue(Op, VM, Flags, TypeMapper);
if (Mapped_Op == 0 && (Flags & RF_IgnoreMissingEntries))
Mapped_Op = Op;
Elts.push_back(Mapped_Op);
}
}
MDNode *NewMD = MDNode::get(V->getContext(), Elts);
Dummy->replaceAllUsesWith(NewMD);
VM[V] = NewMD;
MDNode::deleteTemporary(Dummy);
return NewMD;
}
VM[V] = const_cast<Value*>(V);
MDNode::deleteTemporary(Dummy);
return const_cast<Value*>(V);
}
Constant *C = const_cast<Constant*>(dyn_cast<Constant>(V));
if (C == 0)
return 0;
if (BlockAddress *BA = dyn_cast<BlockAddress>(C)) {
Function *F =
cast<Function>(MapValue(BA->getFunction(), VM, Flags, TypeMapper));
BasicBlock *BB = cast_or_null<BasicBlock>(MapValue(BA->getBasicBlock(), VM,
Flags, TypeMapper));
return VM[V] = BlockAddress::get(F, BB ? BB : BA->getBasicBlock());
}
unsigned OpNo = 0, NumOperands = C->getNumOperands();
Value *Mapped = 0;
for (; OpNo != NumOperands; ++OpNo) {
Value *Op = C->getOperand(OpNo);
Mapped = MapValue(Op, VM, Flags, TypeMapper);
if (Mapped != C) break;
}
Type *NewTy = C->getType();
if (TypeMapper)
NewTy = TypeMapper->remapType(NewTy);
if (OpNo == NumOperands && NewTy == C->getType())
return VM[V] = C;
SmallVector<Constant*, 8> Ops;
Ops.reserve(NumOperands);
for (unsigned j = 0; j != OpNo; ++j)
Ops.push_back(cast<Constant>(C->getOperand(j)));
if (OpNo != NumOperands) {
Ops.push_back(cast<Constant>(Mapped));
for (++OpNo; OpNo != NumOperands; ++OpNo)
Ops.push_back(MapValue(cast<Constant>(C->getOperand(OpNo)), VM,
Flags, TypeMapper));
}
if (ConstantExpr *CE = dyn_cast<ConstantExpr>(C))
return VM[V] = CE->getWithOperands(Ops, NewTy);
if (isa<ConstantArray>(C))
return VM[V] = ConstantArray::get(cast<ArrayType>(NewTy), Ops);
if (isa<ConstantStruct>(C))
return VM[V] = ConstantStruct::get(cast<StructType>(NewTy), Ops);
if (isa<ConstantVector>(C))
return VM[V] = ConstantVector::get(Ops);
if (isa<UndefValue>(C))
return VM[V] = UndefValue::get(NewTy);
if (isa<ConstantAggregateZero>(C))
return VM[V] = ConstantAggregateZero::get(NewTy);
assert(isa<ConstantPointerNull>(C));
return VM[V] = ConstantPointerNull::get(cast<PointerType>(NewTy));
}
void llvm::RemapInstruction(Instruction *I, ValueToValueMapTy &VMap,
RemapFlags Flags, ValueMapTypeRemapper *TypeMapper){
for (User::op_iterator op = I->op_begin(), E = I->op_end(); op != E; ++op) {
Value *V = MapValue(*op, VMap, Flags, TypeMapper);
if (V != 0)
*op = V;
else
assert((Flags & RF_IgnoreMissingEntries) &&
"Referenced value not in value map!");
}
if (PHINode *PN = dyn_cast<PHINode>(I)) {
for (unsigned i = 0, e = PN->getNumIncomingValues(); i != e; ++i) {
Value *V = MapValue(PN->getIncomingBlock(i), VMap, Flags);
if (V != 0)
PN->setIncomingBlock(i, cast<BasicBlock>(V));
else
assert((Flags & RF_IgnoreMissingEntries) &&
"Referenced block not in value map!");
}
}
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) {
MDNode *Old = MI->second;
MDNode *New = MapValue(Old, VMap, Flags, TypeMapper);
if (New != Old)
I->setMetadata(MI->first, New);
}
if (TypeMapper)
I->mutateType(TypeMapper->remapType(I->getType()));
}