@@ -58,7 +58,23 @@ static cl::opt<unsigned> MaxDeoptOrUnreachableSuccessorCheckDepth(
5858 " is followed by a block that either has a terminating "
5959 " deoptimizing call or is terminated with an unreachable" ));
6060
61- static void zapAllInstructionInDeadBasicBlock (BasicBlock *BB) {
61+ // / Zap all the instructions in the block and replace them with an unreachable
62+ // / instruction and notify the basic block's successors that one of their
63+ // / predecessors is going away.
64+ static void
65+ emptyAndDetachBlock (BasicBlock *BB,
66+ SmallVectorImpl<DominatorTree::UpdateType> *Updates,
67+ bool KeepOneInputPHIs) {
68+ // Loop through all of our successors and make sure they know that one
69+ // of their predecessors is going away.
70+ SmallPtrSet<BasicBlock *, 4 > UniqueSuccessors;
71+ for (BasicBlock *Succ : successors (BB)) {
72+ Succ->removePredecessor (BB, KeepOneInputPHIs);
73+ if (Updates && UniqueSuccessors.insert (Succ).second )
74+ Updates->push_back ({DominatorTree::Delete, BB, Succ});
75+ }
76+
77+ // Zap all the instructions in the block.
6278 while (!BB->empty ()) {
6379 Instruction &I = BB->back ();
6480 // If this instruction is used, replace uses with an arbitrary value.
@@ -76,77 +92,6 @@ static void zapAllInstructionInDeadBasicBlock(BasicBlock *BB) {
7692 " applying corresponding DTU updates." );
7793}
7894
79- static void deleteBasicBlockFromSuccessor (
80- BasicBlock *BB, SmallVectorImpl<DominatorTree::UpdateType> *Updates,
81- bool KeepOneInputPHIs) {
82- // Loop through all of our successors and make sure they know that one
83- // of their predecessors is going away.
84- SmallPtrSet<BasicBlock *, 4 > UniqueSuccessors;
85- for (BasicBlock *Succ : successors (BB)) {
86- Succ->removePredecessor (BB, KeepOneInputPHIs);
87- if (Updates && UniqueSuccessors.insert (Succ).second )
88- Updates->push_back ({DominatorTree::Delete, BB, Succ});
89- }
90- }
91-
92- static void replaceFuncletPadsRetWithUnreachable (
93- Instruction &I, SmallVectorImpl<DominatorTree::UpdateType> *Updates,
94- bool KeepOneInputPHIs) {
95- assert (isa<FuncletPadInst>(I) && " Instruction must be a funclet pad!" );
96- for (User *User : make_early_inc_range (I.users ())) {
97- Instruction *ReturnInstr = dyn_cast<Instruction>(User);
98- // If we have a cleanupret or catchret block, replace it with just an
99- // unreachable. The other alternative, that may use a catchpad is a
100- // catchswitch. That is not handled here.
101- if (isa<CatchReturnInst>(ReturnInstr) ||
102- isa<CleanupReturnInst>(ReturnInstr)) {
103- BasicBlock *ReturnInstrBB = ReturnInstr->getParent ();
104- // This catchret or catchpad basic block is detached now. Let the
105- // successors know it.
106- // This basic block also may have some predecessors too. For
107- // example the following LLVM-IR legit:
108- //
109- // +-------------------------------------------+
110- // | funclet: %unreachable |
111- // | %cleanuppad = cleanuppad within none [] |
112- // | br label %middle_block |
113- // +-------------------------------------------+
114- // |
115- // +-------------------------+
116- // | middle_block: |
117- // | br label %funclet_end |
118- // +-------------------------+
119- // |
120- // +------------------------------------------------+
121- // | funclet_end: |
122- // | cleanupret from %cleanuppad unwind to caller |
123- // +------------------------------------------------+
124- //
125- // The IR after the cleanup will look like this:
126- //
127- // +-------------------------------------------+
128- // | funclet: %unreachable |
129- // | %cleanuppad = cleanuppad within none [] |
130- // | br label %middle_block |
131- // +-------------------------------------------+
132- // |
133- // +-------------------------+
134- // | middle_block: |
135- // | br label %funclet_end |
136- // +-------------------------+
137- // |
138- // +-------------+
139- // | unreachable |
140- // +-------------+
141- //
142- // So middle_block will lead to an unreachable block, which is also legit.
143-
144- deleteBasicBlockFromSuccessor (ReturnInstrBB, Updates, KeepOneInputPHIs);
145- zapAllInstructionInDeadBasicBlock (ReturnInstrBB);
146- }
147- }
148- }
149-
15095void llvm::detachDeadBlocks (ArrayRef<BasicBlock *> BBs,
15196 SmallVectorImpl<DominatorTree::UpdateType> *Updates,
15297 bool KeepOneInputPHIs) {
@@ -160,13 +105,47 @@ void llvm::detachDeadBlocks(ArrayRef<BasicBlock *> BBs,
160105 // basic blocks than the pad instruction. If we would only delete the
161106 // first block, the we would have possible cleanupret and catchret
162107 // instructions with poison arguments, which wouldn't be valid.
163- if (isa<FuncletPadInst>(I))
164- replaceFuncletPadsRetWithUnreachable (I, Updates, KeepOneInputPHIs);
108+ if (isa<FuncletPadInst>(I)) {
109+ for (User *User : make_early_inc_range (I.users ())) {
110+ Instruction *ReturnInstr = dyn_cast<Instruction>(User);
111+ // If we have a cleanupret or catchret block, replace it with just an
112+ // unreachable. The other alternative, that may use a catchpad is a
113+ // catchswitch. That does not need special handling for now.
114+ if (isa<CatchReturnInst>(ReturnInstr) ||
115+ isa<CleanupReturnInst>(ReturnInstr)) {
116+ BasicBlock *ReturnInstrBB = ReturnInstr->getParent ();
117+ // This catchret or catchpad basic block is detached now. Let the
118+ // successors know it.
119+ // This basic block also may have some predecessors too. For
120+ // example the following LLVM-IR is valid:
121+ //
122+ // [cleanuppad_block]
123+ // |
124+ // [regular_block]
125+ // |
126+ // [cleanupret_block]
127+ //
128+ // The IR after the cleanup will look like this:
129+ //
130+ // [cleanuppad_block]
131+ // |
132+ // [regular_block]
133+ // |
134+ // [unreachable]
135+ //
136+ // So regular_block will lead to an unreachable block, which is also
137+ // valid. There is no need to replace regular_block with unreachable
138+ // in this context now.
139+ // On the other hand, the cleanupret/catchret block's successors
140+ // need to know about the deletion of their predecessors.
141+ emptyAndDetachBlock (ReturnInstrBB, Updates, KeepOneInputPHIs);
142+ }
143+ }
144+ }
165145 }
166146
167147 // Detaching and emptying the current basic block.
168- deleteBasicBlockFromSuccessor (BB, Updates, KeepOneInputPHIs);
169- zapAllInstructionInDeadBasicBlock (BB);
148+ emptyAndDetachBlock (BB, Updates, KeepOneInputPHIs);
170149 }
171150}
172151
0 commit comments