@@ -65,7 +65,8 @@ hasLoopInvariantOperands(SILInstruction *inst, SILLoop *loop,
65
65
static bool
66
66
canDuplicateOrMoveToPreheader (SILLoop *loop, SILBasicBlock *preheader,
67
67
SILBasicBlock *bb,
68
- SmallVectorImpl<SILInstruction *> &moves) {
68
+ SmallVectorImpl<SILInstruction *> &moves,
69
+ SinkAddressProjections &sinkProj) {
69
70
llvm::DenseSet<SILInstruction *> invariants;
70
71
int cost = 0 ;
71
72
for (auto &instRef : *bb) {
@@ -120,6 +121,9 @@ canDuplicateOrMoveToPreheader(SILLoop *loop, SILBasicBlock *preheader,
120
121
invariants.insert (inst);
121
122
continue ;
122
123
}
124
+ if (!sinkProj.analyzeAddressProjections (inst)) {
125
+ return false ;
126
+ }
123
127
124
128
cost += (int )instructionInlineCost (instRef);
125
129
}
@@ -392,8 +396,9 @@ bool swift::rotateLoop(SILLoop *loop, DominanceInfo *domInfo,
392
396
393
397
// Make sure we can duplicate the header.
394
398
SmallVector<SILInstruction *, 8 > moveToPreheader;
395
- if (!canDuplicateOrMoveToPreheader (loop, preheader, header,
396
- moveToPreheader)) {
399
+ SinkAddressProjections sinkProj;
400
+ if (!canDuplicateOrMoveToPreheader (loop, preheader, header, moveToPreheader,
401
+ sinkProj)) {
397
402
LLVM_DEBUG (llvm::dbgs ()
398
403
<< *loop << " instructions in header preventing rotating\n " );
399
404
return false ;
@@ -440,6 +445,13 @@ bool swift::rotateLoop(SILLoop *loop, DominanceInfo *domInfo,
440
445
// The other instructions are just cloned to the preheader.
441
446
TermInst *preheaderBranch = preheader->getTerminator ();
442
447
448
+ // sink address projections to avoid address phis.
449
+ for (auto &inst : *header) {
450
+ bool success = sinkProj.analyzeAddressProjections (&inst);
451
+ assert (success);
452
+ sinkProj.cloneProjections ();
453
+ }
454
+
443
455
for (auto &inst : *header) {
444
456
if (SILInstruction *cloned = inst.clone (preheaderBranch)) {
445
457
mapOperands (cloned, valueMap);
0 commit comments