aboutsummaryrefslogtreecommitdiff
path: root/contrib/llvm-project/llvm/lib/Bitcode/Writer/ValueEnumerator.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'contrib/llvm-project/llvm/lib/Bitcode/Writer/ValueEnumerator.cpp')
-rw-r--r--contrib/llvm-project/llvm/lib/Bitcode/Writer/ValueEnumerator.cpp127
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() {