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
diff --git a/lib/Analysis/DebugInfo.cpp b/lib/Analysis/DebugInfo.cpp
index 3732818..256a7d1 100644
--- a/lib/Analysis/DebugInfo.cpp
+++ b/lib/Analysis/DebugInfo.cpp
@@ -1117,9 +1117,7 @@
/// processModule - Process entire module and collect debug info.
void DebugInfoFinder::processModule(Module &M) {
-
- MetadataContext &TheMetadata = M.getContext().getMetadata();
- unsigned MDDbgKind = TheMetadata.getMDKindID("dbg");
+ unsigned MDDbgKind = M.getContext().getMetadata().getMDKindID("dbg");
for (Module::iterator I = M.begin(), E = M.end(); I != E; ++I)
for (Function::iterator FI = (*I).begin(), FE = (*I).end(); FI != FE; ++FI)
@@ -1127,7 +1125,7 @@
++BI) {
if (DbgDeclareInst *DDI = dyn_cast<DbgDeclareInst>(BI))
processDeclare(DDI);
- else if (MDNode *L = TheMetadata.getMD(MDDbgKind, BI))
+ else if (MDNode *L = BI->getMetadata(MDDbgKind))
processLocation(DILocation(L));
}
diff --git a/lib/AsmParser/LLParser.cpp b/lib/AsmParser/LLParser.cpp
index a84336d..d9d2a4b 100644
--- a/lib/AsmParser/LLParser.cpp
+++ b/lib/AsmParser/LLParser.cpp
@@ -2826,10 +2826,9 @@
ParseOptionalCustomMetadata();
// Set metadata attached with this instruction.
- MetadataContext &TheMetadata = M->getContext().getMetadata();
for (SmallVector<std::pair<unsigned, MDNode *>, 2>::iterator
MDI = MDsOnInst.begin(), MDE = MDsOnInst.end(); MDI != MDE; ++MDI)
- TheMetadata.addMD(MDI->first, MDI->second, Inst);
+ Inst->setMetadata(MDI->first, MDI->second);
MDsOnInst.clear();
BB->getInstList().push_back(Inst);
diff --git a/lib/Bitcode/Reader/BitcodeReader.cpp b/lib/Bitcode/Reader/BitcodeReader.cpp
index 0bda03e..568968d 100644
--- a/lib/Bitcode/Reader/BitcodeReader.cpp
+++ b/lib/Bitcode/Reader/BitcodeReader.cpp
@@ -18,7 +18,6 @@
#include "llvm/InlineAsm.h"
#include "llvm/IntrinsicInst.h"
#include "llvm/LLVMContext.h"
-#include "llvm/Metadata.h"
#include "llvm/Module.h"
#include "llvm/Operator.h"
#include "llvm/AutoUpgrade.h"
@@ -1573,7 +1572,6 @@
if (Stream.EnterSubBlock(bitc::METADATA_ATTACHMENT_ID))
return Error("Malformed block record");
- MetadataContext &TheMetadata = Context.getMetadata();
SmallVector<uint64_t, 64> Record;
while(1) {
unsigned Code = Stream.ReadCode();
@@ -1599,7 +1597,7 @@
for (unsigned i = 1; i != RecordLength; i = i+2) {
unsigned Kind = Record[i];
Value *Node = MDValueList.getValueFwdRef(Record[i+1]);
- TheMetadata.addMD(Kind, cast<MDNode>(Node), Inst);
+ Inst->setMetadata(Kind, cast<MDNode>(Node));
}
break;
}
diff --git a/lib/Bitcode/Writer/BitcodeWriter.cpp b/lib/Bitcode/Writer/BitcodeWriter.cpp
index cf8f767..21548cd 100644
--- a/lib/Bitcode/Writer/BitcodeWriter.cpp
+++ b/lib/Bitcode/Writer/BitcodeWriter.cpp
@@ -561,32 +561,29 @@
// Write metadata attachments
// METADATA_ATTACHMENT - [m x [value, [n x [id, mdnode]]]
- MetadataContext &TheMetadata = F.getContext().getMetadata();
- typedef SmallVector<std::pair<unsigned, MDNode*>, 2> MDMapTy;
- MDMapTy MDs;
+ SmallVector<std::pair<unsigned, MDNode*>, 4> MDs;
+
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) {
MDs.clear();
- TheMetadata.getMDs(I, MDs);
- bool RecordedInstruction = false;
- for (MDMapTy::const_iterator PI = MDs.begin(), PE = MDs.end();
- PI != PE; ++PI) {
- if (RecordedInstruction == false) {
- Record.push_back(VE.getInstructionID(I));
- RecordedInstruction = true;
- }
- Record.push_back(PI->first);
- Record.push_back(VE.getValueID(PI->second));
+ I->getAllMetadata(MDs);
+
+ // If no metadata, ignore instruction.
+ if (MDs.empty()) continue;
+
+ Record.push_back(VE.getInstructionID(I));
+
+ for (unsigned i = 0, e = MDs.size(); i != e; ++i) {
+ Record.push_back(MDs[i].first);
+ Record.push_back(VE.getValueID(MDs[i].second));
}
- if (!Record.empty()) {
- if (!StartedMetadataBlock) {
- Stream.EnterSubblock(bitc::METADATA_ATTACHMENT_ID, 3);
- StartedMetadataBlock = true;
- }
- Stream.EmitRecord(bitc::METADATA_ATTACHMENT, Record, 0);
- Record.clear();
+ if (!StartedMetadataBlock) {
+ Stream.EnterSubblock(bitc::METADATA_ATTACHMENT_ID, 3);
+ StartedMetadataBlock = true;
}
+ Stream.EmitRecord(bitc::METADATA_ATTACHMENT, Record, 0);
+ Record.clear();
}
if (StartedMetadataBlock)
@@ -1208,7 +1205,7 @@
for (BasicBlock::const_iterator I = BB->begin(), E = BB->end();
I != E; ++I) {
WriteInstruction(*I, InstID, VE, Stream, Vals);
- if (I->getType() != Type::getVoidTy(F.getContext()))
+ if (!I->getType()->isVoidTy())
++InstID;
}
diff --git a/lib/Bitcode/Writer/ValueEnumerator.cpp b/lib/Bitcode/Writer/ValueEnumerator.cpp
index 29c6d37..a6da44f 100644
--- a/lib/Bitcode/Writer/ValueEnumerator.cpp
+++ b/lib/Bitcode/Writer/ValueEnumerator.cpp
@@ -14,8 +14,6 @@
#include "ValueEnumerator.h"
#include "llvm/Constants.h"
#include "llvm/DerivedTypes.h"
-#include "llvm/LLVMContext.h"
-#include "llvm/Metadata.h"
#include "llvm/Module.h"
#include "llvm/TypeSymbolTable.h"
#include "llvm/ValueSymbolTable.h"
@@ -87,9 +85,7 @@
I != E; ++I)
EnumerateType(I->getType());
- MetadataContext &TheMetadata = F->getContext().getMetadata();
- typedef SmallVector<std::pair<unsigned, MDNode*>, 2> MDMapTy;
- MDMapTy MDs;
+ SmallVector<std::pair<unsigned, MDNode*>, 2> MDs;
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 (User::const_op_iterator OI = I->op_begin(), E = I->op_end();
@@ -103,10 +99,9 @@
// Enumerate metadata attached with this instruction.
MDs.clear();
- TheMetadata.getMDs(I, MDs);
- for (MDMapTy::const_iterator MI = MDs.begin(), ME = MDs.end(); MI != ME;
- ++MI)
- EnumerateMetadata(MI->second);
+ I->getAllMetadata(MDs);
+ for (unsigned i = 0, e = MDs.size(); i != e; ++i)
+ EnumerateMetadata(MDs[i].second);
}
}
diff --git a/lib/CodeGen/SelectionDAG/FastISel.cpp b/lib/CodeGen/SelectionDAG/FastISel.cpp
index 24a5b0d..714345d 100644
--- a/lib/CodeGen/SelectionDAG/FastISel.cpp
+++ b/lib/CodeGen/SelectionDAG/FastISel.cpp
@@ -43,7 +43,6 @@
#include "llvm/GlobalVariable.h"
#include "llvm/Instructions.h"
#include "llvm/IntrinsicInst.h"
-#include "llvm/LLVMContext.h"
#include "llvm/CodeGen/FastISel.h"
#include "llvm/CodeGen/MachineInstrBuilder.h"
#include "llvm/CodeGen/MachineModuleInfo.h"
@@ -349,10 +348,7 @@
if (SI == StaticAllocaMap.end()) break; // VLAs.
int FI = SI->second;
if (MMI) {
- MetadataContext &TheMetadata =
- DI->getParent()->getContext().getMetadata();
- unsigned MDDbgKind = TheMetadata.getMDKindID("dbg");
- if (MDNode *Dbg = TheMetadata.getMD(MDDbgKind, DI))
+ if (MDNode *Dbg = DI->getMetadata("dbg"))
MMI->setVariableDbgInfo(DI->getVariable(), FI, Dbg);
}
return true;
diff --git a/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp b/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp
index 266cb64..ec949fc 100644
--- a/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp
+++ b/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp
@@ -27,7 +27,6 @@
#include "llvm/Instructions.h"
#include "llvm/Intrinsics.h"
#include "llvm/IntrinsicInst.h"
-#include "llvm/LLVMContext.h"
#include "llvm/Module.h"
#include "llvm/CodeGen/FastISel.h"
#include "llvm/CodeGen/GCStrategy.h"
@@ -4379,14 +4378,9 @@
return 0; // VLAs.
int FI = SI->second;
- MachineModuleInfo *MMI = DAG.getMachineModuleInfo();
- if (MMI) {
- MetadataContext &TheMetadata =
- DI.getParent()->getContext().getMetadata();
- unsigned MDDbgKind = TheMetadata.getMDKindID("dbg");
- if (MDNode *Dbg = TheMetadata.getMD(MDDbgKind, &DI))
+ if (MachineModuleInfo *MMI = DAG.getMachineModuleInfo())
+ if (MDNode *Dbg = DI.getMetadata("dbg"))
MMI->setVariableDbgInfo(Variable, FI, Dbg);
- }
return 0;
}
case Intrinsic::eh_exception: {
diff --git a/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp b/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp
index 7efd480..a46aad7 100644
--- a/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp
+++ b/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp
@@ -362,12 +362,12 @@
/// SetDebugLoc - Update MF's and SDB's DebugLocs if debug information is
/// attached with this instruction.
-static void SetDebugLoc(unsigned MDDbgKind, MetadataContext &TheMetadata,
- Instruction *I, SelectionDAGBuilder *SDB,
+static void SetDebugLoc(unsigned MDDbgKind, Instruction *I,
+ SelectionDAGBuilder *SDB,
FastISel *FastIS, MachineFunction *MF) {
if (isa<DbgInfoIntrinsic>(I)) return;
- if (MDNode *Dbg = TheMetadata.getMD(MDDbgKind, I)) {
+ if (MDNode *Dbg = I->getMetadata(MDDbgKind)) {
DILocation DILoc(Dbg);
DebugLoc Loc = ExtractDebugLocation(DILoc, MF->getDebugLocInfo());
@@ -384,8 +384,7 @@
}
/// ResetDebugLoc - Set MF's and SDB's DebugLocs to Unknown.
-static void ResetDebugLoc(SelectionDAGBuilder *SDB,
- FastISel *FastIS) {
+static void ResetDebugLoc(SelectionDAGBuilder *SDB, FastISel *FastIS) {
SDB->setCurDebugLoc(DebugLoc::getUnknownLoc());
if (FastIS)
FastIS->setCurDebugLoc(DebugLoc::getUnknownLoc());
@@ -402,7 +401,7 @@
// Lower all of the non-terminator instructions. If a call is emitted
// as a tail call, cease emitting nodes for this block.
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)) {
SDB->visit(*I);
@@ -425,7 +424,7 @@
HandlePHINodesInSuccessorBlocks(LLVMBB);
// 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());
ResetDebugLoc(SDB, 0);
}
@@ -776,7 +775,7 @@
break;
}
- SetDebugLoc(MDDbgKind, TheMetadata, BI, SDB, FastIS, &MF);
+ SetDebugLoc(MDDbgKind, BI, SDB, FastIS, &MF);
// First try normal tablegen-generated "fast" selection.
if (FastIS->SelectInstruction(BI)) {
diff --git a/lib/Transforms/IPO/StripSymbols.cpp b/lib/Transforms/IPO/StripSymbols.cpp
index b213b01..0d75626 100644
--- a/lib/Transforms/IPO/StripSymbols.cpp
+++ b/lib/Transforms/IPO/StripSymbols.cpp
@@ -228,7 +228,7 @@
++FI)
for (BasicBlock::iterator BI = FI->begin(), BE = FI->end(); BI != BE;
++BI)
- TheMetadata.removeMD(MDDbgKind, BI);
+ BI->setMetadata(MDDbgKind, 0);
return true;
}
diff --git a/lib/Transforms/Utils/CloneFunction.cpp b/lib/Transforms/Utils/CloneFunction.cpp
index 2f94ee1..995d6e4 100644
--- a/lib/Transforms/Utils/CloneFunction.cpp
+++ b/lib/Transforms/Utils/CloneFunction.cpp
@@ -426,7 +426,7 @@
MDNode *TheCallMD = NULL;
SmallVector<Value *, 4> MDVs;
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
// blocks.
@@ -436,32 +436,38 @@
for (; (PN = dyn_cast<PHINode>(I)); ++I, ++OldI) {
if (I->hasMetadata()) {
if (TheCallMD) {
- if (MDNode *IMD = Context.getMetadata().getMD(DbgKind, I)) {
+ if (MDNode *IMD = I->getMetadata(DbgKind)) {
MDNode *NewMD = UpdateInlinedAtInfo(IMD, TheCallMD, Context);
- Context.getMetadata().addMD(DbgKind, NewMD, I);
+ I->setMetadata(DbgKind, NewMD);
}
} else {
// The cloned instruction has dbg info but the call 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));
}
}
+ // FIXME:
+ // FIXME:
+ // FIXME: Unclone all this metadata stuff.
+ // FIXME:
+ // FIXME:
+
// Otherwise, remap the rest of the instructions normally.
for (; I != NewBB->end(); ++I) {
if (I->hasMetadata()) {
if (TheCallMD) {
- if (MDNode *IMD = Context.getMetadata().getMD(DbgKind, I)) {
+ if (MDNode *IMD = I->getMetadata(DbgKind)) {
MDNode *NewMD = UpdateInlinedAtInfo(IMD, TheCallMD, Context);
- Context.getMetadata().addMD(DbgKind, NewMD, I);
+ I->setMetadata(DbgKind, NewMD);
}
} else {
// The cloned instruction has dbg info but the call instruction
// does not have dbg info. Remove dbg info from cloned instruction.
- Context.getMetadata().removeMD(DbgKind, I);
+ I->setMetadata(DbgKind, 0);
}
}
RemapInstruction(I, ValueMap);
diff --git a/lib/VMCore/AsmWriter.cpp b/lib/VMCore/AsmWriter.cpp
index c9c9bf0..824eac0 100644
--- a/lib/VMCore/AsmWriter.cpp
+++ b/lib/VMCore/AsmWriter.cpp
@@ -21,11 +21,9 @@
#include "llvm/Constants.h"
#include "llvm/DerivedTypes.h"
#include "llvm/InlineAsm.h"
-#include "llvm/Instruction.h"
-#include "llvm/Instructions.h"
+#include "llvm/IntrinsicInst.h"
#include "llvm/LLVMContext.h"
#include "llvm/Operator.h"
-#include "llvm/Metadata.h"
#include "llvm/Module.h"
#include "llvm/ValueSymbolTable.h"
#include "llvm/TypeSymbolTable.h"
@@ -680,30 +678,30 @@
ST_DEBUG("Inserting Instructions:\n");
- MetadataContext &TheMetadata = TheFunction->getContext().getMetadata();
- typedef SmallVector<std::pair<unsigned, MDNode*>, 2> MDMapTy;
- MDMapTy MDs;
+ SmallVector<std::pair<unsigned, MDNode*>, 2> MDForInst;
// Add all of the basic blocks and instructions with no names.
for (Function::const_iterator BB = TheFunction->begin(),
E = TheFunction->end(); BB != E; ++BB) {
if (!BB->hasName())
CreateFunctionSlot(BB);
+
for (BasicBlock::const_iterator I = BB->begin(), E = BB->end(); I != E;
++I) {
- if (I->getType() != Type::getVoidTy(TheFunction->getContext()) &&
- !I->hasName())
+ if (!I->getType()->isVoidTy() && !I->hasName())
CreateFunctionSlot(I);
- for (unsigned i = 0, e = I->getNumOperands(); i != e; ++i)
- if (MDNode *N = dyn_cast_or_null<MDNode>(I->getOperand(i)))
- CreateMetadataSlot(N);
+
+ // Intrinsics can directly use metadata.
+ 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.
- MDs.clear();
- TheMetadata.getMDs(I, MDs);
- for (MDMapTy::const_iterator MI = MDs.begin(), ME = MDs.end(); MI != ME;
- ++MI)
- CreateMetadataSlot(MI->second);
+ MDForInst.clear();
+ I->getAllMetadata(MDForInst);
+ for (unsigned i = 0, e = MDForInst.size(); i != e; ++i)
+ CreateMetadataSlot(MDForInst[i].second);
}
}
@@ -2076,14 +2074,11 @@
// Print Metadata info.
if (!MDNames.empty()) {
- MetadataContext &TheMetadata = I.getContext().getMetadata();
- typedef SmallVector<std::pair<unsigned, MDNode*>, 2> MDMapTy;
- MDMapTy MDs;
- TheMetadata.getMDs(&I, MDs);
- for (MDMapTy::const_iterator MI = MDs.begin(), ME = MDs.end(); MI != ME;
- ++MI)
- Out << ", !" << MDNames[MI->first]
- << " !" << Machine.getMetadataSlot(MI->second);
+ SmallVector<std::pair<unsigned, MDNode*>, 4> InstMD;
+ I.getAllMetadata(InstMD);
+ for (unsigned i = 0, e = InstMD.size(); i != e; ++i)
+ Out << ", !" << MDNames[InstMD[i].first]
+ << " !" << Machine.getMetadataSlot(InstMD[i].second);
}
printInfoComment(I);
}
diff --git a/lib/VMCore/IRBuilder.cpp b/lib/VMCore/IRBuilder.cpp
index 0b4a109..4c0299c 100644
--- a/lib/VMCore/IRBuilder.cpp
+++ b/lib/VMCore/IRBuilder.cpp
@@ -43,7 +43,7 @@
void IRBuilderBase::SetInstDebugLocation(Instruction *I) const {
if (CurDbgLocation)
- Context.getMetadata().addMD(DbgMDKind, CurDbgLocation, I);
+ I->setMetadata(DbgMDKind, CurDbgLocation);
}
const Type *IRBuilderBase::getCurrentFunctionReturnType() const {
diff --git a/lib/VMCore/Instruction.cpp b/lib/VMCore/Instruction.cpp
index ce253d6..f468c1b 100644
--- a/lib/VMCore/Instruction.cpp
+++ b/lib/VMCore/Instruction.cpp
@@ -24,7 +24,8 @@
Instruction::Instruction(const Type *ty, unsigned it, Use *Ops, unsigned NumOps,
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
LeakDetector::addGarbageObject(this);
@@ -38,7 +39,8 @@
Instruction::Instruction(const Type *ty, unsigned it, Use *Ops, unsigned NumOps,
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
LeakDetector::addGarbageObject(this);
@@ -51,10 +53,8 @@
// Out of line virtual method, so the vtable, etc has a home.
Instruction::~Instruction() {
assert(Parent == 0 && "Instruction still linked in the program!");
- if (hasMetadata()) {
- LLVMContext &Context = getContext();
- Context.pImpl->TheMetadata.ValueIsDeleted(this);
- }
+ if (HasMetadata)
+ getContext().pImpl->TheMetadata.ValueIsDeleted(this);
}
@@ -464,7 +464,7 @@
Instruction *Instruction::clone() const {
Instruction *New = clone_impl();
New->SubclassOptionalData = SubclassOptionalData;
- if (hasMetadata())
+ if (HasMetadata)
getContext().pImpl->TheMetadata.ValueIsCloned(this, New);
return New;
}
diff --git a/lib/VMCore/Metadata.cpp b/lib/VMCore/Metadata.cpp
index a516d7b..1374754 100644
--- a/lib/VMCore/Metadata.cpp
+++ b/lib/VMCore/Metadata.cpp
@@ -261,32 +261,27 @@
StringMap<unsigned> MDHandlerNames;
public:
+ // Name <-> ID mapping methods.
unsigned getMDKindID(StringRef Name);
-
- /// 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);
+ void getMDKindNames(SmallVectorImpl<StringRef> &) const;
- /// removeMD - Remove metadata of given kind attached with an instruction.
- void removeMD(unsigned Kind, Instruction *Inst);
+ // Instruction metadata methods.
+ MDNode *getMetadata(const Instruction *Inst, unsigned Kind);
+ void getAllMetadata(const Instruction *Inst,
+ SmallVectorImpl<std::pair<unsigned, MDNode*> > &MDs)const;
+
+ void setMetadata(Instruction *Inst, unsigned Kind, MDNode *Node);
+
/// removeAllMetadata - Remove all metadata attached with an instruction.
void removeAllMetadata(Instruction *Inst);
-
+
+
+
/// copyMD - If metadata is attached with Instruction In1 then attach
/// the same metadata to 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
/// when a value is deleted.
@@ -308,96 +303,9 @@
// If this is new, assign it its ID.
if (Entry == 0) Entry = MDHandlerNames.size();
-
return Entry;
}
-/// addMD - Attach the metadata of given kind to an Instruction.
-void MetadataContextImpl::addMD(unsigned MDKind, MDNode *Node,
- Instruction *Inst) {
- assert(Node && "Invalid null MDNode");
- Inst->HasMetadata = true;
- MDMapTy &Info = MetadataStore[Inst];
- if (Info.empty()) {
- Info.push_back(std::make_pair(MDKind, Node));
- MetadataStore.insert(std::make_pair(Inst, Info));
- return;
- }
-
- // 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;
- for (MDMapTy::iterator MI = Info.begin(), ME = Info.end(); MI != ME; ++MI) {
- MDPairTy &P = *MI;
- if (P.first == Kind) {
- Info.erase(MI);
- return;
- }
- }
-}
-
-/// removeAllMetadata - Remove all metadata attached with an instruction.
-void MetadataContextImpl::removeAllMetadata(Instruction *Inst) {
- MetadataStore.erase(Inst);
- Inst->HasMetadata = false;
-}
-
-/// copyMD - If metadata is attached with Instruction In1 then attach
-/// the same metadata to In2.
-void MetadataContextImpl::copyMD(Instruction *In1, Instruction *In2) {
- assert(In1 && In2 && "Invalid instruction!");
- MDMapTy &In1Info = MetadataStore[In1];
- if (In1Info.empty())
- return;
-
- for (MDMapTy::iterator I = In1Info.begin(), E = In1Info.end(); I != E; ++I)
- addMD(I->first, I->second, In2);
-}
-
-/// 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::
@@ -405,11 +313,107 @@
Names.resize(MDHandlerNames.size()+1);
Names[0] = "";
for (StringMap<unsigned>::const_iterator I = MDHandlerNames.begin(),
- E = MDHandlerNames.end(); I != E; ++I)
+ E = MDHandlerNames.end(); I != E; ++I)
// MD Handlers are numbered from 1.
Names[I->second] = I->first();
}
+
+/// getMetadata - Get the metadata of given kind attached to an Instruction.
+/// If the metadata is not found then return 0.
+MDNode *MetadataContextImpl::
+getMetadata(const Instruction *Inst, unsigned MDKind) {
+ 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;
+ }
+ // Otherwise, removing an entry that doesn't exist on the instruction.
+}
+
+/// removeAllMetadata - Remove all metadata attached with an instruction.
+void MetadataContextImpl::removeAllMetadata(Instruction *Inst) {
+ MetadataStore.erase(Inst);
+ Inst->HasMetadata = false;
+}
+
+
+/// copyMD - If metadata is attached with Instruction In1 then attach
+/// the same metadata to In2.
+void MetadataContextImpl::copyMD(Instruction *In1, Instruction *In2) {
+ assert(In1 && In2 && "Invalid instruction!");
+ MDMapTy &In1Info = MetadataStore[In1];
+ if (In1Info.empty())
+ return;
+
+ for (MDMapTy::iterator I = In1Info.begin(), E = In1Info.end(); I != E; ++I)
+ In2->setMetadata(I->first, I->second);
+}
+
/// ValueIsCloned - This handler is used to update metadata store
/// when In1 is cloned to create In2.
void MetadataContextImpl::ValueIsCloned(const Instruction *In1,
@@ -421,7 +425,7 @@
// FIXME: Give all metadata handlers a chance to adjust.
MDMapTy &In1Info = I->second;
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
@@ -463,34 +467,6 @@
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
/// the same metadata to In2.
void MetadataContext::copyMD(Instruction *In1, Instruction *In2) {
@@ -517,3 +493,35 @@
void MetadataContext::ValueIsCloned(const Instruction *In1, Instruction *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);
+}
+
diff --git a/lib/VMCore/Value.cpp b/lib/VMCore/Value.cpp
index 826e8a1..0155fa5 100644
--- a/lib/VMCore/Value.cpp
+++ b/lib/VMCore/Value.cpp
@@ -41,7 +41,7 @@
}
Value::Value(const Type *ty, unsigned scid)
- : SubclassID(scid), HasValueHandle(0), HasMetadata(0),
+ : SubclassID(scid), HasValueHandle(0),
SubclassOptionalData(0), SubclassData(0), VTy(checkType(ty)),
UseList(0), Name(0) {
if (isa<CallInst>(this) || isa<InvokeInst>(this))
@@ -57,11 +57,6 @@
}
Value::~Value() {
- if (HasMetadata) {
- LLVMContext &Context = getContext();
- Context.pImpl->TheMetadata.ValueIsDeleted(this);
- }
-
// Notify all ValueHandles (if present) that this value is going away.
if (HasValueHandle)
ValueHandleBase::ValueIsDeleted(this);
@@ -306,10 +301,14 @@
// Notify all ValueHandles (if present) that this value is going away.
if (HasValueHandle)
ValueHandleBase::ValueIsRAUWd(this, New);
- if (HasMetadata) {
- LLVMContext &Context = getContext();
- Context.pImpl->TheMetadata.ValueIsRAUWd(this, New);
- }
+
+ // FIXME: It doesn't make sense at all for metadata to follow RAUW.
+ 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()) {
Use &U = *UseList;