diff --git a/include/llvm/Instruction.h b/include/llvm/Instruction.h index c4c746a49f6..6cfe0a1ca7b 100644 --- a/include/llvm/Instruction.h +++ b/include/llvm/Instruction.h @@ -21,6 +21,8 @@ namespace llvm { class LLVMContext; +class MDNode; +class MetadataContextImpl; template class SymbolTableListTraits; @@ -30,6 +32,10 @@ class Instruction : public User, public ilist_node { Instruction(const Instruction &); // Do not implement BasicBlock *Parent; + + // FIXME: Bitfieldize this. + bool HasMetadata; + friend class MetadataContextImpl; friend class SymbolTableListTraits; void setParent(BasicBlock *P); @@ -74,19 +80,19 @@ public: /// MovePos. void moveBefore(Instruction *MovePos); - // --------------------------------------------------------------------------- - /// Subclass classification... getOpcode() returns a member of - /// one of the enums that is coming soon (down below)... - /// + //===--------------------------------------------------------------------===// + // Subclass classification. + //===--------------------------------------------------------------------===// + + /// getOpcode() returns a member of one of the enums like Instruction::Add. unsigned getOpcode() const { return getValueID() - InstructionVal; } + const char *getOpcodeName() const { return getOpcodeName(getOpcode()); } bool isTerminator() const { return isTerminator(getOpcode()); } bool isBinaryOp() const { return isBinaryOp(getOpcode()); } bool isShift() { return isShift(getOpcode()); } bool isCast() const { return isCast(getOpcode()); } - - static const char* getOpcodeName(unsigned OpCode); static inline bool isTerminator(unsigned OpCode) { @@ -118,6 +124,55 @@ public: 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 > &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 > &)const; +public: + //===--------------------------------------------------------------------===// + // Predicates and helper methods. + //===--------------------------------------------------------------------===// + + /// isAssociative - Return true if the instruction is associative: /// /// Associative operators satisfy: x op (y op z) === (x op y) op z diff --git a/include/llvm/Metadata.h b/include/llvm/Metadata.h index a6e2d812e3a..6f3017df35f 100644 --- a/include/llvm/Metadata.h +++ b/include/llvm/Metadata.h @@ -205,6 +205,7 @@ class MetadataContext { void operator=(MetadataContext&); // DO NOT IMPLEMENT MetadataContextImpl *const pImpl; + friend class Instruction; public: MetadataContext(); ~MetadataContext(); @@ -215,25 +216,6 @@ public: /// isValidName - Return true if Name is a valid custom metadata handler 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 > &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 /// the same metadata to In2. void copyMD(Instruction *In1, Instruction *In2); diff --git a/include/llvm/Value.h b/include/llvm/Value.h index 0960346cb8a..f2fa36decaf 100644 --- a/include/llvm/Value.h +++ b/include/llvm/Value.h @@ -64,7 +64,6 @@ class MetadataContextImpl; class Value { const unsigned char SubclassID; // Subclass identifier (for isa/dyn_cast) unsigned char HasValueHandle : 1; // Has a ValueHandle pointing to this? - unsigned char HasMetadata : 1; // Has a metadata attached to this ? protected: /// SubclassOptionalData - This member is similar to SubclassData, however it /// is for holding information which may be used to aid optimization, but @@ -81,9 +80,7 @@ private: Use *UseList; friend class ValueSymbolTable; // Allow ValueSymbolTable to directly mod Name. - friend class SymbolTable; // Allow SymbolTable to directly poke Name. friend class ValueHandleBase; - friend class MetadataContextImpl; friend class AbstractTypeUser; ValueName *Name; @@ -303,9 +300,6 @@ 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/Analysis/DebugInfo.cpp b/lib/Analysis/DebugInfo.cpp index 3732818de36..256a7d1c364 100644 --- a/lib/Analysis/DebugInfo.cpp +++ b/lib/Analysis/DebugInfo.cpp @@ -1117,9 +1117,7 @@ Instruction *DIFactory::InsertDbgValueIntrinsic(Value *V, Value *Offset, /// 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 @@ void DebugInfoFinder::processModule(Module &M) { ++BI) { if (DbgDeclareInst *DDI = dyn_cast(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 a84336d6077..d9d2a4b2add 100644 --- a/lib/AsmParser/LLParser.cpp +++ b/lib/AsmParser/LLParser.cpp @@ -2826,10 +2826,9 @@ bool LLParser::ParseBasicBlock(PerFunctionState &PFS) { ParseOptionalCustomMetadata(); // Set metadata attached with this instruction. - MetadataContext &TheMetadata = M->getContext().getMetadata(); for (SmallVector, 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 0bda03e337f..568968d9276 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 @@ bool BitcodeReader::ParseMetadataAttachment() { if (Stream.EnterSubBlock(bitc::METADATA_ATTACHMENT_ID)) return Error("Malformed block record"); - MetadataContext &TheMetadata = Context.getMetadata(); SmallVector Record; while(1) { unsigned Code = Stream.ReadCode(); @@ -1599,7 +1597,7 @@ bool BitcodeReader::ParseMetadataAttachment() { for (unsigned i = 1; i != RecordLength; i = i+2) { unsigned Kind = Record[i]; Value *Node = MDValueList.getValueFwdRef(Record[i+1]); - TheMetadata.addMD(Kind, cast(Node), Inst); + Inst->setMetadata(Kind, cast(Node)); } break; } diff --git a/lib/Bitcode/Writer/BitcodeWriter.cpp b/lib/Bitcode/Writer/BitcodeWriter.cpp index cf8f7670c72..21548cd18d0 100644 --- a/lib/Bitcode/Writer/BitcodeWriter.cpp +++ b/lib/Bitcode/Writer/BitcodeWriter.cpp @@ -561,32 +561,29 @@ static void WriteMetadataAttachment(const Function &F, // Write metadata attachments // METADATA_ATTACHMENT - [m x [value, [n x [id, mdnode]]] - MetadataContext &TheMetadata = F.getContext().getMetadata(); - typedef SmallVector, 2> MDMapTy; - MDMapTy MDs; + SmallVector, 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 @@ static void WriteFunction(const Function &F, ValueEnumerator &VE, 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 29c6d374da9..a6da44f77ae 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 @@ ValueEnumerator::ValueEnumerator(const Module *M) { I != E; ++I) EnumerateType(I->getType()); - MetadataContext &TheMetadata = F->getContext().getMetadata(); - typedef SmallVector, 2> MDMapTy; - MDMapTy MDs; + SmallVector, 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 @@ ValueEnumerator::ValueEnumerator(const Module *M) { // 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 24a5b0d6481..714345db2c4 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 @@ bool FastISel::SelectCall(User *I) { 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 266cb64b715..ec949fc27b3 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 @@ SelectionDAGBuilder::visitIntrinsicCall(CallInst &I, unsigned Intrinsic) { 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 7efd480dccf..a46aad7e488 100644 --- a/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp +++ b/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp @@ -362,12 +362,12 @@ bool SelectionDAGISel::runOnMachineFunction(MachineFunction &mf) { /// 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(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 @@ static void SetDebugLoc(unsigned MDDbgKind, MetadataContext &TheMetadata, } /// 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 @@ void SelectionDAGISel::SelectBasicBlock(BasicBlock *LLVMBB, // 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(I)) { SDB->visit(*I); @@ -425,7 +424,7 @@ void SelectionDAGISel::SelectBasicBlock(BasicBlock *LLVMBB, 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 @@ void SelectionDAGISel::SelectAllBasicBlocks(Function &Fn, 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 b213b014eb2..0d756267cf5 100644 --- a/lib/Transforms/IPO/StripSymbols.cpp +++ b/lib/Transforms/IPO/StripSymbols.cpp @@ -228,7 +228,7 @@ static bool StripDebugInfo(Module &M) { ++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 2f94ee16cb4..995d6e4baa7 100644 --- a/lib/Transforms/Utils/CloneFunction.cpp +++ b/lib/Transforms/Utils/CloneFunction.cpp @@ -426,7 +426,7 @@ void llvm::CloneAndPruneFunctionInto(Function *NewFunc, const Function *OldFunc, MDNode *TheCallMD = NULL; SmallVector 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 @@ void llvm::CloneAndPruneFunctionInto(Function *NewFunc, const Function *OldFunc, for (; (PN = dyn_cast(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(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 c9c9bf0fe9e..824eac09023 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 @@ void SlotTracker::processFunction() { ST_DEBUG("Inserting Instructions:\n"); - MetadataContext &TheMetadata = TheFunction->getContext().getMetadata(); - typedef SmallVector, 2> MDMapTy; - MDMapTy MDs; + SmallVector, 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(I->getOperand(i))) - CreateMetadataSlot(N); + + // Intrinsics can directly use metadata. + if (isa(I)) + for (unsigned i = 0, e = I->getNumOperands(); i != e; ++i) + if (MDNode *N = dyn_cast_or_null(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 @@ void AssemblyWriter::printInstruction(const Instruction &I) { // Print Metadata info. if (!MDNames.empty()) { - MetadataContext &TheMetadata = I.getContext().getMetadata(); - typedef SmallVector, 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, 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 0b4a10925a2..4c0299c6fcf 100644 --- a/lib/VMCore/IRBuilder.cpp +++ b/lib/VMCore/IRBuilder.cpp @@ -43,7 +43,7 @@ void IRBuilderBase::SetCurrentDebugLocation(MDNode *L) { 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 ce253d64ced..f468c1bf3af 100644 --- a/lib/VMCore/Instruction.cpp +++ b/lib/VMCore/Instruction.cpp @@ -24,7 +24,8 @@ using namespace llvm; 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, 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 @@ Instruction::Instruction(const Type *ty, unsigned it, Use *Ops, unsigned NumOps, // 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 @@ bool Instruction::isSafeToSpeculativelyExecute() const { 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 a516d7bf93d..13747547318 100644 --- a/lib/VMCore/Metadata.cpp +++ b/lib/VMCore/Metadata.cpp @@ -261,32 +261,27 @@ private: StringMap 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 > &MDs) const; - - /// addMD - Attach the metadata of given kind to an Instruction. - void addMD(unsigned Kind, MDNode *Node, Instruction *Inst); + void getMDKindNames(SmallVectorImpl &) 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 > &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 &) const; + /// ValueIsDeleted - This handler is used to update metadata store /// when a value is deleted. @@ -308,96 +303,9 @@ unsigned MetadataContextImpl::getMDKindID(StringRef Name) { // 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 > &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 @@ getMDKindNames(SmallVectorImpl &Names) const { Names.resize(MDHandlerNames.size()+1); Names[0] = ""; for (StringMap::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 > &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 @@ void MetadataContextImpl::ValueIsCloned(const Instruction *In1, // 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 @@ unsigned MetadataContext::getMDKindID(StringRef Name) const { 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 > &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::ValueIsRAUWd(Value *V1, Value *V2) { 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 > &Result)const { + getContext().getMetadata().pImpl->getAllMetadata(this, Result); +} + diff --git a/lib/VMCore/Value.cpp b/lib/VMCore/Value.cpp index 826e8a10b5e..0155fa5cfef 100644 --- a/lib/VMCore/Value.cpp +++ b/lib/VMCore/Value.cpp @@ -41,7 +41,7 @@ static inline const Type *checkType(const Type *Ty) { } 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(this) || isa(this)) @@ -57,11 +57,6 @@ Value::Value(const Type *ty, unsigned scid) } 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 @@ void Value::uncheckedReplaceAllUsesWith(Value *New) { // 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(this)) + if (I->hasMetadata()) { + LLVMContext &Context = getContext(); + // FIXME: NUKE ValueIsRAUWd?? + Context.pImpl->TheMetadata.ValueIsRAUWd(this, New); + } while (!use_empty()) { Use &U = *UseList;