@@ -58,7 +58,23 @@ static cl::opt<unsigned> MaxDeoptOrUnreachableSuccessorCheckDepth(
58
58
" is followed by a block that either has a terminating "
59
59
" deoptimizing call or is terminated with an unreachable" ));
60
60
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.
62
78
while (!BB->empty ()) {
63
79
Instruction &I = BB->back ();
64
80
// If this instruction is used, replace uses with an arbitrary value.
@@ -76,77 +92,6 @@ static void zapAllInstructionInDeadBasicBlock(BasicBlock *BB) {
76
92
" applying corresponding DTU updates." );
77
93
}
78
94
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
-
150
95
void llvm::detachDeadBlocks (ArrayRef<BasicBlock *> BBs,
151
96
SmallVectorImpl<DominatorTree::UpdateType> *Updates,
152
97
bool KeepOneInputPHIs) {
@@ -160,13 +105,47 @@ void llvm::detachDeadBlocks(ArrayRef<BasicBlock *> BBs,
160
105
// basic blocks than the pad instruction. If we would only delete the
161
106
// first block, the we would have possible cleanupret and catchret
162
107
// 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
+ }
165
145
}
166
146
167
147
// Detaching and emptying the current basic block.
168
- deleteBasicBlockFromSuccessor (BB, Updates, KeepOneInputPHIs);
169
- zapAllInstructionInDeadBasicBlock (BB);
148
+ emptyAndDetachBlock (BB, Updates, KeepOneInputPHIs);
170
149
}
171
150
}
172
151
0 commit comments