This is a major cleanup of the instruction metadata interfaces that

I asked Devang to do back on Sep 27.  Instead of going through the
MetadataContext class with methods like getMD() and getMDs(), just
ask the instruction directly for its metadata with getMetadata()
and getAllMetadata().

This includes a variety of other fixes and improvements: previously
all Value*'s were bloated because the HasMetadata bit was thrown into
value, adding a 9th bit to a byte.  Now this is properly sunk down to
the Instruction class (the only place where it makes sense) and it
will be folded away somewhere soon.

This also fixes some confusion in getMDs and its clients about 
whether the returned list is indexed by the MDID or densely packed.
This is now returned sorted and densely packed and the comments make
this clear.

This introduces a number of fixme's which I'll follow up on.


git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@92235 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Chris Lattner 2009-12-28 23:41:32 +00:00
parent f309880ad8
commit 3990b121cf
18 changed files with 291 additions and 276 deletions

View File

@ -21,6 +21,8 @@
namespace llvm { namespace llvm {
class LLVMContext; class LLVMContext;
class MDNode;
class MetadataContextImpl;
template<typename ValueSubClass, typename ItemParentClass> template<typename ValueSubClass, typename ItemParentClass>
class SymbolTableListTraits; class SymbolTableListTraits;
@ -31,6 +33,10 @@ class Instruction : public User, public ilist_node<Instruction> {
BasicBlock *Parent; BasicBlock *Parent;
// FIXME: Bitfieldize this.
bool HasMetadata;
friend class MetadataContextImpl;
friend class SymbolTableListTraits<Instruction, BasicBlock>; friend class SymbolTableListTraits<Instruction, BasicBlock>;
void setParent(BasicBlock *P); void setParent(BasicBlock *P);
protected: protected:
@ -74,19 +80,19 @@ public:
/// MovePos. /// MovePos.
void moveBefore(Instruction *MovePos); void moveBefore(Instruction *MovePos);
// --------------------------------------------------------------------------- //===--------------------------------------------------------------------===//
/// Subclass classification... getOpcode() returns a member of // Subclass classification.
/// one of the enums that is coming soon (down below)... //===--------------------------------------------------------------------===//
///
/// getOpcode() returns a member of one of the enums like Instruction::Add.
unsigned getOpcode() const { return getValueID() - InstructionVal; } unsigned getOpcode() const { return getValueID() - InstructionVal; }
const char *getOpcodeName() const { return getOpcodeName(getOpcode()); } const char *getOpcodeName() const { return getOpcodeName(getOpcode()); }
bool isTerminator() const { return isTerminator(getOpcode()); } bool isTerminator() const { return isTerminator(getOpcode()); }
bool isBinaryOp() const { return isBinaryOp(getOpcode()); } bool isBinaryOp() const { return isBinaryOp(getOpcode()); }
bool isShift() { return isShift(getOpcode()); } bool isShift() { return isShift(getOpcode()); }
bool isCast() const { return isCast(getOpcode()); } bool isCast() const { return isCast(getOpcode()); }
static const char* getOpcodeName(unsigned OpCode); static const char* getOpcodeName(unsigned OpCode);
static inline bool isTerminator(unsigned OpCode) { static inline bool isTerminator(unsigned OpCode) {
@ -118,6 +124,55 @@ public:
return OpCode >= CastOpsBegin && OpCode < CastOpsEnd; return OpCode >= CastOpsBegin && OpCode < CastOpsEnd;
} }
//===--------------------------------------------------------------------===//
// Metadata manipulation.
//===--------------------------------------------------------------------===//
/// hasMetadata() - Return true if this instruction has any metadata attached
/// to it.
bool hasMetadata() const {
return HasMetadata;
}
/// getMetadata - Get the metadata of given kind attached to this Instruction.
/// If the metadata is not found then return null.
MDNode *getMetadata(unsigned KindID) const {
if (!hasMetadata()) return 0;
return getMetadataImpl(KindID);
}
/// getMetadata - Get the metadata of given kind attached to this Instruction.
/// If the metadata is not found then return null.
MDNode *getMetadata(const char *Kind) const {
if (!hasMetadata()) return 0;
return getMetadataImpl(Kind);
}
/// getAllMetadata - Get all metadata attached to this Instruction. The first
/// element of each pair returned is the KindID, the second element is the
/// metadata value. This list is returned sorted by the KindID.
void getAllMetadata(SmallVectorImpl<std::pair<unsigned, MDNode*> > &MDs)const{
if (hasMetadata())
getAllMetadataImpl(MDs);
}
/// setMetadata - Set the metadata of of the specified kind to the specified
/// node. This updates/replaces metadata if already present, or removes it if
/// Node is null.
void setMetadata(unsigned KindID, MDNode *Node);
void setMetadata(const char *Kind, MDNode *Node);
private:
// These are all implemented in Metadata.cpp.
MDNode *getMetadataImpl(unsigned KindID) const;
MDNode *getMetadataImpl(const char *Kind) const;
void getAllMetadataImpl(SmallVectorImpl<std::pair<unsigned,MDNode*> > &)const;
public:
//===--------------------------------------------------------------------===//
// Predicates and helper methods.
//===--------------------------------------------------------------------===//
/// isAssociative - Return true if the instruction is associative: /// isAssociative - Return true if the instruction is associative:
/// ///
/// Associative operators satisfy: x op (y op z) === (x op y) op z /// Associative operators satisfy: x op (y op z) === (x op y) op z

View File

@ -205,6 +205,7 @@ class MetadataContext {
void operator=(MetadataContext&); // DO NOT IMPLEMENT void operator=(MetadataContext&); // DO NOT IMPLEMENT
MetadataContextImpl *const pImpl; MetadataContextImpl *const pImpl;
friend class Instruction;
public: public:
MetadataContext(); MetadataContext();
~MetadataContext(); ~MetadataContext();
@ -215,25 +216,6 @@ public:
/// isValidName - Return true if Name is a valid custom metadata handler name. /// isValidName - Return true if Name is a valid custom metadata handler name.
static bool isValidName(StringRef Name); static bool isValidName(StringRef Name);
#if 1
/// getMD - Get the metadata of given kind attached to an Instruction.
/// If the metadata is not found then return 0.
MDNode *getMD(unsigned Kind, const Instruction *Inst);
/// getMDs - Get the metadata attached to an Instruction.
void getMDs(const Instruction *Inst,
SmallVectorImpl<std::pair<unsigned, MDNode*> > &MDs) const;
/// addMD - Attach the metadata of given kind to an Instruction.
void addMD(unsigned Kind, MDNode *Node, Instruction *Inst);
/// removeMD - Remove metadata of given kind attached with an instuction.
void removeMD(unsigned Kind, Instruction *Inst);
/// removeAllMetadata - Remove all metadata attached with an instruction.
void removeAllMetadata(Instruction *Inst);
#endif
/// copyMD - If metadata is attached with Instruction In1 then attach /// copyMD - If metadata is attached with Instruction In1 then attach
/// the same metadata to In2. /// the same metadata to In2.
void copyMD(Instruction *In1, Instruction *In2); void copyMD(Instruction *In1, Instruction *In2);

View File

@ -64,7 +64,6 @@ class MetadataContextImpl;
class Value { class Value {
const unsigned char SubclassID; // Subclass identifier (for isa/dyn_cast) const unsigned char SubclassID; // Subclass identifier (for isa/dyn_cast)
unsigned char HasValueHandle : 1; // Has a ValueHandle pointing to this? unsigned char HasValueHandle : 1; // Has a ValueHandle pointing to this?
unsigned char HasMetadata : 1; // Has a metadata attached to this ?
protected: protected:
/// SubclassOptionalData - This member is similar to SubclassData, however it /// SubclassOptionalData - This member is similar to SubclassData, however it
/// is for holding information which may be used to aid optimization, but /// is for holding information which may be used to aid optimization, but
@ -81,9 +80,7 @@ private:
Use *UseList; Use *UseList;
friend class ValueSymbolTable; // Allow ValueSymbolTable to directly mod Name. friend class ValueSymbolTable; // Allow ValueSymbolTable to directly mod Name.
friend class SymbolTable; // Allow SymbolTable to directly poke Name.
friend class ValueHandleBase; friend class ValueHandleBase;
friend class MetadataContextImpl;
friend class AbstractTypeUser; friend class AbstractTypeUser;
ValueName *Name; ValueName *Name;
@ -303,9 +300,6 @@ public:
const BasicBlock *PredBB) const{ const BasicBlock *PredBB) const{
return const_cast<Value*>(this)->DoPHITranslation(CurBB, PredBB); return const_cast<Value*>(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) { inline raw_ostream &operator<<(raw_ostream &OS, const Value &V) {

View File

@ -1117,9 +1117,7 @@ Instruction *DIFactory::InsertDbgValueIntrinsic(Value *V, Value *Offset,
/// processModule - Process entire module and collect debug info. /// processModule - Process entire module and collect debug info.
void DebugInfoFinder::processModule(Module &M) { void DebugInfoFinder::processModule(Module &M) {
unsigned MDDbgKind = M.getContext().getMetadata().getMDKindID("dbg");
MetadataContext &TheMetadata = M.getContext().getMetadata();
unsigned MDDbgKind = TheMetadata.getMDKindID("dbg");
for (Module::iterator I = M.begin(), E = M.end(); I != E; ++I) for (Module::iterator I = M.begin(), E = M.end(); I != E; ++I)
for (Function::iterator FI = (*I).begin(), FE = (*I).end(); FI != FE; ++FI) for (Function::iterator FI = (*I).begin(), FE = (*I).end(); FI != FE; ++FI)
@ -1127,7 +1125,7 @@ void DebugInfoFinder::processModule(Module &M) {
++BI) { ++BI) {
if (DbgDeclareInst *DDI = dyn_cast<DbgDeclareInst>(BI)) if (DbgDeclareInst *DDI = dyn_cast<DbgDeclareInst>(BI))
processDeclare(DDI); processDeclare(DDI);
else if (MDNode *L = TheMetadata.getMD(MDDbgKind, BI)) else if (MDNode *L = BI->getMetadata(MDDbgKind))
processLocation(DILocation(L)); processLocation(DILocation(L));
} }

View File

@ -2826,10 +2826,9 @@ bool LLParser::ParseBasicBlock(PerFunctionState &PFS) {
ParseOptionalCustomMetadata(); ParseOptionalCustomMetadata();
// Set metadata attached with this instruction. // Set metadata attached with this instruction.
MetadataContext &TheMetadata = M->getContext().getMetadata();
for (SmallVector<std::pair<unsigned, MDNode *>, 2>::iterator for (SmallVector<std::pair<unsigned, MDNode *>, 2>::iterator
MDI = MDsOnInst.begin(), MDE = MDsOnInst.end(); MDI != MDE; ++MDI) MDI = MDsOnInst.begin(), MDE = MDsOnInst.end(); MDI != MDE; ++MDI)
TheMetadata.addMD(MDI->first, MDI->second, Inst); Inst->setMetadata(MDI->first, MDI->second);
MDsOnInst.clear(); MDsOnInst.clear();
BB->getInstList().push_back(Inst); BB->getInstList().push_back(Inst);

View File

@ -18,7 +18,6 @@
#include "llvm/InlineAsm.h" #include "llvm/InlineAsm.h"
#include "llvm/IntrinsicInst.h" #include "llvm/IntrinsicInst.h"
#include "llvm/LLVMContext.h" #include "llvm/LLVMContext.h"
#include "llvm/Metadata.h"
#include "llvm/Module.h" #include "llvm/Module.h"
#include "llvm/Operator.h" #include "llvm/Operator.h"
#include "llvm/AutoUpgrade.h" #include "llvm/AutoUpgrade.h"
@ -1573,7 +1572,6 @@ bool BitcodeReader::ParseMetadataAttachment() {
if (Stream.EnterSubBlock(bitc::METADATA_ATTACHMENT_ID)) if (Stream.EnterSubBlock(bitc::METADATA_ATTACHMENT_ID))
return Error("Malformed block record"); return Error("Malformed block record");
MetadataContext &TheMetadata = Context.getMetadata();
SmallVector<uint64_t, 64> Record; SmallVector<uint64_t, 64> Record;
while(1) { while(1) {
unsigned Code = Stream.ReadCode(); unsigned Code = Stream.ReadCode();
@ -1599,7 +1597,7 @@ bool BitcodeReader::ParseMetadataAttachment() {
for (unsigned i = 1; i != RecordLength; i = i+2) { for (unsigned i = 1; i != RecordLength; i = i+2) {
unsigned Kind = Record[i]; unsigned Kind = Record[i];
Value *Node = MDValueList.getValueFwdRef(Record[i+1]); Value *Node = MDValueList.getValueFwdRef(Record[i+1]);
TheMetadata.addMD(Kind, cast<MDNode>(Node), Inst); Inst->setMetadata(Kind, cast<MDNode>(Node));
} }
break; break;
} }

View File

@ -561,32 +561,29 @@ static void WriteMetadataAttachment(const Function &F,
// Write metadata attachments // Write metadata attachments
// METADATA_ATTACHMENT - [m x [value, [n x [id, mdnode]]] // METADATA_ATTACHMENT - [m x [value, [n x [id, mdnode]]]
MetadataContext &TheMetadata = F.getContext().getMetadata(); SmallVector<std::pair<unsigned, MDNode*>, 4> MDs;
typedef SmallVector<std::pair<unsigned, MDNode*>, 2> MDMapTy;
MDMapTy MDs;
for (Function::const_iterator BB = F.begin(), E = F.end(); BB != E; ++BB) for (Function::const_iterator BB = F.begin(), E = F.end(); BB != E; ++BB)
for (BasicBlock::const_iterator I = BB->begin(), E = BB->end(); for (BasicBlock::const_iterator I = BB->begin(), E = BB->end();
I != E; ++I) { I != E; ++I) {
MDs.clear(); MDs.clear();
TheMetadata.getMDs(I, MDs); I->getAllMetadata(MDs);
bool RecordedInstruction = false;
for (MDMapTy::const_iterator PI = MDs.begin(), PE = MDs.end(); // If no metadata, ignore instruction.
PI != PE; ++PI) { if (MDs.empty()) continue;
if (RecordedInstruction == false) {
Record.push_back(VE.getInstructionID(I)); Record.push_back(VE.getInstructionID(I));
RecordedInstruction = true;
} for (unsigned i = 0, e = MDs.size(); i != e; ++i) {
Record.push_back(PI->first); Record.push_back(MDs[i].first);
Record.push_back(VE.getValueID(PI->second)); Record.push_back(VE.getValueID(MDs[i].second));
} }
if (!Record.empty()) { if (!StartedMetadataBlock) {
if (!StartedMetadataBlock) { Stream.EnterSubblock(bitc::METADATA_ATTACHMENT_ID, 3);
Stream.EnterSubblock(bitc::METADATA_ATTACHMENT_ID, 3); StartedMetadataBlock = true;
StartedMetadataBlock = true;
}
Stream.EmitRecord(bitc::METADATA_ATTACHMENT, Record, 0);
Record.clear();
} }
Stream.EmitRecord(bitc::METADATA_ATTACHMENT, Record, 0);
Record.clear();
} }
if (StartedMetadataBlock) if (StartedMetadataBlock)
@ -1208,7 +1205,7 @@ static void WriteFunction(const Function &F, ValueEnumerator &VE,
for (BasicBlock::const_iterator I = BB->begin(), E = BB->end(); for (BasicBlock::const_iterator I = BB->begin(), E = BB->end();
I != E; ++I) { I != E; ++I) {
WriteInstruction(*I, InstID, VE, Stream, Vals); WriteInstruction(*I, InstID, VE, Stream, Vals);
if (I->getType() != Type::getVoidTy(F.getContext())) if (!I->getType()->isVoidTy())
++InstID; ++InstID;
} }

View File

@ -14,8 +14,6 @@
#include "ValueEnumerator.h" #include "ValueEnumerator.h"
#include "llvm/Constants.h" #include "llvm/Constants.h"
#include "llvm/DerivedTypes.h" #include "llvm/DerivedTypes.h"
#include "llvm/LLVMContext.h"
#include "llvm/Metadata.h"
#include "llvm/Module.h" #include "llvm/Module.h"
#include "llvm/TypeSymbolTable.h" #include "llvm/TypeSymbolTable.h"
#include "llvm/ValueSymbolTable.h" #include "llvm/ValueSymbolTable.h"
@ -87,9 +85,7 @@ ValueEnumerator::ValueEnumerator(const Module *M) {
I != E; ++I) I != E; ++I)
EnumerateType(I->getType()); EnumerateType(I->getType());
MetadataContext &TheMetadata = F->getContext().getMetadata(); SmallVector<std::pair<unsigned, MDNode*>, 2> MDs;
typedef SmallVector<std::pair<unsigned, MDNode*>, 2> MDMapTy;
MDMapTy MDs;
for (Function::const_iterator BB = F->begin(), E = F->end(); BB != E; ++BB) for (Function::const_iterator BB = F->begin(), E = F->end(); BB != E; ++BB)
for (BasicBlock::const_iterator I = BB->begin(), E = BB->end(); I!=E;++I){ for (BasicBlock::const_iterator I = BB->begin(), E = BB->end(); I!=E;++I){
for (User::const_op_iterator OI = I->op_begin(), E = I->op_end(); for (User::const_op_iterator OI = I->op_begin(), E = I->op_end();
@ -103,10 +99,9 @@ ValueEnumerator::ValueEnumerator(const Module *M) {
// Enumerate metadata attached with this instruction. // Enumerate metadata attached with this instruction.
MDs.clear(); MDs.clear();
TheMetadata.getMDs(I, MDs); I->getAllMetadata(MDs);
for (MDMapTy::const_iterator MI = MDs.begin(), ME = MDs.end(); MI != ME; for (unsigned i = 0, e = MDs.size(); i != e; ++i)
++MI) EnumerateMetadata(MDs[i].second);
EnumerateMetadata(MI->second);
} }
} }

View File

@ -43,7 +43,6 @@
#include "llvm/GlobalVariable.h" #include "llvm/GlobalVariable.h"
#include "llvm/Instructions.h" #include "llvm/Instructions.h"
#include "llvm/IntrinsicInst.h" #include "llvm/IntrinsicInst.h"
#include "llvm/LLVMContext.h"
#include "llvm/CodeGen/FastISel.h" #include "llvm/CodeGen/FastISel.h"
#include "llvm/CodeGen/MachineInstrBuilder.h" #include "llvm/CodeGen/MachineInstrBuilder.h"
#include "llvm/CodeGen/MachineModuleInfo.h" #include "llvm/CodeGen/MachineModuleInfo.h"
@ -349,10 +348,7 @@ bool FastISel::SelectCall(User *I) {
if (SI == StaticAllocaMap.end()) break; // VLAs. if (SI == StaticAllocaMap.end()) break; // VLAs.
int FI = SI->second; int FI = SI->second;
if (MMI) { if (MMI) {
MetadataContext &TheMetadata = if (MDNode *Dbg = DI->getMetadata("dbg"))
DI->getParent()->getContext().getMetadata();
unsigned MDDbgKind = TheMetadata.getMDKindID("dbg");
if (MDNode *Dbg = TheMetadata.getMD(MDDbgKind, DI))
MMI->setVariableDbgInfo(DI->getVariable(), FI, Dbg); MMI->setVariableDbgInfo(DI->getVariable(), FI, Dbg);
} }
return true; return true;

View File

@ -27,7 +27,6 @@
#include "llvm/Instructions.h" #include "llvm/Instructions.h"
#include "llvm/Intrinsics.h" #include "llvm/Intrinsics.h"
#include "llvm/IntrinsicInst.h" #include "llvm/IntrinsicInst.h"
#include "llvm/LLVMContext.h"
#include "llvm/Module.h" #include "llvm/Module.h"
#include "llvm/CodeGen/FastISel.h" #include "llvm/CodeGen/FastISel.h"
#include "llvm/CodeGen/GCStrategy.h" #include "llvm/CodeGen/GCStrategy.h"
@ -4379,14 +4378,9 @@ SelectionDAGBuilder::visitIntrinsicCall(CallInst &I, unsigned Intrinsic) {
return 0; // VLAs. return 0; // VLAs.
int FI = SI->second; int FI = SI->second;
MachineModuleInfo *MMI = DAG.getMachineModuleInfo(); if (MachineModuleInfo *MMI = DAG.getMachineModuleInfo())
if (MMI) { if (MDNode *Dbg = DI.getMetadata("dbg"))
MetadataContext &TheMetadata =
DI.getParent()->getContext().getMetadata();
unsigned MDDbgKind = TheMetadata.getMDKindID("dbg");
if (MDNode *Dbg = TheMetadata.getMD(MDDbgKind, &DI))
MMI->setVariableDbgInfo(Variable, FI, Dbg); MMI->setVariableDbgInfo(Variable, FI, Dbg);
}
return 0; return 0;
} }
case Intrinsic::eh_exception: { case Intrinsic::eh_exception: {

View File

@ -362,12 +362,12 @@ bool SelectionDAGISel::runOnMachineFunction(MachineFunction &mf) {
/// SetDebugLoc - Update MF's and SDB's DebugLocs if debug information is /// SetDebugLoc - Update MF's and SDB's DebugLocs if debug information is
/// attached with this instruction. /// attached with this instruction.
static void SetDebugLoc(unsigned MDDbgKind, MetadataContext &TheMetadata, static void SetDebugLoc(unsigned MDDbgKind, Instruction *I,
Instruction *I, SelectionDAGBuilder *SDB, SelectionDAGBuilder *SDB,
FastISel *FastIS, MachineFunction *MF) { FastISel *FastIS, MachineFunction *MF) {
if (isa<DbgInfoIntrinsic>(I)) return; if (isa<DbgInfoIntrinsic>(I)) return;
if (MDNode *Dbg = TheMetadata.getMD(MDDbgKind, I)) { if (MDNode *Dbg = I->getMetadata(MDDbgKind)) {
DILocation DILoc(Dbg); DILocation DILoc(Dbg);
DebugLoc Loc = ExtractDebugLocation(DILoc, MF->getDebugLocInfo()); DebugLoc Loc = ExtractDebugLocation(DILoc, MF->getDebugLocInfo());
@ -384,8 +384,7 @@ static void SetDebugLoc(unsigned MDDbgKind, MetadataContext &TheMetadata,
} }
/// ResetDebugLoc - Set MF's and SDB's DebugLocs to Unknown. /// ResetDebugLoc - Set MF's and SDB's DebugLocs to Unknown.
static void ResetDebugLoc(SelectionDAGBuilder *SDB, static void ResetDebugLoc(SelectionDAGBuilder *SDB, FastISel *FastIS) {
FastISel *FastIS) {
SDB->setCurDebugLoc(DebugLoc::getUnknownLoc()); SDB->setCurDebugLoc(DebugLoc::getUnknownLoc());
if (FastIS) if (FastIS)
FastIS->setCurDebugLoc(DebugLoc::getUnknownLoc()); FastIS->setCurDebugLoc(DebugLoc::getUnknownLoc());
@ -402,7 +401,7 @@ void SelectionDAGISel::SelectBasicBlock(BasicBlock *LLVMBB,
// Lower all of the non-terminator instructions. If a call is emitted // Lower all of the non-terminator instructions. If a call is emitted
// as a tail call, cease emitting nodes for this block. // as a tail call, cease emitting nodes for this block.
for (BasicBlock::iterator I = Begin; I != End && !SDB->HasTailCall; ++I) { for (BasicBlock::iterator I = Begin; I != End && !SDB->HasTailCall; ++I) {
SetDebugLoc(MDDbgKind, TheMetadata, I, SDB, 0, MF); SetDebugLoc(MDDbgKind, I, SDB, 0, MF);
if (!isa<TerminatorInst>(I)) { if (!isa<TerminatorInst>(I)) {
SDB->visit(*I); SDB->visit(*I);
@ -425,7 +424,7 @@ void SelectionDAGISel::SelectBasicBlock(BasicBlock *LLVMBB,
HandlePHINodesInSuccessorBlocks(LLVMBB); HandlePHINodesInSuccessorBlocks(LLVMBB);
// Lower the terminator after the copies are emitted. // Lower the terminator after the copies are emitted.
SetDebugLoc(MDDbgKind, TheMetadata, LLVMBB->getTerminator(), SDB, 0, MF); SetDebugLoc(MDDbgKind, LLVMBB->getTerminator(), SDB, 0, MF);
SDB->visit(*LLVMBB->getTerminator()); SDB->visit(*LLVMBB->getTerminator());
ResetDebugLoc(SDB, 0); ResetDebugLoc(SDB, 0);
} }
@ -776,7 +775,7 @@ void SelectionDAGISel::SelectAllBasicBlocks(Function &Fn,
break; break;
} }
SetDebugLoc(MDDbgKind, TheMetadata, BI, SDB, FastIS, &MF); SetDebugLoc(MDDbgKind, BI, SDB, FastIS, &MF);
// First try normal tablegen-generated "fast" selection. // First try normal tablegen-generated "fast" selection.
if (FastIS->SelectInstruction(BI)) { if (FastIS->SelectInstruction(BI)) {

View File

@ -228,7 +228,7 @@ static bool StripDebugInfo(Module &M) {
++FI) ++FI)
for (BasicBlock::iterator BI = FI->begin(), BE = FI->end(); BI != BE; for (BasicBlock::iterator BI = FI->begin(), BE = FI->end(); BI != BE;
++BI) ++BI)
TheMetadata.removeMD(MDDbgKind, BI); BI->setMetadata(MDDbgKind, 0);
return true; return true;
} }

View File

@ -426,7 +426,7 @@ void llvm::CloneAndPruneFunctionInto(Function *NewFunc, const Function *OldFunc,
MDNode *TheCallMD = NULL; MDNode *TheCallMD = NULL;
SmallVector<Value *, 4> MDVs; SmallVector<Value *, 4> MDVs;
if (TheCall && TheCall->hasMetadata()) if (TheCall && TheCall->hasMetadata())
TheCallMD = Context.getMetadata().getMD(DbgKind, TheCall); TheCallMD = TheCall->getMetadata(DbgKind);
// Handle PHI nodes specially, as we have to remove references to dead // Handle PHI nodes specially, as we have to remove references to dead
// blocks. // blocks.
@ -436,32 +436,38 @@ void llvm::CloneAndPruneFunctionInto(Function *NewFunc, const Function *OldFunc,
for (; (PN = dyn_cast<PHINode>(I)); ++I, ++OldI) { for (; (PN = dyn_cast<PHINode>(I)); ++I, ++OldI) {
if (I->hasMetadata()) { if (I->hasMetadata()) {
if (TheCallMD) { if (TheCallMD) {
if (MDNode *IMD = Context.getMetadata().getMD(DbgKind, I)) { if (MDNode *IMD = I->getMetadata(DbgKind)) {
MDNode *NewMD = UpdateInlinedAtInfo(IMD, TheCallMD, Context); MDNode *NewMD = UpdateInlinedAtInfo(IMD, TheCallMD, Context);
Context.getMetadata().addMD(DbgKind, NewMD, I); I->setMetadata(DbgKind, NewMD);
} }
} else { } else {
// The cloned instruction has dbg info but the call instruction // The cloned instruction has dbg info but the call instruction
// does not have dbg info. Remove dbg info from cloned instruction. // does not have dbg info. Remove dbg info from cloned instruction.
Context.getMetadata().removeMD(DbgKind, I); I->setMetadata(DbgKind, 0);
} }
} }
PHIToResolve.push_back(cast<PHINode>(OldI)); PHIToResolve.push_back(cast<PHINode>(OldI));
} }
} }
// FIXME:
// FIXME:
// FIXME: Unclone all this metadata stuff.
// FIXME:
// FIXME:
// Otherwise, remap the rest of the instructions normally. // Otherwise, remap the rest of the instructions normally.
for (; I != NewBB->end(); ++I) { for (; I != NewBB->end(); ++I) {
if (I->hasMetadata()) { if (I->hasMetadata()) {
if (TheCallMD) { if (TheCallMD) {
if (MDNode *IMD = Context.getMetadata().getMD(DbgKind, I)) { if (MDNode *IMD = I->getMetadata(DbgKind)) {
MDNode *NewMD = UpdateInlinedAtInfo(IMD, TheCallMD, Context); MDNode *NewMD = UpdateInlinedAtInfo(IMD, TheCallMD, Context);
Context.getMetadata().addMD(DbgKind, NewMD, I); I->setMetadata(DbgKind, NewMD);
} }
} else { } else {
// The cloned instruction has dbg info but the call instruction // The cloned instruction has dbg info but the call instruction
// does not have dbg info. Remove dbg info from cloned instruction. // does not have dbg info. Remove dbg info from cloned instruction.
Context.getMetadata().removeMD(DbgKind, I); I->setMetadata(DbgKind, 0);
} }
} }
RemapInstruction(I, ValueMap); RemapInstruction(I, ValueMap);

View File

@ -21,11 +21,9 @@
#include "llvm/Constants.h" #include "llvm/Constants.h"
#include "llvm/DerivedTypes.h" #include "llvm/DerivedTypes.h"
#include "llvm/InlineAsm.h" #include "llvm/InlineAsm.h"
#include "llvm/Instruction.h" #include "llvm/IntrinsicInst.h"
#include "llvm/Instructions.h"
#include "llvm/LLVMContext.h" #include "llvm/LLVMContext.h"
#include "llvm/Operator.h" #include "llvm/Operator.h"
#include "llvm/Metadata.h"
#include "llvm/Module.h" #include "llvm/Module.h"
#include "llvm/ValueSymbolTable.h" #include "llvm/ValueSymbolTable.h"
#include "llvm/TypeSymbolTable.h" #include "llvm/TypeSymbolTable.h"
@ -680,30 +678,30 @@ void SlotTracker::processFunction() {
ST_DEBUG("Inserting Instructions:\n"); ST_DEBUG("Inserting Instructions:\n");
MetadataContext &TheMetadata = TheFunction->getContext().getMetadata(); SmallVector<std::pair<unsigned, MDNode*>, 2> MDForInst;
typedef SmallVector<std::pair<unsigned, MDNode*>, 2> MDMapTy;
MDMapTy MDs;
// Add all of the basic blocks and instructions with no names. // Add all of the basic blocks and instructions with no names.
for (Function::const_iterator BB = TheFunction->begin(), for (Function::const_iterator BB = TheFunction->begin(),
E = TheFunction->end(); BB != E; ++BB) { E = TheFunction->end(); BB != E; ++BB) {
if (!BB->hasName()) if (!BB->hasName())
CreateFunctionSlot(BB); CreateFunctionSlot(BB);
for (BasicBlock::const_iterator I = BB->begin(), E = BB->end(); I != E; for (BasicBlock::const_iterator I = BB->begin(), E = BB->end(); I != E;
++I) { ++I) {
if (I->getType() != Type::getVoidTy(TheFunction->getContext()) && if (!I->getType()->isVoidTy() && !I->hasName())
!I->hasName())
CreateFunctionSlot(I); CreateFunctionSlot(I);
for (unsigned i = 0, e = I->getNumOperands(); i != e; ++i)
if (MDNode *N = dyn_cast_or_null<MDNode>(I->getOperand(i))) // Intrinsics can directly use metadata.
CreateMetadataSlot(N); if (isa<IntrinsicInst>(I))
for (unsigned i = 0, e = I->getNumOperands(); i != e; ++i)
if (MDNode *N = dyn_cast_or_null<MDNode>(I->getOperand(i)))
CreateMetadataSlot(N);
// Process metadata attached with this instruction. // Process metadata attached with this instruction.
MDs.clear(); MDForInst.clear();
TheMetadata.getMDs(I, MDs); I->getAllMetadata(MDForInst);
for (MDMapTy::const_iterator MI = MDs.begin(), ME = MDs.end(); MI != ME; for (unsigned i = 0, e = MDForInst.size(); i != e; ++i)
++MI) CreateMetadataSlot(MDForInst[i].second);
CreateMetadataSlot(MI->second);
} }
} }
@ -2076,14 +2074,11 @@ void AssemblyWriter::printInstruction(const Instruction &I) {
// Print Metadata info. // Print Metadata info.
if (!MDNames.empty()) { if (!MDNames.empty()) {
MetadataContext &TheMetadata = I.getContext().getMetadata(); SmallVector<std::pair<unsigned, MDNode*>, 4> InstMD;
typedef SmallVector<std::pair<unsigned, MDNode*>, 2> MDMapTy; I.getAllMetadata(InstMD);
MDMapTy MDs; for (unsigned i = 0, e = InstMD.size(); i != e; ++i)
TheMetadata.getMDs(&I, MDs); Out << ", !" << MDNames[InstMD[i].first]
for (MDMapTy::const_iterator MI = MDs.begin(), ME = MDs.end(); MI != ME; << " !" << Machine.getMetadataSlot(InstMD[i].second);
++MI)
Out << ", !" << MDNames[MI->first]
<< " !" << Machine.getMetadataSlot(MI->second);
} }
printInfoComment(I); printInfoComment(I);
} }

View File

@ -43,7 +43,7 @@ void IRBuilderBase::SetCurrentDebugLocation(MDNode *L) {
void IRBuilderBase::SetInstDebugLocation(Instruction *I) const { void IRBuilderBase::SetInstDebugLocation(Instruction *I) const {
if (CurDbgLocation) if (CurDbgLocation)
Context.getMetadata().addMD(DbgMDKind, CurDbgLocation, I); I->setMetadata(DbgMDKind, CurDbgLocation);
} }
const Type *IRBuilderBase::getCurrentFunctionReturnType() const { const Type *IRBuilderBase::getCurrentFunctionReturnType() const {

View File

@ -24,7 +24,8 @@ using namespace llvm;
Instruction::Instruction(const Type *ty, unsigned it, Use *Ops, unsigned NumOps, Instruction::Instruction(const Type *ty, unsigned it, Use *Ops, unsigned NumOps,
Instruction *InsertBefore) Instruction *InsertBefore)
: User(ty, Value::InstructionVal + it, Ops, NumOps), Parent(0) { : User(ty, Value::InstructionVal + it, Ops, NumOps), Parent(0),
HasMetadata(false) {
// Make sure that we get added to a basicblock // Make sure that we get added to a basicblock
LeakDetector::addGarbageObject(this); LeakDetector::addGarbageObject(this);
@ -38,7 +39,8 @@ Instruction::Instruction(const Type *ty, unsigned it, Use *Ops, unsigned NumOps,
Instruction::Instruction(const Type *ty, unsigned it, Use *Ops, unsigned NumOps, Instruction::Instruction(const Type *ty, unsigned it, Use *Ops, unsigned NumOps,
BasicBlock *InsertAtEnd) BasicBlock *InsertAtEnd)
: User(ty, Value::InstructionVal + it, Ops, NumOps), Parent(0) { : User(ty, Value::InstructionVal + it, Ops, NumOps), Parent(0),
HasMetadata(false) {
// Make sure that we get added to a basicblock // Make sure that we get added to a basicblock
LeakDetector::addGarbageObject(this); LeakDetector::addGarbageObject(this);
@ -51,10 +53,8 @@ Instruction::Instruction(const Type *ty, unsigned it, Use *Ops, unsigned NumOps,
// Out of line virtual method, so the vtable, etc has a home. // Out of line virtual method, so the vtable, etc has a home.
Instruction::~Instruction() { Instruction::~Instruction() {
assert(Parent == 0 && "Instruction still linked in the program!"); assert(Parent == 0 && "Instruction still linked in the program!");
if (hasMetadata()) { if (HasMetadata)
LLVMContext &Context = getContext(); getContext().pImpl->TheMetadata.ValueIsDeleted(this);
Context.pImpl->TheMetadata.ValueIsDeleted(this);
}
} }
@ -464,7 +464,7 @@ bool Instruction::isSafeToSpeculativelyExecute() const {
Instruction *Instruction::clone() const { Instruction *Instruction::clone() const {
Instruction *New = clone_impl(); Instruction *New = clone_impl();
New->SubclassOptionalData = SubclassOptionalData; New->SubclassOptionalData = SubclassOptionalData;
if (hasMetadata()) if (HasMetadata)
getContext().pImpl->TheMetadata.ValueIsCloned(this, New); getContext().pImpl->TheMetadata.ValueIsCloned(this, New);
return New; return New;
} }

View File

@ -261,32 +261,27 @@ private:
StringMap<unsigned> MDHandlerNames; StringMap<unsigned> MDHandlerNames;
public: public:
// Name <-> ID mapping methods.
unsigned getMDKindID(StringRef Name); unsigned getMDKindID(StringRef Name);
void getMDKindNames(SmallVectorImpl<StringRef> &) const;
/// getMD - Get the metadata of given kind attached to an Instruction.
/// If the metadata is not found then return 0.
MDNode *getMD(unsigned Kind, const Instruction *Inst);
/// getMDs - Get the metadata attached to an Instruction. // Instruction metadata methods.
void getMDs(const Instruction *Inst, MDNode *getMetadata(const Instruction *Inst, unsigned Kind);
SmallVectorImpl<std::pair<unsigned, MDNode*> > &MDs) const; void getAllMetadata(const Instruction *Inst,
SmallVectorImpl<std::pair<unsigned, MDNode*> > &MDs)const;
/// addMD - Attach the metadata of given kind to an Instruction. void setMetadata(Instruction *Inst, unsigned Kind, MDNode *Node);
void addMD(unsigned Kind, MDNode *Node, Instruction *Inst);
/// removeMD - Remove metadata of given kind attached with an instruction.
void removeMD(unsigned Kind, Instruction *Inst);
/// removeAllMetadata - Remove all metadata attached with an instruction. /// removeAllMetadata - Remove all metadata attached with an instruction.
void removeAllMetadata(Instruction *Inst); void removeAllMetadata(Instruction *Inst);
/// copyMD - If metadata is attached with Instruction In1 then attach /// copyMD - If metadata is attached with Instruction In1 then attach
/// the same metadata to In2. /// the same metadata to In2.
void copyMD(Instruction *In1, Instruction *In2); void copyMD(Instruction *In1, Instruction *In2);
/// getMDKindNames - Populate client-supplied smallvector using custom
/// metadata name and ID.
void getMDKindNames(SmallVectorImpl<StringRef> &) const;
/// ValueIsDeleted - This handler is used to update metadata store /// ValueIsDeleted - This handler is used to update metadata store
/// when a value is deleted. /// when a value is deleted.
@ -308,49 +303,96 @@ unsigned MetadataContextImpl::getMDKindID(StringRef Name) {
// If this is new, assign it its ID. // If this is new, assign it its ID.
if (Entry == 0) Entry = MDHandlerNames.size(); if (Entry == 0) Entry = MDHandlerNames.size();
return Entry; return Entry;
} }
/// addMD - Attach the metadata of given kind to an Instruction. /// getHandlerNames - Populate client supplied smallvector using custome
void MetadataContextImpl::addMD(unsigned MDKind, MDNode *Node, /// metadata name and ID.
Instruction *Inst) { void MetadataContextImpl::
assert(Node && "Invalid null MDNode"); getMDKindNames(SmallVectorImpl<StringRef> &Names) const {
Inst->HasMetadata = true; Names.resize(MDHandlerNames.size()+1);
MDMapTy &Info = MetadataStore[Inst]; Names[0] = "";
if (Info.empty()) { for (StringMap<unsigned>::const_iterator I = MDHandlerNames.begin(),
Info.push_back(std::make_pair(MDKind, Node)); E = MDHandlerNames.end(); I != E; ++I)
MetadataStore.insert(std::make_pair(Inst, Info)); // MD Handlers are numbered from 1.
return; Names[I->second] = I->first();
}
// If there is an entry for this MDKind then replace it.
for (unsigned i = 0, e = Info.size(); i != e; ++i) {
MDPairTy &P = Info[i];
if (P.first == MDKind) {
Info[i] = std::make_pair(MDKind, Node);
return;
}
}
// Otherwise add a new entry.
Info.push_back(std::make_pair(MDKind, Node));
} }
/// removeMD - Remove metadata of given kind attached with an instruction.
void MetadataContextImpl::removeMD(unsigned Kind, Instruction *Inst) {
MDStoreTy::iterator I = MetadataStore.find(Inst);
if (I == MetadataStore.end())
return;
MDMapTy &Info = I->second; /// getMetadata - Get the metadata of given kind attached to an Instruction.
for (MDMapTy::iterator MI = Info.begin(), ME = Info.end(); MI != ME; ++MI) { /// If the metadata is not found then return 0.
MDPairTy &P = *MI; MDNode *MetadataContextImpl::
if (P.first == Kind) { getMetadata(const Instruction *Inst, unsigned MDKind) {
Info.erase(MI); MDMapTy &Info = MetadataStore[Inst];
assert(Inst->hasMetadata() && !Info.empty() && "Shouldn't have called this");
for (MDMapTy::iterator I = Info.begin(), E = Info.end(); I != E; ++I)
if (I->first == MDKind)
return I->second;
return 0;
}
/// getAllMetadata - Get all of the metadata attached to an Instruction.
void MetadataContextImpl::
getAllMetadata(const Instruction *Inst,
SmallVectorImpl<std::pair<unsigned, MDNode*> > &Result) const {
assert(Inst->hasMetadata() && MetadataStore.find(Inst) != MetadataStore.end()
&& "Shouldn't have called this");
const MDMapTy &Info = MetadataStore.find(Inst)->second;
assert(!Info.empty() && "Shouldn't have called this");
Result.clear();
Result.append(Info.begin(), Info.end());
// Sort the resulting array so it is stable.
if (Result.size() > 1)
array_pod_sort(Result.begin(), Result.end());
}
void MetadataContextImpl::setMetadata(Instruction *Inst, unsigned Kind,
MDNode *Node) {
// Handle the case when we're adding/updating metadata on an instruction.
if (Node) {
MDMapTy &Info = MetadataStore[Inst];
assert(!Info.empty() == Inst->HasMetadata && "HasMetadata bit is wonked");
if (Info.empty()) {
Inst->HasMetadata = true;
} else {
// Handle replacement of an existing value.
for (unsigned i = 0, e = Info.size(); i != e; ++i)
if (Info[i].first == Kind) {
Info[i].second = Node;
return;
}
}
// No replacement, just add it to the list.
Info.push_back(std::make_pair(Kind, Node));
return;
}
// Otherwise, we're removing metadata from an instruction.
assert(Inst->HasMetadata && MetadataStore.count(Inst) &&
"HasMetadata bit out of date!");
MDMapTy &Info = MetadataStore[Inst];
// Common case is removing the only entry.
if (Info.size() == 1 && Info[0].first == Kind) {
MetadataStore.erase(Inst);
Inst->HasMetadata = false;
return;
}
// Handle replacement of an existing value.
for (unsigned i = 0, e = Info.size(); i != e; ++i)
if (Info[i].first == Kind) {
Info[i] = Info.back();
Info.pop_back();
assert(!Info.empty() && "Removing last entry should be handled above");
return; return;
} }
} // Otherwise, removing an entry that doesn't exist on the instruction.
} }
/// removeAllMetadata - Remove all metadata attached with an instruction. /// removeAllMetadata - Remove all metadata attached with an instruction.
@ -359,6 +401,7 @@ void MetadataContextImpl::removeAllMetadata(Instruction *Inst) {
Inst->HasMetadata = false; Inst->HasMetadata = false;
} }
/// copyMD - If metadata is attached with Instruction In1 then attach /// copyMD - If metadata is attached with Instruction In1 then attach
/// the same metadata to In2. /// the same metadata to In2.
void MetadataContextImpl::copyMD(Instruction *In1, Instruction *In2) { void MetadataContextImpl::copyMD(Instruction *In1, Instruction *In2) {
@ -368,46 +411,7 @@ void MetadataContextImpl::copyMD(Instruction *In1, Instruction *In2) {
return; return;
for (MDMapTy::iterator I = In1Info.begin(), E = In1Info.end(); I != E; ++I) for (MDMapTy::iterator I = In1Info.begin(), E = In1Info.end(); I != E; ++I)
addMD(I->first, I->second, In2); In2->setMetadata(I->first, I->second);
}
/// getMD - Get the metadata of given kind attached to an Instruction.
/// If the metadata is not found then return 0.
MDNode *MetadataContextImpl::getMD(unsigned MDKind, const Instruction *Inst) {
MDMapTy &Info = MetadataStore[Inst];
if (Info.empty())
return NULL;
for (MDMapTy::iterator I = Info.begin(), E = Info.end(); I != E; ++I)
if (I->first == MDKind)
return I->second;
return NULL;
}
/// getMDs - Get the metadata attached to an Instruction.
void MetadataContextImpl::
getMDs(const Instruction *Inst,
SmallVectorImpl<std::pair<unsigned, MDNode*> > &MDs) const {
MDStoreTy::const_iterator I = MetadataStore.find(Inst);
if (I == MetadataStore.end())
return;
MDs.resize(I->second.size());
for (MDMapTy::const_iterator MI = I->second.begin(), ME = I->second.end();
MI != ME; ++MI)
// MD kinds are numbered from 1.
MDs[MI->first - 1] = std::make_pair(MI->first, MI->second);
}
/// getHandlerNames - Populate client supplied smallvector using custome
/// metadata name and ID.
void MetadataContextImpl::
getMDKindNames(SmallVectorImpl<StringRef> &Names) const {
Names.resize(MDHandlerNames.size()+1);
Names[0] = "";
for (StringMap<unsigned>::const_iterator I = MDHandlerNames.begin(),
E = MDHandlerNames.end(); I != E; ++I)
// MD Handlers are numbered from 1.
Names[I->second] = I->first();
} }
/// ValueIsCloned - This handler is used to update metadata store /// ValueIsCloned - This handler is used to update metadata store
@ -421,7 +425,7 @@ void MetadataContextImpl::ValueIsCloned(const Instruction *In1,
// FIXME: Give all metadata handlers a chance to adjust. // FIXME: Give all metadata handlers a chance to adjust.
MDMapTy &In1Info = I->second; MDMapTy &In1Info = I->second;
for (MDMapTy::iterator I = In1Info.begin(), E = In1Info.end(); I != E; ++I) for (MDMapTy::iterator I = In1Info.begin(), E = In1Info.end(); I != E; ++I)
addMD(I->first, I->second, In2); In2->setMetadata(I->first, I->second);
} }
/// ValueIsRAUWd - This handler is used when V1's all uses are replaced by /// ValueIsRAUWd - This handler is used when V1's all uses are replaced by
@ -463,34 +467,6 @@ unsigned MetadataContext::getMDKindID(StringRef Name) const {
return pImpl->getMDKindID(Name); return pImpl->getMDKindID(Name);
} }
/// getMD - Get the metadata of given kind attached to an Instruction.
/// If the metadata is not found then return 0.
MDNode *MetadataContext::getMD(unsigned Kind, const Instruction *Inst) {
return pImpl->getMD(Kind, Inst);
}
/// getMDs - Get the metadata attached to an Instruction.
void MetadataContext::
getMDs(const Instruction *Inst,
SmallVectorImpl<std::pair<unsigned, MDNode*> > &MDs) const {
return pImpl->getMDs(Inst, MDs);
}
/// addMD - Attach the metadata of given kind to an Instruction.
void MetadataContext::addMD(unsigned Kind, MDNode *Node, Instruction *Inst) {
pImpl->addMD(Kind, Node, Inst);
}
/// removeMD - Remove metadata of given kind attached with an instruction.
void MetadataContext::removeMD(unsigned Kind, Instruction *Inst) {
pImpl->removeMD(Kind, Inst);
}
/// removeAllMetadata - Remove all metadata attached with an instruction.
void MetadataContext::removeAllMetadata(Instruction *Inst) {
pImpl->removeAllMetadata(Inst);
}
/// copyMD - If metadata is attached with Instruction In1 then attach /// copyMD - If metadata is attached with Instruction In1 then attach
/// the same metadata to In2. /// the same metadata to In2.
void MetadataContext::copyMD(Instruction *In1, Instruction *In2) { void MetadataContext::copyMD(Instruction *In1, Instruction *In2) {
@ -517,3 +493,35 @@ void MetadataContext::ValueIsRAUWd(Value *V1, Value *V2) {
void MetadataContext::ValueIsCloned(const Instruction *In1, Instruction *In2) { void MetadataContext::ValueIsCloned(const Instruction *In1, Instruction *In2) {
pImpl->ValueIsCloned(In1, In2); pImpl->ValueIsCloned(In1, In2);
} }
//===----------------------------------------------------------------------===//
// Instruction Metadata method implementations.
//
void Instruction::setMetadata(const char *Kind, MDNode *Node) {
if (Node == 0 && !hasMetadata()) return;
setMetadata(getContext().getMetadata().getMDKindID(Kind), Node);
}
MDNode *Instruction::getMetadataImpl(const char *Kind) const {
return getMetadataImpl(getContext().getMetadata().getMDKindID(Kind));
}
/// setMetadata - Set the metadata of of the specified kind to the specified
/// node. This updates/replaces metadata if already present, or removes it if
/// Node is null.
void Instruction::setMetadata(unsigned KindID, MDNode *Node) {
if (Node == 0 && !hasMetadata()) return;
getContext().getMetadata().pImpl->setMetadata(this, KindID, Node);
}
MDNode *Instruction::getMetadataImpl(unsigned KindID) const {
return getContext().getMetadata().pImpl->getMetadata(this, KindID);
}
void Instruction::getAllMetadataImpl(SmallVectorImpl<std::pair<unsigned,
MDNode*> > &Result)const {
getContext().getMetadata().pImpl->getAllMetadata(this, Result);
}

View File

@ -41,7 +41,7 @@ static inline const Type *checkType(const Type *Ty) {
} }
Value::Value(const Type *ty, unsigned scid) Value::Value(const Type *ty, unsigned scid)
: SubclassID(scid), HasValueHandle(0), HasMetadata(0), : SubclassID(scid), HasValueHandle(0),
SubclassOptionalData(0), SubclassData(0), VTy(checkType(ty)), SubclassOptionalData(0), SubclassData(0), VTy(checkType(ty)),
UseList(0), Name(0) { UseList(0), Name(0) {
if (isa<CallInst>(this) || isa<InvokeInst>(this)) if (isa<CallInst>(this) || isa<InvokeInst>(this))
@ -57,11 +57,6 @@ Value::Value(const Type *ty, unsigned scid)
} }
Value::~Value() { Value::~Value() {
if (HasMetadata) {
LLVMContext &Context = getContext();
Context.pImpl->TheMetadata.ValueIsDeleted(this);
}
// Notify all ValueHandles (if present) that this value is going away. // Notify all ValueHandles (if present) that this value is going away.
if (HasValueHandle) if (HasValueHandle)
ValueHandleBase::ValueIsDeleted(this); ValueHandleBase::ValueIsDeleted(this);
@ -306,10 +301,14 @@ void Value::uncheckedReplaceAllUsesWith(Value *New) {
// Notify all ValueHandles (if present) that this value is going away. // Notify all ValueHandles (if present) that this value is going away.
if (HasValueHandle) if (HasValueHandle)
ValueHandleBase::ValueIsRAUWd(this, New); ValueHandleBase::ValueIsRAUWd(this, New);
if (HasMetadata) {
LLVMContext &Context = getContext(); // FIXME: It doesn't make sense at all for metadata to follow RAUW.
Context.pImpl->TheMetadata.ValueIsRAUWd(this, New); if (Instruction *I = dyn_cast<Instruction>(this))
} if (I->hasMetadata()) {
LLVMContext &Context = getContext();
// FIXME: NUKE ValueIsRAUWd??
Context.pImpl->TheMetadata.ValueIsRAUWd(this, New);
}
while (!use_empty()) { while (!use_empty()) {
Use &U = *UseList; Use &U = *UseList;