2222#include " llvm/IR/Attributes.h"
2323#include " llvm/IR/CFG.h"
2424#include " llvm/IR/Instructions.h"
25- #include " llvm/Transforms/Utils/BasicBlockUtils.h"
2625#include " llvm/Transforms/Utils/Cloning.h"
2726
2827using namespace llvm ;
@@ -55,7 +54,7 @@ static void rewriteFuncWithReturnType(Function &OldF, Value *NewRetValue) {
5554 BasicBlock *NewRetBlock = NewRetI ? NewRetI->getParent () : &EntryBB;
5655
5756 BasicBlock::iterator NewValIt =
58- NewRetI ? NewRetI->getIterator () : EntryBB.end ();
57+ NewRetI ? std::next ( NewRetI->getIterator ()) : EntryBB.begin ();
5958
6059 Type *OldRetTy = OldFuncTy->getReturnType ();
6160
@@ -73,28 +72,16 @@ static void rewriteFuncWithReturnType(Function &OldF, Value *NewRetValue) {
7372 }
7473 }
7574
76- // Now prune any CFG edges we have to deal with.
77- //
78- // Use KeepOneInputPHIs in case the instruction we are using for the return is
79- // that phi.
80- // TODO: Could avoid this with fancier iterator management.
81- for (BasicBlock *Succ : successors (NewRetBlock))
82- Succ->removePredecessor (NewRetBlock, /* KeepOneInputPHIs=*/ true );
83-
84- // Now delete the tail of this block, in reverse to delete uses before defs.
85- for (Instruction &I : make_early_inc_range (
86- make_range (NewRetBlock->rbegin (), NewValIt.getReverse ()))) {
87- Value *Replacement = getDefaultValue (I.getType ());
88- I.replaceAllUsesWith (Replacement);
89- I.eraseFromParent ();
90- }
75+ // If we're returning an instruction, split the basic block so we can let
76+ // EliminateUnreachableBlocks cleanup the successors.
77+ BasicBlock *TailBB = NewRetBlock->splitBasicBlock (NewValIt);
9178
79+ // Replace the unconditional branch splitBasicBlock created
80+ NewRetBlock->getTerminator ()->eraseFromParent ();
9281 ReturnInst::Create (Ctx, NewRetValue, NewRetBlock);
9382
94- // TODO: We may be eliminating blocks that were originally unreachable. We
95- // probably ought to only be pruning blocks that became dead directly as a
96- // result of our pruning here.
97- EliminateUnreachableBlocks (OldF);
83+ // Now prune any CFG edges we have to deal with.
84+ simpleSimplifyCFG (OldF, {TailBB}, /* FoldBlockIntoPredecessor=*/ false );
9885
9986 // Drop the incompatible attributes before we copy over to the new function.
10087 if (OldRetTy != NewRetTy) {
@@ -199,20 +186,6 @@ static bool shouldReplaceNonVoidReturnValue(const BasicBlock &BB,
199186 return true ;
200187}
201188
202- static bool canHandleSuccessors (const BasicBlock &BB) {
203- // TODO: Handle invoke and other exotic terminators
204- if (!isa<ReturnInst, UnreachableInst, BranchInst, SwitchInst>(
205- BB.getTerminator ()))
206- return false ;
207-
208- for (const BasicBlock *Succ : successors (&BB)) {
209- if (!Succ->canSplitPredecessors ())
210- return false ;
211- }
212-
213- return true ;
214- }
215-
216189static bool shouldForwardValueToReturn (const BasicBlock &BB, const Value *V,
217190 Type *RetTy) {
218191 if (!isReallyValidReturnType (V->getType ()))
@@ -231,10 +204,9 @@ static bool tryForwardingInstructionsToReturn(
231204 Type *RetTy = F.getReturnType ();
232205
233206 for (BasicBlock &BB : F) {
234- if (!canHandleSuccessors (BB))
235- continue ;
236-
237- for (Instruction &I : BB) {
207+ // Skip the terminator, we can't insert a second terminator to return its
208+ // value.
209+ for (Instruction &I : make_range (BB.begin (), std::prev (BB.end ()))) {
238210 if (shouldForwardValueToReturn (BB, &I, RetTy) && !O.shouldKeep ()) {
239211 FuncsToReplace.emplace_back (&F, &I);
240212 return true ;
0 commit comments