diff --git a/include/llvm/Metadata.h b/include/llvm/Metadata.h index 21f907a371c..001bfca9616 100644 --- a/include/llvm/Metadata.h +++ b/include/llvm/Metadata.h @@ -351,8 +351,12 @@ public: /// ValueIsDeleted - This handler is used to update metadata store /// when a value is deleted. - void ValueIsDeleted(Value *V) {} + void ValueIsDeleted(const Value *V) {} void ValueIsDeleted(const Instruction *Inst); + + /// ValueIsCloned - This handler is used to update metadata store + /// when In1 is cloned to create In2. + void ValueIsCloned(const Instruction *In1, Instruction *In2); }; } // end llvm namespace diff --git a/include/llvm/Value.h b/include/llvm/Value.h index 864d4904c8f..ab6247e801d 100644 --- a/include/llvm/Value.h +++ b/include/llvm/Value.h @@ -298,6 +298,9 @@ public: const BasicBlock *PredBB) const{ return const_cast(this)->DoPHITranslation(CurBB, PredBB); } + + /// hasMetadata - Return true if metadata is attached with this value. + bool hasMetadata() const { return HasMetadata; } }; inline raw_ostream &operator<<(raw_ostream &OS, const Value &V) { diff --git a/lib/VMCore/Instructions.cpp b/lib/VMCore/Instructions.cpp index 8250ec009db..b7acce71e3a 100644 --- a/lib/VMCore/Instructions.cpp +++ b/lib/VMCore/Instructions.cpp @@ -12,6 +12,7 @@ // //===----------------------------------------------------------------------===// +#include "LLVMContextImpl.h" #include "llvm/Constants.h" #include "llvm/DerivedTypes.h" #include "llvm/Function.h" @@ -23,6 +24,7 @@ #include "llvm/Support/CallSite.h" #include "llvm/Support/ConstantRange.h" #include "llvm/Support/MathExtras.h" + using namespace llvm; //===----------------------------------------------------------------------===// @@ -3000,34 +3002,58 @@ void SwitchInst::setSuccessorV(unsigned idx, BasicBlock *B) { GetElementPtrInst *GetElementPtrInst::clone(LLVMContext&) const { GetElementPtrInst *New = new(getNumOperands()) GetElementPtrInst(*this); New->SubclassOptionalData = SubclassOptionalData; + if (hasMetadata()) { + LLVMContext &Context = getContext(); + Context.pImpl->TheMetadata.ValueIsCloned(this, New); + } return New; } BinaryOperator *BinaryOperator::clone(LLVMContext&) const { BinaryOperator *New = Create(getOpcode(), Op<0>(), Op<1>()); New->SubclassOptionalData = SubclassOptionalData; + if (hasMetadata()) { + LLVMContext &Context = getContext(); + Context.pImpl->TheMetadata.ValueIsCloned(this, New); + } return New; } FCmpInst* FCmpInst::clone(LLVMContext &Context) const { FCmpInst *New = new FCmpInst(getPredicate(), Op<0>(), Op<1>()); New->SubclassOptionalData = SubclassOptionalData; + if (hasMetadata()) { + LLVMContext &Context = getContext(); + Context.pImpl->TheMetadata.ValueIsCloned(this, New); + } return New; } ICmpInst* ICmpInst::clone(LLVMContext &Context) const { ICmpInst *New = new ICmpInst(getPredicate(), Op<0>(), Op<1>()); New->SubclassOptionalData = SubclassOptionalData; + if (hasMetadata()) { + LLVMContext &Context = getContext(); + Context.pImpl->TheMetadata.ValueIsCloned(this, New); + } return New; } ExtractValueInst *ExtractValueInst::clone(LLVMContext&) const { ExtractValueInst *New = new ExtractValueInst(*this); New->SubclassOptionalData = SubclassOptionalData; + if (hasMetadata()) { + LLVMContext &Context = getContext(); + Context.pImpl->TheMetadata.ValueIsCloned(this, New); + } return New; } InsertValueInst *InsertValueInst::clone(LLVMContext&) const { InsertValueInst *New = new InsertValueInst(*this); New->SubclassOptionalData = SubclassOptionalData; + if (hasMetadata()) { + LLVMContext &Context = getContext(); + Context.pImpl->TheMetadata.ValueIsCloned(this, New); + } return New; } @@ -3036,6 +3062,10 @@ MallocInst *MallocInst::clone(LLVMContext&) const { (Value*)getOperand(0), getAlignment()); New->SubclassOptionalData = SubclassOptionalData; + if (hasMetadata()) { + LLVMContext &Context = getContext(); + Context.pImpl->TheMetadata.ValueIsCloned(this, New); + } return New; } @@ -3044,12 +3074,20 @@ AllocaInst *AllocaInst::clone(LLVMContext&) const { (Value*)getOperand(0), getAlignment()); New->SubclassOptionalData = SubclassOptionalData; + if (hasMetadata()) { + LLVMContext &Context = getContext(); + Context.pImpl->TheMetadata.ValueIsCloned(this, New); + } return New; } FreeInst *FreeInst::clone(LLVMContext&) const { FreeInst *New = new FreeInst(getOperand(0)); New->SubclassOptionalData = SubclassOptionalData; + if (hasMetadata()) { + LLVMContext &Context = getContext(); + Context.pImpl->TheMetadata.ValueIsCloned(this, New); + } return New; } @@ -3058,6 +3096,10 @@ LoadInst *LoadInst::clone(LLVMContext&) const { Twine(), isVolatile(), getAlignment()); New->SubclassOptionalData = SubclassOptionalData; + if (hasMetadata()) { + LLVMContext &Context = getContext(); + Context.pImpl->TheMetadata.ValueIsCloned(this, New); + } return New; } @@ -3065,84 +3107,140 @@ StoreInst *StoreInst::clone(LLVMContext&) const { StoreInst *New = new StoreInst(getOperand(0), getOperand(1), isVolatile(), getAlignment()); New->SubclassOptionalData = SubclassOptionalData; + if (hasMetadata()) { + LLVMContext &Context = getContext(); + Context.pImpl->TheMetadata.ValueIsCloned(this, New); + } return New; } TruncInst *TruncInst::clone(LLVMContext&) const { TruncInst *New = new TruncInst(getOperand(0), getType()); New->SubclassOptionalData = SubclassOptionalData; + if (hasMetadata()) { + LLVMContext &Context = getContext(); + Context.pImpl->TheMetadata.ValueIsCloned(this, New); + } return New; } ZExtInst *ZExtInst::clone(LLVMContext&) const { ZExtInst *New = new ZExtInst(getOperand(0), getType()); New->SubclassOptionalData = SubclassOptionalData; + if (hasMetadata()) { + LLVMContext &Context = getContext(); + Context.pImpl->TheMetadata.ValueIsCloned(this, New); + } return New; } SExtInst *SExtInst::clone(LLVMContext&) const { SExtInst *New = new SExtInst(getOperand(0), getType()); New->SubclassOptionalData = SubclassOptionalData; + if (hasMetadata()) { + LLVMContext &Context = getContext(); + Context.pImpl->TheMetadata.ValueIsCloned(this, New); + } return New; } FPTruncInst *FPTruncInst::clone(LLVMContext&) const { FPTruncInst *New = new FPTruncInst(getOperand(0), getType()); New->SubclassOptionalData = SubclassOptionalData; + if (hasMetadata()) { + LLVMContext &Context = getContext(); + Context.pImpl->TheMetadata.ValueIsCloned(this, New); + } return New; } FPExtInst *FPExtInst::clone(LLVMContext&) const { FPExtInst *New = new FPExtInst(getOperand(0), getType()); New->SubclassOptionalData = SubclassOptionalData; + if (hasMetadata()) { + LLVMContext &Context = getContext(); + Context.pImpl->TheMetadata.ValueIsCloned(this, New); + } return New; } UIToFPInst *UIToFPInst::clone(LLVMContext&) const { UIToFPInst *New = new UIToFPInst(getOperand(0), getType()); New->SubclassOptionalData = SubclassOptionalData; + if (hasMetadata()) { + LLVMContext &Context = getContext(); + Context.pImpl->TheMetadata.ValueIsCloned(this, New); + } return New; } SIToFPInst *SIToFPInst::clone(LLVMContext&) const { SIToFPInst *New = new SIToFPInst(getOperand(0), getType()); New->SubclassOptionalData = SubclassOptionalData; + if (hasMetadata()) { + LLVMContext &Context = getContext(); + Context.pImpl->TheMetadata.ValueIsCloned(this, New); + } return New; } FPToUIInst *FPToUIInst::clone(LLVMContext&) const { FPToUIInst *New = new FPToUIInst(getOperand(0), getType()); New->SubclassOptionalData = SubclassOptionalData; + if (hasMetadata()) { + LLVMContext &Context = getContext(); + Context.pImpl->TheMetadata.ValueIsCloned(this, New); + } return New; } FPToSIInst *FPToSIInst::clone(LLVMContext&) const { FPToSIInst *New = new FPToSIInst(getOperand(0), getType()); New->SubclassOptionalData = SubclassOptionalData; + if (hasMetadata()) { + LLVMContext &Context = getContext(); + Context.pImpl->TheMetadata.ValueIsCloned(this, New); + } return New; } PtrToIntInst *PtrToIntInst::clone(LLVMContext&) const { PtrToIntInst *New = new PtrToIntInst(getOperand(0), getType()); New->SubclassOptionalData = SubclassOptionalData; + if (hasMetadata()) { + LLVMContext &Context = getContext(); + Context.pImpl->TheMetadata.ValueIsCloned(this, New); + } return New; } IntToPtrInst *IntToPtrInst::clone(LLVMContext&) const { IntToPtrInst *New = new IntToPtrInst(getOperand(0), getType()); New->SubclassOptionalData = SubclassOptionalData; + if (hasMetadata()) { + LLVMContext &Context = getContext(); + Context.pImpl->TheMetadata.ValueIsCloned(this, New); + } return New; } BitCastInst *BitCastInst::clone(LLVMContext&) const { BitCastInst *New = new BitCastInst(getOperand(0), getType()); New->SubclassOptionalData = SubclassOptionalData; + if (hasMetadata()) { + LLVMContext &Context = getContext(); + Context.pImpl->TheMetadata.ValueIsCloned(this, New); + } return New; } CallInst *CallInst::clone(LLVMContext&) const { CallInst *New = new(getNumOperands()) CallInst(*this); New->SubclassOptionalData = SubclassOptionalData; + if (hasMetadata()) { + LLVMContext &Context = getContext(); + Context.pImpl->TheMetadata.ValueIsCloned(this, New); + } return New; } @@ -3151,12 +3249,20 @@ SelectInst *SelectInst::clone(LLVMContext&) const { getOperand(1), getOperand(2)); New->SubclassOptionalData = SubclassOptionalData; + if (hasMetadata()) { + LLVMContext &Context = getContext(); + Context.pImpl->TheMetadata.ValueIsCloned(this, New); + } return New; } VAArgInst *VAArgInst::clone(LLVMContext&) const { VAArgInst *New = new VAArgInst(getOperand(0), getType()); New->SubclassOptionalData = SubclassOptionalData; + if (hasMetadata()) { + LLVMContext &Context = getContext(); + Context.pImpl->TheMetadata.ValueIsCloned(this, New); + } return New; } @@ -3164,6 +3270,10 @@ ExtractElementInst *ExtractElementInst::clone(LLVMContext&) const { ExtractElementInst *New = ExtractElementInst::Create(getOperand(0), getOperand(1)); New->SubclassOptionalData = SubclassOptionalData; + if (hasMetadata()) { + LLVMContext &Context = getContext(); + Context.pImpl->TheMetadata.ValueIsCloned(this, New); + } return New; } @@ -3172,6 +3282,10 @@ InsertElementInst *InsertElementInst::clone(LLVMContext&) const { getOperand(1), getOperand(2)); New->SubclassOptionalData = SubclassOptionalData; + if (hasMetadata()) { + LLVMContext &Context = getContext(); + Context.pImpl->TheMetadata.ValueIsCloned(this, New); + } return New; } @@ -3180,18 +3294,30 @@ ShuffleVectorInst *ShuffleVectorInst::clone(LLVMContext&) const { getOperand(1), getOperand(2)); New->SubclassOptionalData = SubclassOptionalData; + if (hasMetadata()) { + LLVMContext &Context = getContext(); + Context.pImpl->TheMetadata.ValueIsCloned(this, New); + } return New; } PHINode *PHINode::clone(LLVMContext&) const { PHINode *New = new PHINode(*this); New->SubclassOptionalData = SubclassOptionalData; + if (hasMetadata()) { + LLVMContext &Context = getContext(); + Context.pImpl->TheMetadata.ValueIsCloned(this, New); + } return New; } ReturnInst *ReturnInst::clone(LLVMContext&) const { ReturnInst *New = new(getNumOperands()) ReturnInst(*this); New->SubclassOptionalData = SubclassOptionalData; + if (hasMetadata()) { + LLVMContext &Context = getContext(); + Context.pImpl->TheMetadata.ValueIsCloned(this, New); + } return New; } @@ -3199,29 +3325,49 @@ BranchInst *BranchInst::clone(LLVMContext&) const { unsigned Ops(getNumOperands()); BranchInst *New = new(Ops, Ops == 1) BranchInst(*this); New->SubclassOptionalData = SubclassOptionalData; + if (hasMetadata()) { + LLVMContext &Context = getContext(); + Context.pImpl->TheMetadata.ValueIsCloned(this, New); + } return New; } SwitchInst *SwitchInst::clone(LLVMContext&) const { SwitchInst *New = new SwitchInst(*this); New->SubclassOptionalData = SubclassOptionalData; + if (hasMetadata()) { + LLVMContext &Context = getContext(); + Context.pImpl->TheMetadata.ValueIsCloned(this, New); + } return New; } InvokeInst *InvokeInst::clone(LLVMContext&) const { InvokeInst *New = new(getNumOperands()) InvokeInst(*this); New->SubclassOptionalData = SubclassOptionalData; + if (hasMetadata()) { + LLVMContext &Context = getContext(); + Context.pImpl->TheMetadata.ValueIsCloned(this, New); + } return New; } UnwindInst *UnwindInst::clone(LLVMContext &C) const { UnwindInst *New = new UnwindInst(C); New->SubclassOptionalData = SubclassOptionalData; + if (hasMetadata()) { + LLVMContext &Context = getContext(); + Context.pImpl->TheMetadata.ValueIsCloned(this, New); + } return New; } UnreachableInst *UnreachableInst::clone(LLVMContext &C) const { UnreachableInst *New = new UnreachableInst(C); New->SubclassOptionalData = SubclassOptionalData; + if (hasMetadata()) { + LLVMContext &Context = getContext(); + Context.pImpl->TheMetadata.ValueIsCloned(this, New); + } return New; } diff --git a/lib/VMCore/Metadata.cpp b/lib/VMCore/Metadata.cpp index 8ae584e9207..67bb66f30ad 100644 --- a/lib/VMCore/Metadata.cpp +++ b/lib/VMCore/Metadata.cpp @@ -338,3 +338,20 @@ void Metadata::ValueIsDeleted(const Instruction *Inst) { Info.clear(); MetadataStore.erase(Inst); } + +/// ValueIsCloned - This handler is used to update metadata store +/// when In1 is cloned to create In2. +void Metadata::ValueIsCloned(const Instruction *In1, Instruction *In2) { + // Find Metadata handles for In1. + MDStoreTy::iterator I = MetadataStore.find(In1); + if (I == MetadataStore.end()) + return; + + // FIXME : Give all metadata handlers a chance to adjust. + + MDMapTy &In1Info = I->second; + MDMapTy In2Info; + for (MDMapTy::iterator I = In1Info.begin(), E = In1Info.end(); I != E; ++I) + if (MDNode *MD = dyn_cast_or_null(I->second)) + setMD(I->first, MD, In2); +}