} // 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;
// 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());
+ }
}
}
}
continue;
}
- // Local metadata is enumerated during function-incorporation.
- if (isa<LocalAsMetadata>(MD->getMetadata()) ||
- isa<DIArgList>(MD->getMetadata()))
+ // 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());
}
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;
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) {
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))
// DIArgList entries must come after function-local metadata, as it is not
// possible to forward-reference them.
for (const DIArgList *ArgList : ArgListMDVector)
- EnumerateMetadata(&F, ArgList);
+ EnumerateFunctionLocalListMetadata(F, ArgList);
}
void ValueEnumerator::purgeFunction() {
target triple = "x86_64-pc-windows-msvc19.16.27034"\r
\r
; CHECK-COUNT-3: llvm.dbg.value(\r
-; CHECK-SAME: metadata !DIArgList(i32 %a, i32 %b)\r
+; CHECK-SAME: metadata !DIArgList(i32 %a, i32 %b, i32 5)\r
; CHECK-SAME: metadata !16,\r
-; CHECK-SAME: metadata !DIExpression(DW_OP_LLVM_arg, 0, DW_OP_LLVM_arg, 1, DW_OP_plus)\r
+; CHECK-SAME: metadata !DIExpression(DW_OP_LLVM_arg, 0, DW_OP_LLVM_arg, 1, DW_OP_plus, DW_OP_LLVM_arg, 2, DW_OP_plus)\r
define dso_local i32 @"?foo@@YAHHH@Z"(i32 %a, i32 %b) local_unnamed_addr !dbg !8 {\r
entry:\r
call void @llvm.dbg.value(metadata !DIArgList(i32 %b), metadata !14, metadata !DIExpression(DW_OP_LLVM_arg, 0)), !dbg !17\r
call void @llvm.dbg.value(metadata !DIArgList(i32 %a), metadata !15, metadata !DIExpression(DW_OP_LLVM_arg, 0)), !dbg !17\r
call void @llvm.dbg.value(\r
- metadata !DIArgList(i32 %a, i32 %b),\r
+ metadata !DIArgList(i32 %a, i32 %b, i32 5),\r
metadata !16,\r
- metadata !DIExpression(DW_OP_LLVM_arg, 0, DW_OP_LLVM_arg, 1, DW_OP_plus)), !dbg !17\r
+ metadata !DIExpression(DW_OP_LLVM_arg, 0, DW_OP_LLVM_arg, 1, DW_OP_plus, DW_OP_LLVM_arg, 2, DW_OP_plus)), !dbg !17\r
%mul = mul nsw i32 %b, %a, !dbg !18\r
ret i32 %mul, !dbg !18\r
}\r