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 | 136 |
1 files changed, 49 insertions, 87 deletions
diff --git a/contrib/llvm-project/llvm/lib/Bitcode/Writer/ValueEnumerator.cpp b/contrib/llvm-project/llvm/lib/Bitcode/Writer/ValueEnumerator.cpp index 01f7e85bd60e..727ec2e02cc2 100644 --- a/contrib/llvm-project/llvm/lib/Bitcode/Writer/ValueEnumerator.cpp +++ b/contrib/llvm-project/llvm/lib/Bitcode/Writer/ValueEnumerator.cpp @@ -50,17 +50,12 @@ namespace { struct OrderMap { DenseMap<const Value *, std::pair<unsigned, bool>> IDs; - unsigned LastGlobalConstantID = 0; unsigned LastGlobalValueID = 0; OrderMap() = default; - bool isGlobalConstant(unsigned ID) const { - return ID <= LastGlobalConstantID; - } - bool isGlobalValue(unsigned ID) const { - return ID <= LastGlobalValueID && !isGlobalConstant(ID); + return ID <= LastGlobalValueID; } unsigned size() const { return IDs.size(); } @@ -84,7 +79,7 @@ static void orderValue(const Value *V, OrderMap &OM) { return; if (const Constant *C = dyn_cast<Constant>(V)) { - if (C->getNumOperands() && !isa<GlobalValue>(C)) { + if (C->getNumOperands()) { for (const Value *Op : C->operands()) if (!isa<BasicBlock>(Op) && !isa<GlobalValue>(Op)) orderValue(Op, OM); @@ -104,39 +99,40 @@ static OrderMap orderModule(const Module &M) { // and ValueEnumerator::incorporateFunction(). OrderMap OM; - // In the reader, initializers of GlobalValues are set *after* all the - // globals have been read. Rather than awkwardly modeling this behaviour - // directly in predictValueUseListOrderImpl(), just assign IDs to - // initializers of GlobalValues before GlobalValues themselves to model this - // implicitly. - for (const GlobalVariable &G : M.globals()) - if (G.hasInitializer()) - if (!isa<GlobalValue>(G.getInitializer())) - orderValue(G.getInitializer(), OM); - for (const GlobalAlias &A : M.aliases()) - if (!isa<GlobalValue>(A.getAliasee())) - orderValue(A.getAliasee(), OM); - for (const GlobalIFunc &I : M.ifuncs()) - if (!isa<GlobalValue>(I.getResolver())) - orderValue(I.getResolver(), OM); - for (const Function &F : M) { - for (const Use &U : F.operands()) - if (!isa<GlobalValue>(U.get())) - orderValue(U.get(), OM); - } + // Initializers of GlobalValues are processed in + // BitcodeReader::ResolveGlobalAndAliasInits(). Match the order there rather + // than ValueEnumerator, and match the code in predictValueUseListOrderImpl() + // by giving IDs in reverse order. + // + // Since GlobalValues never reference each other directly (just through + // initializers), their relative IDs only matter for determining order of + // uses in their initializers. + for (const GlobalVariable &G : reverse(M.globals())) + orderValue(&G, OM); + for (const GlobalAlias &A : reverse(M.aliases())) + orderValue(&A, OM); + for (const GlobalIFunc &I : reverse(M.ifuncs())) + orderValue(&I, OM); + for (const Function &F : reverse(M)) + orderValue(&F, OM); + OM.LastGlobalValueID = OM.size(); - // As constants used in metadata operands are emitted as module-level - // constants, we must order them before other operands. Also, we must order - // 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)) + if (isa<Constant>(V) || isa<InlineAsm>(V)) orderValue(V, OM); }; + for (const Function &F : M) { if (F.isDeclaration()) continue; + // Here we need to match the union of ValueEnumerator::incorporateFunction() + // and WriteFunction(). Basic blocks are implicitly declared before + // anything else (by declaring their size). + for (const BasicBlock &BB : F) + orderValue(&BB, OM); + + // Metadata used by instructions is decoded before the actual instructions, + // so visit any constants used by it beforehand. for (const BasicBlock &BB : F) for (const Instruction &I : BB) for (const Value *V : I.operands()) { @@ -151,49 +147,17 @@ static OrderMap orderModule(const Module &M) { } } } - } - OM.LastGlobalConstantID = OM.size(); - - // Initializers of GlobalValues are processed in - // BitcodeReader::ResolveGlobalAndAliasInits(). Match the order there rather - // than ValueEnumerator, and match the code in predictValueUseListOrderImpl() - // by giving IDs in reverse order. - // - // Since GlobalValues never reference each other directly (just through - // initializers), their relative IDs only matter for determining order of - // uses in their initializers. - for (const Function &F : M) - orderValue(&F, OM); - for (const GlobalAlias &A : M.aliases()) - orderValue(&A, OM); - for (const GlobalIFunc &I : M.ifuncs()) - orderValue(&I, OM); - for (const GlobalVariable &G : M.globals()) - orderValue(&G, OM); - OM.LastGlobalValueID = OM.size(); - for (const Function &F : M) { - if (F.isDeclaration()) - continue; - // Here we need to match the union of ValueEnumerator::incorporateFunction() - // and WriteFunction(). Basic blocks are implicitly declared before - // anything else (by declaring their size). - for (const BasicBlock &BB : F) - orderValue(&BB, OM); for (const Argument &A : F.args()) orderValue(&A, OM); for (const BasicBlock &BB : F) for (const Instruction &I : BB) { for (const Value *Op : I.operands()) - if ((isa<Constant>(*Op) && !isa<GlobalValue>(*Op)) || - isa<InlineAsm>(*Op)) - orderValue(Op, OM); + orderConstantValue(Op); if (auto *SVI = dyn_cast<ShuffleVectorInst>(&I)) orderValue(SVI->getShuffleMaskForBitcode(), OM); - } - for (const BasicBlock &BB : F) - for (const Instruction &I : BB) orderValue(&I, OM); + } } return OM; } @@ -223,18 +187,6 @@ static void predictValueUseListOrderImpl(const Value *V, const Function *F, auto LID = OM.lookup(LU->getUser()).first; auto RID = OM.lookup(RU->getUser()).first; - // Global values are processed in reverse order. - // - // Moreover, initializers of GlobalValues are set *after* all the globals - // have been read (despite having earlier IDs). Rather than awkwardly - // modeling this behaviour here, orderModule() has assigned IDs to - // initializers of GlobalValues before GlobalValues themselves. - if (OM.isGlobalValue(LID) && OM.isGlobalValue(RID)) { - if (LID == RID) - return LU->getOperandNo() > RU->getOperandNo(); - return LID < RID; - } - // If ID is 4, then expect: 7 6 5 1 2 3. if (LID < RID) { if (RID <= ID) @@ -257,9 +209,7 @@ static void predictValueUseListOrderImpl(const Value *V, const Function *F, return LU->getOperandNo() > RU->getOperandNo(); }); - if (llvm::is_sorted(List, [](const Entry &L, const Entry &R) { - return L.second < R.second; - })) + if (llvm::is_sorted(List, llvm::less_second())) // Order is already correct. return; @@ -319,16 +269,25 @@ static UseListOrderStack predictUseListOrder(const Module &M) { predictValueUseListOrder(&A, &F, OM, Stack); for (const BasicBlock &BB : F) for (const Instruction &I : BB) { - for (const Value *Op : I.operands()) + for (const Value *Op : I.operands()) { if (isa<Constant>(*Op) || isa<InlineAsm>(*Op)) // Visit GlobalValues. predictValueUseListOrder(Op, &F, OM, Stack); + if (const auto *MAV = dyn_cast<MetadataAsValue>(Op)) { + if (const auto *VAM = + dyn_cast<ValueAsMetadata>(MAV->getMetadata())) { + predictValueUseListOrder(VAM->getValue(), &F, OM, Stack); + } else if (const auto *AL = + dyn_cast<DIArgList>(MAV->getMetadata())) { + for (const auto *VAM : AL->getArgs()) + predictValueUseListOrder(VAM->getValue(), &F, OM, Stack); + } + } + } if (auto *SVI = dyn_cast<ShuffleVectorInst>(&I)) predictValueUseListOrder(SVI->getShuffleMaskForBitcode(), &F, OM, Stack); - } - for (const BasicBlock &BB : F) - for (const Instruction &I : BB) predictValueUseListOrder(&I, &F, OM, Stack); + } } // Visit globals last, since the module-level use-list block will be seen @@ -939,9 +898,12 @@ void ValueEnumerator::EnumerateValue(const Value *V) { I != E; ++I) if (!isa<BasicBlock>(*I)) // Don't enumerate BB operand to BlockAddress. EnumerateValue(*I); - if (auto *CE = dyn_cast<ConstantExpr>(C)) + if (auto *CE = dyn_cast<ConstantExpr>(C)) { if (CE->getOpcode() == Instruction::ShuffleVector) EnumerateValue(CE->getShuffleMaskForBitcode()); + if (auto *GEP = dyn_cast<GEPOperator>(CE)) + EnumerateType(GEP->getSourceElementType()); + } // Finally, add the value. Doing this could make the ValueID reference be // dangling, don't reuse it. |