diff --git a/llvm/lib/Transforms/Scalar/StructurizeCFG.cpp b/llvm/lib/Transforms/Scalar/StructurizeCFG.cpp index eb22b50532695..a69d64956d6d9 100644 --- a/llvm/lib/Transforms/Scalar/StructurizeCFG.cpp +++ b/llvm/lib/Transforms/Scalar/StructurizeCFG.cpp @@ -129,8 +129,6 @@ using BBPredicates = DenseMap; using PredMap = DenseMap; using BB2BBMap = DenseMap; -using BranchDebugLocMap = DenseMap; - // 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 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(); - 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 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; } diff --git a/llvm/test/CodeGen/AMDGPU/si-annotate-dbg-info.ll b/llvm/test/CodeGen/AMDGPU/si-annotate-dbg-info.ll index f296cb19c8810..f163c63f074ae 100644 --- a/llvm/test/CodeGen/AMDGPU/si-annotate-dbg-info.ll +++ b/llvm/test/CodeGen/AMDGPU/si-annotate-dbg-info.ll @@ -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]] = !{} diff --git a/llvm/test/Transforms/StructurizeCFG/structurizecfg-debug-loc.ll b/llvm/test/Transforms/StructurizeCFG/structurizecfg-debug-loc.ll index d5ee7693032e4..8a79526ad3412 100644 --- a/llvm/test/Transforms/StructurizeCFG/structurizecfg-debug-loc.ll +++ b/llvm/test/Transforms/StructurizeCFG/structurizecfg-debug-loc.ll @@ -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: