@@ -65,49 +65,67 @@ 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) {
72
- OwnershipForwardingMixin *ofm = nullptr ;
73
73
auto *inst = &instRef;
74
- if (auto *MI = dyn_cast<MethodInst>(inst)) {
75
- if (MI->getMember ().isForeign )
76
- return false ;
77
- if (!hasLoopInvariantOperands (inst, loop, invariants))
78
- continue ;
79
- moves.push_back (inst);
80
- invariants.insert (inst);
81
- } else if (!inst->isTriviallyDuplicatable ())
74
+ if (!inst->isTriviallyDuplicatable ()) {
82
75
return false ;
76
+ }
83
77
// It wouldn't make sense to rotate dealloc_stack without also rotating the
84
78
// alloc_stack, which is covered by isTriviallyDuplicatable.
85
- else if (isa<DeallocStackInst>(inst))
79
+ if (isa<DeallocStackInst>(inst)) {
80
+ return false ;
81
+ }
82
+ OwnershipForwardingMixin *ofm = nullptr ;
83
+ if ((ofm = OwnershipForwardingMixin::get (inst)) &&
84
+ ofm->getForwardingOwnershipKind () == OwnershipKind::Guaranteed) {
86
85
return false ;
87
- else if (isa<FunctionRefInst>(inst)) {
86
+ }
87
+ if (isa<FunctionRefInst>(inst)) {
88
88
moves.push_back (inst);
89
89
invariants.insert (inst);
90
- } else if (isa<DynamicFunctionRefInst>(inst)) {
90
+ continue ;
91
+ }
92
+ if (isa<DynamicFunctionRefInst>(inst)) {
91
93
moves.push_back (inst);
92
94
invariants.insert (inst);
93
- } else if (isa<PreviousDynamicFunctionRefInst>(inst)) {
95
+ continue ;
96
+ }
97
+ if (isa<PreviousDynamicFunctionRefInst>(inst)) {
94
98
moves.push_back (inst);
95
99
invariants.insert (inst);
96
- } else if (isa<IntegerLiteralInst>(inst)) {
100
+ continue ;
101
+ }
102
+ if (isa<IntegerLiteralInst>(inst)) {
97
103
moves.push_back (inst);
98
104
invariants.insert (inst);
99
- } else if ((ofm = OwnershipForwardingMixin::get (inst)) &&
100
- ofm-> getForwardingOwnershipKind () == OwnershipKind::Guaranteed) {
101
- return false ;
102
- } else if (!inst-> mayHaveSideEffects () && !inst-> mayReadFromMemory ( )
103
- && !isa<TermInst>(inst) && !isa<AllocationInst>(inst)
104
- && /* not marked mayhavesideffects */
105
- hasLoopInvariantOperands (inst, loop, invariants)) {
105
+ continue ;
106
+ }
107
+ if ( auto *MI = dyn_cast<MethodInst>(inst)) {
108
+ if (MI-> getMember (). isForeign )
109
+ return false ;
110
+ if (! hasLoopInvariantOperands (inst, loop, invariants))
111
+ continue ;
106
112
moves.push_back (inst);
107
113
invariants.insert (inst);
108
- } else {
109
- cost += (int )instructionInlineCost (instRef);
114
+ continue ;
110
115
}
116
+ if (!inst->mayHaveSideEffects () && !inst->mayReadFromMemory () &&
117
+ !isa<TermInst>(inst) &&
118
+ !isa<AllocationInst>(inst) && /* not marked mayhavesideffects */
119
+ hasLoopInvariantOperands (inst, loop, invariants)) {
120
+ moves.push_back (inst);
121
+ invariants.insert (inst);
122
+ continue ;
123
+ }
124
+ if (!sinkProj.analyzeAddressProjections (inst)) {
125
+ return false ;
126
+ }
127
+
128
+ cost += (int )instructionInlineCost (instRef);
111
129
}
112
130
113
131
return cost < LoopRotateSizeLimit;
@@ -378,8 +396,9 @@ bool swift::rotateLoop(SILLoop *loop, DominanceInfo *domInfo,
378
396
379
397
// Make sure we can duplicate the header.
380
398
SmallVector<SILInstruction *, 8 > moveToPreheader;
381
- if (!canDuplicateOrMoveToPreheader (loop, preheader, header,
382
- moveToPreheader)) {
399
+ SinkAddressProjections sinkProj;
400
+ if (!canDuplicateOrMoveToPreheader (loop, preheader, header, moveToPreheader,
401
+ sinkProj)) {
383
402
LLVM_DEBUG (llvm::dbgs ()
384
403
<< *loop << " instructions in header preventing rotating\n " );
385
404
return false ;
@@ -425,6 +444,14 @@ bool swift::rotateLoop(SILLoop *loop, DominanceInfo *domInfo,
425
444
426
445
// The other instructions are just cloned to the preheader.
427
446
TermInst *preheaderBranch = preheader->getTerminator ();
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
+
428
455
for (auto &inst : *header) {
429
456
if (SILInstruction *cloned = inst.clone (preheaderBranch)) {
430
457
mapOperands (cloned, valueMap);
@@ -488,16 +515,10 @@ namespace {
488
515
class LoopRotation : public SILFunctionTransform {
489
516
490
517
void run () override {
518
+ SILFunction *f = getFunction ();
491
519
SILLoopAnalysis *loopAnalysis = PM->getAnalysis <SILLoopAnalysis>();
492
- assert (loopAnalysis);
493
520
DominanceAnalysis *domAnalysis = PM->getAnalysis <DominanceAnalysis>();
494
- assert (domAnalysis);
495
-
496
- SILFunction *f = getFunction ();
497
- assert (f);
498
-
499
521
SILLoopInfo *loopInfo = loopAnalysis->get (f);
500
- assert (loopInfo);
501
522
DominanceInfo *domInfo = domAnalysis->get (f);
502
523
503
524
if (loopInfo->empty ()) {
0 commit comments