Skip to content

Commit 7d9e272

Browse files
committed
[BranchFolding] Kill common hoisted debug instructions
branch-folder hoists common instructions from TBB and FBB into their pred. Without this patch it achieves this by splicing the instructions from TBB and deleting the common ones in FBB. That moves the debug locations and debug instructions from TBB into the pred without modification, which is not ideal. Debug locations are handled in #140063. This patch handles debug instructions - in the simplest way possible, which is to just kill (undef) them. We kill and hoist the ones in FBB as well as TBB because otherwise the fact there's an assignment on the code path is deleted (which might lead to a prior location extending further than it should). There's possibly something we could do to preserve some variable locations in some cases, but this is the easiest not-incorrect thing to do. Note I had to replace the constant DBG_VALUEs to use registers in the test- it turns out setDebugValueUndef doesn't undef constant DBG_VALUEs... which feels wrong to me, but isn't something I want to touch right now.
1 parent 0d44dea commit 7d9e272

File tree

3 files changed

+61
-22
lines changed

3 files changed

+61
-22
lines changed

llvm/lib/CodeGen/BranchFolding.cpp

Lines changed: 41 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@
2525
#include "llvm/Analysis/ProfileSummaryInfo.h"
2626
#include "llvm/CodeGen/Analysis.h"
2727
#include "llvm/CodeGen/BranchFoldingPass.h"
28+
#include "llvm/CodeGen/GlobalISel/MachineIRBuilder.h"
2829
#include "llvm/CodeGen/MBFIWrapper.h"
2930
#include "llvm/CodeGen/MachineBlockFrequencyInfo.h"
3031
#include "llvm/CodeGen/MachineBranchProbabilityInfo.h"
@@ -2072,25 +2073,56 @@ bool BranchFolder::HoistCommonCodeInSuccs(MachineBasicBlock *MBB) {
20722073
return false;
20732074

20742075
// Hoist the instructions from [T.begin, TIB) and then delete [F.begin, FIB).
2075-
// Merge the debug locations. FIXME: We should do something with the
2076-
// debug instructions too (from BOTH branches).
2076+
// Merge the debug locations, and hoist and kill the debug instructions from
2077+
// both branches. FIXME: We could probably try harder to preserve some debug
2078+
// instructions (but at least this isn't producing wrong locations).
20772079
{
2080+
MachineIRBuilder MIRBuilder(*MBB, Loc);
2081+
auto HoistAndKillDbgInstr =
2082+
[&MIRBuilder](MachineBasicBlock::iterator DI,
2083+
MachineBasicBlock::iterator InsertBefore) {
2084+
assert(DI->isDebugInstr() && "Expected a debug instruction");
2085+
if (DI->isDebugRef()) {
2086+
MIRBuilder.setDebugLoc(DI->getDebugLoc());
2087+
MIRBuilder.buildDirectDbgValue(
2088+
0, DI->getDebugVariable(),
2089+
DI->getDebugExpression());
2090+
return;
2091+
}
2092+
2093+
DI->setDebugValueUndef();
2094+
DI->moveBefore(&*InsertBefore);
2095+
};
2096+
20782097
// TIB and FIB point to the end of the regions to hoist/merge in TBB and
20792098
// FBB.
20802099
MachineBasicBlock::iterator FE = FIB;
20812100
MachineBasicBlock::iterator FI = FBB->begin();
20822101
for (MachineBasicBlock::iterator TI :
20832102
make_early_inc_range(make_range(TBB->begin(), TIB))) {
2084-
// Move debug instructions and pseudo probes without modifying them.
2085-
// FIXME: This is the wrong thing to do for debug locations, which
2086-
// should at least be killed.
2087-
if (TI->isDebugOrPseudoInstr()) {
2103+
2104+
// Hoist and kill debug instructions from FBB. Skip over pseudo
2105+
// instructions. After this loop FI points to the next non-debug
2106+
// instruction to hoist (checked in assert after the TBB debug
2107+
// instruction handling code).
2108+
while (FI->isDebugOrPseudoInstr()) {
2109+
assert(FI != FE && "Unexpected end of FBB range");
2110+
MachineBasicBlock::iterator FINext = std::next(FI) ;
2111+
HoistAndKillDbgInstr(FI, Loc);
2112+
FI = FINext;
2113+
}
2114+
2115+
// Move pseudo probes without modifying them.
2116+
if (TI->isPseudoProbe()) {
20882117
TI->moveBefore(&*Loc);
20892118
continue;
20902119
}
2120+
// Kill debug instructions before moving.
2121+
if (TI->isDebugInstr()) {
2122+
HoistAndKillDbgInstr(TI, Loc);
2123+
continue;
2124+
}
20912125

2092-
// Get the next non-meta instruction in FBB.
2093-
FI = skipDebugInstructionsForward(FI, FE, false);
20942126
assert(TI->isIdenticalTo(*FI, MachineInstr::CheckKillDead) &&
20952127
"Expected non-debug lockstep");
20962128

@@ -2101,6 +2133,7 @@ bool BranchFolder::HoistCommonCodeInSuccs(MachineBasicBlock *MBB) {
21012133
++FI;
21022134
}
21032135
}
2136+
assert(FIB->getParent() == FBB && "Unexpectedly moved FIB?");
21042137
FBB->erase(FBB->begin(), FIB);
21052138

21062139
if (UpdateLiveIns)

llvm/test/DebugInfo/X86/branch-folder-dbg.mir

Lines changed: 20 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,21 @@
11
# RUN: llc %s --start-before=branch-folder --stop-after=branch-folder -o - | FileCheck %s
22

33
## Check that common instructions hoisted from `if.then` and `if.else` into
4-
## common pred `entry` get merged debug locations.
5-
6-
## FIXME: The debug instructions handling here is wrong.
4+
## common pred `entry` get merged debug locations. The debug instructions from
5+
## both branches should get hoisted and killed.
6+
##
7+
## The MIR debug instructions have been modified by hand in order to check they
8+
## can be killed.
79

810
# CHECK: bb.0
911
# CHECK: CALL64pcrel32 @f, csr_64, implicit $rsp, implicit $ssp, implicit-def $rsp, implicit-def $ssp, implicit-def $rax
10-
## --- Start splice from bb.2.if.else ---
11-
# CHECK-NEXT: DBG_VALUE 2, $noreg, ![[#]], !DIExpression(), debug-location ![[#]]
12-
# CHECK-NEXT: $edi = MOV32r0 implicit-def dead $eflags, debug-location !DILocation(line: 0, scope: ![[#]])
13-
## --- End splice --------------
12+
## --- Start splice from bb.2.if.else (and debug instructions from bb.1.if.then) ---
13+
# CHECK-NEXT: DBG_VALUE $noreg, $noreg, ![[#]], !DIExpression(), debug-location ![[#]]
14+
# CHECK-NEXT: DBG_VALUE $noreg, $noreg, ![[#]], !DIExpression(), debug-location ![[#]]
15+
# CHECK-NEXT: $edi = MOV32r0 implicit-def dead $eflags, debug-instr-number 2, debug-location !DILocation(line: 0, scope: ![[#]])
16+
# CHECK-NEXT: DBG_VALUE $noreg, $noreg, ![[#]], !DIExpression(DW_OP_LLVM_arg, 0), debug-location ![[#]]
17+
# CHECK-NEXT: DBG_VALUE $noreg, $noreg, ![[#]], !DIExpression(DW_OP_LLVM_arg, 0), debug-location ![[#]]
18+
## --- End splice ------------------------------------------------------------------
1419
# CHECK-NEXT: TEST64rr killed renamable $rax, renamable $rax, implicit-def $eflags
1520
# CHECK-NEXT: JCC_1 %bb.2, 9, implicit killed $eflags
1621
# CHECK: bb.1
@@ -73,6 +78,8 @@
7378
...
7479
---
7580
name: g
81+
tracksRegLiveness: true
82+
isSSA: false
7683
body: |
7784
bb.0 (%ir-block.0):
7885
successors: %bb.1(0x40000000), %bb.2(0x40000000)
@@ -86,22 +93,21 @@ body: |
8693
8794
bb.1.if.then:
8895
successors: %bb.3(0x80000000)
89-
90-
DBG_VALUE 0, $noreg, !11, !DIExpression(), debug-location !13
91-
$edi = MOV32r0 implicit-def dead $eflags, debug-location !14
96+
DBG_VALUE $esi, $noreg, !11, !DIExpression(), debug-location !13
97+
$edi = MOV32r0 implicit-def dead $eflags, debug-instr-number 1, debug-location !14
98+
DBG_INSTR_REF !11, !DIExpression(DW_OP_LLVM_arg, 0), dbg-instr-ref(1, 0), debug-location !13
9299
$esi = MOV32r0 implicit-def dead $eflags, debug-location !14
93100
CALL64pcrel32 target-flags(x86-plt) @_Z3fooii, csr_64, implicit $rsp, implicit $ssp, implicit killed $edi, implicit killed $esi, implicit-def $rsp, implicit-def $ssp, debug-location !14
94-
DBG_VALUE 1, $noreg, !11, !DIExpression(), debug-location !13
95101
JMP_1 %bb.3, debug-location !15
96102
97103
bb.2.if.else:
98104
successors: %bb.3(0x80000000)
99105
100-
DBG_VALUE 2, $noreg, !11, !DIExpression(), debug-location !13
101-
$edi = MOV32r0 implicit-def dead $eflags, debug-location !16
106+
DBG_VALUE $esp, $noreg, !11, !DIExpression(), debug-location !13
107+
$edi = MOV32r0 implicit-def dead $eflags, debug-instr-number 2, debug-location !16
108+
DBG_INSTR_REF !11, !DIExpression(DW_OP_LLVM_arg, 0), dbg-instr-ref(2, 0), debug-location !13
102109
$esi = MOV32ri 1, debug-location !16
103110
CALL64pcrel32 target-flags(x86-plt) @_Z3barii, csr_64, implicit $rsp, implicit $ssp, implicit killed $edi, implicit killed $esi, implicit-def $rsp, implicit-def $ssp, debug-location !16
104-
DBG_VALUE 3, $noreg, !11, !DIExpression(), debug-location !13
105111
106112
bb.3.if.end:
107113
$eax = MOV32ri 2

obj

3.03 KB
Binary file not shown.

0 commit comments

Comments
 (0)