Skip to content

Commit cceae7f

Browse files
committed
Add support for metadata attachments for global variables.
This patch adds an IR, assembly and bitcode representation for metadata attachments for globals. Future patches will port existing features to use these new attachments. Differential Revision: http://reviews.llvm.org/D20074 llvm-svn: 271348
1 parent 81fbadb commit cceae7f

File tree

18 files changed

+217
-110
lines changed

18 files changed

+217
-110
lines changed

llvm/docs/BitCodeFormat.rst

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -856,6 +856,16 @@ be one ``GCNAME`` record for each garbage collector name referenced in function
856856
``gc`` attributes within the module. These records can be referenced by 1-based
857857
index in the *gc* fields of ``FUNCTION`` records.
858858

859+
MODULE_CODE_GLOBALVAR_ATTACHMENT Record
860+
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
861+
862+
``[GLOBALVAR_ATTACHMENT, valueid, n x [id, mdnode]]``
863+
864+
The ``GLOBALVAR_ATTACHMENT`` record (code 19) describes the metadata
865+
attachments for a global variable. The ``valueid`` is the value index for
866+
the global variable, and the remaining fields are pairs of metadata name
867+
indices and metadata node indices.
868+
859869
.. _PARAMATTR_BLOCK:
860870

861871
PARAMATTR_BLOCK Contents

llvm/docs/LangRef.rst

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -619,7 +619,8 @@ assume that the globals are densely packed in their section and try to
619619
iterate over them as an array, alignment padding would break this
620620
iteration. The maximum alignment is ``1 << 29``.
621621

622-
Globals can also have a :ref:`DLL storage class <dllstorageclass>`.
622+
Globals can also have a :ref:`DLL storage class <dllstorageclass>` and
623+
an optional list of attached :ref:`metadata <metadata>`,
623624

624625
Variables and aliases can have a
625626
:ref:`Thread Local Storage Model <tls_model>`.
@@ -630,7 +631,7 @@ Syntax::
630631
[unnamed_addr] [AddrSpace] [ExternallyInitialized]
631632
<global | constant> <Type> [<InitializerConstant>]
632633
[, section "name"] [, comdat [($name)]]
633-
[, align <Alignment>]
634+
[, align <Alignment>] (, !name !N)*
634635

635636
For example, the following defines a global in a numbered address space
636637
with an initializer, section, and alignment:

llvm/include/llvm/Bitcode/LLVMBitCodes.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -113,6 +113,9 @@ enum ModuleCodes {
113113

114114
// IFUNC: [ifunc value type, addrspace, resolver val#, linkage, visibility]
115115
MODULE_CODE_IFUNC = 18,
116+
117+
// GLOBALVAR_ATTACHMENT: [valueid, n x [id, mdnode]]
118+
MODULE_CODE_GLOBALVAR_ATTACHMENT = 19,
116119
};
117120

118121
/// PARAMATTR blocks have code for defining a parameter attribute set.

llvm/include/llvm/IR/Function.h

