diff options
author | Javed Absar <javed.absar@arm.com> | 2017-05-11 12:28:08 +0000 |
---|---|---|
committer | Javed Absar <javed.absar@arm.com> | 2017-05-11 12:28:08 +0000 |
commit | f3d7904d20120fb6e4b33cd391b916ca6701e03e (patch) | |
tree | 45229dfdd32c355e31e095a197b3bb53d84f2d85 /llvm/lib/IR | |
parent | a44fc83d9fa3bcbe45b1ebb2f0aca2a86dba181d (diff) | |
download | bcm5719-llvm-f3d7904d20120fb6e4b33cd391b916ca6701e03e.tar.gz bcm5719-llvm-f3d7904d20120fb6e4b33cd391b916ca6701e03e.zip |
[IR] Allow attributes with global variables
This patch extends llvm-ir to allow attributes to be set on global variables.
An RFC was sent out earlier by my colleague James Molloy: http://lists.llvm.org/pipermail/cfe-dev/2017-March/053100.html
A key part of that proposal was to extend LLVM-IR to carry attributes on global variables.
This generic feature could be useful for multiple purposes.
In our present context, it would be useful to carry user specified sections for bss/rodata/data.
Reviewed by: Jonathan Roelofs, Reid Kleckner
Differential Revision: https://reviews.llvm.org/D32009
llvm-svn: 302794
Diffstat (limited to 'llvm/lib/IR')
-rw-r--r-- | llvm/lib/IR/AsmWriter.cpp | 7 | ||||
-rw-r--r-- | llvm/lib/IR/Attributes.cpp | 66 | ||||
-rw-r--r-- | llvm/lib/IR/Globals.cpp | 1 |
3 files changed, 74 insertions, 0 deletions
diff --git a/llvm/lib/IR/AsmWriter.cpp b/llvm/lib/IR/AsmWriter.cpp index 4c6e3e3788b..ec4663018bd 100644 --- a/llvm/lib/IR/AsmWriter.cpp +++ b/llvm/lib/IR/AsmWriter.cpp @@ -805,6 +805,9 @@ void SlotTracker::processModule() { if (!Var.hasName()) CreateModuleSlot(&Var); processGlobalObjectMetadata(Var); + auto Attrs = Var.getAttributes(); + if (Attrs.hasAttributes()) + CreateAttributeSetSlot(Attrs); } for (const GlobalAlias &A : TheModule->aliases()) { @@ -2502,6 +2505,10 @@ void AssemblyWriter::printGlobal(const GlobalVariable *GV) { GV->getAllMetadata(MDs); printMetadataAttachments(MDs, ", "); + auto Attrs = GV->getAttributes(); + if (Attrs.hasAttributes()) + Out << " #" << Machine.getAttributeGroupSlot(Attrs); + printInfoComment(*GV); } diff --git a/llvm/lib/IR/Attributes.cpp b/llvm/lib/IR/Attributes.cpp index 3b1140ab542..b97afb6f4a6 100644 --- a/llvm/lib/IR/Attributes.cpp +++ b/llvm/lib/IR/Attributes.cpp @@ -504,6 +504,64 @@ AttributeSet AttributeSet::get(LLVMContext &C, ArrayRef<Attribute> Attrs) { return AttributeSet(AttributeSetNode::get(C, Attrs)); } +AttributeSet AttributeSet::addAttribute(LLVMContext &C, + Attribute::AttrKind Kind) const { + if (hasAttribute(Kind)) return *this; + AttrBuilder B; + B.addAttribute(Kind); + return addAttributes(C, AttributeSet::get(C, B)); +} + +AttributeSet AttributeSet::addAttribute(LLVMContext &C, StringRef Kind, + StringRef Value) const { + AttrBuilder B; + B.addAttribute(Kind, Value); + return addAttributes(C, AttributeSet::get(C, B)); +} + +AttributeSet AttributeSet::addAttributes(LLVMContext &C, + const AttributeSet AS) const { + if (!hasAttributes()) + return AS; + + if (!AS.hasAttributes()) + return *this; + + AttrBuilder B(AS); + for (Attribute I : *this) + B.addAttribute(I); + + return get(C, B); +} + +AttributeSet AttributeSet::removeAttribute(LLVMContext &C, + Attribute::AttrKind Kind) const { + if (!hasAttribute(Kind)) return *this; + AttrBuilder B; + B.addAttribute(Kind); + return removeAttributes(C, B); +} + +AttributeSet AttributeSet::removeAttribute(LLVMContext &C, + StringRef Kind) const { + if (!hasAttribute(Kind)) return *this; + AttrBuilder B; + B.addAttribute(Kind); + return removeAttributes(C, B); +} + +AttributeSet AttributeSet::removeAttributes(LLVMContext &C, + const AttrBuilder &Attrs) const { + + // FIXME it is not obvious how this should work for alignment. + // For now, say we can't pass in alignment, which no current use does. + assert(!Attrs.hasAlignmentAttr() && "Attempt to change alignment!"); + + AttrBuilder B(*this); + B.remove(Attrs); + return get(C, B); +} + unsigned AttributeSet::getNumAttributes() const { return SetNode ? SetNode->getNumAttributes() : 0; } @@ -557,6 +615,14 @@ AttributeSet::iterator AttributeSet::end() const { return SetNode ? SetNode->end() : nullptr; } +#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP) +LLVM_DUMP_METHOD void AttributeSet::dump() const { + dbgs() << "AS =\n"; + dbgs() << " { "; + dbgs() << getAsString(true) << " }\n"; +} +#endif + //===----------------------------------------------------------------------===// // AttributeSetNode Definition //===----------------------------------------------------------------------===// diff --git a/llvm/lib/IR/Globals.cpp b/llvm/lib/IR/Globals.cpp index 5f338f58d94..5fbf51e0089 100644 --- a/llvm/lib/IR/Globals.cpp +++ b/llvm/lib/IR/Globals.cpp @@ -338,6 +338,7 @@ void GlobalVariable::copyAttributesFrom(const GlobalValue *Src) { if (const GlobalVariable *SrcVar = dyn_cast<GlobalVariable>(Src)) { setThreadLocalMode(SrcVar->getThreadLocalMode()); setExternallyInitialized(SrcVar->isExternallyInitialized()); + setAttributes(SrcVar->getAttributes()); } } |