6
6
//
7
7
// ===----------------------------------------------------------------------===//
8
8
//
9
- // To convert an irreducible cycle C to a natural loop L:
10
- //
11
- // 1. Add a new node N to C.
12
- // 2. Redirect all external incoming edges through N.
13
- // 3. Redirect all edges incident on header H through N.
14
- //
15
- // This is sufficient to ensure that:
16
- //
17
- // a. Every closed path in C also exists in L, with the modification that any
18
- // path passing through H now passes through N before reaching H.
19
- // b. Every external path incident on any entry of C is now incident on N and
20
- // then redirected to the entry.
21
- //
22
- // Thus, L is a strongly connected component dominated by N, and hence L is a
23
- // natural loop with header N.
24
- //
25
- // INPUT CFG: The blocks H and B form an irreducible loop with two headers.
9
+ // INPUT CFG: The blocks H and B form an irreducible cycle with two headers.
26
10
//
27
11
// Entry
28
12
// / \
33
17
// v
34
18
// Exit
35
19
//
36
- // OUTPUT CFG:
20
+ // OUTPUT CFG: Converted to a natural loop with a new header N.
37
21
//
38
22
// Entry
39
23
// |
47
31
// v
48
32
// Exit
49
33
//
34
+ // To convert an irreducible cycle C to a natural loop L:
35
+ //
36
+ // 1. Add a new node N to C.
37
+ // 2. Redirect all external incoming edges through N.
38
+ // 3. Redirect all edges incident on header H through N.
39
+ //
40
+ // This is sufficient to ensure that:
41
+ //
42
+ // a. Every closed path in C also exists in L, with the modification that any
43
+ // path passing through H now passes through N before reaching H.
44
+ // b. Every external path incident on any entry of C is now incident on N and
45
+ // then redirected to the entry.
46
+ //
47
+ // Thus, L is a strongly connected component dominated by N, and hence L is a
48
+ // natural loop with header N.
49
+ //
50
+ // When an irreducible cycle C with header H is transformed into a loop, the
51
+ // following invariants hold:
52
+ //
53
+ // 1. No new subcycles are "discovered" in the set (C-H). The only internal
54
+ // edges that are redirected by the transform are incident on H. Any subcycle
55
+ // S in (C-H), already existed prior to this transform, and is already in the
56
+ // list of children for this cycle C.
50
57
//
51
- // The actual transformation is handled by function CreateControlFlowHub, which
52
- // takes a set of incoming blocks (the predecessors) and outgoing blocks (the
53
- // entries). The function also moves every PHINode in an outgoing block to the
54
- // hub. Since the hub dominates all the outgoing blocks, each such PHINode
55
- // continues to dominate its uses. Since every entry the cycle has at least two
56
- // predecessors, every value used in the entry (or later) but defined in a
57
- // predecessor (or earlier) is represented by a PHINode in a entry. Hence the
58
- // above handling of PHINodes is sufficient and no further processing is
59
- // required to restore SSA.
58
+ // 2. Subcycles of C are not modified by the transform. For some subcycle S of
59
+ // C, edges incident on the entries of S are either internal to C, or they
60
+ // are now redirected through N, which is outside of S. So the list of
61
+ // entries to S does not change. Since the transform only adds a block
62
+ // outside S, and redirects edges that are not internal to S, the list of
63
+ // blocks in S does not change.
64
+ //
65
+ // 3. Similarly, any natural loop L included in C is not affected, with one
66
+ // exception: L is "destroyed" by the transform iff its header is H. The
67
+ // backedges of such a loop are now redirected to N instead, and hence the
68
+ // body of this loop gets merged into the new loop with header N.
69
+ //
70
+ // The actual transformation is handled by the ControlFlowHub, which redirects
71
+ // specified control flow edges through a set of guard blocks. This also moves
72
+ // every PHINode in an outgoing block to the hub. Since the hub dominates all
73
+ // the outgoing blocks, each such PHINode continues to dominate its uses. Since
74
+ // every header in an SCC has at least two predecessors, every value used in the
75
+ // header (or later) but defined in a predecessor (or earlier) is represented by
76
+ // a PHINode in a header. Hence the above handling of PHINodes is sufficient and
77
+ // no further processing is required to restore SSA.
60
78
//
61
79
// Limitation: The pass cannot handle switch statements and indirect
62
80
// branches. Both must be lowered to plain branches first.
@@ -119,8 +137,9 @@ static void reconnectChildLoops(LoopInfo &LI, Loop *ParentLoop, Loop *NewLoop,
119
137
// Any candidate is a child iff its header is owned by the new loop. Move all
120
138
// the children to a new vector.
121
139
auto FirstChild = std::partition (
122
- CandidateLoops.begin (), CandidateLoops.end (),
123
- [&](Loop *L) { return !NewLoop->contains (L->getHeader ()); });
140
+ CandidateLoops.begin (), CandidateLoops.end (), [&](Loop *L) {
141
+ return NewLoop == L || !NewLoop->contains (L->getHeader ());
142
+ });
124
143
SmallVector<Loop *, 8 > ChildLoops (FirstChild, CandidateLoops.end ());
125
144
CandidateLoops.erase (FirstChild, CandidateLoops.end ());
126
145
@@ -154,57 +173,127 @@ static void reconnectChildLoops(LoopInfo &LI, Loop *ParentLoop, Loop *NewLoop,
154
173
}
155
174
}
156
175
176
+ static void updateLoopInfo (LoopInfo &LI, Cycle &C,
177
+ ArrayRef<BasicBlock *> GuardBlocks) {
178
+ // The parent loop is a natural loop L mapped to the cycle header H as long as
179
+ // H is not also the header of L. In the latter case, L is destroyed and we
180
+ // seek its parent instead.
181
+ BasicBlock *CycleHeader = C.getHeader ();
182
+ Loop *ParentLoop = LI.getLoopFor (CycleHeader);
183
+ if (ParentLoop && ParentLoop->getHeader () == CycleHeader)
184
+ ParentLoop = ParentLoop->getParentLoop ();
185
+
186
+ // Create a new loop from the now-transformed cycle
187
+ auto *NewLoop = LI.AllocateLoop ();
188
+ if (ParentLoop) {
189
+ ParentLoop->addChildLoop (NewLoop);
190
+ } else {
191
+ LI.addTopLevelLoop (NewLoop);
192
+ }
193
+
194
+ // Add the guard blocks to the new loop. The first guard block is
195
+ // the head of all the backedges, and it is the first to be inserted
196
+ // in the loop. This ensures that it is recognized as the
197
+ // header. Since the new loop is already in LoopInfo, the new blocks
198
+ // are also propagated up the chain of parent loops.
199
+ for (auto *G : GuardBlocks) {
200
+ LLVM_DEBUG (dbgs () << " added guard block to loop: " << G->getName () << " \n " );
201
+ NewLoop->addBasicBlockToLoop (G, LI);
202
+ }
203
+
204
+ for (auto *BB : C.blocks ()) {
205
+ NewLoop->addBlockEntry (BB);
206
+ if (LI.getLoopFor (BB) == ParentLoop) {
207
+ LLVM_DEBUG (dbgs () << " moved block from parent: " << BB->getName ()
208
+ << " \n " );
209
+ LI.changeLoopFor (BB, NewLoop);
210
+ } else {
211
+ LLVM_DEBUG (dbgs () << " added block from child: " << BB->getName () << " \n " );
212
+ }
213
+ }
214
+ LLVM_DEBUG (dbgs () << " header for new loop: "
215
+ << NewLoop->getHeader ()->getName () << " \n " );
216
+
217
+ reconnectChildLoops (LI, ParentLoop, NewLoop, C.getHeader ());
218
+
219
+ LLVM_DEBUG (dbgs () << " Verify new loop.\n " ; NewLoop->print (dbgs ()));
220
+ NewLoop->verifyLoop ();
221
+ if (ParentLoop) {
222
+ LLVM_DEBUG (dbgs () << " Verify parent loop.\n " ; ParentLoop->print (dbgs ()));
223
+ ParentLoop->verifyLoop ();
224
+ }
225
+ }
226
+
157
227
// Given a set of blocks and headers in an irreducible SCC, convert it into a
158
228
// natural loop. Also insert this new loop at its appropriate place in the
159
229
// hierarchy of loops.
160
230
static bool fixIrreducible (Cycle &C, CycleInfo &CI, DominatorTree &DT,
161
231
LoopInfo *LI) {
162
232
if (C.isReducible ())
163
233
return false ;
234
+ LLVM_DEBUG (dbgs () << " Processing cycle:\n " << CI.print (&C) << " \n " ;);
164
235
236
+ ControlFlowHub CHub;
165
237
SetVector<BasicBlock *> Predecessors;
166
238
167
239
// Redirect internal edges incident on the header.
168
- BasicBlock *OldHeader = C.getHeader ();
169
- for (BasicBlock *P : predecessors (OldHeader )) {
240
+ BasicBlock *Header = C.getHeader ();
241
+ for (BasicBlock *P : predecessors (Header )) {
170
242
if (C.contains (P))
171
243
Predecessors.insert (P);
172
244
}
173
245
246
+ for (BasicBlock *P : Predecessors) {
247
+ auto *Branch = cast<BranchInst>(P->getTerminator ());
248
+ // Exactly one of the two successors is the header.
249
+ BasicBlock *Succ0 = Branch->getSuccessor (0 ) == Header ? Header : nullptr ;
250
+ BasicBlock *Succ1 = Succ0 ? nullptr : Header;
251
+ if (!Succ0)
252
+ assert (Branch->getSuccessor (1 ) == Header);
253
+ assert (Succ0 || Succ1);
254
+ CHub.addBranch (P, Succ0, Succ1);
255
+
256
+ LLVM_DEBUG (dbgs () << " Added internal branch: " << P->getName () << " -> "
257
+ << (Succ0 ? Succ0->getName () : " " ) << " "
258
+ << (Succ1 ? Succ1->getName () : " " ) << " \n " );
259
+ }
260
+
174
261
// Redirect external incoming edges. This includes the edges on the header.
262
+ Predecessors.clear ();
175
263
for (BasicBlock *E : C.entries ()) {
176
264
for (BasicBlock *P : predecessors (E)) {
177
265
if (!C.contains (P))
178
266
Predecessors.insert (P);
179
267
}
180
268
}
181
269
182
- LLVM_DEBUG (
183
- dbgs () << " Found predecessors:" ;
184
- for (auto P : Predecessors) {
185
- dbgs () << " " << P->getName ();
186
- }
187
- dbgs () << " \n " );
188
-
189
- // Redirect all the backedges through a "hub" consisting of a series
190
- // of guard blocks that manage the flow of control from the
191
- // predecessors to the headers.
192
- ControlFlowHub CHub;
193
270
for (BasicBlock *P : Predecessors) {
194
271
auto *Branch = cast<BranchInst>(P->getTerminator ());
195
272
BasicBlock *Succ0 = Branch->getSuccessor (0 );
196
- Succ0 = Headers. count (Succ0) ? Succ0 : nullptr ;
273
+ Succ0 = C. contains (Succ0) ? Succ0 : nullptr ;
197
274
BasicBlock *Succ1 =
198
275
Branch->isUnconditional () ? nullptr : Branch->getSuccessor (1 );
199
- Succ1 = Succ1 && Headers. count (Succ1) ? Succ1 : nullptr ;
276
+ Succ1 = Succ1 && C. contains (Succ1) ? Succ1 : nullptr ;
200
277
CHub.addBranch (P, Succ0, Succ1);
201
278
202
- LLVM_DEBUG (dbgs () << " Added branch: " << P->getName () << " -> "
279
+ LLVM_DEBUG (dbgs () << " Added external branch: " << P->getName () << " -> "
203
280
<< (Succ0 ? Succ0->getName () : " " ) << " "
204
281
<< (Succ1 ? Succ1->getName () : " " ) << " \n " );
205
282
}
206
283
207
- SmallVector<BasicBlock *, 8 > GuardBlocks;
284
+ // Redirect all the backedges through a "hub" consisting of a series
285
+ // of guard blocks that manage the flow of control from the
286
+ // predecessors to the headers.
287
+ SmallVector<BasicBlock *> GuardBlocks;
288
+
289
+ // Minor optimization: The cycle entries are discovered in an order that is
290
+ // the opposite of the order in which these blocks appear as branch targets.
291
+ // This results in a lot of condition inversions in the control flow out of
292
+ // the new ControlFlowHub, which can be mitigated if the orders match. So we
293
+ // reverse the entries when adding them to the hub.
294
+ SetVector<BasicBlock *> Entries;
295
+ Entries.insert (C.entry_rbegin (), C.entry_rend ());
296
+
208
297
DomTreeUpdater DTU (DT, DomTreeUpdater::UpdateStrategy::Eager);
209
298
CHub.finalize (&DTU, GuardBlocks, " irr" );
210
299
#if defined(EXPENSIVE_CHECKS)
@@ -213,57 +302,23 @@ static bool fixIrreducible(Cycle &C, CycleInfo &CI, DominatorTree &DT,
213
302
assert (DT.verify (DominatorTree::VerificationLevel::Fast));
214
303
#endif
215
304
305
+ // If we are updating LoopInfo, do that now before modifying the cycle. This
306
+ // ensures that the first guard block is the header of a new natural loop.
307
+ if (LI)
308
+ updateLoopInfo (*LI, C, GuardBlocks);
309
+
216
310
for (auto *G : GuardBlocks) {
217
- LLVM_DEBUG (dbgs () << " added guard block: " << G->getName () << " \n " );
311
+ LLVM_DEBUG (dbgs () << " added guard block to cycle: " << G->getName ()
312
+ << " \n " );
218
313
CI.addBlockToCycle (G, &C);
219
314
}
220
315
C.setSingleEntry (GuardBlocks[0 ]);
221
316
222
- if (!LI)
223
- return true ;
224
-
225
- Loop *ParentLoop = LI->getLoopFor (OldHeader);
226
- // Create a new loop from the now-transformed cycle
227
- auto *NewLoop = LI->AllocateLoop ();
228
- if (ParentLoop) {
229
- ParentLoop->addChildLoop (NewLoop);
230
- } else {
231
- LI->addTopLevelLoop (NewLoop);
232
- }
233
-
234
- // Add the guard blocks to the new loop. The first guard block is
235
- // the head of all the backedges, and it is the first to be inserted
236
- // in the loop. This ensures that it is recognized as the
237
- // header. Since the new loop is already in LoopInfo, the new blocks
238
- // are also propagated up the chain of parent loops.
239
- for (auto *G : GuardBlocks) {
240
- LLVM_DEBUG (dbgs () << " added guard block: " << G->getName () << " \n " );
241
- NewLoop->addBasicBlockToLoop (G, *LI);
242
- }
243
-
244
- for (auto *BB : C.blocks ()) {
245
- NewLoop->addBlockEntry (BB);
246
- if (LI->getLoopFor (BB) == ParentLoop) {
247
- LLVM_DEBUG (dbgs () << " moved block from parent: " << BB->getName ()
248
- << " \n " );
249
- LI->changeLoopFor (BB, NewLoop);
250
- } else {
251
- LLVM_DEBUG (dbgs () << " added block from child: " << BB->getName () << " \n " );
252
- }
253
- }
254
- LLVM_DEBUG (dbgs () << " header for new loop: "
255
- << NewLoop->getHeader ()->getName () << " \n " );
256
-
257
- reconnectChildLoops (*LI, ParentLoop, NewLoop, OldHeader);
258
-
259
- NewLoop->verifyLoop ();
260
- if (ParentLoop) {
261
- ParentLoop->verifyLoop ();
262
- }
263
- #if defined(EXPENSIVE_CHECKS)
264
- LI->verify (DT);
265
- #endif // EXPENSIVE_CHECKS
317
+ C.verifyCycle ();
318
+ if (Cycle *Parent = C.getParentCycle ())
319
+ Parent->verifyCycle ();
266
320
321
+ LLVM_DEBUG (dbgs () << " Finished one cycle:\n " ; CI.print (dbgs ()););
267
322
return true ;
268
323
}
269
324
@@ -275,15 +330,23 @@ static bool FixIrreducibleImpl(Function &F, CycleInfo &CI, DominatorTree &DT,
275
330
assert (hasOnlySimpleTerminator (F) && " Unsupported block terminator." );
276
331
277
332
bool Changed = false ;
278
- SmallVector<Cycle *> Worklist{CI.toplevel_cycles ()};
333
+ for (Cycle *TopCycle : CI.toplevel_cycles ()) {
334
+ for (Cycle *C : depth_first (TopCycle)) {
335
+ Changed |= fixIrreducible (*C, CI, DT, LI);
336
+ }
337
+ }
338
+
339
+ if (!Changed)
340
+ return false ;
279
341
280
- while (!Worklist. empty ()) {
281
- Cycle *C = Worklist. pop_back_val ();
282
- Changed |= fixIrreducible (*C, CI, DT, LI);
283
- append_range (Worklist, C-> children () );
342
+ # if defined(EXPENSIVE_CHECKS)
343
+ CI. verify ();
344
+ if ( LI) {
345
+ LI. verify (DT );
284
346
}
347
+ #endif // EXPENSIVE_CHECKS
285
348
286
- return Changed ;
349
+ return true ;
287
350
}
288
351
289
352
bool FixIrreducible::runOnFunction (Function &F) {
0 commit comments