Lines changed: 1 addition & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -72,13 +72,8 @@ class Function : public GlobalObject, public ilist_node<Function> {
7272
/// Bits from GlobalObject::GlobalObjectSubclassData.
7373
enum {
7474
/// Whether this function is materializable.
75-
IsMaterializableBit = 1 << 0,
76-
HasMetadataHashEntryBit = 1 << 1
75+
IsMaterializableBit = 0,
7776
};
78-
void setGlobalObjectBit(unsigned Mask, bool Value) {
79-
setGlobalObjectSubClassData((~Mask & getGlobalObjectSubClassData()) |
80-
(Value ? Mask : 0u));
81-
}
8277

8378
friend class SymbolTableListTraits<Function>;
8479

@@ -614,35 +609,6 @@ class Function : public GlobalObject, public ilist_node<Function> {
614609
/// setjmp or other function that gcc recognizes as "returning twice".
615610
bool callsFunctionThatReturnsTwice() const;
616611

617-
/// \brief Check if this has any metadata.
618-
bool hasMetadata() const { return hasMetadataHashEntry(); }
619-
620-
/// \brief Get the current metadata attachment, if any.
621-
///
622-
/// Returns \c nullptr if such an attachment is missing.
623-
/// @{
624-
MDNode *getMetadata(unsigned KindID) const;
625-
MDNode *getMetadata(StringRef Kind) const;
626-
/// @}
627-
628-
/// \brief Set a particular kind of metadata attachment.
629-
///
630-
/// Sets the given attachment to \c MD, erasing it if \c MD is \c nullptr or
631-
/// replacing it if it already exists.
632-
/// @{
633-
void setMetadata(unsigned KindID, MDNode *MD);
634-
void setMetadata(StringRef Kind, MDNode *MD);
635-
/// @}
636-
637-
/// \brief Get all current metadata attachments.
638-
void
639-
getAllMetadata(SmallVectorImpl<std::pair<unsigned, MDNode *>> &MDs) const;
640-
641-
/// \brief Drop metadata not in the given list.
642-
///
643-
/// Drop all metadata from \c this not included in \c KnownIDs.
644-
void dropUnknownMetadata(ArrayRef<unsigned> KnownIDs);
645-
646612
/// \brief Set the attached subprogram.
647613
///
648614
/// Calls \a setMetadata() with \a LLVMContext::MD_dbg.
@@ -664,15 +630,6 @@ class Function : public GlobalObject, public ilist_node<Function> {
664630
Value::setValueSubclassData(D);
665631
}
666632
void setValueSubclassDataBit(unsigned Bit, bool On);
667-
668-
bool hasMetadataHashEntry() const {
669-
return getGlobalObjectSubClassData() & HasMetadataHashEntryBit;
670-
}
671-
void setHasMetadataHashEntry(bool HasEntry) {
672-
setGlobalObjectBit(HasMetadataHashEntryBit, HasEntry);
673-
}
674-
675-
void clearMetadata();
676633
};
677634

678635
template <>

llvm/include/llvm/IR/GlobalObject.h

Lines changed: 52 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@
2020

2121
namespace llvm {
2222
class Comdat;
23+
class MDNode;
2324
class Module;
2425

2526
class GlobalObject : public GlobalValue {
@@ -36,12 +37,19 @@ class GlobalObject : public GlobalValue {
3637

3738
std::string Section; // Section to emit this into, empty means default
3839
Comdat *ObjComdat;
39-
static const unsigned AlignmentBits = 5;
40+
enum {
41+
LastAlignmentBit = 4,
42+
HasMetadataHashEntryBit,
43+
44+
GlobalObjectBits,
45+
};
4046
static const unsigned GlobalObjectSubClassDataBits =
41-
GlobalValueSubClassDataBits - AlignmentBits;
47+
GlobalValueSubClassDataBits - GlobalObjectBits;
4248

4349
private:
50+
static const unsigned AlignmentBits = LastAlignmentBit + 1;
4451
static const unsigned AlignmentMask = (1 << AlignmentBits) - 1;
52+
static const unsigned GlobalObjectMask = (1 << GlobalObjectBits) - 1;
4553

4654
public:
4755
unsigned getAlignment() const {
@@ -63,13 +71,55 @@ class GlobalObject : public GlobalValue {
6371
Comdat *getComdat() { return ObjComdat; }
6472
void setComdat(Comdat *C) { ObjComdat = C; }
6573

74+
/// Check if this has any metadata.
75+
bool hasMetadata() const { return hasMetadataHashEntry(); }
76+
77+
/// Get the current metadata attachment, if any.
78+
///
79+
/// Returns \c nullptr if such an attachment is missing.
80+
/// @{
81+
MDNode *getMetadata(unsigned KindID) const;
82+
MDNode *getMetadata(StringRef Kind) const;
83+
/// @}
84+
85+
/// Set a particular kind of metadata attachment.
86+
///
87+
/// Sets the given attachment to \c MD, erasing it if \c MD is \c nullptr or
88+
/// replacing it if it already exists.
89+
/// @{
90+
void setMetadata(unsigned KindID, MDNode *MD);
91+
void setMetadata(StringRef Kind, MDNode *MD);
92+
/// @}
93+
94+
/// Get all current metadata attachments.
95+
void
96+
getAllMetadata(SmallVectorImpl<std::pair<unsigned, MDNode *>> &MDs) const;
97+
98+
/// Drop metadata not in the given list.
99+
///
100+
/// Drop all metadata from \c this not included in \c KnownIDs.
101+
void dropUnknownMetadata(ArrayRef<unsigned> KnownIDs);
102+
66103
void copyAttributesFrom(const GlobalValue *Src) override;
67104

68105
// Methods for support type inquiry through isa, cast, and dyn_cast:
69106
static inline bool classof(const Value *V) {
70107
return V->getValueID() == Value::FunctionVal ||
71108
V->getValueID() == Value::GlobalVariableVal;
72109
}
110+
111+
protected:
112+
void clearMetadata();
113+
114+
private:
115+
bool hasMetadataHashEntry() const {
116+
return getGlobalValueSubClassData() & (1 << HasMetadataHashEntryBit);
117+
}
118+
void setHasMetadataHashEntry(bool HasEntry) {
119+
unsigned Mask = 1 << HasMetadataHashEntryBit;
120+
setGlobalValueSubClassData((~Mask & getGlobalValueSubClassData()) |
121+
(HasEntry ? Mask : 0u));
122+
}
73123
};
74124

75125
} // End llvm namespace

llvm/include/llvm/IR/GlobalVariable.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -159,6 +159,10 @@ class GlobalVariable : public GlobalObject, public ilist_node<GlobalVariable> {
159159
///
160160
void eraseFromParent() override;
161161

162+
/// Drop all references in preparation to destroy the GlobalVariable. This
163+
/// drops not only the reference to the initializer but also to any metadata.
164+
void dropAllReferences();
165+
162166
// Methods for support type inquiry through isa, cast, and dyn_cast:
163167
static inline bool classof(const Value *V) {
164168
return V->getValueID() == Value::GlobalVariableVal;

llvm/lib/AsmParser/LLParser.cpp

Lines changed: 17 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -891,6 +891,9 @@ bool LLParser::ParseGlobal(const std::string &Name, LocTy NameLoc,
891891
unsigned Alignment;
892892
if (ParseOptionalAlignment(Alignment)) return true;
893893
GV->setAlignment(Alignment);
894+
} else if (Lex.getKind() == lltok::MetadataVar) {
895+
if (ParseGlobalObjectMetadataAttachment(*GV))
896+
return true;
894897
} else {
895898
Comdat *C;
896899
if (parseOptionalComdat(Name, C))
@@ -1708,17 +1711,24 @@ bool LLParser::ParseInstructionMetadata(Instruction &Inst) {
17081711
return false;
17091712
}
17101713

1714+
/// ParseGlobalObjectMetadataAttachment
1715+
/// ::= !dbg !57
1716+
bool LLParser::ParseGlobalObjectMetadataAttachment(GlobalObject &GO) {
1717+
unsigned MDK;
1718+
MDNode *N;
1719+
if (ParseMetadataAttachment(MDK, N))
1720+
return true;
1721+
1722+
GO.setMetadata(MDK, N);
1723+
return false;
1724+
}
1725+
17111726
/// ParseOptionalFunctionMetadata
17121727
/// ::= (!dbg !57)*
17131728
bool LLParser::ParseOptionalFunctionMetadata(Function &F) {
1714-
while (Lex.getKind() == lltok::MetadataVar) {
1715-
unsigned MDK;
1716-
MDNode *N;
1717-
if (ParseMetadataAttachment(MDK, N))
1729+
while (Lex.getKind() == lltok::MetadataVar)
1730+
if (ParseGlobalObjectMetadataAttachment(F))
17181731
return true;
1719-
1720-
F.setMetadata(MDK, N);
1721-
}
17221732
return false;
17231733
}
17241734

llvm/lib/AsmParser/LLParser.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -424,6 +424,7 @@ namespace llvm {
424424
bool ParseMDNodeVector(SmallVectorImpl<Metadata *> &MDs);
425425
bool ParseMetadataAttachment(unsigned &Kind, MDNode *&MD);
426426
bool ParseInstructionMetadata(Instruction &Inst);
427+
bool ParseGlobalObjectMetadataAttachment(GlobalObject &GO);
427428
bool ParseOptionalFunctionMetadata(Function &F);
428429

429430
template <class FieldTy>

llvm/lib/Bitcode/Reader/BitcodeReader.cpp

Lines changed: 30 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -443,6 +443,9 @@ class BitcodeReader : public GVMaterializer {
443443
unsigned &NextMetadataNo);
444444
std::error_code parseMetadataKinds();
445445
std::error_code parseMetadataKindRecord(SmallVectorImpl<uint64_t> &Record);
446+
std::error_code
447+
parseGlobalObjectAttachment(GlobalObject &GO,
448+
ArrayRef<uint64_t> Record);
446449
std::error_code parseMetadataAttachment(Function &F);
447450
ErrorOr<std::string> parseModuleTriple();
448451
std::error_code parseUseLists();
@@ -3820,6 +3823,16 @@ std::error_code BitcodeReader::parseModule(uint64_t ResumeBit,
38203823
}
38213824
break;
38223825
}
3826+
case bitc::MODULE_CODE_GLOBALVAR_ATTACHMENT: {
3827+
if (Record.size() % 2 == 0)
3828+
return error("Invalid record");
3829+
unsigned ValueID = Record[0];
3830+
if (ValueID >= ValueList.size())
3831+
return error("Invalid record");
3832+
if (auto *GV = dyn_cast<GlobalVariable>(ValueList[ValueID]))
3833+
parseGlobalObjectAttachment(*GV, ArrayRef<uint64_t>(Record).slice(1));
3834+
break;
3835+
}
38233836
// FUNCTION: [type, callingconv, isproto, linkage, paramattr,
38243837
// alignment, section, visibility, gc, unnamed_addr,
38253838
// prologuedata, dllstorageclass, comdat, prefixdata]
@@ -4144,6 +4157,21 @@ ErrorOr<std::string> BitcodeReader::parseIdentificationBlock() {
41444157
}
41454158
}
41464159

4160+
std::error_code BitcodeReader::parseGlobalObjectAttachment(
4161+
GlobalObject &GO, ArrayRef<uint64_t> Record) {
4162+
assert(Record.size() % 2 == 0);
4163+
for (unsigned I = 0, E = Record.size(); I != E; I += 2) {
4164+
auto K = MDKindMap.find(Record[I]);
4165+
if (K == MDKindMap.end())
4166+
return error("Invalid ID");
4167+
MDNode *MD = MetadataList.getMDNodeFwdRefOrNull(Record[I + 1]);
4168+
if (!MD)
4169+
return error("Invalid metadata attachment");
4170+
GO.setMetadata(K->second, MD);
4171+
}
4172+
return std::error_code();
4173+
}
4174+
41474175
/// Parse metadata attachments.
41484176
std::error_code BitcodeReader::parseMetadataAttachment(Function &F) {
41494177
if (Stream.EnterSubBlock(bitc::METADATA_ATTACHMENT_ID))
@@ -4175,15 +4203,8 @@ std::error_code BitcodeReader::parseMetadataAttachment(Function &F) {
41754203
return error("Invalid record");
41764204
if (RecordLength % 2 == 0) {
41774205
// A function attachment.
4178-
for (unsigned I = 0; I != RecordLength; I += 2) {
4179-
auto K = MDKindMap.find(Record[I]);
4180-
if (K == MDKindMap.end())
4181-
return error("Invalid ID");
4182-
MDNode *MD = MetadataList.getMDNodeFwdRefOrNull(Record[I + 1]);
4183-
if (!MD)
4184-
return error("Invalid metadata attachment");
4185-
F.setMetadata(K->second, MD);
4186-
}
4206+
if (std::error_code EC = parseGlobalObjectAttachment(F, Record))
4207+
return EC;
41874208
continue;
41884209
}
41894210

0 commit comments

Comments
 (0)