Skip to content

Commit adec8c2

Browse files
Use DIExpression:foldConstantMath() at the result of an append()
1 parent dcf20f1 commit adec8c2

File tree

5 files changed

+180
-3
lines changed

5 files changed

+180
-3
lines changed

llvm/include/llvm/IR/DebugInfoMetadata.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3069,6 +3069,7 @@ class DIExpression : public MDNode {
30693069
/// evaluated at compile time. Returns a new expression on success, or the old
30703070
/// expression if there is nothing to be reduced.
30713071
SmallVector<uint64_t> foldConstantMath(ArrayRef<uint64_t> WorkingOps);
3072+
static constexpr unsigned MaxRuleOpSize = 6;
30723073
};
30733074

30743075
inline bool operator==(const DIExpression::FragmentInfo &A,

llvm/lib/IR/DebugInfoMetadata.cpp

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1859,6 +1859,7 @@ DIExpression *DIExpression::append(const DIExpression *Expr,
18591859

18601860
// Copy Expr's current op list.
18611861
SmallVector<uint64_t, 16> NewOps;
1862+
uint64_t OpCount = 0;
18621863
for (auto Op : Expr->expr_ops()) {
18631864
// Append new opcodes before DW_OP_{stack_value, LLVM_fragment}.
18641865
if (Op.getOp() == dwarf::DW_OP_stack_value ||
@@ -1869,10 +1870,47 @@ DIExpression *DIExpression::append(const DIExpression *Expr,
18691870
Ops = std::nullopt;
18701871
}
18711872
Op.appendToVector(NewOps);
1873+
OpCount++;
18721874
}
18731875
NewOps.append(Ops.begin(), Ops.end());
18741876
auto *result = DIExpression::get(Expr->getContext(), NewOps);
18751877
assert(result->isValid() && "concatenated expression is not valid");
1878+
1879+
// Instead of applying a foldConstantMath on the entire expression, apply it
1880+
// only to the new operations to be added to the expression + the the
1881+
// preceding operations totalling to the longest foldable pattern.
1882+
uint64_t NewOpCount = 0;
1883+
for (auto It = result->expr_op_begin(); It != result->expr_op_end(); It++)
1884+
NewOpCount++;
1885+
1886+
// This is the number of new operations that were added to the expression,
1887+
// i.e. the number of operations in the Ops argument.
1888+
unsigned NumOfAddedOps = NewOpCount - OpCount;
1889+
// This is the number of operations that DIExpression::foldConstantMath should
1890+
// be applied upon, which is the number of new operations added + the
1891+
// preceding operations totalling to the longest foldable pattern.
1892+
unsigned NumOfOpsToBeFolded = 0;
1893+
if (OpCount < DIExpression::MaxRuleOpSize)
1894+
NumOfOpsToBeFolded = 0;
1895+
else
1896+
NumOfOpsToBeFolded =
1897+
NewOpCount - NumOfAddedOps - DIExpression::MaxRuleOpSize;
1898+
SmallVector<uint64_t> FoldedOps;
1899+
1900+
unsigned Count = 0;
1901+
SmallVector<uint64_t> OpsToBeFolded;
1902+
for (auto Op : result->expr_ops()) {
1903+
if (Count < NumOfOpsToBeFolded) {
1904+
Op.appendToVector(FoldedOps);
1905+
Count++;
1906+
} else
1907+
Op.appendToVector(OpsToBeFolded);
1908+
}
1909+
1910+
OpsToBeFolded = result->foldConstantMath(OpsToBeFolded);
1911+
FoldedOps.append(OpsToBeFolded);
1912+
result = DIExpression::get(Expr->getContext(), FoldedOps);
1913+
assert(result->isValid() && "concatenated expression is not valid");
18761914
return result;
18771915
}
18781916

llvm/test/Bitcode/upgrade-dbg-addr.ll

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ entry:
88
%num.addr = alloca i32, align 4
99
store i32 %num, ptr %num.addr, align 4
1010
; CHECK-NOT: call void @llvm.dbg.addr
11-
; CHECK: call void @llvm.dbg.value(metadata ptr %num.addr, metadata ![[#]], metadata !DIExpression(DW_OP_plus_uconst, 0, DW_OP_deref))
11+
; CHECK: call void @llvm.dbg.value(metadata ptr %num.addr, metadata ![[#]], metadata !DIExpression(DW_OP_deref))
1212
call void @llvm.dbg.addr(metadata ptr %num.addr, metadata !16, metadata !DIExpression(DW_OP_plus_uconst, 0)), !dbg !17
1313
%0 = load i32, ptr %num.addr, align 4
1414
ret i32 %0

llvm/test/DebugInfo/MIR/AArch64/dbgcall-site-expr-chain.mir

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -105,12 +105,12 @@ body: |
105105

106106
# CHECK: DW_TAG_GNU_call_site_parameter
107107
# CHECK-NEXT: DW_AT_location (DW_OP_reg2 W2)
108-
# CHECK-NEXT: DW_AT_GNU_call_site_value (DW_OP_breg19 W19+700, DW_OP_plus_uconst 0x9, DW_OP_plus_uconst 0x50)
108+
# CHECK-NEXT: DW_AT_GNU_call_site_value (DW_OP_breg19 W19+789)
109109

110110
# CHECK: DW_TAG_GNU_call_site_parameter
111111
# CHECK-NEXT: DW_AT_location (DW_OP_reg1 W1)
112112
# CHECK-NEXT: DW_AT_GNU_call_site_value (DW_OP_breg19 W19-406, DW_OP_constu 0x32, DW_OP_minus)
113113

114114
# CHECK: DW_TAG_GNU_call_site_parameter
115115
# CHECK-NEXT: DW_AT_location (DW_OP_reg0 W0)
116-
# CHECK-NEXT: DW_AT_GNU_call_site_value (DW_OP_breg19 W19+100, DW_OP_plus_uconst 0x17)
116+
# CHECK-NEXT: DW_AT_GNU_call_site_value (DW_OP_breg19 W19+123)

llvm/unittests/IR/MetadataTest.cpp

Lines changed: 138 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3606,6 +3606,144 @@ TEST_F(DIExpressionTest, Fold) {
36063606
EXPECT_EQ(E, ResExpr);
36073607
}
36083608

3609+
TEST_F(DIExpressionTest, Append) {
3610+
// Test appending a {dwarf::DW_OP_constu, <const>, DW_OP_plus} to a DW_OP_plus
3611+
// expression
3612+
SmallVector<uint64_t, 8> Ops = {dwarf::DW_OP_LLVM_arg, 0, dwarf::DW_OP_constu,
3613+
2, dwarf::DW_OP_plus};
3614+
auto *Expr = DIExpression::get(Context, Ops);
3615+
SmallVector<uint64_t, 8> AppendOps = {dwarf::DW_OP_constu, 3,
3616+
dwarf::DW_OP_plus};
3617+
auto *AppendExpr = DIExpression::append(Expr, AppendOps);
3618+
SmallVector<uint64_t, 8> OpsRes = {dwarf::DW_OP_LLVM_arg, 0,
3619+
dwarf::DW_OP_plus_uconst, 5};
3620+
auto *ResExpr = DIExpression::get(Context, OpsRes);
3621+
EXPECT_EQ(ResExpr, AppendExpr);
3622+
3623+
// Test appending a {dwarf::DW_OP_plus_uconst, <const>} to a DW_OP_plus
3624+
// expression uint64_t PlusUConstOps[] = {dwarf::DW_OP_plus_uconst, 3};
3625+
AppendOps.clear();
3626+
AppendOps.push_back(dwarf::DW_OP_plus_uconst);
3627+
AppendOps.push_back(3);
3628+
AppendExpr = DIExpression::append(Expr, AppendOps);
3629+
OpsRes.clear();
3630+
OpsRes.push_back(dwarf::DW_OP_LLVM_arg);
3631+
OpsRes.push_back(0);
3632+
OpsRes.push_back(dwarf::DW_OP_plus_uconst);
3633+
OpsRes.push_back(5);
3634+
ResExpr = DIExpression::get(Context, OpsRes);
3635+
EXPECT_EQ(ResExpr, AppendExpr);
3636+
3637+
// Test appending a {dwarf::DW_OP_constu, 0, DW_OP_plus} to an expression
3638+
AppendOps.clear();
3639+
AppendOps.push_back(dwarf::DW_OP_constu);
3640+
AppendOps.push_back(0);
3641+
AppendOps.push_back(dwarf::DW_OP_plus);
3642+
AppendExpr = DIExpression::append(Expr, AppendOps);
3643+
OpsRes.clear();
3644+
OpsRes.push_back(dwarf::DW_OP_LLVM_arg);
3645+
OpsRes.push_back(0);
3646+
OpsRes.push_back(dwarf::DW_OP_plus_uconst);
3647+
OpsRes.push_back(2);
3648+
ResExpr = DIExpression::get(Context, OpsRes);
3649+
EXPECT_EQ(ResExpr, AppendExpr);
3650+
3651+
// Test appending a {dwarf::DW_OP_constu, 0, DW_OP_minus} to an expression
3652+
AppendOps.clear();
3653+
AppendOps.push_back(dwarf::DW_OP_constu);
3654+
AppendOps.push_back(0);
3655+
AppendOps.push_back(dwarf::DW_OP_minus);
3656+
AppendExpr = DIExpression::append(Expr, AppendOps);
3657+
OpsRes.clear();
3658+
OpsRes.push_back(dwarf::DW_OP_LLVM_arg);
3659+
OpsRes.push_back(0);
3660+
OpsRes.push_back(dwarf::DW_OP_plus_uconst);
3661+
OpsRes.push_back(2);
3662+
ResExpr = DIExpression::get(Context, OpsRes);
3663+
EXPECT_EQ(ResExpr, AppendExpr);
3664+
3665+
// Test appending a {dwarf::DW_OP_constu, 0, DW_OP_shl} to an expression
3666+
AppendOps.clear();
3667+
AppendOps.push_back(dwarf::DW_OP_constu);
3668+
AppendOps.push_back(0);
3669+
AppendOps.push_back(dwarf::DW_OP_shl);
3670+
AppendExpr = DIExpression::append(Expr, AppendOps);
3671+
OpsRes.clear();
3672+
OpsRes.push_back(dwarf::DW_OP_LLVM_arg);
3673+
OpsRes.push_back(0);
3674+
OpsRes.push_back(dwarf::DW_OP_plus_uconst);
3675+
OpsRes.push_back(2);
3676+
ResExpr = DIExpression::get(Context, OpsRes);
3677+
EXPECT_EQ(ResExpr, AppendExpr);
3678+
3679+
// Test appending a {dwarf::DW_OP_constu, 0, DW_OP_shr} to an expression
3680+
AppendOps.clear();
3681+
AppendOps.push_back(dwarf::DW_OP_constu);
3682+
AppendOps.push_back(0);
3683+
AppendOps.push_back(dwarf::DW_OP_shr);
3684+
AppendExpr = DIExpression::append(Expr, AppendOps);
3685+
OpsRes.clear();
3686+
OpsRes.push_back(dwarf::DW_OP_LLVM_arg);
3687+
OpsRes.push_back(0);
3688+
OpsRes.push_back(dwarf::DW_OP_plus_uconst);
3689+
OpsRes.push_back(2);
3690+
ResExpr = DIExpression::get(Context, OpsRes);
3691+
EXPECT_EQ(ResExpr, AppendExpr);
3692+
3693+
// Test appending a {dwarf::DW_OP_constu, <const>, DW_OP_mul} to a DW_OP_mul
3694+
// expression
3695+
Ops.clear();
3696+
Ops.push_back(dwarf::DW_OP_LLVM_arg);
3697+
Ops.push_back(0);
3698+
Ops.push_back(dwarf::DW_OP_constu);
3699+
Ops.push_back(2);
3700+
Ops.push_back(dwarf::DW_OP_mul);
3701+
Expr = DIExpression::get(Context, Ops);
3702+
AppendOps.clear();
3703+
AppendOps.push_back(dwarf::DW_OP_constu);
3704+
AppendOps.push_back(3);
3705+
AppendOps.push_back(dwarf::DW_OP_mul);
3706+
AppendExpr = DIExpression::append(Expr, AppendOps);
3707+
OpsRes.clear();
3708+
OpsRes.push_back(dwarf::DW_OP_LLVM_arg);
3709+
OpsRes.push_back(0);
3710+
OpsRes.push_back(dwarf::DW_OP_constu);
3711+
OpsRes.push_back(6);
3712+
OpsRes.push_back(dwarf::DW_OP_mul);
3713+
ResExpr = DIExpression::get(Context, OpsRes);
3714+
EXPECT_EQ(ResExpr, AppendExpr);
3715+
3716+
// Test appending a {dwarf::DW_OP_constu, 1, DW_OP_mul} to an expression
3717+
AppendOps.clear();
3718+
AppendOps.push_back(dwarf::DW_OP_constu);
3719+
AppendOps.push_back(1);
3720+
AppendOps.push_back(dwarf::DW_OP_mul);
3721+
AppendExpr = DIExpression::append(Expr, AppendOps);
3722+
OpsRes.clear();
3723+
OpsRes.push_back(dwarf::DW_OP_LLVM_arg);
3724+
OpsRes.push_back(0);
3725+
OpsRes.push_back(dwarf::DW_OP_constu);
3726+
OpsRes.push_back(2);
3727+
OpsRes.push_back(dwarf::DW_OP_mul);
3728+
ResExpr = DIExpression::get(Context, OpsRes);
3729+
EXPECT_EQ(ResExpr, AppendExpr);
3730+
3731+
// Test appending a {dwarf::DW_OP_constu, 1, DW_OP_div} to an expression
3732+
AppendOps.clear();
3733+
AppendOps.push_back(dwarf::DW_OP_constu);
3734+
AppendOps.push_back(1);
3735+
AppendOps.push_back(dwarf::DW_OP_div);
3736+
AppendExpr = DIExpression::append(Expr, AppendOps);
3737+
OpsRes.clear();
3738+
OpsRes.push_back(dwarf::DW_OP_LLVM_arg);
3739+
OpsRes.push_back(0);
3740+
OpsRes.push_back(dwarf::DW_OP_constu);
3741+
OpsRes.push_back(2);
3742+
OpsRes.push_back(dwarf::DW_OP_mul);
3743+
ResExpr = DIExpression::get(Context, OpsRes);
3744+
EXPECT_EQ(ResExpr, AppendExpr);
3745+
}
3746+
36093747
TEST_F(DIExpressionTest, isValid) {
36103748
#define EXPECT_VALID(...) \
36113749
do { \

0 commit comments

Comments
 (0)