From f69baf64ebc546681b296d8f339a11de2c411642 Mon Sep 17 00:00:00 2001 From: Vedant Kumar Date: Fri, 2 Mar 2018 22:46:48 +0000 Subject: [Utils] Salvage debug info in block simplification In stage2 -O3 builds of llc, this results in small but measurable increases in the number of variables with locations, and in the number of unique source variables overall. (According to llvm-dwarfdump --statistics, there are 123 additional variables with locations, which is just a 0.006% improvement). The size of the .debug_loc section of the llc dsym increases by 0.004%. llvm-svn: 326629 --- llvm/unittests/Transforms/Utils/Local.cpp | 93 +++++++++++++++++++++---------- 1 file changed, 65 insertions(+), 28 deletions(-) (limited to 'llvm/unittests/Transforms/Utils/Local.cpp') diff --git a/llvm/unittests/Transforms/Utils/Local.cpp b/llvm/unittests/Transforms/Utils/Local.cpp index 679a7a3c3ff..8e21ec6a990 100644 --- a/llvm/unittests/Transforms/Utils/Local.cpp +++ b/llvm/unittests/Transforms/Utils/Local.cpp @@ -332,11 +332,14 @@ TEST(Local, ConstantFoldTerminator) { runWithDomTree(*M, "indirectbr_unreachable", CFAllTerminators); } -TEST(Local, SalvageDebugValuesInRecursiveInstDeletion) { +struct SalvageDebugInfoTest : ::testing::Test { LLVMContext C; + std::unique_ptr M; + Function *F = nullptr; - std::unique_ptr M = parseIR(C, - R"( + void SetUp() { + M = parseIR(C, + R"( define void @f() !dbg !8 { entry: %x = add i32 0, 1 @@ -361,34 +364,68 @@ TEST(Local, SalvageDebugValuesInRecursiveInstDeletion) { !13 = !DILocation(line: 2, column: 7, scope: !8) !14 = !DILocation(line: 3, column: 1, scope: !8) )"); - auto *GV = M->getNamedValue("f"); - ASSERT_TRUE(GV); - auto *F = dyn_cast(GV); - ASSERT_TRUE(F); + + auto *GV = M->getNamedValue("f"); + ASSERT_TRUE(GV); + F = dyn_cast(GV); + ASSERT_TRUE(F); + } + + bool doesDebugValueDescribeX(const DbgValueInst &DI) { + const auto &CI = *cast(DI.getValue()); + if (CI.isZero()) + return DI.getExpression()->getElements().equals( + {dwarf::DW_OP_plus_uconst, 1, dwarf::DW_OP_stack_value}); + else if (CI.isOneValue()) + return DI.getExpression()->getElements().empty(); + return false; + } + + bool doesDebugValueDescribeY(const DbgValueInst &DI) { + const auto &CI = *cast(DI.getValue()); + if (CI.isZero()) + return DI.getExpression()->getElements().equals( + {dwarf::DW_OP_plus_uconst, 1, dwarf::DW_OP_plus_uconst, 2, + dwarf::DW_OP_stack_value}); + else if (CI.isOneValue()) + return DI.getExpression()->getElements().equals( + {dwarf::DW_OP_plus_uconst, 2, dwarf::DW_OP_stack_value}); + return false; + } + + void verifyDebugValuesAreSalvaged() { + // Check that the debug values for %x and %y are preserved. + bool FoundX = false; + bool FoundY = false; + for (const Instruction &I : F->front()) { + auto DI = dyn_cast(&I); + if (!DI) { + // The function should only contain debug values and a terminator. + ASSERT_TRUE(isa(&I)); + continue; + } + EXPECT_EQ(DI->getVariable()->getName(), "x"); + FoundX |= doesDebugValueDescribeX(*DI); + FoundY |= doesDebugValueDescribeY(*DI); + } + ASSERT_TRUE(FoundX); + ASSERT_TRUE(FoundY); + } +}; + +TEST_F(SalvageDebugInfoTest, RecursiveInstDeletion) { Instruction *Inst = &F->front().front(); - Inst = Inst->getNextNode(); + Inst = Inst->getNextNode(); // Get %y = add ... ASSERT_TRUE(Inst); bool Deleted = RecursivelyDeleteTriviallyDeadInstructions(Inst); ASSERT_TRUE(Deleted); + verifyDebugValuesAreSalvaged(); +} - // The debug values should have been salvaged. - bool FoundX = false; - bool FoundY = false; - uint64_t X_expr[] = {dwarf::DW_OP_plus_uconst, 1, dwarf::DW_OP_stack_value}; - uint64_t Y_expr[] = {dwarf::DW_OP_plus_uconst, 1, dwarf::DW_OP_plus_uconst, 2, - dwarf::DW_OP_stack_value}; - for (const Instruction &I : F->front()) { - auto DI = dyn_cast(&I); - if (!DI) - continue; - EXPECT_EQ(DI->getVariable()->getName(), "x"); - ASSERT_TRUE(cast(DI->getValue())->isZero()); - ArrayRef ExprElts = DI->getExpression()->getElements(); - if (ExprElts.equals(X_expr)) - FoundX = true; - else if (ExprElts.equals(Y_expr)) - FoundY = true; - } - ASSERT_TRUE(FoundX); - ASSERT_TRUE(FoundY); +TEST_F(SalvageDebugInfoTest, RecursiveBlockSimplification) { + BasicBlock *BB = &F->front(); + ASSERT_TRUE(BB); + bool Deleted = SimplifyInstructionsInBlock(BB); + ASSERT_TRUE(Deleted); + verifyDebugValuesAreSalvaged(); } -- cgit v1.2.3