Skip to content

Commit e69c7e5

Browse files
committed
Avoid generating address phis in LoopRotate
1 parent 04f1cde commit e69c7e5

File tree

1 file changed

+54
-33
lines changed

1 file changed

+54
-33
lines changed

lib/SILOptimizer/LoopTransforms/LoopRotate.cpp

Lines changed: 54 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -65,49 +65,67 @@ hasLoopInvariantOperands(SILInstruction *inst, SILLoop *loop,
6565
static bool
6666
canDuplicateOrMoveToPreheader(SILLoop *loop, SILBasicBlock *preheader,
6767
SILBasicBlock *bb,
68-
SmallVectorImpl<SILInstruction *> &moves) {
68+
SmallVectorImpl<SILInstruction *> &moves,
69+
SinkAddressProjections &sinkProj) {
6970
llvm::DenseSet<SILInstruction *> invariants;
7071
int cost = 0;
7172
for (auto &instRef : *bb) {
72-
OwnershipForwardingMixin *ofm = nullptr;
7373
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()) {
8275
return false;
76+
}
8377
// It wouldn't make sense to rotate dealloc_stack without also rotating the
8478
// 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) {
8685
return false;
87-
else if (isa<FunctionRefInst>(inst)) {
86+
}
87+
if (isa<FunctionRefInst>(inst)) {
8888
moves.push_back(inst);
8989
invariants.insert(inst);
90-
} else if (isa<DynamicFunctionRefInst>(inst)) {
90+
continue;
91+
}
92+
if (isa<DynamicFunctionRefInst>(inst)) {
9193
moves.push_back(inst);
9294
invariants.insert(inst);
93-
} else if (isa<PreviousDynamicFunctionRefInst>(inst)) {
95+
continue;
96+
}
97+
if (isa<PreviousDynamicFunctionRefInst>(inst)) {
9498
moves.push_back(inst);
9599
invariants.insert(inst);
96-
} else if (isa<IntegerLiteralInst>(inst)) {
100+
continue;
101+
}
102+
if (isa<IntegerLiteralInst>(inst)) {
97103
moves.push_back(inst);
98104
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;
106112
moves.push_back(inst);
107113
invariants.insert(inst);
108-
} else {
109-
cost += (int)instructionInlineCost(instRef);
114+
continue;
110115
}
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);
111129
}
112130

113131
return cost < LoopRotateSizeLimit;
@@ -378,8 +396,9 @@ bool swift::rotateLoop(SILLoop *loop, DominanceInfo *domInfo,
378396

379397
// Make sure we can duplicate the header.
380398
SmallVector<SILInstruction *, 8> moveToPreheader;
381-
if (!canDuplicateOrMoveToPreheader(loop, preheader, header,
382-
moveToPreheader)) {
399+
SinkAddressProjections sinkProj;
400+
if (!canDuplicateOrMoveToPreheader(loop, preheader, header, moveToPreheader,
401+
sinkProj)) {
383402
LLVM_DEBUG(llvm::dbgs()
384403
<< *loop << " instructions in header preventing rotating\n");
385404
return false;
@@ -425,6 +444,14 @@ bool swift::rotateLoop(SILLoop *loop, DominanceInfo *domInfo,
425444

426445
// The other instructions are just cloned to the preheader.
427446
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+
428455
for (auto &inst : *header) {
429456
if (SILInstruction *cloned = inst.clone(preheaderBranch)) {
430457
mapOperands(cloned, valueMap);
@@ -488,16 +515,10 @@ namespace {
488515
class LoopRotation : public SILFunctionTransform {
489516

490517
void run() override {
518+
SILFunction *f = getFunction();
491519
SILLoopAnalysis *loopAnalysis = PM->getAnalysis<SILLoopAnalysis>();
492-
assert(loopAnalysis);
493520
DominanceAnalysis *domAnalysis = PM->getAnalysis<DominanceAnalysis>();
494-
assert(domAnalysis);
495-
496-
SILFunction *f = getFunction();
497-
assert(f);
498-
499521
SILLoopInfo *loopInfo = loopAnalysis->get(f);
500-
assert(loopInfo);
501522
DominanceInfo *domInfo = domAnalysis->get(f);
502523

503524
if (loopInfo->empty()) {

0 commit comments

Comments
 (0)