diff options
Diffstat (limited to 'contrib/llvm-project/llvm/lib/Bitcode/Writer/ValueEnumerator.cpp')
| -rw-r--r-- | contrib/llvm-project/llvm/lib/Bitcode/Writer/ValueEnumerator.cpp | 127 |
1 files changed, 105 insertions, 22 deletions
diff --git a/contrib/llvm-project/llvm/lib/Bitcode/Writer/ValueEnumerator.cpp b/contrib/llvm-project/llvm/lib/Bitcode/Writer/ValueEnumerator.cpp index bbee8b324954..d86db61ee1f4 100644 --- a/contrib/llvm-project/llvm/lib/Bitcode/Writer/ValueEnumerator.cpp +++ b/contrib/llvm-project/llvm/lib/Bitcode/Writer/ValueEnumerator.cpp @@ -28,6 +28,7 @@ #include "llvm/IR/Instructions.h" #include "llvm/IR/Metadata.h" #include "llvm/IR/Module.h" +#include "llvm/IR/Operator.h" #include "llvm/IR/Type.h" #include "llvm/IR/Use.h" #include "llvm/IR/User.h" @@ -78,16 +79,6 @@ struct OrderMap { } // end anonymous namespace -/// Look for a value that might be wrapped as metadata, e.g. a value in a -/// metadata operand. Returns nullptr for a non-wrapped input value if -/// OnlyWrapped is true, or it returns the input value as-is if false. -static const Value *skipMetadataWrapper(const Value *V, bool OnlyWrapped) { - if (const auto *MAV = dyn_cast<MetadataAsValue>(V)) - if (const auto *VAM = dyn_cast<ValueAsMetadata>(MAV->getMetadata())) - return VAM->getValue(); - return OnlyWrapped ? nullptr : V; -} - static void orderValue(const Value *V, OrderMap &OM) { if (OM.lookup(V).first) return; @@ -139,16 +130,25 @@ static OrderMap orderModule(const Module &M) { // these before global values, as these will be read before setting the // global values' initializers. The latter matters for constants which have // uses towards other constants that are used as initializers. + auto orderConstantValue = [&OM](const Value *V) { + if ((isa<Constant>(V) && !isa<GlobalValue>(V)) || isa<InlineAsm>(V)) + orderValue(V, OM); + }; for (const Function &F : M) { if (F.isDeclaration()) continue; for (const BasicBlock &BB : F) for (const Instruction &I : BB) for (const Value *V : I.operands()) { - if (const Value *Op = skipMetadataWrapper(V, true)) { - if ((isa<Constant>(*Op) && !isa<GlobalValue>(*Op)) || - isa<InlineAsm>(*Op)) - orderValue(Op, OM); + if (const auto *MAV = dyn_cast<MetadataAsValue>(V)) { + if (const auto *VAM = + dyn_cast<ValueAsMetadata>(MAV->getMetadata())) { + orderConstantValue(VAM->getValue()); + } else if (const auto *AL = + dyn_cast<DIArgList>(MAV->getMetadata())) { + for (const auto *VAM : AL->getArgs()) + orderConstantValue(VAM->getValue()); + } } } } @@ -365,18 +365,23 @@ ValueEnumerator::ValueEnumerator(const Module &M, UseListOrders = predictUseListOrder(M); // Enumerate the global variables. - for (const GlobalVariable &GV : M.globals()) + for (const GlobalVariable &GV : M.globals()) { EnumerateValue(&GV); + EnumerateType(GV.getValueType()); + } // Enumerate the functions. for (const Function & F : M) { EnumerateValue(&F); + EnumerateType(F.getValueType()); EnumerateAttributes(F.getAttributes()); } // Enumerate the aliases. - for (const GlobalAlias &GA : M.aliases()) + for (const GlobalAlias &GA : M.aliases()) { EnumerateValue(&GA); + EnumerateType(GA.getValueType()); + } // Enumerate the ifuncs. for (const GlobalIFunc &GIF : M.ifuncs()) @@ -448,17 +453,31 @@ ValueEnumerator::ValueEnumerator(const Module &M, continue; } - // Local metadata is enumerated during function-incorporation. + // Local metadata is enumerated during function-incorporation, but + // any ConstantAsMetadata arguments in a DIArgList should be examined + // now. if (isa<LocalAsMetadata>(MD->getMetadata())) continue; + if (auto *AL = dyn_cast<DIArgList>(MD->getMetadata())) { + for (auto *VAM : AL->getArgs()) + if (isa<ConstantAsMetadata>(VAM)) + EnumerateMetadata(&F, VAM); + continue; + } EnumerateMetadata(&F, MD->getMetadata()); } if (auto *SVI = dyn_cast<ShuffleVectorInst>(&I)) EnumerateType(SVI->getShuffleMaskForBitcode()->getType()); + if (auto *GEP = dyn_cast<GetElementPtrInst>(&I)) + EnumerateType(GEP->getSourceElementType()); + if (auto *AI = dyn_cast<AllocaInst>(&I)) + EnumerateType(AI->getAllocatedType()); EnumerateType(I.getType()); - if (const auto *Call = dyn_cast<CallBase>(&I)) + if (const auto *Call = dyn_cast<CallBase>(&I)) { EnumerateAttributes(Call->getAttributes()); + EnumerateType(Call->getFunctionType()); + } // Enumerate metadata attached with this instruction. MDs.clear(); @@ -619,6 +638,11 @@ void ValueEnumerator::EnumerateFunctionLocalMetadata( EnumerateFunctionLocalMetadata(getMetadataFunctionID(&F), Local); } +void ValueEnumerator::EnumerateFunctionLocalListMetadata( + const Function &F, const DIArgList *ArgList) { + EnumerateFunctionLocalListMetadata(getMetadataFunctionID(&F), ArgList); +} + void ValueEnumerator::dropFunctionFromMetadata( MetadataMapType::value_type &FirstMD) { SmallVector<const MDNode *, 64> Worklist; @@ -729,7 +753,7 @@ const MDNode *ValueEnumerator::enumerateMetadataImpl(unsigned F, const Metadata return nullptr; } -/// EnumerateFunctionLocalMetadataa - Incorporate function-local metadata +/// EnumerateFunctionLocalMetadata - Incorporate function-local metadata /// information reachable from the metadata. void ValueEnumerator::EnumerateFunctionLocalMetadata( unsigned F, const LocalAsMetadata *Local) { @@ -749,6 +773,39 @@ void ValueEnumerator::EnumerateFunctionLocalMetadata( EnumerateValue(Local->getValue()); } +/// EnumerateFunctionLocalListMetadata - Incorporate function-local metadata +/// information reachable from the metadata. +void ValueEnumerator::EnumerateFunctionLocalListMetadata( + unsigned F, const DIArgList *ArgList) { + assert(F && "Expected a function"); + + // Check to see if it's already in! + MDIndex &Index = MetadataMap[ArgList]; + if (Index.ID) { + assert(Index.F == F && "Expected the same function"); + return; + } + + for (ValueAsMetadata *VAM : ArgList->getArgs()) { + if (isa<LocalAsMetadata>(VAM)) { + assert(MetadataMap.count(VAM) && + "LocalAsMetadata should be enumerated before DIArgList"); + assert(MetadataMap[VAM].F == F && + "Expected LocalAsMetadata in the same function"); + } else { + assert(isa<ConstantAsMetadata>(VAM) && + "Expected LocalAsMetadata or ConstantAsMetadata"); + assert(ValueMap.count(VAM->getValue()) && + "Constant should be enumerated beforeDIArgList"); + EnumerateMetadata(F, VAM); + } + } + + MDs.push_back(ArgList); + Index.F = F; + Index.ID = MDs.size(); +} + static unsigned getMetadataTypeOrder(const Metadata *MD) { // Strings are emitted in bulk and must come first. if (isa<MDString>(MD)) @@ -959,9 +1016,12 @@ void ValueEnumerator::EnumerateOperandType(const Value *V) { EnumerateOperandType(Op); } - if (auto *CE = dyn_cast<ConstantExpr>(C)) + if (auto *CE = dyn_cast<ConstantExpr>(C)) { if (CE->getOpcode() == Instruction::ShuffleVector) EnumerateOperandType(CE->getShuffleMaskForBitcode()); + if (CE->getOpcode() == Instruction::GetElementPtr) + EnumerateType(cast<GEPOperator>(CE)->getSourceElementType()); + } } void ValueEnumerator::EnumerateAttributes(AttributeList PAL) { @@ -985,6 +1045,11 @@ void ValueEnumerator::EnumerateAttributes(AttributeList PAL) { if (Entry == 0) { AttributeGroups.push_back(Pair); Entry = AttributeGroups.size(); + + for (Attribute Attr : AS) { + if (Attr.isTypeAttribute()) + EnumerateType(Attr.getValueAsType()); + } } } } @@ -1004,6 +1069,8 @@ void ValueEnumerator::incorporateFunction(const Function &F) { EnumerateType(I.getParamByValType()); else if (I.hasAttribute(Attribute::StructRet)) EnumerateType(I.getParamStructRetType()); + else if (I.hasAttribute(Attribute::ByRef)) + EnumerateType(I.getParamByRefType()); } FirstFuncConstantID = Values.size(); @@ -1031,14 +1098,26 @@ void ValueEnumerator::incorporateFunction(const Function &F) { FirstInstID = Values.size(); SmallVector<LocalAsMetadata *, 8> FnLocalMDVector; + SmallVector<DIArgList *, 8> ArgListMDVector; // Add all of the instructions. for (const BasicBlock &BB : F) { for (const Instruction &I : BB) { for (const Use &OI : I.operands()) { - if (auto *MD = dyn_cast<MetadataAsValue>(&OI)) - if (auto *Local = dyn_cast<LocalAsMetadata>(MD->getMetadata())) + if (auto *MD = dyn_cast<MetadataAsValue>(&OI)) { + if (auto *Local = dyn_cast<LocalAsMetadata>(MD->getMetadata())) { // Enumerate metadata after the instructions they might refer to. FnLocalMDVector.push_back(Local); + } else if (auto *ArgList = dyn_cast<DIArgList>(MD->getMetadata())) { + ArgListMDVector.push_back(ArgList); + for (ValueAsMetadata *VMD : ArgList->getArgs()) { + if (auto *Local = dyn_cast<LocalAsMetadata>(VMD)) { + // Enumerate metadata after the instructions they might refer + // to. + FnLocalMDVector.push_back(Local); + } + } + } + } } if (!I.getType()->isVoidTy()) @@ -1054,6 +1133,10 @@ void ValueEnumerator::incorporateFunction(const Function &F) { "Missing value for metadata operand"); EnumerateFunctionLocalMetadata(F, FnLocalMDVector[i]); } + // DIArgList entries must come after function-local metadata, as it is not + // possible to forward-reference them. + for (const DIArgList *ArgList : ArgListMDVector) + EnumerateFunctionLocalListMetadata(F, ArgList); } void ValueEnumerator::purgeFunction() { |
