[StructurizeCFG] Stop setting DebugLocs in flow blocks (#139088)

Flow blocks are generated code that don't really correspond to any
location in the source, so principally they should have empty DebugLocs.
Practically, setting these debug locs leads to redundant is_stmts being
generated after #108251, causing stepping test failures in the ROCm GDB
test suite.

Fixes SWDEV-502134
This commit is contained in:
Emma Pilkington
2025-05-09 14:22:14 -04:00
committed by GitHub
parent 49c22e3ee1
commit 7babf22461
3 changed files with 36 additions and 61 deletions

View File

@@ -129,8 +129,6 @@ using BBPredicates = DenseMap<BasicBlock *, PredInfo>;
using PredMap = DenseMap<BasicBlock *, BBPredicates>;
using BB2BBMap = DenseMap<BasicBlock *, BasicBlock *>;
using BranchDebugLocMap = DenseMap<BasicBlock *, DebugLoc>;
// A traits type that is intended to be used in graph algorithms. The graph
// traits starts at an entry node, and traverses the RegionNodes that are in
// the Nodes set.
@@ -303,8 +301,6 @@ class StructurizeCFG {
PredMap LoopPreds;
BranchVector LoopConds;
BranchDebugLocMap TermDL;
RegionNode *PrevNode;
void orderNodes();
@@ -336,14 +332,14 @@ class StructurizeCFG {
void simplifyAffectedPhis();
void killTerminator(BasicBlock *BB);
DebugLoc killTerminator(BasicBlock *BB);
void changeExit(RegionNode *Node, BasicBlock *NewExit,
bool IncludeDominator);
BasicBlock *getNextFlow(BasicBlock *Dominator);
BasicBlock *needPrefix(bool NeedEmpty);
std::pair<BasicBlock *, DebugLoc> needPrefix(bool NeedEmpty);
BasicBlock *needPostfix(BasicBlock *Flow, bool ExitUseAllowed);
@@ -361,8 +357,6 @@ class StructurizeCFG {
void rebuildSSA();
void setDebugLoc(BranchInst *Br, BasicBlock *BB);
public:
void init(Region *R);
bool run(Region *R, DominatorTree *DT);
@@ -918,28 +912,18 @@ void StructurizeCFG::simplifyAffectedPhis() {
} while (Changed);
}
void StructurizeCFG::setDebugLoc(BranchInst *Br, BasicBlock *BB) {
auto I = TermDL.find(BB);
if (I == TermDL.end())
return;
Br->setDebugLoc(I->second);
TermDL.erase(I);
}
/// Remove phi values from all successors and then remove the terminator.
void StructurizeCFG::killTerminator(BasicBlock *BB) {
DebugLoc StructurizeCFG::killTerminator(BasicBlock *BB) {
Instruction *Term = BB->getTerminator();
if (!Term)
return;
if (const DebugLoc &DL = Term->getDebugLoc())
TermDL[BB] = DL;
return DebugLoc();
for (BasicBlock *Succ : successors(BB))
delPhiValues(BB, Succ);
DebugLoc DL = Term->getDebugLoc();
Term->eraseFromParent();
return DL;
}
/// Let node exit(s) point to NewExit
@@ -978,9 +962,9 @@ void StructurizeCFG::changeExit(RegionNode *Node, BasicBlock *NewExit,
SubRegion->replaceExit(NewExit);
} else {
BasicBlock *BB = Node->getNodeAs<BasicBlock>();
killTerminator(BB);
DebugLoc DL = killTerminator(BB);
BranchInst *Br = BranchInst::Create(NewExit, BB);
setDebugLoc(Br, BB);
Br->setDebugLoc(DL);
addPhiValues(BB, NewExit);
if (IncludeDominator)
DT->changeImmediateDominator(NewExit, BB);
@@ -995,29 +979,20 @@ BasicBlock *StructurizeCFG::getNextFlow(BasicBlock *Dominator) {
BasicBlock *Flow = BasicBlock::Create(Context, FlowBlockName,
Func, Insert);
FlowSet.insert(Flow);
if (auto *Term = Dominator->getTerminator()) {
if (const DebugLoc &DL = Term->getDebugLoc())
TermDL[Flow] = DL;
} else if (DebugLoc DLTemp = TermDL.lookup(Dominator)) {
// Use a temporary copy to avoid a use-after-free if the map's storage
// is reallocated.
TermDL[Flow] = DLTemp;
}
DT->addNewBlock(Flow, Dominator);
ParentRegion->getRegionInfo()->setRegionFor(Flow, ParentRegion);
return Flow;
}
/// Create a new or reuse the previous node as flow node
BasicBlock *StructurizeCFG::needPrefix(bool NeedEmpty) {
/// Create a new or reuse the previous node as flow node. Returns a block and a
/// debug location to be used for new instructions in that block.
std::pair<BasicBlock *, DebugLoc> StructurizeCFG::needPrefix(bool NeedEmpty) {
BasicBlock *Entry = PrevNode->getEntry();
if (!PrevNode->isSubRegion()) {
killTerminator(Entry);
DebugLoc DL = killTerminator(Entry);
if (!NeedEmpty || Entry->getFirstInsertionPt() == Entry->end())
return Entry;
return {Entry, DL};
}
// create a new flow node
@@ -1026,7 +1001,7 @@ BasicBlock *StructurizeCFG::needPrefix(bool NeedEmpty) {
// and wire it up
changeExit(PrevNode, Flow, true);
PrevNode = ParentRegion->getBBNode(Flow);
return Flow;
return {Flow, DebugLoc()};
}
/// Returns the region exit if possible, otherwise just a new flow node
@@ -1090,7 +1065,7 @@ void StructurizeCFG::wireFlow(bool ExitUseAllowed,
PrevNode = Node;
} else {
// Insert extra prefix node (or reuse last one)
BasicBlock *Flow = needPrefix(false);
auto [Flow, DL] = needPrefix(false);
// Insert extra postfix node (or use exit instead)
BasicBlock *Entry = Node->getEntry();
@@ -1098,7 +1073,7 @@ void StructurizeCFG::wireFlow(bool ExitUseAllowed,
// let it point to entry and next block
BranchInst *Br = BranchInst::Create(Entry, Next, BoolPoison, Flow);
setDebugLoc(Br, Flow);
Br->setDebugLoc(DL);
Conditions.push_back(Br);
addPhiValues(Flow, Entry);
DT->changeImmediateDominator(Entry, Flow);
@@ -1125,7 +1100,7 @@ void StructurizeCFG::handleLoops(bool ExitUseAllowed,
}
if (!isPredictableTrue(Node))
LoopStart = needPrefix(true);
LoopStart = needPrefix(true).first;
LoopEnd = Loops[Node->getEntry()];
wireFlow(false, LoopEnd);
@@ -1136,10 +1111,11 @@ void StructurizeCFG::handleLoops(bool ExitUseAllowed,
assert(LoopStart != &LoopStart->getParent()->getEntryBlock());
// Create an extra loop end node
LoopEnd = needPrefix(false);
DebugLoc DL;
std::tie(LoopEnd, DL) = needPrefix(false);
BasicBlock *Next = needPostfix(LoopEnd, ExitUseAllowed);
BranchInst *Br = BranchInst::Create(Next, LoopStart, BoolPoison, LoopEnd);
setDebugLoc(Br, LoopEnd);
Br->setDebugLoc(DL);
LoopConds.push_back(Br);
addPhiValues(LoopEnd, LoopStart);
setPrevNode(Next);
@@ -1339,7 +1315,6 @@ bool StructurizeCFG::run(Region *R, DominatorTree *DT) {
LoopPreds.clear();
LoopConds.clear();
FlowSet.clear();
TermDL.clear();
return true;
}

View File

@@ -11,10 +11,10 @@ define amdgpu_ps i32 @if_else(i32 %0) !dbg !5 {
; OPT-NEXT: [[TMP4:%.*]] = extractvalue { i1, i64 } [[TMP2]], 1, !dbg [[DBG14]]
; OPT-NEXT: br i1 [[TMP3]], label [[FALSE:%.*]], label [[FLOW:%.*]], !dbg [[DBG14]]
; OPT: Flow:
; OPT-NEXT: [[TMP5:%.*]] = call { i1, i64 } @llvm.amdgcn.else.i64.i64(i64 [[TMP4]]), !dbg [[DBG14]]
; OPT-NEXT: [[TMP6:%.*]] = extractvalue { i1, i64 } [[TMP5]], 0, !dbg [[DBG14]]
; OPT-NEXT: [[TMP8:%.*]] = extractvalue { i1, i64 } [[TMP5]], 1, !dbg [[DBG14]]
; OPT-NEXT: br i1 [[TMP6]], label [[TRUE:%.*]], label [[EXIT:%.*]], !dbg [[DBG14]]
; OPT-NEXT: [[TMP5:%.*]] = call { i1, i64 } @llvm.amdgcn.else.i64.i64(i64 [[TMP4]])
; OPT-NEXT: [[TMP6:%.*]] = extractvalue { i1, i64 } [[TMP5]], 0
; OPT-NEXT: [[TMP8:%.*]] = extractvalue { i1, i64 } [[TMP5]], 1
; OPT-NEXT: br i1 [[TMP6]], label [[TRUE:%.*]], label [[EXIT:%.*]]
; OPT: true:
; OPT-NEXT: br label [[EXIT]], !dbg [[DBG15:![0-9]+]]
; OPT: false:
@@ -64,9 +64,9 @@ define amdgpu_ps void @loop_if_break(i32 %n) !dbg !19 {
; OPT-NEXT: [[TMP3]] = phi i32 [ [[I_NEXT]], [[LOOP_BODY]] ], [ poison, [[LOOP]] ]
; OPT-NEXT: [[TMP4:%.*]] = phi i1 [ false, [[LOOP_BODY]] ], [ true, [[LOOP]] ]
; OPT-NEXT: call void @llvm.amdgcn.end.cf.i64(i64 [[TMP2]])
; OPT-NEXT: [[TMP5]] = call i64 @llvm.amdgcn.if.break.i64(i1 [[TMP4]], i64 [[PHI_BROKEN]]), !dbg [[DBG27]]
; OPT-NEXT: [[TMP6:%.*]] = call i1 @llvm.amdgcn.loop.i64(i64 [[TMP5]]), !dbg [[DBG27]]
; OPT-NEXT: br i1 [[TMP6]], label [[EXIT:%.*]], label [[LOOP]], !dbg [[DBG27]]
; OPT-NEXT: [[TMP5]] = call i64 @llvm.amdgcn.if.break.i64(i1 [[TMP4]], i64 [[PHI_BROKEN]])
; OPT-NEXT: [[TMP6:%.*]] = call i1 @llvm.amdgcn.loop.i64(i64 [[TMP5]])
; OPT-NEXT: br i1 [[TMP6]], label [[EXIT:%.*]], label [[LOOP]]
; OPT: exit:
; OPT-NEXT: call void @llvm.amdgcn.end.cf.i64(i64 [[TMP5]])
; OPT-NEXT: ret void, !dbg [[DBG30:![0-9]+]]
@@ -132,7 +132,7 @@ attributes #0 = { nocallback nofree nosync nounwind speculatable willreturn memo
!30 = !DILocation(line: 13, column: 1, scope: !19)
;.
; OPT: [[META0:![0-9]+]] = distinct !DICompileUnit(language: DW_LANG_C, file: [[META1:![0-9]+]], producer: "debugify", isOptimized: true, runtimeVersion: 0, emissionKind: FullDebug)
; OPT: [[META1]] = !DIFile(filename: "../../../test/CodeGen/AMDGPU/si-annotate-dbg-info.ll", directory: {{.*}})
; OPT: [[META1]] = !DIFile(filename: "{{.*}}si-annotate-dbg-info.ll", directory: {{.*}})
; OPT: [[DBG5]] = distinct !DISubprogram(name: "if_else", linkageName: "if_else", scope: null, file: [[META1]], line: 1, type: [[META6:![0-9]+]], scopeLine: 1, spFlags: DISPFlagDefinition | DISPFlagOptimized, unit: [[META0]], retainedNodes: [[META8:![0-9]+]])
; OPT: [[META6]] = !DISubroutineType(types: [[META7:![0-9]+]])
; OPT: [[META7]] = !{}

View File

@@ -5,7 +5,7 @@ define void @if_then_else(ptr addrspace(1) %out, i1 %arg) !dbg !7 {
; CHECK: entry:
; CHECK: br i1 {{.*}}, label %if.else, label %Flow, !dbg [[ITE_ENTRY_DL:![0-9]+]]
; CHECK: Flow:
; CHECK: br i1 {{.*}}, label %if.then, label %exit, !dbg [[ITE_ENTRY_DL]]
; CHECK: br i1 {{.*}}, label %if.then, label %exit
; CHECK: if.then:
; CHECK: br label %exit, !dbg [[ITE_IFTHEN_DL:![0-9]+]]
; CHECK: if.else:
@@ -36,7 +36,7 @@ define void @while_loop(ptr addrspace(1) %out) !dbg !14 {
; CHECK: while.body:
; CHECK: br label %Flow, !dbg [[WHILE_BODY_DL:![0-9]+]]
; CHECK: Flow:
; CHECK: br i1 {{.*}}, label %exit, label %while.header, !dbg [[WHILE_HEADER_DL]]
; CHECK: br i1 {{.*}}, label %exit, label %while.header
; CHECK: exit:
;
entry:
@@ -63,7 +63,7 @@ define void @while_multiple_exits(ptr addrspace(1) %out) !dbg !21 {
; CHECK: while.exiting:
; CHECK: br label %Flow, !dbg [[WHILEME_EXITING_DL:![0-9]+]]
; CHECK: Flow:
; CHECK: br i1 {{.*}}, label %exit, label %while.header, !dbg [[WHILEME_HEADER_DL]]
; CHECK: br i1 {{.*}}, label %exit, label %while.header
; CHECK: exit:
;
entry:
@@ -86,11 +86,11 @@ define void @nested_if_then_else(ptr addrspace(1) %out, i1 %a, i1 %b) !dbg !28 {
; CHECK: entry:
; CHECK: br i1 {{.*}}, label %if.else, label %Flow4, !dbg [[NESTED_ENTRY_DL:![0-9]+]]
; CHECK: Flow4:
; CHECK: br i1 {{.*}}, label %if.then, label %exit, !dbg [[NESTED_ENTRY_DL]]
; CHECK: br i1 {{.*}}, label %if.then, label %exit
; CHECK: if.then:
; CHECK: br i1 {{.*}}, label %if.then.else, label %Flow2, !dbg [[NESTED_IFTHEN_DL:![0-9]+]]
; CHECK: Flow2:
; CHECK: br i1 {{.*}}, label %if.then.then, label %Flow3, !dbg [[NESTED_IFTHEN_DL]]
; CHECK: br i1 {{.*}}, label %if.then.then, label %Flow3
; CHECK: if.then.then:
; CHECK: br label %Flow3, !dbg [[NESTED_IFTHENTHEN_DL:![0-9]+]]
; CHECK: if.then.else:
@@ -98,15 +98,15 @@ define void @nested_if_then_else(ptr addrspace(1) %out, i1 %a, i1 %b) !dbg !28 {
; CHECK: if.else:
; CHECK: br i1 {{.*}}, label %if.else.else, label %Flow, !dbg [[NESTED_IFELSE_DL:![0-9]+]]
; CHECK: Flow:
; CHECK: br i1 {{.*}}, label %if.else.then, label %Flow1, !dbg [[NESTED_IFELSE_DL]]
; CHECK: br i1 {{.*}}, label %if.else.then, label %Flow1
; CHECK: if.else.then:
; CHECK: br label %Flow1, !dbg [[NESTED_IFELSETHEN_DL:![0-9]+]]
; CHECK: if.else.else:
; CHECK: br label %Flow, !dbg [[NESTED_IFELSEELSE_DL:![0-9]+]]
; CHECK: Flow1:
; CHECK: br label %Flow4, !dbg [[NESTED_IFELSE_DL]]
; CHECK: br label %Flow4
; CHECK: Flow3:
; CHECK: br label %exit, !dbg [[NESTED_IFTHEN_DL]]
; CHECK: br label %exit
; CHECK: exit:
;
entry: