diff options
Diffstat (limited to 'contrib/llvm/lib/IR/Metadata.cpp')
-rw-r--r-- | contrib/llvm/lib/IR/Metadata.cpp | 123 |
1 files changed, 70 insertions, 53 deletions
diff --git a/contrib/llvm/lib/IR/Metadata.cpp b/contrib/llvm/lib/IR/Metadata.cpp index f35c64b..1d19304 100644 --- a/contrib/llvm/lib/IR/Metadata.cpp +++ b/contrib/llvm/lib/IR/Metadata.cpp @@ -16,6 +16,7 @@ #include "MetadataImpl.h" #include "SymbolTableListTraitsImpl.h" #include "llvm/ADT/STLExtras.h" +#include "llvm/ADT/SetVector.h" #include "llvm/ADT/SmallSet.h" #include "llvm/ADT/StringMap.h" #include "llvm/IR/ConstantRange.h" @@ -313,8 +314,7 @@ ValueAsMetadata *ValueAsMetadata::get(Value *V) { if (!Entry) { assert((isa<Constant>(V) || isa<Argument>(V) || isa<Instruction>(V)) && "Expected constant or function-local value"); - assert(!V->IsUsedByMD && - "Expected this to be the only metadata use"); + assert(!V->IsUsedByMD && "Expected this to be the only metadata use"); V->IsUsedByMD = true; if (auto *C = dyn_cast<Constant>(V)) Entry = new ConstantAsMetadata(C); @@ -359,14 +359,12 @@ void ValueAsMetadata::handleRAUW(Value *From, Value *To) { auto &Store = Context.pImpl->ValuesAsMetadata; auto I = Store.find(From); if (I == Store.end()) { - assert(!From->IsUsedByMD && - "Expected From not to be used by metadata"); + assert(!From->IsUsedByMD && "Expected From not to be used by metadata"); return; } // Remove old entry from the map. - assert(From->IsUsedByMD && - "Expected From to be used by metadata"); + assert(From->IsUsedByMD && "Expected From to be used by metadata"); From->IsUsedByMD = false; ValueAsMetadata *MD = I->second; assert(MD && "Expected valid metadata"); @@ -403,8 +401,7 @@ void ValueAsMetadata::handleRAUW(Value *From, Value *To) { } // Update MD in place (and update the map entry). - assert(!To->IsUsedByMD && - "Expected this to be the only metadata use"); + assert(!To->IsUsedByMD && "Expected this to be the only metadata use"); To->IsUsedByMD = true; MD->V = To; Entry = MD; @@ -416,7 +413,7 @@ void ValueAsMetadata::handleRAUW(Value *From, Value *To) { MDString *MDString::get(LLVMContext &Context, StringRef Str) { auto &Store = Context.pImpl->MDStringCache; - auto I = Store.emplace_second(Str); + auto I = Store.try_emplace(Str); auto &MapEntry = I.first->getValue(); if (!I.second) return &MapEntry; @@ -437,7 +434,7 @@ StringRef MDString::getString() const { // prepended to them. #define HANDLE_MDNODE_LEAF(CLASS) \ static_assert( \ - llvm::AlignOf<uint64_t>::Alignment >= llvm::AlignOf<CLASS>::Alignment, \ + alignof(uint64_t) >= alignof(CLASS), \ "Alignment is insufficient after objects prepended to " #CLASS); #include "llvm/IR/Metadata.def" @@ -445,7 +442,7 @@ void *MDNode::operator new(size_t Size, unsigned NumOps) { size_t OpSize = NumOps * sizeof(MDOperand); // uint64_t is the most aligned type we need support (ensured by static_assert // above) - OpSize = alignTo(OpSize, llvm::alignOf<uint64_t>()); + OpSize = alignTo(OpSize, alignof(uint64_t)); void *Ptr = reinterpret_cast<char *>(::operator new(OpSize + Size)) + OpSize; MDOperand *O = static_cast<MDOperand *>(Ptr); for (MDOperand *E = O - NumOps; O != E; --O) @@ -456,7 +453,7 @@ void *MDNode::operator new(size_t Size, unsigned NumOps) { void MDNode::operator delete(void *Mem) { MDNode *N = static_cast<MDNode *>(Mem); size_t OpSize = N->NumOperands * sizeof(MDOperand); - OpSize = alignTo(OpSize, llvm::alignOf<uint64_t>()); + OpSize = alignTo(OpSize, alignof(uint64_t)); MDOperand *O = static_cast<MDOperand *>(Mem); for (MDOperand *E = O - N->NumOperands; O != E; --O) @@ -862,42 +859,32 @@ MDNode *MDNode::concatenate(MDNode *A, MDNode *B) { if (!B) return A; - SmallVector<Metadata *, 4> MDs; - MDs.reserve(A->getNumOperands() + B->getNumOperands()); - MDs.append(A->op_begin(), A->op_end()); - MDs.append(B->op_begin(), B->op_end()); + SmallSetVector<Metadata *, 4> MDs(A->op_begin(), A->op_end()); + MDs.insert(B->op_begin(), B->op_end()); // FIXME: This preserves long-standing behaviour, but is it really the right // behaviour? Or was that an unintended side-effect of node uniquing? - return getOrSelfReference(A->getContext(), MDs); + return getOrSelfReference(A->getContext(), MDs.getArrayRef()); } MDNode *MDNode::intersect(MDNode *A, MDNode *B) { if (!A || !B) return nullptr; - SmallVector<Metadata *, 4> MDs; - for (Metadata *MD : A->operands()) - if (std::find(B->op_begin(), B->op_end(), MD) != B->op_end()) - MDs.push_back(MD); + SmallSetVector<Metadata *, 4> MDs(A->op_begin(), A->op_end()); + SmallPtrSet<Metadata *, 4> BSet(B->op_begin(), B->op_end()); + MDs.remove_if([&](Metadata *MD) { return !is_contained(BSet, MD); }); // FIXME: This preserves long-standing behaviour, but is it really the right // behaviour? Or was that an unintended side-effect of node uniquing? - return getOrSelfReference(A->getContext(), MDs); + return getOrSelfReference(A->getContext(), MDs.getArrayRef()); } MDNode *MDNode::getMostGenericAliasScope(MDNode *A, MDNode *B) { if (!A || !B) return nullptr; - SmallVector<Metadata *, 4> MDs(B->op_begin(), B->op_end()); - for (Metadata *MD : A->operands()) - if (std::find(B->op_begin(), B->op_end(), MD) == B->op_end()) - MDs.push_back(MD); - - // FIXME: This preserves long-standing behaviour, but is it really the right - // behaviour? Or was that an unintended side-effect of node uniquing? - return getOrSelfReference(A->getContext(), MDs); + return concatenate(A, B); } MDNode *MDNode::getMostGenericFPMath(MDNode *A, MDNode *B) { @@ -1065,17 +1052,11 @@ void NamedMDNode::setOperand(unsigned I, MDNode *New) { getNMDOps(Operands)[I].reset(New); } -void NamedMDNode::eraseFromParent() { - getParent()->eraseNamedMetadata(this); -} +void NamedMDNode::eraseFromParent() { getParent()->eraseNamedMetadata(this); } -void NamedMDNode::dropAllReferences() { - getNMDOps(Operands).clear(); -} +void NamedMDNode::clearOperands() { getNMDOps(Operands).clear(); } -StringRef NamedMDNode::getName() const { - return StringRef(Name); -} +StringRef NamedMDNode::getName() const { return StringRef(Name); } //===----------------------------------------------------------------------===// // Instruction Metadata method implementations. @@ -1173,14 +1154,13 @@ MDNode *Instruction::getMetadataImpl(StringRef Kind) const { } void Instruction::dropUnknownNonDebugMetadata(ArrayRef<unsigned> KnownIDs) { - SmallSet<unsigned, 5> KnownSet; - KnownSet.insert(KnownIDs.begin(), KnownIDs.end()); - if (!hasMetadataHashEntry()) return; // Nothing to remove! auto &InstructionMetadata = getContext().pImpl->InstructionMetadata; + SmallSet<unsigned, 4> KnownSet; + KnownSet.insert(KnownIDs.begin(), KnownIDs.end()); if (KnownSet.empty()) { // Just drop our entry at the store. InstructionMetadata.erase(this); @@ -1209,7 +1189,7 @@ void Instruction::setMetadata(unsigned KindID, MDNode *Node) { DbgLoc = DebugLoc(Node); return; } - + // Handle the case when we're adding/updating metadata on an instruction. if (Node) { auto &Info = getContext().pImpl->InstructionMetadata[this]; @@ -1226,7 +1206,7 @@ void Instruction::setMetadata(unsigned KindID, MDNode *Node) { (getContext().pImpl->InstructionMetadata.count(this) > 0)) && "HasMetadata bit out of date!"); if (!hasMetadataHashEntry()) - return; // Nothing to remove! + return; // Nothing to remove! auto &Info = getContext().pImpl->InstructionMetadata[this]; // Handle removal of an existing value. @@ -1261,12 +1241,13 @@ MDNode *Instruction::getMetadataImpl(unsigned KindID) const { void Instruction::getAllMetadataImpl( SmallVectorImpl<std::pair<unsigned, MDNode *>> &Result) const { Result.clear(); - + // Handle 'dbg' as a special case since it is not stored in the hash table. if (DbgLoc) { Result.push_back( std::make_pair((unsigned)LLVMContext::MD_dbg, DbgLoc.getAsMDNode())); - if (!hasMetadataHashEntry()) return; + if (!hasMetadataHashEntry()) + return; } assert(hasMetadataHashEntry() && @@ -1288,10 +1269,11 @@ void Instruction::getAllMetadataOtherThanDebugLocImpl( Info.getAll(Result); } -bool Instruction::extractProfMetadata(uint64_t &TrueVal, uint64_t &FalseVal) { - assert((getOpcode() == Instruction::Br || - getOpcode() == Instruction::Select) && - "Looking for branch weights on something besides branch or select"); +bool Instruction::extractProfMetadata(uint64_t &TrueVal, + uint64_t &FalseVal) const { + assert( + (getOpcode() == Instruction::Br || getOpcode() == Instruction::Select) && + "Looking for branch weights on something besides branch or select"); auto *ProfileData = getMetadata(LLVMContext::MD_prof); if (!ProfileData || ProfileData->getNumOperands() != 3) @@ -1312,11 +1294,12 @@ bool Instruction::extractProfMetadata(uint64_t &TrueVal, uint64_t &FalseVal) { return true; } -bool Instruction::extractProfTotalWeight(uint64_t &TotalVal) { +bool Instruction::extractProfTotalWeight(uint64_t &TotalVal) const { assert((getOpcode() == Instruction::Br || getOpcode() == Instruction::Select || getOpcode() == Instruction::Call || - getOpcode() == Instruction::Invoke) && + getOpcode() == Instruction::Invoke || + getOpcode() == Instruction::Switch) && "Looking for branch weights on something besides branch"); TotalVal = 0; @@ -1433,7 +1416,29 @@ void GlobalObject::copyMetadata(const GlobalObject *Other, unsigned Offset) { *MDNode::get(getContext(), {NewOffsetMD, TypeId})); continue; } - addMetadata(MD.first, *MD.second); + // If an offset adjustment was specified we need to modify the DIExpression + // to prepend the adjustment: + // !DIExpression(DW_OP_plus, Offset, [original expr]) + auto *Attachment = MD.second; + if (Offset != 0 && MD.first == LLVMContext::MD_dbg) { + DIGlobalVariable *GV = dyn_cast<DIGlobalVariable>(Attachment); + DIExpression *E = nullptr; + if (!GV) { + auto *GVE = cast<DIGlobalVariableExpression>(Attachment); + GV = GVE->getVariable(); + E = GVE->getExpression(); + } + ArrayRef<uint64_t> OrigElements; + if (E) + OrigElements = E->getElements(); + std::vector<uint64_t> Elements(OrigElements.size() + 2); + Elements[0] = dwarf::DW_OP_plus; + Elements[1] = Offset; + std::copy(OrigElements.begin(), OrigElements.end(), Elements.begin() + 2); + E = DIExpression::get(getContext(), Elements); + Attachment = DIGlobalVariableExpression::get(getContext(), GV, E); + } + addMetadata(MD.first, *Attachment); } } @@ -1453,3 +1458,15 @@ void Function::setSubprogram(DISubprogram *SP) { DISubprogram *Function::getSubprogram() const { return cast_or_null<DISubprogram>(getMetadata(LLVMContext::MD_dbg)); } + +void GlobalVariable::addDebugInfo(DIGlobalVariableExpression *GV) { + addMetadata(LLVMContext::MD_dbg, *GV); +} + +void GlobalVariable::getDebugInfo( + SmallVectorImpl<DIGlobalVariableExpression *> &GVs) const { + SmallVector<MDNode *, 1> MDs; + getMetadata(LLVMContext::MD_dbg, MDs); + for (MDNode *MD : MDs) + GVs.push_back(cast<DIGlobalVariableExpression>(MD)); +} |