Skip to content

Commit a067e43

Browse files
Use DIExpression:foldConstantMath() at the result of an append()
1 parent 836d8fc commit a067e43

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
@@ -3121,6 +3121,7 @@ class DIExpression : public MDNode {
31213121
/// evaluated at compile time. Returns a new expression on success, or the old
31223122
/// expression if there is nothing to be reduced.
31233123
SmallVector<uint64_t> foldConstantMath(ArrayRef<uint64_t> WorkingOps);
3124+
static constexpr unsigned MaxRuleOpSize = 6;
31243125
};
31253126

31263127
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
@@ -1870,6 +1870,7 @@ DIExpression *DIExpression::append(const DIExpression *Expr,
18701870

18711871
// Copy Expr's current op list.
18721872
SmallVector<uint64_t, 16> NewOps;
1873+
uint64_t OpCount = 0;
18731874
for (auto Op : Expr->expr_ops()) {
18741875
// Append new opcodes before DW_OP_{stack_value, LLVM_fragment}.
18751876
if (Op.getOp() == dwarf::DW_OP_stack_value ||
@@ -1880,10 +1881,47 @@ DIExpression *DIExpression::append(const DIExpression *Expr,
18801881
Ops = std::nullopt;
18811882
}
18821883
Op.appendToVector(NewOps);
1884+
OpCount++;
18831885
}
18841886
NewOps.append(Ops.begin(), Ops.end());
18851887
auto *result = DIExpression::get(Expr->getContext(), NewOps);
18861888
assert(result->isValid() && "concatenated expression is not valid");
1889+
1890+
// Instead of applying a foldConstantMath on the entire expression, apply it
1891+
// only to the new operations to be added to the expression + the the
1892+
// preceding operations totalling to the longest foldable pattern.
1893+
uint64_t NewOpCount = 0;
1894+
for (auto It = result->expr_op_begin(); It != result->expr_op_end(); It++)
1895+
NewOpCount++;
1896+
1897+
// This is the number of new operations that were added to the expression,
1898+
// i.e. the number of operations in the Ops argument.
1899+
unsigned NumOfAddedOps = NewOpCount - OpCount;
1900+
// This is the number of operations that DIExpression::foldConstantMath should
1901+
// be applied upon, which is the number of new operations added + the
1902+
// preceding operations totalling to the longest foldable pattern.
1903+
unsigned NumOfOpsToBeFolded = 0;
1904+
if (OpCount < DIExpression::MaxRuleOpSize)
1905+
NumOfOpsToBeFolded = 0;
1906+
else
1907+
NumOfOpsToBeFolded =
1908+
NewOpCount - NumOfAddedOps - DIExpression::MaxRuleOpSize;
1909+
SmallVector<uint64_t> FoldedOps;
1910+
1911+
unsigned Count = 0;
1912+
SmallVector<uint64_t> OpsToBeFolded;
1913+
for (auto Op : result->expr_ops()) {
1914+
if (Count < NumOfOpsToBeFolded) {
1915+
Op.appendToVector(FoldedOps);
1916+
Count++;
1917+
} else
1918+
Op.appendToVector(OpsToBeFolded);
1919+
}
1920+
1921+
OpsToBeFolded = result->foldConstantMath(OpsToBeFolded);
1922+
FoldedOps.append(OpsToBeFolded);
1923+
result = DIExpression::get(Expr->getContext(), FoldedOps);
1924+
assert(result->isValid() && "concatenated expression is not valid");
18871925
return result;
18881926
}
18891927

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ entry:
99
%num.addr = alloca i32, align 4
1010
store i32 %num, ptr %num.addr, align 4
1111
; CHECK-NOT: call void @llvm.dbg.addr
12-
; CHECK: call void @llvm.dbg.value(metadata ptr %num.addr, metadata ![[#]], metadata !DIExpression(DW_OP_plus_uconst, 0, DW_OP_deref))
12+
; CHECK: call void @llvm.dbg.value(metadata ptr %num.addr, metadata ![[#]], metadata !DIExpression(DW_OP_deref))
1313
call void @llvm.dbg.addr(metadata ptr %num.addr, metadata !16, metadata !DIExpression(DW_OP_plus_uconst, 0)), !dbg !17
1414
%0 = load i32, ptr %num.addr, align 4
1515
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
@@ -3639,6 +3639,144 @@ TEST_F(DIExpressionTest, Fold) {
36393639
EXPECT_EQ(E, ResExpr);
36403640
}
36413641

3642+
TEST_F(DIExpressionTest, Append) {
3643+
// Test appending a {dwarf::DW_OP_constu, <const>, DW_OP_plus} to a DW_OP_plus
3644+
// expression
3645+
SmallVector<uint64_t, 8> Ops = {dwarf::DW_OP_LLVM_arg, 0, dwarf::DW_OP_constu,
3646+
2, dwarf::DW_OP_plus};
3647+
auto *Expr = DIExpression::get(Context, Ops);
3648+
SmallVector<uint64_t, 8> AppendOps = {dwarf::DW_OP_constu, 3,
3649+
dwarf::DW_OP_plus};
3650+
auto *AppendExpr = DIExpression::append(Expr, AppendOps);
3651+
SmallVector<uint64_t, 8> OpsRes = {dwarf::DW_OP_LLVM_arg, 0,
3652+
dwarf::DW_OP_plus_uconst, 5};
3653+
auto *ResExpr = DIExpression::get(Context, OpsRes);
3654+
EXPECT_EQ(ResExpr, AppendExpr);
3655+
3656+
// Test appending a {dwarf::DW_OP_plus_uconst, <const>} to a DW_OP_plus
3657+
// expression uint64_t PlusUConstOps[] = {dwarf::DW_OP_plus_uconst, 3};
3658+
AppendOps.clear();
3659+
AppendOps.push_back(dwarf::DW_OP_plus_uconst);
3660+
AppendOps.push_back(3);
3661+
AppendExpr = DIExpression::append(Expr, AppendOps);
3662+
OpsRes.clear();
3663+
OpsRes.push_back(dwarf::DW_OP_LLVM_arg);
3664+
OpsRes.push_back(0);
3665+
OpsRes.push_back(dwarf::DW_OP_plus_uconst);
3666+
OpsRes.push_back(5);
3667+
ResExpr = DIExpression::get(Context, OpsRes);
3668+
EXPECT_EQ(ResExpr, AppendExpr);
3669+
3670+
// Test appending a {dwarf::DW_OP_constu, 0, DW_OP_plus} to an expression
3671+
AppendOps.clear();
3672+
AppendOps.push_back(dwarf::DW_OP_constu);
3673+
AppendOps.push_back(0);
3674+
AppendOps.push_back(dwarf::DW_OP_plus);
3675+
AppendExpr = DIExpression::append(Expr, AppendOps);
3676+
OpsRes.clear();
3677+
OpsRes.push_back(dwarf::DW_OP_LLVM_arg);
3678+
OpsRes.push_back(0);
3679+
OpsRes.push_back(dwarf::DW_OP_plus_uconst);
3680+
OpsRes.push_back(2);
3681+
ResExpr = DIExpression::get(Context, OpsRes);
3682+
EXPECT_EQ(ResExpr, AppendExpr);
3683+
3684+
// Test appending a {dwarf::DW_OP_constu, 0, DW_OP_minus} to an expression
3685+
AppendOps.clear();
3686+
AppendOps.push_back(dwarf::DW_OP_constu);
3687+
AppendOps.push_back(0);
3688+
AppendOps.push_back(dwarf::DW_OP_minus);
3689+
AppendExpr = DIExpression::append(Expr, AppendOps);
3690+
OpsRes.clear();
3691+
OpsRes.push_back(dwarf::DW_OP_LLVM_arg);
3692+
OpsRes.push_back(0);
3693+
OpsRes.push_back(dwarf::DW_OP_plus_uconst);
3694+
OpsRes.push_back(2);
3695+
ResExpr = DIExpression::get(Context, OpsRes);
3696+
EXPECT_EQ(ResExpr, AppendExpr);
3697+
3698+
// Test appending a {dwarf::DW_OP_constu, 0, DW_OP_shl} to an expression
3699+
AppendOps.clear();
3700+
AppendOps.push_back(dwarf::DW_OP_constu);
3701+
AppendOps.push_back(0);
3702+
AppendOps.push_back(dwarf::DW_OP_shl);
3703+
AppendExpr = DIExpression::append(Expr, AppendOps);
3704+
OpsRes.clear();
3705+
OpsRes.push_back(dwarf::DW_OP_LLVM_arg);
3706+
OpsRes.push_back(0);
3707+
OpsRes.push_back(dwarf::DW_OP_plus_uconst);
3708+
OpsRes.push_back(2);
3709+
ResExpr = DIExpression::get(Context, OpsRes);
3710+
EXPECT_EQ(ResExpr, AppendExpr);
3711+
3712+
// Test appending a {dwarf::DW_OP_constu, 0, DW_OP_shr} to an expression
3713+
AppendOps.clear();
3714+
AppendOps.push_back(dwarf::DW_OP_constu);
3715+
AppendOps.push_back(0);
3716+
AppendOps.push_back(dwarf::DW_OP_shr);
3717+
AppendExpr = DIExpression::append(Expr, AppendOps);
3718+
OpsRes.clear();
3719+
OpsRes.push_back(dwarf::DW_OP_LLVM_arg);
3720+
OpsRes.push_back(0);
3721+
OpsRes.push_back(dwarf::DW_OP_plus_uconst);
3722+
OpsRes.push_back(2);
3723+
ResExpr = DIExpression::get(Context, OpsRes);
3724+
EXPECT_EQ(ResExpr, AppendExpr);
3725+
3726+
// Test appending a {dwarf::DW_OP_constu, <const>, DW_OP_mul} to a DW_OP_mul
3727+
// expression
3728+
Ops.clear();
3729+
Ops.push_back(dwarf::DW_OP_LLVM_arg);
3730+
Ops.push_back(0);
3731+
Ops.push_back(dwarf::DW_OP_constu);
3732+
Ops.push_back(2);
3733+
Ops.push_back(dwarf::DW_OP_mul);
3734+
Expr = DIExpression::get(Context, Ops);
3735+
AppendOps.clear();
3736+
AppendOps.push_back(dwarf::DW_OP_constu);
3737+
AppendOps.push_back(3);
3738+
AppendOps.push_back(dwarf::DW_OP_mul);
3739+
AppendExpr = DIExpression::append(Expr, AppendOps);
3740+
OpsRes.clear();
3741+
OpsRes.push_back(dwarf::DW_OP_LLVM_arg);
3742+
OpsRes.push_back(0);
3743+
OpsRes.push_back(dwarf::DW_OP_constu);
3744+
OpsRes.push_back(6);
3745+
OpsRes.push_back(dwarf::DW_OP_mul);
3746+
ResExpr = DIExpression::get(Context, OpsRes);
3747+
EXPECT_EQ(ResExpr, AppendExpr);
3748+
3749+
// Test appending a {dwarf::DW_OP_constu, 1, DW_OP_mul} to an expression
3750+
AppendOps.clear();
3751+
AppendOps.push_back(dwarf::DW_OP_constu);
3752+
AppendOps.push_back(1);
3753+
AppendOps.push_back(dwarf::DW_OP_mul);
3754+
AppendExpr = DIExpression::append(Expr, AppendOps);
3755+
OpsRes.clear();
3756+
OpsRes.push_back(dwarf::DW_OP_LLVM_arg);
3757+
OpsRes.push_back(0);
3758+
OpsRes.push_back(dwarf::DW_OP_constu);
3759+
OpsRes.push_back(2);
3760+
OpsRes.push_back(dwarf::DW_OP_mul);
3761+
ResExpr = DIExpression::get(Context, OpsRes);
3762+
EXPECT_EQ(ResExpr, AppendExpr);
3763+
3764+
// Test appending a {dwarf::DW_OP_constu, 1, DW_OP_div} to an expression
3765+
AppendOps.clear();
3766+
AppendOps.push_back(dwarf::DW_OP_constu);
3767+
AppendOps.push_back(1);
3768+
AppendOps.push_back(dwarf::DW_OP_div);
3769+
AppendExpr = DIExpression::append(Expr, AppendOps);
3770+
OpsRes.clear();
3771+
OpsRes.push_back(dwarf::DW_OP_LLVM_arg);
3772+
OpsRes.push_back(0);
3773+
OpsRes.push_back(dwarf::DW_OP_constu);
3774+
OpsRes.push_back(2);
3775+
OpsRes.push_back(dwarf::DW_OP_mul);
3776+
ResExpr = DIExpression::get(Context, OpsRes);
3777+
EXPECT_EQ(ResExpr, AppendExpr);
3778+
}
3779+
36423780
TEST_F(DIExpressionTest, isValid) {
36433781
#define EXPECT_VALID(...) \
36443782
do { \

0 commit comments

Comments
 (0)