[llvm-commits] PATCH: BasicBlock metadata
Ralf Karrenberg
karrenberg at cdl.uni-saarland.de
Tue May 8 14:18:10 PDT 2012
> On 5/8/12 7:07 AM, Richard Osborne wrote:
> > On 08/05/12 11:29, Ralf Karrenberg wrote:
> >> On 5/8/12 11:40 AM, Richard Osborne wrote:
> >>>> Cheers,
> >>>> Ralf
> >>>> /// hasAddressTaken - returns true if there are any uses of
this basic block
> >>>> /// other than direct branches, switches, etc. to it.
> >>>> - bool hasAddressTaken() const { return
getSubclassDataFromValue() != 0; }
> >>>> + bool hasAddressTaken() const {
> >>>> + return (getSubclassDataFromValue()& ~HasMetadataBit) != 0;
> >>>> + }
> >>> I think this will result in basic block metadata effecting
> >>> optimizations. What would happen if you just ignored metadata here?
> >> It will always treat a block that has metadata attached as a block
> >> whose address has been taken, which results in a crash at a later
> >> point (don't remember exactly where) because the address was never
taken.
>
> I think you might want to update the comment explaining what you said
> above and providing a justification for it. Developers misunderstanding
> code seems like a flag for a better comment, IMHO.
That makes sense. I attached the updated patch.
> -- John T.
>
> > Ah sorry, I totally misread this bit of the code. It looks fine to me.
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20120508/51cbd02d/attachment.html>
-------------- next part --------------
Index: test/Assembler/metadata-block.ll
===================================================================
--- test/Assembler/metadata-block.ll (revision 0)
+++ test/Assembler/metadata-block.ll (revision 0)
@@ -0,0 +1,36 @@
+; RUN: llvm-as < %s | llvm-dis | llvm-as | llvm-dis | FileCheck %s
+
+; CHECK: @test
+; CHECK: !foo !0
+; CHECK: !bar !1
+; CHECK: !bar !2
+; CHECK: !foo !3, !bar !4
+define i32 @test(i32 %a) {
+entry:
+ !foo !0
+ %x = mul i32 %a, %a
+ %cmp = icmp ogt i32 %x, 13
+ br i1 %cmp, label %if.then, label %if.else
+
+if.then:
+ !bar !1
+ %y = add i32 %a, 1
+ br label %if.end
+
+if.else:
+ !bar !2
+ %z = sub i32 %a, 1
+ br label %if.end
+
+if.end:
+ !foo !3, !bar !4
+ %r = phi i32 [ %y, %if.then ], [ %z, %if.else ]
+ ret i32 %r
+}
+
+!0 = metadata !{null}
+!1 = metadata !{i1 false}
+!2 = metadata !{i32 42}
+!3 = metadata !{i1 true}
+!4 = metadata !{i32 13}
+
Index: include/llvm/BasicBlock.h
===================================================================
--- include/llvm/BasicBlock.h (revision 156419)
+++ include/llvm/BasicBlock.h (working copy)
@@ -88,6 +88,12 @@
///
explicit BasicBlock(LLVMContext &C, const Twine &Name = "",
Function *Parent = 0, BasicBlock *InsertBefore = 0);
+
+ enum {
+ /// HasMetadataBit - This is a bit stored in the SubClassData field which
+ /// indicates whether this block has metadata attached to it or not.
+ HasMetadataBit = 1 << 15
+ };
public:
/// getContext - Get the context in which this basic block lives.
LLVMContext &getContext() const;
@@ -255,7 +261,11 @@
/// hasAddressTaken - returns true if there are any uses of this basic block
/// other than direct branches, switches, etc. to it.
- bool hasAddressTaken() const { return getSubclassDataFromValue() != 0; }
+ /// The metadatabit is deactivated to prevent returning 'true' in cases where
+ /// the address has not been taken but the block has metadata attached.
+ bool hasAddressTaken() const {
+ return (getSubclassDataFromValue() & ~HasMetadataBit) != 0;
+ }
/// replaceSuccessorsPhiUsesWith - Update all phi nodes in all our successors
/// to refer to basic block New instead of to us.
@@ -284,6 +294,69 @@
void setValueSubclassData(unsigned short D) {
Value::setValueSubclassData(D);
}
+ unsigned short getSubclassDataFromValue() const {
+ return Value::getSubclassDataFromValue();
+ }
+
+public:
+ //===--------------------------------------------------------------------===//
+ // Metadata manipulation.
+ //===--------------------------------------------------------------------===//
+
+ /// hasMetadata() - Return true if this block has any metadata attached
+ /// to it.
+ bool hasMetadata() const {
+ return hasMetadataHashEntry();
+ }
+
+ /// getMetadata - Get the metadata of given kind attached to this block.
+ /// 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 block.
+ /// If the metadata is not found then return null.
+ MDNode *getMetadata(StringRef Kind) const {
+ if (!hasMetadata()) return 0;
+ return getMetadataImpl(Kind);
+ }
+
+ /// getAllMetadata - Get all metadata attached to this block. 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 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(StringRef Kind, MDNode *Node);
+
+private:
+ /// hasMetadataHashEntry - Return true if we have an entry in the on-the-side
+ /// metadata hash.
+ bool hasMetadataHashEntry() const {
+ return (getSubclassDataFromValue() & HasMetadataBit) != 0;
+ }
+
+ // These are all implemented in Metadata.cpp.
+ MDNode *getMetadataImpl(unsigned KindID) const;
+ MDNode *getMetadataImpl(StringRef Kind) const;
+ void getAllMetadataImpl(SmallVectorImpl<std::pair<unsigned,MDNode*> > &)const;
+ void getAllMetadataOtherThanDebugLocImpl(SmallVectorImpl<std::pair<unsigned,
+ MDNode*> > &) const;
+ void clearMetadataHashEntries();
+
+ void setHasMetadataHashEntry(bool V) {
+ setValueSubclassData((getSubclassDataFromValue() & ~HasMetadataBit) |
+ (V ? HasMetadataBit : 0));
+ }
+
};
} // End llvm namespace
Index: include/llvm/Bitcode/LLVMBitCodes.h
===================================================================
--- include/llvm/Bitcode/LLVMBitCodes.h (revision 156419)
+++ include/llvm/Bitcode/LLVMBitCodes.h (working copy)
@@ -126,17 +126,18 @@
};
enum MetadataCodes {
- METADATA_STRING = 1, // MDSTRING: [values]
+ METADATA_STRING = 1, // MDSTRING: [values]
// 2 is unused.
// 3 is unused.
- METADATA_NAME = 4, // STRING: [values]
+ METADATA_NAME = 4, // STRING: [values]
// 5 is unused.
- METADATA_KIND = 6, // [n x [id, name]]
+ METADATA_KIND = 6, // [n x [id, name]]
// 7 is unused.
- METADATA_NODE = 8, // NODE: [n x (type num, value num)]
- METADATA_FN_NODE = 9, // FN_NODE: [n x (type num, value num)]
- METADATA_NAMED_NODE = 10, // NAMED_NODE: [n x mdnodes]
- METADATA_ATTACHMENT = 11 // [m x [value, [n x [id, mdnode]]]
+ METADATA_NODE = 8, // NODE: [n x (type num, value num)]
+ METADATA_FN_NODE = 9, // FN_NODE: [n x (type num, value num)]
+ METADATA_NAMED_NODE = 10, // NAMED_NODE: [n x mdnodes]
+ METADATA_ATTACHMENT = 11, // [m x [value, [n x [id, mdnode]]]
+ METADATA_BLOCK_ATTACHMENT = 12 // [m x [value, [n x [id, mdnode]]]
};
// The constants block (CONSTANTS_BLOCK_ID) describes emission for each
// constant and maintains an implicit current type value.
Index: docs/LangRef.html
===================================================================
--- docs/LangRef.html (revision 156419)
+++ docs/LangRef.html (working copy)
@@ -2898,12 +2898,12 @@
<div>
-<p>LLVM IR allows metadata to be attached to instructions in the program that
- can convey extra information about the code to the optimizers and code
- generator. One example application of metadata is source-level debug
- information. There are two metadata primitives: strings and nodes. All
- metadata has the <tt>metadata</tt> type and is identified in syntax by a
- preceding exclamation point ('<tt>!</tt>').</p>
+<p>LLVM IR allows metadata to be attached to instructions and basic blocks
+ in the program that can convey extra information about the code to the
+ optimizers and code generator. One example application of metadata is
+ source-level debug information. There are two metadata primitives: strings
+ and nodes. All metadata has the <tt>metadata</tt> type and is identified
+ in syntax by a preceding exclamation point ('<tt>!</tt>').</p>
<p>A metadata string is a string surrounded by double quotes. It can contain
any character by escaping non-printable characters with "<tt>\xx</tt>" where
@@ -2931,7 +2931,7 @@
</pre>
</div>
-<p>Metadata can be used as function arguments. Here <tt>llvm.dbg.value</tt>
+<p>Metadata can be used as function arguments. Here, <tt>llvm.dbg.value</tt>
function is using two metadata arguments:</p>
<div class="doc_code">
@@ -2940,7 +2940,7 @@
</pre>
</div>
-<p>Metadata can be attached with an instruction. Here metadata <tt>!21</tt> is
+<p>Metadata can be attached to an instruction. Here, metadata <tt>!21</tt> is
attached to the <tt>add</tt> instruction using the <tt>!dbg</tt>
identifier:</p>
@@ -2950,6 +2950,19 @@
</pre>
</div>
+<p>Metadata can be attached to a basic block. Here, metadata <tt>!42</tt> is
+ attached to the basic block <tt>entry</tt> using the <tt>!divergent</tt>
+ identifier:</p>
+
+<div class="doc_code">
+<pre>
+if.else:
+ !divergent !42
+ %x = fadd float %a, %b
+ br label %if.end
+</pre>
+</div>
+
<p>More information about specific metadata nodes recognized by the optimizers
and code generator is found below.</p>
Index: lib/VMCore/AsmWriter.cpp
===================================================================
--- lib/VMCore/AsmWriter.cpp (revision 156419)
+++ lib/VMCore/AsmWriter.cpp (working copy)
@@ -484,7 +484,7 @@
ST_DEBUG("Inserting Instructions:\n");
- SmallVector<std::pair<unsigned, MDNode*>, 4> MDForInst;
+ SmallVector<std::pair<unsigned, MDNode*>, 4> MDForInstOrBlock;
// Add all of the basic blocks and instructions with no names.
for (Function::const_iterator BB = TheFunction->begin(),
@@ -492,6 +492,12 @@
if (!BB->hasName())
CreateFunctionSlot(BB);
+ // Process metadata attached with this block.
+ BB->getAllMetadata(MDForInstOrBlock);
+ for (unsigned i = 0, e = MDForInstOrBlock.size(); i != e; ++i)
+ CreateMetadataSlot(MDForInstOrBlock[i].second);
+ MDForInstOrBlock.clear();
+
for (BasicBlock::const_iterator I = BB->begin(), E = BB->end(); I != E;
++I) {
if (!I->getType()->isVoidTy() && !I->hasName())
@@ -509,10 +515,10 @@
}
// Process metadata attached with this instruction.
- I->getAllMetadata(MDForInst);
- for (unsigned i = 0, e = MDForInst.size(); i != e; ++i)
- CreateMetadataSlot(MDForInst[i].second);
- MDForInst.clear();
+ I->getAllMetadata(MDForInstOrBlock);
+ for (unsigned i = 0, e = MDForInstOrBlock.size(); i != e; ++i)
+ CreateMetadataSlot(MDForInstOrBlock[i].second);
+ MDForInstOrBlock.clear();
}
}
@@ -1640,6 +1646,28 @@
Out << "\n";
+ // Print Metadata info.
+ SmallVector<std::pair<unsigned, MDNode*>, 4> BlockMD;
+ BB->getAllMetadata(BlockMD);
+ if (!BlockMD.empty()) {
+ Out << " ";
+ SmallVector<StringRef, 8> MDNames;
+ BB->getType()->getContext().getMDKindNames(MDNames);
+ for (unsigned i = 0, e = BlockMD.size(); i != e; ++i) {
+ unsigned Kind = BlockMD[i].first;
+ if (i != 0) Out << ',';
+ if (Kind < MDNames.size()) {
+ Out << " !" << MDNames[Kind];
+ } else {
+ Out << ", !<unknown kind #" << Kind << ">";
+ }
+ Out << ' ';
+ WriteAsOperandInternal(Out, BlockMD[i].second, &TypePrinter, &Machine,
+ TheModule);
+ }
+ Out << "\n";
+ }
+
if (AnnotationWriter) AnnotationWriter->emitBasicBlockStartAnnot(BB, Out);
// Output all of the instructions in the basic block...
Index: lib/VMCore/LLVMContextImpl.h
===================================================================
--- lib/VMCore/LLVMContextImpl.h (revision 156419)
+++ lib/VMCore/LLVMContextImpl.h (working copy)
@@ -333,6 +333,9 @@
/// MetadataStore - Collection of per-instruction metadata used in this
/// context.
DenseMap<const Instruction *, MDMapTy> MetadataStore;
+ /// MetadataBlockStore - Collection of per-block metadata used in this
+ /// context.
+ DenseMap<const BasicBlock *, MDMapTy> MetadataBlockStore;
/// ScopeRecordIdx - This is the index in ScopeRecords for an MDNode scope
/// entry with no "inlined at" element.
Index: lib/VMCore/Metadata.cpp
===================================================================
--- lib/VMCore/Metadata.cpp (revision 156419)
+++ lib/VMCore/Metadata.cpp (working copy)
@@ -16,6 +16,7 @@
#include "llvm/LLVMContext.h"
#include "llvm/Module.h"
#include "llvm/Instruction.h"
+#include "llvm/BasicBlock.h"
#include "llvm/ADT/DenseMap.h"
#include "llvm/ADT/StringMap.h"
#include "llvm/ADT/SmallString.h"
@@ -592,3 +593,109 @@
setHasMetadataHashEntry(false);
}
+
+//===----------------------------------------------------------------------===//
+// BasicBlock Metadata method implementations.
+//
+
+void BasicBlock::setMetadata(StringRef Kind, MDNode *Node) {
+ if (Node == 0 && !hasMetadata()) return;
+ setMetadata(getContext().getMDKindID(Kind), Node);
+}
+
+MDNode *BasicBlock::getMetadataImpl(StringRef Kind) const {
+ return getMetadataImpl(getContext().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 BasicBlock::setMetadata(unsigned KindID, MDNode *Node) {
+ if (Node == 0 && !hasMetadata()) return;
+
+ // Handle the case when we're adding/updating metadata on a BasicBlock.
+ if (Node) {
+ LLVMContextImpl::MDMapTy &Info = getContext().pImpl->MetadataBlockStore[this];
+ assert(!Info.empty() == hasMetadataHashEntry() &&
+ "HasMetadata bit is wonked");
+ if (Info.empty()) {
+ setHasMetadataHashEntry(true);
+ } else {
+ // Handle replacement of an existing value.
+ for (unsigned i = 0, e = Info.size(); i != e; ++i)
+ if (Info[i].first == KindID) {
+ Info[i].second = Node;
+ return;
+ }
+ }
+
+ // No replacement, just add it to the list.
+ Info.push_back(std::make_pair(KindID, Node));
+ return;
+ }
+
+ // Otherwise, we're removing metadata from a BasicBlock.
+ assert((hasMetadataHashEntry() ==
+ getContext().pImpl->MetadataBlockStore.count(this)) &&
+ "HasMetadata bit out of date!");
+ if (!hasMetadataHashEntry())
+ return; // Nothing to remove!
+ LLVMContextImpl::MDMapTy &Info = getContext().pImpl->MetadataBlockStore[this];
+
+ // Common case is removing the only entry.
+ if (Info.size() == 1 && Info[0].first == KindID) {
+ getContext().pImpl->MetadataBlockStore.erase(this);
+ setHasMetadataHashEntry(false);
+ return;
+ }
+
+ // Handle removal of an existing value.
+ for (unsigned i = 0, e = Info.size(); i != e; ++i)
+ if (Info[i].first == KindID) {
+ 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 BasicBlock.
+}
+
+MDNode *BasicBlock::getMetadataImpl(unsigned KindID) const {
+ if (!hasMetadataHashEntry()) return 0;
+
+ LLVMContextImpl::MDMapTy &Info = getContext().pImpl->MetadataBlockStore[this];
+ assert(!Info.empty() && "bit out of sync with hash table");
+
+ for (LLVMContextImpl::MDMapTy::iterator I = Info.begin(), E = Info.end();
+ I != E; ++I)
+ if (I->first == KindID)
+ return I->second;
+ return 0;
+}
+
+void BasicBlock::getAllMetadataImpl(SmallVectorImpl<std::pair<unsigned,
+ MDNode*> > &Result) const {
+ Result.clear();
+
+ assert(hasMetadataHashEntry() &&
+ getContext().pImpl->MetadataBlockStore.count(this) &&
+ "Shouldn't have called this");
+ const LLVMContextImpl::MDMapTy &Info =
+ getContext().pImpl->MetadataBlockStore.find(this)->second;
+ assert(!Info.empty() && "Shouldn't have called this");
+
+ 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());
+}
+
+/// clearMetadataHashEntries - Clear all hashtable-based metadata from
+/// this BasicBlock.
+void BasicBlock::clearMetadataHashEntries() {
+ assert(hasMetadataHashEntry() && "Caller should check");
+ getContext().pImpl->MetadataBlockStore.erase(this);
+ setHasMetadataHashEntry(false);
+}
+
Index: lib/AsmParser/LLParser.cpp
===================================================================
--- lib/AsmParser/LLParser.cpp (revision 156419)
+++ lib/AsmParser/LLParser.cpp (working copy)
@@ -45,6 +45,26 @@
/// ValidateEndOfModule - Do final validity and sanity checks at the end of the
/// module.
bool LLParser::ValidateEndOfModule() {
+ // Handle any block metadata forward references.
+ if (!ForwardRefBlockMetadata.empty()) {
+ for (DenseMap<BasicBlock*, std::vector<MDRef> >::iterator
+ BB = ForwardRefBlockMetadata.begin(), E = ForwardRefBlockMetadata.end();
+ BB != E; ++BB) {
+ BasicBlock *Block = BB->first;
+ const std::vector<MDRef> &MDList = BB->second;
+
+ for (unsigned i = 0, e = MDList.size(); i != e; ++i) {
+ unsigned SlotNo = MDList[i].MDSlot;
+
+ if (SlotNo >= NumberedMetadata.size() || NumberedMetadata[SlotNo] == 0)
+ return Error(MDList[i].Loc, "use of undefined metadata '!" +
+ Twine(SlotNo) + "'");
+ Block->setMetadata(MDList[i].MDKind, NumberedMetadata[SlotNo]);
+ }
+ }
+ ForwardRefBlockMetadata.clear();
+ }
+
// Handle any instruction metadata forward references.
if (!ForwardRefInstMetadata.empty()) {
for (DenseMap<Instruction*, std::vector<MDRef> >::iterator
@@ -1054,6 +1074,53 @@
return false;
}
+/// ParseBasicBlockMetadata
+/// ::= !propertyA !42 (',' !propertyB !57)*
+bool LLParser::ParseBasicBlockMetadata(BasicBlock *Block,
+ PerFunctionState *PFS) {
+ do {
+ if (Lex.getKind() != lltok::MetadataVar)
+ return TokError("expected metadata");
+
+ std::string Name = Lex.getStrVal();
+ unsigned MDK = M->getMDKindID(Name);
+ Lex.Lex();
+
+ MDNode *Node;
+ SMLoc Loc = Lex.getLoc();
+
+ if (ParseToken(lltok::exclaim, "expected '!' here"))
+ return true;
+
+ // This code is similar to that of ParseMetadataValue, however it needs to
+ // have special-case code for a forward reference; see the comments on
+ // ForwardRefInstMetadata for details. Also, MDStrings are not supported
+ // at the top level here.
+ if (Lex.getKind() == lltok::lbrace) {
+ ValID ID;
+ if (ParseMetadataListValue(ID, PFS))
+ return true;
+ assert(ID.Kind == ValID::t_MDNode);
+ Block->setMetadata(MDK, ID.MDNodeVal);
+ } else {
+ unsigned NodeID = 0;
+ if (ParseMDNodeID(Node, NodeID))
+ return true;
+ if (Node) {
+ // If we got the node, add it to the block.
+ Block->setMetadata(MDK, Node);
+ } else {
+ MDRef R = { Loc, MDK, NodeID };
+ // Otherwise, remember that this should be resolved later.
+ ForwardRefBlockMetadata[Block].push_back(R);
+ }
+ }
+
+ // If this is the end of the list, we're done.
+ } while (EatIfPresent(lltok::comma));
+ return false;
+}
+
/// ParseInstructionMetadata
/// ::= !dbg !42 (',' !dbg !57)*
bool LLParser::ParseInstructionMetadata(Instruction *Inst,
@@ -2799,7 +2866,7 @@
}
/// ParseBasicBlock
-/// ::= LabelStr? Instruction*
+/// ::= LabelStr? Metadata? Instruction*
bool LLParser::ParseBasicBlock(PerFunctionState &PFS) {
// If this basic block starts out with a name, remember it.
std::string Name;
@@ -2812,6 +2879,11 @@
BasicBlock *BB = PFS.DefineBB(Name, NameLoc);
if (BB == 0) return true;
+ // Check if the block has metadata attached.
+ if (Lex.getKind() == lltok::MetadataVar) {
+ ParseBasicBlockMetadata(BB, &PFS);
+ }
+
std::string NameStr;
// Parse the instructions in this block until we get a terminator.
Index: lib/AsmParser/LLParser.h
===================================================================
--- lib/AsmParser/LLParser.h (revision 156419)
+++ lib/AsmParser/LLParser.h (working copy)
@@ -104,6 +104,7 @@
SMLoc Loc;
unsigned MDKind, MDSlot;
};
+ DenseMap<BasicBlock*, std::vector<MDRef> > ForwardRefBlockMetadata;
DenseMap<Instruction*, std::vector<MDRef> > ForwardRefInstMetadata;
// Type resolution handling data structures. The location is set when we
@@ -320,6 +321,7 @@
bool ParseMetadataListValue(ValID &ID, PerFunctionState *PFS);
bool ParseMetadataValue(ValID &ID, PerFunctionState *PFS);
bool ParseMDNodeVector(SmallVectorImpl<Value*> &, PerFunctionState *PFS);
+ bool ParseBasicBlockMetadata(BasicBlock *Block, PerFunctionState *PFS);
bool ParseInstructionMetadata(Instruction *Inst, PerFunctionState *PFS);
// Function Parsing.
Index: lib/Bitcode/Reader/BitcodeReader.cpp
===================================================================
--- lib/Bitcode/Reader/BitcodeReader.cpp (revision 156419)
+++ lib/Bitcode/Reader/BitcodeReader.cpp (working copy)
@@ -1846,7 +1846,23 @@
}
break;
}
+ case bitc::METADATA_BLOCK_ATTACHMENT: {
+ unsigned RecordLength = Record.size();
+ if (Record.empty() || (RecordLength - 1) % 2 == 1)
+ return Error ("Invalid METADATA_BLOCK_ATTACHMENT reader!");
+ BasicBlock *Block = getBasicBlock(Record[0]);
+ for (unsigned i = 1; i != RecordLength; i = i+2) {
+ unsigned Kind = Record[i];
+ DenseMap<unsigned, unsigned>::iterator I =
+ MDKindMap.find(Kind);
+ if (I == MDKindMap.end())
+ return Error("Invalid metadata kind ID");
+ Value *Node = MDValueList.getValueFwdRef(Record[i+1]);
+ Block->setMetadata(I->second, cast<MDNode>(Node));
+ }
+ break;
}
+ }
}
return false;
}
Index: lib/Bitcode/Writer/ValueEnumerator.cpp
===================================================================
--- lib/Bitcode/Writer/ValueEnumerator.cpp (revision 156419)
+++ lib/Bitcode/Writer/ValueEnumerator.cpp (working copy)
@@ -74,7 +74,19 @@
I != E; ++I)
EnumerateType(I->getType());
- 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) {
+ // Enumerate metadata attached with this block.
+ MDs.clear();
+ BB->getAllMetadataOtherThanDebugLoc(MDs);
+ for (unsigned i = 0, e = MDs.size(); i != e; ++i)
+ EnumerateMetadata(MDs[i].second);
+ if (!BB->getDebugLoc().isUnknown()) {
+ MDNode *Scope, *BBA;
+ BB->getDebugLoc().getScopeAndInlinedAt(Scope, BBA, BB->getContext());
+ if (Scope) EnumerateMetadata(Scope);
+ if (BBA) EnumerateMetadata(BBA);
+ }
+
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();
OI != E; ++OI) {
@@ -103,6 +115,7 @@
if (IA) EnumerateMetadata(IA);
}
}
+ }
}
// Optimize constant ordering.
@@ -465,6 +478,14 @@
SmallVector<MDNode *, 8> FnLocalMDVector;
// Add all of the instructions.
for (Function::const_iterator BB = F.begin(), E = F.end(); BB != E; ++BB) {
+ SmallVector<std::pair<unsigned, MDNode*>, 8> MDs;
+ BB->getAllMetadataOtherThanDebugLoc(MDs);
+ for (unsigned i = 0, e = MDs.size(); i != e; ++i) {
+ MDNode *N = MDs[i].second;
+ if (N->isFunctionLocal() && N->getFunction())
+ FnLocalMDVector.push_back(N);
+ }
+
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();
OI != E; ++OI) {
Index: lib/Bitcode/Writer/BitcodeWriter.cpp
===================================================================
--- lib/Bitcode/Writer/BitcodeWriter.cpp (revision 156419)
+++ lib/Bitcode/Writer/BitcodeWriter.cpp (working copy)
@@ -670,10 +670,26 @@
SmallVector<uint64_t, 64> Record;
// Write metadata attachments
- // METADATA_ATTACHMENT - [m x [value, [n x [id, mdnode]]]
+ // METADATA_ATTACHMENT - [m x [value, [n x [id, mdnode]]]
+ // METADATA_BLOCK_ATTACHMENT - [m x [value, [n x [id, mdnode]]]
SmallVector<std::pair<unsigned, MDNode*>, 4> 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) {
+ // Write block metadata
+ MDs.clear();
+ BB->getAllMetadataOtherThanDebugLoc(MDs);
+ if (!MDs.empty()) {
+ //Record.push_back(VE.getGlobalBasicBlockID(BB));
+ Record.push_back(VE.getValueID(BB));
+ for (unsigned i = 0, e = MDs.size(); i != e; ++i) {
+ Record.push_back(MDs[i].first);
+ Record.push_back(VE.getValueID(MDs[i].second));
+ }
+ Stream.EmitRecord(bitc::METADATA_BLOCK_ATTACHMENT, Record, 0);
+ Record.clear();
+ }
+
+ // Write instruction metadata
for (BasicBlock::const_iterator I = BB->begin(), E = BB->end();
I != E; ++I) {
MDs.clear();
@@ -691,6 +707,7 @@
Stream.EmitRecord(bitc::METADATA_ATTACHMENT, Record, 0);
Record.clear();
}
+ }
Stream.ExitBlock();
}
@@ -1406,7 +1423,31 @@
DebugLoc LastDL;
// Finally, emit all the instructions, in order.
- 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) {
+ // If the block has metadata, write a metadata attachment later.
+ NeedsMetadataAttachment |= BB->hasMetadataOtherThanDebugLoc();
+
+ // If the block has a debug location, emit it.
+ DebugLoc DL = BB->getDebugLoc();
+ if (DL.isUnknown()) {
+ // nothing todo.
+ } else if (DL == LastDL) {
+ // Just repeat the same debug loc as last time.
+ Stream.EmitRecord(bitc::FUNC_CODE_DEBUG_LOC_AGAIN, Vals);
+ } else {
+ MDNode *Scope, *BBA;
+ DL.getScopeAndInlinedAt(Scope, BBA, BB->getContext());
+
+ Vals.push_back(DL.getLine());
+ Vals.push_back(DL.getCol());
+ Vals.push_back(Scope ? VE.getValueID(Scope)+1 : 0);
+ Vals.push_back(BBA ? VE.getValueID(BBA)+1 : 0);
+ Stream.EmitRecord(bitc::FUNC_CODE_DEBUG_LOC, Vals);
+ Vals.clear();
+
+ LastDL = DL;
+ }
+
for (BasicBlock::const_iterator I = BB->begin(), E = BB->end();
I != E; ++I) {
WriteInstruction(*I, InstID, VE, Stream, Vals);
@@ -1438,6 +1479,7 @@
LastDL = DL;
}
}
+ }
// Emit names for all the instructions etc.
WriteValueSymbolTable(F.getValueSymbolTable(), VE, Stream);
More information about the llvm-commits
mailing list