@@ -181,52 +181,14 @@ BasicBlock *AMDGPUUnifyDivergentExitNodesImpl::unifyReturnBlockSet(
181181 return NewRetBlock;
182182}
183183
184- static BasicBlock *
185- createDummyReturnBlock (Function &F,
186- SmallVector<BasicBlock *, 4 > &ReturningBlocks) {
187- BasicBlock *DummyReturnBB =
188- BasicBlock::Create (F.getContext (), " DummyReturnBlock" , &F);
189- Type *RetTy = F.getReturnType ();
190- Value *RetVal = RetTy->isVoidTy () ? nullptr : PoisonValue::get (RetTy);
191- ReturnInst::Create (F.getContext (), RetVal, DummyReturnBB);
192- ReturningBlocks.push_back (DummyReturnBB);
193- return DummyReturnBB;
194- }
195-
196- // / Handle conditional branch instructions (-> 2 targets) and callbr
197- // / instructions with N targets.
198- static void handleNBranch (Function &F, BasicBlock *BB, Instruction *BI,
199- BasicBlock *DummyReturnBB,
200- std::vector<DominatorTree::UpdateType> &Updates) {
201- SmallVector<BasicBlock *, 2 > Successors (successors (BB));
202-
203- // Create a new transition block to hold the conditional branch.
204- BasicBlock *TransitionBB = BB->splitBasicBlock (BI, " TransitionBlock" );
205-
206- Updates.reserve (Updates.size () + 2 * Successors.size () + 2 );
207-
208- // 'Successors' become successors of TransitionBB instead of BB,
209- // and TransitionBB becomes a single successor of BB.
210- Updates.emplace_back (DominatorTree::Insert, BB, TransitionBB);
211- for (BasicBlock *Successor : Successors) {
212- Updates.emplace_back (DominatorTree::Insert, TransitionBB, Successor);
213- Updates.emplace_back (DominatorTree::Delete, BB, Successor);
214- }
215-
216- // Create a branch that will always branch to the transition block and
217- // references DummyReturnBB.
218- BB->getTerminator ()->eraseFromParent ();
219- BranchInst::Create (TransitionBB, DummyReturnBB,
220- ConstantInt::getTrue (F.getContext ()), BB);
221- Updates.emplace_back (DominatorTree::Insert, BB, DummyReturnBB);
222- }
223-
224184bool AMDGPUUnifyDivergentExitNodesImpl::run (Function &F, DominatorTree *DT,
225185 const PostDominatorTree &PDT,
226186 const UniformityInfo &UA) {
187+ assert (hasOnlySimpleTerminator (F) && " Unsupported block terminator." );
188+
227189 if (PDT.root_size () == 0 ||
228190 (PDT.root_size () == 1 &&
229- !isa<BranchInst, CallBrInst >(PDT.getRoot ()->getTerminator ())))
191+ !isa<BranchInst>(PDT.getRoot ()->getTerminator ())))
230192 return false ;
231193
232194 // Loop over all of the blocks in a function, tracking all of the blocks that
@@ -260,27 +222,46 @@ bool AMDGPUUnifyDivergentExitNodesImpl::run(Function &F, DominatorTree *DT,
260222 if (HasDivergentExitBlock)
261223 UnreachableBlocks.push_back (BB);
262224 } else if (BranchInst *BI = dyn_cast<BranchInst>(BB->getTerminator ())) {
263- if (!DummyReturnBB)
264- DummyReturnBB = createDummyReturnBlock (F, ReturningBlocks);
225+
226+ ConstantInt *BoolTrue = ConstantInt::getTrue (F.getContext ());
227+ if (DummyReturnBB == nullptr ) {
228+ DummyReturnBB =
229+ BasicBlock::Create (F.getContext (), " DummyReturnBlock" , &F);
230+ Type *RetTy = F.getReturnType ();
231+ Value *RetVal = RetTy->isVoidTy () ? nullptr : PoisonValue::get (RetTy);
232+ ReturnInst::Create (F.getContext (), RetVal, DummyReturnBB);
233+ ReturningBlocks.push_back (DummyReturnBB);
234+ }
265235
266236 if (BI->isUnconditional ()) {
267237 BasicBlock *LoopHeaderBB = BI->getSuccessor (0 );
268238 BI->eraseFromParent (); // Delete the unconditional branch.
269239 // Add a new conditional branch with a dummy edge to the return block.
270- BranchInst::Create (LoopHeaderBB, DummyReturnBB,
271- ConstantInt::getTrue (F.getContext ()), BB);
240+ BranchInst::Create (LoopHeaderBB, DummyReturnBB, BoolTrue, BB);
241+ Updates.emplace_back (DominatorTree::Insert, BB, DummyReturnBB);
242+ } else { // Conditional branch.
243+ SmallVector<BasicBlock *, 2 > Successors (successors (BB));
244+
245+ // Create a new transition block to hold the conditional branch.
246+ BasicBlock *TransitionBB = BB->splitBasicBlock (BI, " TransitionBlock" );
247+
248+ Updates.reserve (Updates.size () + 2 * Successors.size () + 2 );
249+
250+ // 'Successors' become successors of TransitionBB instead of BB,
251+ // and TransitionBB becomes a single successor of BB.
252+ Updates.emplace_back (DominatorTree::Insert, BB, TransitionBB);
253+ for (BasicBlock *Successor : Successors) {
254+ Updates.emplace_back (DominatorTree::Insert, TransitionBB, Successor);
255+ Updates.emplace_back (DominatorTree::Delete, BB, Successor);
256+ }
257+
258+ // Create a branch that will always branch to the transition block and
259+ // references DummyReturnBB.
260+ BB->getTerminator ()->eraseFromParent ();
261+ BranchInst::Create (TransitionBB, DummyReturnBB, BoolTrue, BB);
272262 Updates.emplace_back (DominatorTree::Insert, BB, DummyReturnBB);
273- } else {
274- handleNBranch (F, BB, BI, DummyReturnBB, Updates);
275263 }
276264 Changed = true ;
277- } else if (CallBrInst *CBI = dyn_cast<CallBrInst>(BB->getTerminator ())) {
278- if (!DummyReturnBB)
279- DummyReturnBB = createDummyReturnBlock (F, ReturningBlocks);
280-
281- handleNBranch (F, BB, CBI, DummyReturnBB, Updates);
282- } else {
283- llvm_unreachable (" unsupported block terminator" );
284265 }
285266 }
286267
0 commit comments