@@ -40,6 +40,8 @@ struct ConditionInfo {
40
40
ICmpInst::Predicate Pred;
41
41
// / AddRec llvm value
42
42
Value *AddRecValue;
43
+ // / Non PHI AddRec llvm value
44
+ Value *NonPHIAddRecValue;
43
45
// / Bound llvm value
44
46
Value *BoundValue;
45
47
// / AddRec SCEV
@@ -55,7 +57,7 @@ struct ConditionInfo {
55
57
} // namespace
56
58
57
59
static void analyzeICmp (ScalarEvolution &SE, ICmpInst *ICmp,
58
- ConditionInfo &Cond) {
60
+ ConditionInfo &Cond, const Loop &L ) {
59
61
Cond.ICmp = ICmp;
60
62
if (match (ICmp, m_ICmp (Cond.Pred , m_Value (Cond.AddRecValue ),
61
63
m_Value (Cond.BoundValue )))) {
@@ -72,6 +74,14 @@ static void analyzeICmp(ScalarEvolution &SE, ICmpInst *ICmp,
72
74
73
75
Cond.AddRecSCEV = dyn_cast<SCEVAddRecExpr>(AddRecSCEV);
74
76
Cond.BoundSCEV = BoundSCEV;
77
+ Cond.NonPHIAddRecValue = Cond.AddRecValue ;
78
+
79
+ // If the Cond.AddRecValue is PHI node, update Cond.NonPHIAddRecValue with
80
+ // value from backedge.
81
+ if (Cond.AddRecSCEV && isa<PHINode>(Cond.AddRecValue )) {
82
+ PHINode *PN = cast<PHINode>(Cond.AddRecValue );
83
+ Cond.NonPHIAddRecValue = PN->getIncomingValueForBlock (L.getLoopLatch ());
84
+ }
75
85
}
76
86
}
77
87
@@ -123,7 +133,7 @@ static bool calculateUpperBound(const Loop &L, ScalarEvolution &SE,
123
133
static bool hasProcessableCondition (const Loop &L, ScalarEvolution &SE,
124
134
ICmpInst *ICmp, ConditionInfo &Cond,
125
135
bool IsExitCond) {
126
- analyzeICmp (SE, ICmp, Cond);
136
+ analyzeICmp (SE, ICmp, Cond, L );
127
137
128
138
// The BoundSCEV should be evaluated at loop entry.
129
139
if (!SE.isAvailableAtLoopEntry (Cond.BoundSCEV , &L))
@@ -353,13 +363,45 @@ static bool splitLoopBound(Loop &L, DominatorTree &DT, LoopInfo &LI,
353
363
" .split" , &LI, &DT, PostLoopBlocks);
354
364
remapInstructionsInBlocks (PostLoopBlocks, VMap);
355
365
356
- // Add conditional branch to check we can skip post-loop in its preheader.
357
366
BasicBlock *PostLoopPreHeader = PostLoop->getLoopPreheader ();
358
- IRBuilder<> Builder (PostLoopPreHeader);
367
+ IRBuilder<> Builder (&PostLoopPreHeader->front ());
368
+
369
+ // Update phi nodes in header of post-loop.
370
+ bool isExitingLatch =
371
+ (L.getExitingBlock () == L.getLoopLatch ()) ? true : false ;
372
+ Value *ExitingCondLCSSAPhi = nullptr ;
373
+ for (PHINode &PN : L.getHeader ()->phis ()) {
374
+ // Create LCSSA phi node in preheader of post-loop.
375
+ PHINode *LCSSAPhi =
376
+ Builder.CreatePHI (PN.getType (), 1 , PN.getName () + " .lcssa" );
377
+ LCSSAPhi->setDebugLoc (PN.getDebugLoc ());
378
+ // If the exiting block is loop latch, the phi does not have the update at
379
+ // last iteration. In this case, update lcssa phi with value from backedge.
380
+ LCSSAPhi->addIncoming (
381
+ isExitingLatch ? PN.getIncomingValueForBlock (L.getLoopLatch ()) : &PN,
382
+ L.getExitingBlock ());
383
+
384
+ // Update the start value of phi node in post-loop with the LCSSA phi node.
385
+ PHINode *PostLoopPN = cast<PHINode>(VMap[&PN]);
386
+ PostLoopPN->setIncomingValueForBlock (PostLoopPreHeader, LCSSAPhi);
387
+
388
+ // Find PHI with exiting condition from pre-loop. The PHI should be
389
+ // SCEVAddRecExpr and have same incoming value from backedge with
390
+ // ExitingCond.
391
+ if (!SE.isSCEVable (PN.getType ()))
392
+ continue ;
393
+
394
+ const SCEVAddRecExpr *PhiSCEV = dyn_cast<SCEVAddRecExpr>(SE.getSCEV (&PN));
395
+ if (PhiSCEV && ExitingCond.NonPHIAddRecValue ==
396
+ PN.getIncomingValueForBlock (L.getLoopLatch ()))
397
+ ExitingCondLCSSAPhi = LCSSAPhi;
398
+ }
399
+
400
+ // Add conditional branch to check we can skip post-loop in its preheader.
359
401
Instruction *OrigBI = PostLoopPreHeader->getTerminator ();
360
402
ICmpInst::Predicate Pred = ICmpInst::ICMP_NE;
361
403
Value *Cond =
362
- Builder.CreateICmp (Pred, ExitingCond. AddRecValue , ExitingCond.BoundValue );
404
+ Builder.CreateICmp (Pred, ExitingCondLCSSAPhi , ExitingCond.BoundValue );
363
405
Builder.CreateCondBr (Cond, PostLoop->getHeader (), PostLoop->getExitBlock ());
364
406
OrigBI->eraseFromParent ();
365
407
@@ -380,21 +422,6 @@ static bool splitLoopBound(Loop &L, DominatorTree &DT, LoopInfo &LI,
380
422
// Replace exiting bound value of pre-loop NewBound.
381
423
ExitingCond.ICmp ->setOperand (1 , NewBoundValue);
382
424
383
- // Replace IV's start value of post-loop by NewBound.
384
- for (PHINode &PN : L.getHeader ()->phis ()) {
385
- // Find PHI with exiting condition from pre-loop.
386
- if (SE.isSCEVable (PN.getType ()) && isa<SCEVAddRecExpr>(SE.getSCEV (&PN))) {
387
- for (Value *Op : PN.incoming_values ()) {
388
- if (Op == ExitingCond.AddRecValue ) {
389
- // Find cloned PHI for post-loop.
390
- PHINode *PostLoopPN = cast<PHINode>(VMap[&PN]);
391
- PostLoopPN->setIncomingValueForBlock (PostLoopPreHeader,
392
- NewBoundValue);
393
- }
394
- }
395
- }
396
- }
397
-
398
425
// Replace SplitCandidateCond.BI's condition of pre-loop by True.
399
426
LLVMContext &Context = PreHeader->getContext ();
400
427
SplitCandidateCond.BI ->setCondition (ConstantInt::getTrue (Context));
@@ -411,15 +438,25 @@ static bool splitLoopBound(Loop &L, DominatorTree &DT, LoopInfo &LI,
411
438
ExitingCond.BI ->setSuccessor (1 , PostLoopPreHeader);
412
439
413
440
// Update phi node in exit block of post-loop.
441
+ Builder.SetInsertPoint (&PostLoopPreHeader->front ());
414
442
for (PHINode &PN : PostLoop->getExitBlock ()->phis ()) {
415
443
for (auto i : seq<int >(0 , PN.getNumOperands ())) {
416
444
// Check incoming block is pre-loop's exiting block.
417
445
if (PN.getIncomingBlock (i) == L.getExitingBlock ()) {
446
+ Value *IncomingValue = PN.getIncomingValue (i);
447
+
448
+ // Create LCSSA phi node for incoming value.
449
+ PHINode *LCSSAPhi =
450
+ Builder.CreatePHI (PN.getType (), 1 , PN.getName () + " .lcssa" );
451
+ LCSSAPhi->setDebugLoc (PN.getDebugLoc ());
452
+ LCSSAPhi->addIncoming (IncomingValue, PN.getIncomingBlock (i));
453
+
418
454
// Replace pre-loop's exiting block by post-loop's preheader.
419
455
PN.setIncomingBlock (i, PostLoopPreHeader);
456
+ // Replace incoming value by LCSSAPhi.
457
+ PN.setIncomingValue (i, LCSSAPhi);
420
458
// Add a new incoming value with post-loop's exiting block.
421
- PN.addIncoming (VMap[PN.getIncomingValue (i)],
422
- PostLoop->getExitingBlock ());
459
+ PN.addIncoming (VMap[IncomingValue], PostLoop->getExitingBlock ());
423
460
}
424
461
}
425
462
}
@@ -432,10 +469,7 @@ static bool splitLoopBound(Loop &L, DominatorTree &DT, LoopInfo &LI,
432
469
SE.forgetLoop (&L);
433
470
434
471
// Canonicalize loops.
435
- // TODO: Try to update LCSSA information according to above change.
436
- formLCSSA (L, DT, &LI, &SE);
437
472
simplifyLoop (&L, &DT, &LI, &SE, nullptr , nullptr , true );
438
- formLCSSA (*PostLoop, DT, &LI, &SE);
439
473
simplifyLoop (PostLoop, &DT, &LI, &SE, nullptr , nullptr , true );
440
474
441
475
// Add new post-loop to loop pass manager.
0 commit comments