diff options
author | Devang Patel <dpatel@apple.com> | 2009-09-18 19:26:43 +0000 |
---|---|---|
committer | Devang Patel <dpatel@apple.com> | 2009-09-18 19:26:43 +0000 |
commit | e8e0213cc3daa2d0457c22e4c12e6973f21fc942 (patch) | |
tree | 011f5819548ed35e3c31b6abe45e271bf0eb1147 /lib/Bitcode/Writer | |
parent | 88d9839d07a6b5a03484d664913de0f2b33d3bff (diff) |
Write and read metadata attachments.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@82259 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Bitcode/Writer')
-rw-r--r-- | lib/Bitcode/Writer/BitcodeWriter.cpp | 76 | ||||
-rw-r--r-- | lib/Bitcode/Writer/ValueEnumerator.cpp | 23 | ||||
-rw-r--r-- | lib/Bitcode/Writer/ValueEnumerator.h | 12 |
3 files changed, 106 insertions, 5 deletions
diff --git a/lib/Bitcode/Writer/BitcodeWriter.cpp b/lib/Bitcode/Writer/BitcodeWriter.cpp index 9cb5758576..3d89f3d0f0 100644 --- a/lib/Bitcode/Writer/BitcodeWriter.cpp +++ b/lib/Bitcode/Writer/BitcodeWriter.cpp @@ -551,7 +551,74 @@ static void WriteModuleMetadata(const ValueEnumerator &VE, } if (StartedMetadataBlock) - Stream.ExitBlock(); + Stream.ExitBlock(); +} + +static void WriteMetadataAttachment(const Function &F, + const ValueEnumerator &VE, + BitstreamWriter &Stream) { + bool StartedMetadataBlock = false; + SmallVector<uint64_t, 64> Record; + + // Write metadata attachments + // METADATA_ATTACHMENT - [m x [value, [n x [id, mdnode]]] + Metadata &TheMetadata = F.getContext().getMetadata(); + 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) { + const Metadata::MDMapTy *P = TheMetadata.getMDs(I); + if (!P) continue; + bool RecordedInstruction = false; + for (Metadata::MDMapTy::const_iterator PI = P->begin(), PE = P->end(); + PI != PE; ++PI) { + if (MDNode *ND = dyn_cast_or_null<MDNode>(PI->second)) { + if (RecordedInstruction == false) { + Record.push_back(VE.getInstructionID(I)); + RecordedInstruction = true; + } + Record.push_back(PI->first); + Record.push_back(VE.getValueID(ND)); + } + } + if (!StartedMetadataBlock) { + Stream.EnterSubblock(bitc::METADATA_ATTACHMENT_ID, 3); + StartedMetadataBlock = true; + } + Stream.EmitRecord(bitc::METADATA_ATTACHMENT, Record, 0); + Record.clear(); + } + + if (StartedMetadataBlock) + Stream.ExitBlock(); +} + +static void WriteModuleMetadataStore(const Module *M, + const ValueEnumerator &VE, + BitstreamWriter &Stream) { + + bool StartedMetadataBlock = false; + SmallVector<uint64_t, 64> Record; + + // Write metadata kinds + // METADATA_KIND - [n x [id, name]] + Metadata &TheMetadata = M->getContext().getMetadata(); + const StringMap<unsigned> *Kinds = TheMetadata.getHandlerNames(); + for (StringMap<unsigned>::const_iterator + I = Kinds->begin(), E = Kinds->end(); I != E; ++I) { + Record.push_back(I->second); + StringRef KName = I->first(); + for (unsigned i = 0, e = KName.size(); i != e; ++i) + Record.push_back(KName[i]); + if (!StartedMetadataBlock) { + Stream.EnterSubblock(bitc::METADATA_BLOCK_ID, 3); + StartedMetadataBlock = true; + } + Stream.EmitRecord(bitc::METADATA_KIND, Record, 0); + Record.clear(); + } + + if (StartedMetadataBlock) + Stream.ExitBlock(); } static void WriteConstants(unsigned FirstVal, unsigned LastVal, @@ -833,6 +900,7 @@ static void WriteInstruction(const Instruction &I, unsigned InstID, SmallVector<unsigned, 64> &Vals) { unsigned Code = 0; unsigned AbbrevToUse = 0; + VE.setInstructionID(&I); switch (I.getOpcode()) { default: if (Instruction::isCast(I.getOpcode())) { @@ -1146,7 +1214,8 @@ static void WriteFunction(const Function &F, ValueEnumerator &VE, // Emit names for all the instructions etc. WriteValueSymbolTable(F.getValueSymbolTable(), VE, Stream); - + + WriteMetadataAttachment(F, VE, Stream); VE.purgeFunction(); Stream.ExitBlock(); } @@ -1390,6 +1459,9 @@ static void WriteModule(const Module *M, BitstreamWriter &Stream) { for (Module::const_iterator I = M->begin(), E = M->end(); I != E; ++I) if (!I->isDeclaration()) WriteFunction(*I, VE, Stream); + + // Emit metadata. + WriteModuleMetadataStore(M, VE, Stream); // Emit the type symbol table information. WriteTypeSymbolTable(M->getTypeSymbolTable(), VE, Stream); diff --git a/lib/Bitcode/Writer/ValueEnumerator.cpp b/lib/Bitcode/Writer/ValueEnumerator.cpp index 783022cac2..f4682a2f63 100644 --- a/lib/Bitcode/Writer/ValueEnumerator.cpp +++ b/lib/Bitcode/Writer/ValueEnumerator.cpp @@ -40,6 +40,8 @@ static bool CompareByFrequency(const std::pair<const llvm::Type*, /// ValueEnumerator - Enumerate module-level information. ValueEnumerator::ValueEnumerator(const Module *M) { + InstructionCount = 0; + // Enumerate the global variables. for (Module::const_global_iterator I = M->global_begin(), E = M->global_end(); I != E; ++I) @@ -83,7 +85,8 @@ ValueEnumerator::ValueEnumerator(const Module *M) { for (Function::const_arg_iterator I = F->arg_begin(), E = F->arg_end(); I != E; ++I) EnumerateType(I->getType()); - + + Metadata &TheMetadata = F->getContext().getMetadata(); 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(); @@ -94,6 +97,14 @@ ValueEnumerator::ValueEnumerator(const Module *M) { EnumerateAttributes(CI->getAttributes()); else if (const InvokeInst *II = dyn_cast<InvokeInst>(I)) EnumerateAttributes(II->getAttributes()); + + // Enumerate metadata attached with this instruction. + const Metadata::MDMapTy *MDs = TheMetadata.getMDs(I); + if (MDs) + for (Metadata::MDMapTy::const_iterator MI = MDs->begin(), + ME = MDs->end(); MI != ME; ++MI) + if (MDNode *MDN = dyn_cast_or_null<MDNode>(MI->second)) + EnumerateMetadata(MDN); } } @@ -114,6 +125,16 @@ ValueEnumerator::ValueEnumerator(const Module *M) { TypeMap[Types[i].first] = i+1; } +unsigned ValueEnumerator::getInstructionID(const Instruction *Inst) const { + InstructionMapType::const_iterator I = InstructionMap.find(Inst); + assert (I != InstructionMap.end() && "Instruction is not mapped!"); + return I->second; +} + +void ValueEnumerator::setInstructionID(const Instruction *I) { + InstructionMap[I] = InstructionCount++; +} + unsigned ValueEnumerator::getValueID(const Value *V) const { if (isa<MetadataBase>(V)) { ValueMapType::const_iterator I = MDValueMap.find(V); diff --git a/lib/Bitcode/Writer/ValueEnumerator.h b/lib/Bitcode/Writer/ValueEnumerator.h index b5106f0809..da63dde2a2 100644 --- a/lib/Bitcode/Writer/ValueEnumerator.h +++ b/lib/Bitcode/Writer/ValueEnumerator.h @@ -22,6 +22,7 @@ namespace llvm { class Type; class Value; +class Instruction; class BasicBlock; class Function; class Module; @@ -47,11 +48,15 @@ private: ValueList Values; ValueList MDValues; ValueMapType MDValueMap; - + typedef DenseMap<void*, unsigned> AttributeMapType; AttributeMapType AttributeMap; std::vector<AttrListPtr> Attributes; + typedef DenseMap<const Instruction*, unsigned> InstructionMapType; + InstructionMapType InstructionMap; + unsigned InstructionCount; + /// BasicBlocks - This contains all the basic blocks for the currently /// incorporated function. Their reverse mapping is stored in ValueMap. std::vector<const BasicBlock*> BasicBlocks; @@ -74,7 +79,10 @@ public: assert(I != TypeMap.end() && "Type not in ValueEnumerator!"); return I->second-1; } - + + unsigned getInstructionID(const Instruction *I) const; + void setInstructionID(const Instruction *I); + unsigned getAttributeID(const AttrListPtr &PAL) const { if (PAL.isEmpty()) return 0; // Null maps to zero. AttributeMapType::const_iterator I = AttributeMap.find(PAL.getRawPointer()); |