diff options
| author | Peter Collingbourne <peter@pcc.me.uk> | 2016-05-31 23:01:54 +0000 |
|---|---|---|
| committer | Peter Collingbourne <peter@pcc.me.uk> | 2016-05-31 23:01:54 +0000 |
| commit | cceae7feda8e33194d1a6c5963bd4114bb8d2b36 (patch) | |
| tree | d7f155b4ea8004651b1aadf412465b0d3950f9e6 /llvm/lib | |
| parent | 81fbadb63f4d28f62950e2e2c4967f1429b3ca55 (diff) | |
| download | bcm5719-llvm-cceae7feda8e33194d1a6c5963bd4114bb8d2b36.tar.gz bcm5719-llvm-cceae7feda8e33194d1a6c5963bd4114bb8d2b36.zip | |
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
Diffstat (limited to 'llvm/lib')
| -rw-r--r-- | llvm/lib/AsmParser/LLParser.cpp | 24 | ||||
| -rw-r--r-- | llvm/lib/AsmParser/LLParser.h | 1 | ||||
| -rw-r--r-- | llvm/lib/Bitcode/Reader/BitcodeReader.cpp | 39 | ||||
| -rw-r--r-- | llvm/lib/Bitcode/Writer/BitcodeWriter.cpp | 42 | ||||
| -rw-r--r-- | llvm/lib/Bitcode/Writer/ValueEnumerator.cpp | 16 | ||||
| -rw-r--r-- | llvm/lib/Bitcode/Writer/ValueEnumerator.h | 4 | ||||
| -rw-r--r-- | llvm/lib/IR/AsmWriter.cpp | 15 | ||||
| -rw-r--r-- | llvm/lib/IR/Function.cpp | 6 | ||||
| -rw-r--r-- | llvm/lib/IR/Globals.cpp | 10 | ||||
| -rw-r--r-- | llvm/lib/IR/LLVMContextImpl.h | 4 | ||||
| -rw-r--r-- | llvm/lib/IR/Metadata.cpp | 26 |
11 files changed, 130 insertions, 57 deletions
diff --git a/llvm/lib/AsmParser/LLParser.cpp b/llvm/lib/AsmParser/LLParser.cpp index 3f9ea5766bd..09d012d5375 100644 --- a/llvm/lib/AsmParser/LLParser.cpp +++ b/llvm/lib/AsmParser/LLParser.cpp @@ -891,6 +891,9 @@ bool LLParser::ParseGlobal(const std::string &Name, LocTy NameLoc, unsigned Alignment; if (ParseOptionalAlignment(Alignment)) return true; GV->setAlignment(Alignment); + } else if (Lex.getKind() == lltok::MetadataVar) { + if (ParseGlobalObjectMetadataAttachment(*GV)) + return true; } else { Comdat *C; if (parseOptionalComdat(Name, C)) @@ -1708,17 +1711,24 @@ bool LLParser::ParseInstructionMetadata(Instruction &Inst) { return false; } +/// ParseGlobalObjectMetadataAttachment +/// ::= !dbg !57 +bool LLParser::ParseGlobalObjectMetadataAttachment(GlobalObject &GO) { + unsigned MDK; + MDNode *N; + if (ParseMetadataAttachment(MDK, N)) + return true; + + GO.setMetadata(MDK, N); + return false; +} + /// ParseOptionalFunctionMetadata /// ::= (!dbg !57)* bool LLParser::ParseOptionalFunctionMetadata(Function &F) { - while (Lex.getKind() == lltok::MetadataVar) { - unsigned MDK; - MDNode *N; - if (ParseMetadataAttachment(MDK, N)) + while (Lex.getKind() == lltok::MetadataVar) + if (ParseGlobalObjectMetadataAttachment(F)) return true; - - F.setMetadata(MDK, N); - } return false; } diff --git a/llvm/lib/AsmParser/LLParser.h b/llvm/lib/AsmParser/LLParser.h index cffea25485a..7c32f2c7fac 100644 --- a/llvm/lib/AsmParser/LLParser.h +++ b/llvm/lib/AsmParser/LLParser.h @@ -424,6 +424,7 @@ namespace llvm { bool ParseMDNodeVector(SmallVectorImpl<Metadata *> &MDs); bool ParseMetadataAttachment(unsigned &Kind, MDNode *&MD); bool ParseInstructionMetadata(Instruction &Inst); + bool ParseGlobalObjectMetadataAttachment(GlobalObject &GO); bool ParseOptionalFunctionMetadata(Function &F); template <class FieldTy> diff --git a/llvm/lib/Bitcode/Reader/BitcodeReader.cpp b/llvm/lib/Bitcode/Reader/BitcodeReader.cpp index 2cd1297d902..55c0d064938 100644 --- a/llvm/lib/Bitcode/Reader/BitcodeReader.cpp +++ b/llvm/lib/Bitcode/Reader/BitcodeReader.cpp @@ -443,6 +443,9 @@ private: unsigned &NextMetadataNo); std::error_code parseMetadataKinds(); std::error_code parseMetadataKindRecord(SmallVectorImpl<uint64_t> &Record); + std::error_code + parseGlobalObjectAttachment(GlobalObject &GO, + ArrayRef<uint64_t> Record); std::error_code parseMetadataAttachment(Function &F); ErrorOr<std::string> parseModuleTriple(); std::error_code parseUseLists(); @@ -3820,6 +3823,16 @@ std::error_code BitcodeReader::parseModule(uint64_t ResumeBit, } break; } + case bitc::MODULE_CODE_GLOBALVAR_ATTACHMENT: { + if (Record.size() % 2 == 0) + return error("Invalid record"); + unsigned ValueID = Record[0]; + if (ValueID >= ValueList.size()) + return error("Invalid record"); + if (auto *GV = dyn_cast<GlobalVariable>(ValueList[ValueID])) + parseGlobalObjectAttachment(*GV, ArrayRef<uint64_t>(Record).slice(1)); + break; + } // FUNCTION: [type, callingconv, isproto, linkage, paramattr, // alignment, section, visibility, gc, unnamed_addr, // prologuedata, dllstorageclass, comdat, prefixdata] @@ -4144,6 +4157,21 @@ ErrorOr<std::string> BitcodeReader::parseIdentificationBlock() { } } +std::error_code BitcodeReader::parseGlobalObjectAttachment( + GlobalObject &GO, ArrayRef<uint64_t> Record) { + assert(Record.size() % 2 == 0); + for (unsigned I = 0, E = Record.size(); I != E; I += 2) { + auto K = MDKindMap.find(Record[I]); + if (K == MDKindMap.end()) + return error("Invalid ID"); + MDNode *MD = MetadataList.getMDNodeFwdRefOrNull(Record[I + 1]); + if (!MD) + return error("Invalid metadata attachment"); + GO.setMetadata(K->second, MD); + } + return std::error_code(); +} + /// Parse metadata attachments. std::error_code BitcodeReader::parseMetadataAttachment(Function &F) { if (Stream.EnterSubBlock(bitc::METADATA_ATTACHMENT_ID)) @@ -4175,15 +4203,8 @@ std::error_code BitcodeReader::parseMetadataAttachment(Function &F) { return error("Invalid record"); if (RecordLength % 2 == 0) { // A function attachment. - for (unsigned I = 0; I != RecordLength; I += 2) { - auto K = MDKindMap.find(Record[I]); - if (K == MDKindMap.end()) - return error("Invalid ID"); - MDNode *MD = MetadataList.getMDNodeFwdRefOrNull(Record[I + 1]); - if (!MD) - return error("Invalid metadata attachment"); - F.setMetadata(K->second, MD); - } + if (std::error_code EC = parseGlobalObjectAttachment(F, Record)) + return EC; continue; } diff --git a/llvm/lib/Bitcode/Writer/BitcodeWriter.cpp b/llvm/lib/Bitcode/Writer/BitcodeWriter.cpp index ec3ecb2287e..d65e924507c 100644 --- a/llvm/lib/Bitcode/Writer/BitcodeWriter.cpp +++ b/llvm/lib/Bitcode/Writer/BitcodeWriter.cpp @@ -223,7 +223,10 @@ private: SmallVectorImpl<uint64_t> &Record); void writeModuleMetadata(); void writeFunctionMetadata(const Function &F); - void writeMetadataAttachment(const Function &F); + void writeFunctionMetadataAttachment(const Function &F); + void writeGlobalVariableMetadataAttachment(const GlobalVariable &GV); + void pushGlobalMetadataAttachment(SmallVectorImpl<uint64_t> &Record, + const GlobalObject &GO); void writeModuleMetadataStore(); void writeOperandBundleTags(); void writeConstants(unsigned FirstVal, unsigned LastVal, bool isGlobal); @@ -1831,24 +1834,31 @@ void ModuleBitcodeWriter::writeFunctionMetadata(const Function &F) { Stream.ExitBlock(); } -void ModuleBitcodeWriter::writeMetadataAttachment(const Function &F) { +void ModuleBitcodeWriter::pushGlobalMetadataAttachment( + SmallVectorImpl<uint64_t> &Record, const GlobalObject &GO) { + // [n x [id, mdnode]] + SmallVector<std::pair<unsigned, MDNode *>, 4> MDs; + GO.getAllMetadata(MDs); + for (const auto &I : MDs) { + Record.push_back(I.first); + Record.push_back(VE.getMetadataID(I.second)); + } +} + +void ModuleBitcodeWriter::writeFunctionMetadataAttachment(const Function &F) { Stream.EnterSubblock(bitc::METADATA_ATTACHMENT_ID, 3); SmallVector<uint64_t, 64> Record; - // Write metadata attachments - // METADATA_ATTACHMENT - [m x [value, [n x [id, mdnode]]] - SmallVector<std::pair<unsigned, MDNode *>, 4> MDs; - F.getAllMetadata(MDs); - if (!MDs.empty()) { - for (const auto &I : MDs) { - Record.push_back(I.first); - Record.push_back(VE.getMetadataID(I.second)); - } + if (F.hasMetadata()) { + pushGlobalMetadataAttachment(Record, F); Stream.EmitRecord(bitc::METADATA_ATTACHMENT, Record, 0); Record.clear(); } + // Write metadata attachments + // METADATA_ATTACHMENT - [m x [value, [n x [id, mdnode]]] + SmallVector<std::pair<unsigned, MDNode *>, 4> MDs; for (const BasicBlock &BB : F) for (const Instruction &I : BB) { MDs.clear(); @@ -2894,7 +2904,7 @@ void ModuleBitcodeWriter::writeFunction( writeValueSymbolTable(F.getValueSymbolTable()); if (NeedsMetadataAttachment) - writeMetadataAttachment(F); + writeFunctionMetadataAttachment(F); if (VE.shouldPreserveUseListOrder()) writeUseListBlock(&F); VE.purgeFunction(); @@ -3597,6 +3607,14 @@ void ModuleBitcodeWriter::writeModule() { writeValueSymbolTable(M.getValueSymbolTable(), /* IsModuleLevel */ true, &FunctionToBitcodeIndex); + for (const GlobalVariable &GV : M.globals()) + if (GV.hasMetadata()) { + SmallVector<uint64_t, 4> Record; + Record.push_back(VE.getValueID(&GV)); + pushGlobalMetadataAttachment(Record, GV); + Stream.EmitRecord(bitc::MODULE_CODE_GLOBALVAR_ATTACHMENT, Record); + } + if (GenerateHash) { writeModuleHash(BlockStartPos); } diff --git a/llvm/lib/Bitcode/Writer/ValueEnumerator.cpp b/llvm/lib/Bitcode/Writer/ValueEnumerator.cpp index 6bf95b12d80..6051173eed6 100644 --- a/llvm/lib/Bitcode/Writer/ValueEnumerator.cpp +++ b/llvm/lib/Bitcode/Writer/ValueEnumerator.cpp @@ -344,6 +344,11 @@ ValueEnumerator::ValueEnumerator(const Module &M, EnumerateNamedMetadata(M); SmallVector<std::pair<unsigned, MDNode *>, 8> MDs; + for (const GlobalVariable &GV : M.globals()) { + GV.getAllMetadata(MDs); + for (const auto &I : MDs) + EnumerateMetadata(&GV, I.second); + } // Enumerate types used by function bodies and argument lists. for (const Function &F : M) { @@ -523,17 +528,18 @@ void ValueEnumerator::EnumerateNamedMDNode(const NamedMDNode *MD) { EnumerateMetadata(nullptr, MD->getOperand(i)); } -unsigned ValueEnumerator::getMetadataFunctionID(const Function *F) const { - return F ? getValueID(F) + 1 : 0; +unsigned ValueEnumerator::getMetadataGlobalID(const GlobalObject *GO) const { + return GO ? getValueID(GO) + 1 : 0; } -void ValueEnumerator::EnumerateMetadata(const Function *F, const Metadata *MD) { - EnumerateMetadata(getMetadataFunctionID(F), MD); +void ValueEnumerator::EnumerateMetadata(const GlobalObject *GO, + const Metadata *MD) { + EnumerateMetadata(getMetadataGlobalID(GO), MD); } void ValueEnumerator::EnumerateFunctionLocalMetadata( const Function &F, const LocalAsMetadata *Local) { - EnumerateFunctionLocalMetadata(getMetadataFunctionID(&F), Local); + EnumerateFunctionLocalMetadata(getMetadataGlobalID(&F), Local); } void ValueEnumerator::dropFunctionFromMetadata( diff --git a/llvm/lib/Bitcode/Writer/ValueEnumerator.h b/llvm/lib/Bitcode/Writer/ValueEnumerator.h index bff2de70b3e..34d33fc418b 100644 --- a/llvm/lib/Bitcode/Writer/ValueEnumerator.h +++ b/llvm/lib/Bitcode/Writer/ValueEnumerator.h @@ -255,7 +255,7 @@ private: /// it's an \a MDNode. const MDNode *enumerateMetadataImpl(unsigned F, const Metadata *MD); - unsigned getMetadataFunctionID(const Function *F) const; + unsigned getMetadataGlobalID(const GlobalObject *GO) const; /// Enumerate reachable metadata in (almost) post-order. /// @@ -272,7 +272,7 @@ private: /// \a organizeMetadata() will later partition distinct nodes ahead of /// uniqued ones. ///{ - void EnumerateMetadata(const Function *F, const Metadata *MD); + void EnumerateMetadata(const GlobalObject *GO, const Metadata *MD); void EnumerateMetadata(unsigned F, const Metadata *MD); ///} diff --git a/llvm/lib/IR/AsmWriter.cpp b/llvm/lib/IR/AsmWriter.cpp index ec975c77c96..c5002dc8c2f 100644 --- a/llvm/lib/IR/AsmWriter.cpp +++ b/llvm/lib/IR/AsmWriter.cpp @@ -681,6 +681,9 @@ private: /// Add all of the functions arguments, basic blocks, and instructions. void processFunction(); + /// Add the metadata directly attached to a GlobalObject. + void processGlobalObjectMetadata(const GlobalObject &GO); + /// Add all of the metadata from a function. void processFunctionMetadata(const Function &F); @@ -799,6 +802,7 @@ void SlotTracker::processModule() { for (const GlobalVariable &Var : TheModule->globals()) { if (!Var.hasName()) CreateModuleSlot(&Var); + processGlobalObjectMetadata(Var); } for (const GlobalAlias &A : TheModule->aliases()) { @@ -882,12 +886,15 @@ void SlotTracker::processFunction() { ST_DEBUG("end processFunction!\n"); } -void SlotTracker::processFunctionMetadata(const Function &F) { +void SlotTracker::processGlobalObjectMetadata(const GlobalObject &GO) { SmallVector<std::pair<unsigned, MDNode *>, 4> MDs; - F.getAllMetadata(MDs); + GO.getAllMetadata(MDs); for (auto &MD : MDs) CreateMetadataSlot(MD.second); +} +void SlotTracker::processFunctionMetadata(const Function &F) { + processGlobalObjectMetadata(F); for (auto &BB : F) { for (auto &I : BB) processInstructionMetadata(I); @@ -2473,6 +2480,10 @@ void AssemblyWriter::printGlobal(const GlobalVariable *GV) { if (GV->getAlignment()) Out << ", align " << GV->getAlignment(); + SmallVector<std::pair<unsigned, MDNode *>, 4> MDs; + GV->getAllMetadata(MDs); + printMetadataAttachments(MDs, ", "); + printInfoComment(*GV); } diff --git a/llvm/lib/IR/Function.cpp b/llvm/lib/IR/Function.cpp index c8741964564..815922593e5 100644 --- a/llvm/lib/IR/Function.cpp +++ b/llvm/lib/IR/Function.cpp @@ -218,11 +218,13 @@ bool Argument::hasAttribute(Attribute::AttrKind Kind) const { //===----------------------------------------------------------------------===// bool Function::isMaterializable() const { - return getGlobalObjectSubClassData() & IsMaterializableBit; + return getGlobalObjectSubClassData() & (1 << IsMaterializableBit); } void Function::setIsMaterializable(bool V) { - setGlobalObjectBit(IsMaterializableBit, V); + unsigned Mask = 1 << IsMaterializableBit; + setGlobalObjectSubClassData((~Mask & getGlobalObjectSubClassData()) | + (V ? Mask : 0u)); } LLVMContext &Function::getContext() const { diff --git a/llvm/lib/IR/Globals.cpp b/llvm/lib/IR/Globals.cpp index 3bf3cc25455..d151b9c5dc2 100644 --- a/llvm/lib/IR/Globals.cpp +++ b/llvm/lib/IR/Globals.cpp @@ -81,13 +81,13 @@ void GlobalObject::setAlignment(unsigned Align) { unsigned GlobalObject::getGlobalObjectSubClassData() const { unsigned ValueData = getGlobalValueSubClassData(); - return ValueData >> AlignmentBits; + return ValueData >> GlobalObjectBits; } void GlobalObject::setGlobalObjectSubClassData(unsigned Val) { unsigned OldData = getGlobalValueSubClassData(); - setGlobalValueSubClassData((OldData & AlignmentMask) | - (Val << AlignmentBits)); + setGlobalValueSubClassData((OldData & GlobalObjectMask) | + (Val << GlobalObjectBits)); assert(getGlobalObjectSubClassData() == Val && "representation error"); } @@ -301,6 +301,10 @@ void GlobalVariable::copyAttributesFrom(const GlobalValue *Src) { } } +void GlobalVariable::dropAllReferences() { + User::dropAllReferences(); + clearMetadata(); +} //===----------------------------------------------------------------------===// // GlobalIndirectSymbol Implementation diff --git a/llvm/lib/IR/LLVMContextImpl.h b/llvm/lib/IR/LLVMContextImpl.h index 7d7be4492c7..02af08ac4f9 100644 --- a/llvm/lib/IR/LLVMContextImpl.h +++ b/llvm/lib/IR/LLVMContextImpl.h @@ -1107,8 +1107,8 @@ public: /// Collection of per-instruction metadata used in this context. DenseMap<const Instruction *, MDAttachmentMap> InstructionMetadata; - /// Collection of per-function metadata used in this context. - DenseMap<const Function *, MDAttachmentMap> FunctionMetadata; + /// Collection of per-GlobalObject metadata used in this context. + DenseMap<const GlobalObject *, MDAttachmentMap> GlobalObjectMetadata; /// DiscriminatorTable - This table maps file:line locations to an /// integer representing the next DWARF path discriminator to assign to diff --git a/llvm/lib/IR/Metadata.cpp b/llvm/lib/IR/Metadata.cpp index 9435cd2ec35..a77565cf087 100644 --- a/llvm/lib/IR/Metadata.cpp +++ b/llvm/lib/IR/Metadata.cpp @@ -1281,24 +1281,24 @@ void Instruction::clearMetadataHashEntries() { setHasMetadataHashEntry(false); } -MDNode *Function::getMetadata(unsigned KindID) const { +MDNode *GlobalObject::getMetadata(unsigned KindID) const { if (!hasMetadata()) return nullptr; - return getContext().pImpl->FunctionMetadata[this].lookup(KindID); + return getContext().pImpl->GlobalObjectMetadata[this].lookup(KindID); } -MDNode *Function::getMetadata(StringRef Kind) const { +MDNode *GlobalObject::getMetadata(StringRef Kind) const { if (!hasMetadata()) return nullptr; return getMetadata(getContext().getMDKindID(Kind)); } -void Function::setMetadata(unsigned KindID, MDNode *MD) { +void GlobalObject::setMetadata(unsigned KindID, MDNode *MD) { if (MD) { if (!hasMetadata()) setHasMetadataHashEntry(true); - getContext().pImpl->FunctionMetadata[this].set(KindID, *MD); + getContext().pImpl->GlobalObjectMetadata[this].set(KindID, *MD); return; } @@ -1306,29 +1306,29 @@ void Function::setMetadata(unsigned KindID, MDNode *MD) { if (!hasMetadata()) return; - auto &Store = getContext().pImpl->FunctionMetadata[this]; + auto &Store = getContext().pImpl->GlobalObjectMetadata[this]; Store.erase(KindID); if (Store.empty()) clearMetadata(); } -void Function::setMetadata(StringRef Kind, MDNode *MD) { +void GlobalObject::setMetadata(StringRef Kind, MDNode *MD) { if (!MD && !hasMetadata()) return; setMetadata(getContext().getMDKindID(Kind), MD); } -void Function::getAllMetadata( +void GlobalObject::getAllMetadata( SmallVectorImpl<std::pair<unsigned, MDNode *>> &MDs) const { MDs.clear(); if (!hasMetadata()) return; - getContext().pImpl->FunctionMetadata[this].getAll(MDs); + getContext().pImpl->GlobalObjectMetadata[this].getAll(MDs); } -void Function::dropUnknownMetadata(ArrayRef<unsigned> KnownIDs) { +void GlobalObject::dropUnknownMetadata(ArrayRef<unsigned> KnownIDs) { if (!hasMetadata()) return; if (KnownIDs.empty()) { @@ -1339,7 +1339,7 @@ void Function::dropUnknownMetadata(ArrayRef<unsigned> KnownIDs) { SmallSet<unsigned, 5> KnownSet; KnownSet.insert(KnownIDs.begin(), KnownIDs.end()); - auto &Store = getContext().pImpl->FunctionMetadata[this]; + auto &Store = getContext().pImpl->GlobalObjectMetadata[this]; assert(!Store.empty()); Store.remove_if([&KnownSet](const std::pair<unsigned, TrackingMDNodeRef> &I) { @@ -1350,10 +1350,10 @@ void Function::dropUnknownMetadata(ArrayRef<unsigned> KnownIDs) { clearMetadata(); } -void Function::clearMetadata() { +void GlobalObject::clearMetadata() { if (!hasMetadata()) return; - getContext().pImpl->FunctionMetadata.erase(this); + getContext().pImpl->GlobalObjectMetadata.erase(this); setHasMetadataHashEntry(false); } |

