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 | 37 |
1 files changed, 31 insertions, 6 deletions
diff --git a/contrib/llvm-project/llvm/lib/Bitcode/Writer/ValueEnumerator.cpp b/contrib/llvm-project/llvm/lib/Bitcode/Writer/ValueEnumerator.cpp index 8bdddc27e95a..bbee8b324954 100644 --- a/contrib/llvm-project/llvm/lib/Bitcode/Writer/ValueEnumerator.cpp +++ b/contrib/llvm-project/llvm/lib/Bitcode/Writer/ValueEnumerator.cpp @@ -11,11 +11,9 @@ //===----------------------------------------------------------------------===// #include "ValueEnumerator.h" -#include "llvm/ADT/DenseMap.h" #include "llvm/ADT/SmallVector.h" #include "llvm/Config/llvm-config.h" #include "llvm/IR/Argument.h" -#include "llvm/IR/Attributes.h" #include "llvm/IR/BasicBlock.h" #include "llvm/IR/Constant.h" #include "llvm/IR/DebugInfoMetadata.h" @@ -32,7 +30,6 @@ #include "llvm/IR/Module.h" #include "llvm/IR/Type.h" #include "llvm/IR/Use.h" -#include "llvm/IR/UseListOrder.h" #include "llvm/IR/User.h" #include "llvm/IR/Value.h" #include "llvm/IR/ValueSymbolTable.h" @@ -42,12 +39,9 @@ #include "llvm/Support/MathExtras.h" #include "llvm/Support/raw_ostream.h" #include <algorithm> -#include <cassert> #include <cstddef> #include <iterator> #include <tuple> -#include <utility> -#include <vector> using namespace llvm; @@ -84,6 +78,16 @@ 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; @@ -129,6 +133,25 @@ static OrderMap orderModule(const Module &M) { if (!isa<GlobalValue>(U.get())) orderValue(U.get(), OM); } + + // 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. + 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); + } + } + } OM.LastGlobalConstantID = OM.size(); // Initializers of GlobalValues are processed in @@ -979,6 +1002,8 @@ void ValueEnumerator::incorporateFunction(const Function &F) { EnumerateValue(&I); if (I.hasAttribute(Attribute::ByVal)) EnumerateType(I.getParamByValType()); + else if (I.hasAttribute(Attribute::StructRet)) + EnumerateType(I.getParamStructRetType()); } FirstFuncConstantID = Values.size(); |