Skip to content

Commit 8439d0b

Browse files
committed
LoopRotate: remove redundant phis after ssa-update
Fixes an ownership error
1 parent 6990a19 commit 8439d0b

File tree

2 files changed

+147
-13
lines changed

2 files changed

+147
-13
lines changed

lib/SILOptimizer/LoopTransforms/LoopRotate.cpp

Lines changed: 16 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,7 @@ static llvm::cl::opt<bool> RotateSingleBlockLoop("looprotate-single-block-loop",
4646

4747
static bool rotateLoop(SILLoop *loop, DominanceInfo *domInfo,
4848
SILLoopInfo *loopInfo, bool rotateSingleBlockLoops,
49-
SILBasicBlock *upToBB);
49+
SILBasicBlock *upToBB, SILPassManager *pm);
5050

5151
/// Check whether all operands are loop invariant.
5252
static bool
@@ -151,7 +151,8 @@ static void mapOperands(SILInstruction *inst,
151151
static void updateSSAForUseOfValue(
152152
SILSSAUpdater &updater, SmallVectorImpl<SILPhiArgument *> &insertedPhis,
153153
const llvm::DenseMap<ValueBase *, SILValue> &valueMap,
154-
SILBasicBlock *Header, SILBasicBlock *EntryCheckBlock, SILValue Res) {
154+
SILBasicBlock *Header, SILBasicBlock *EntryCheckBlock, SILValue Res,
155+
SILPassManager *pm) {
155156
// Find the mapped instruction.
156157
assert(valueMap.count(Res) && "Expected to find value in map!");
157158
SILValue MappedValue = valueMap.find(Res)->second;
@@ -187,23 +188,25 @@ static void updateSSAForUseOfValue(
187188
updater.rewriteUse(*use);
188189
}
189190

191+
replacePhisWithIncomingValues(pm, insertedPhis);
190192
}
191193

192194
static void
193195
updateSSAForUseOfInst(SILSSAUpdater &updater,
194196
SmallVectorImpl<SILPhiArgument *> &insertedPhis,
195197
const llvm::DenseMap<ValueBase *, SILValue> &valueMap,
196198
SILBasicBlock *header, SILBasicBlock *entryCheckBlock,
197-
SILInstruction *inst) {
199+
SILInstruction *inst, SILPassManager *pm) {
198200
for (auto result : inst->getResults())
199201
updateSSAForUseOfValue(updater, insertedPhis, valueMap, header,
200-
entryCheckBlock, result);
202+
entryCheckBlock, result, pm);
201203
}
202204

203205
/// Rewrite the code we just created in the preheader and update SSA form.
204206
static void rewriteNewLoopEntryCheckBlock(
205207
SILBasicBlock *header, SILBasicBlock *entryCheckBlock,
206-
const llvm::DenseMap<ValueBase *, SILValue> &valueMap) {
208+
const llvm::DenseMap<ValueBase *, SILValue> &valueMap,
209+
SILPassManager *pm) {
207210
SmallVector<SILPhiArgument *, 8> insertedPhis;
208211
SILSSAUpdater updater(&insertedPhis);
209212

@@ -212,7 +215,7 @@ static void rewriteNewLoopEntryCheckBlock(
212215
for (unsigned i : range(header->getNumArguments())) {
213216
auto *arg = header->getArguments()[i];
214217
updateSSAForUseOfValue(updater, insertedPhis, valueMap, header,
215-
entryCheckBlock, arg);
218+
entryCheckBlock, arg, pm);
216219
}
217220

218221
auto instIter = header->begin();
@@ -221,7 +224,7 @@ static void rewriteNewLoopEntryCheckBlock(
221224
while (instIter != header->end()) {
222225
auto &inst = *instIter;
223226
updateSSAForUseOfInst(updater, insertedPhis, valueMap, header,
224-
entryCheckBlock, &inst);
227+
entryCheckBlock, &inst, pm);
225228
++instIter;
226229
}
227230
}
@@ -243,7 +246,7 @@ static void updateDomTree(DominanceInfo *domInfo, SILBasicBlock *preheader,
243246
}
244247

245248
static bool rotateLoopAtMostUpToLatch(SILLoop *loop, DominanceInfo *domInfo,
246-
SILLoopInfo *loopInfo) {
249+
SILLoopInfo *loopInfo, SILPassManager *pm) {
247250
auto *latch = loop->getLoopLatch();
248251
if (!latch) {
249252
LLVM_DEBUG(llvm::dbgs()
@@ -253,11 +256,11 @@ static bool rotateLoopAtMostUpToLatch(SILLoop *loop, DominanceInfo *domInfo,
253256

254257
bool didRotate = rotateLoop(
255258
loop, domInfo, loopInfo,
256-
RotateSingleBlockLoop /* rotateSingleBlockLoops */, latch);
259+
RotateSingleBlockLoop /* rotateSingleBlockLoops */, latch, pm);
257260

258261
// Keep rotating at most until we hit the original latch.
259262
if (didRotate)
260-
while (rotateLoop(loop, domInfo, loopInfo, false, latch)) {
263+
while (rotateLoop(loop, domInfo, loopInfo, false, latch, pm)) {
261264
}
262265

263266
return didRotate;
@@ -306,7 +309,7 @@ static bool isSingleBlockLoop(SILLoop *L) {
306309
/// loop for termination.
307310
static bool rotateLoop(SILLoop *loop, DominanceInfo *domInfo,
308311
SILLoopInfo *loopInfo, bool rotateSingleBlockLoops,
309-
SILBasicBlock *upToBB) {
312+
SILBasicBlock *upToBB, SILPassManager *pm) {
310313
assert(loop != nullptr && domInfo != nullptr && loopInfo != nullptr
311314
&& "Missing loop information");
312315

@@ -432,7 +435,7 @@ static bool rotateLoop(SILLoop *loop, DominanceInfo *domInfo,
432435

433436
// If there were any uses of instructions in the duplicated loop entry check
434437
// block rewrite them using the ssa updater.
435-
rewriteNewLoopEntryCheckBlock(header, preheader, valueMap);
438+
rewriteNewLoopEntryCheckBlock(header, preheader, valueMap, pm);
436439

437440
loop->moveToHeader(newHeader);
438441

@@ -498,7 +501,7 @@ class LoopRotation : public SILFunctionTransform {
498501
SILLoop *loop = worklist.pop_back_val();
499502
changed |= canonicalizeLoop(loop, domInfo, loopInfo);
500503
changed |=
501-
rotateLoopAtMostUpToLatch(loop, domInfo, loopInfo);
504+
rotateLoopAtMostUpToLatch(loop, domInfo, loopInfo, getPassManager());
502505
}
503506
}
504507

test/SILOptimizer/looprotate_ossa.sil

Lines changed: 131 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -582,3 +582,134 @@ bb3:
582582
return %26 : $Int32
583583
}
584584

585+
// Make sure that no unnecessary phis are inserted which would cause an ownership error.
586+
// CHECK-LABEL: sil [ossa] @test_ssa_updater_owned :
587+
// CHECK: begin_borrow
588+
// CHECK-NOT: bb({{.*@owned.*}}):
589+
// CHECK: end_borrow
590+
// CHECK-LABEL: } // end sil function 'test_ssa_updater_owned'
591+
sil [ossa] @test_ssa_updater_owned : $@convention(thin) (@owned String, @guaranteed String) -> () {
592+
bb0(%0 : @owned $String, %1 : @guaranteed $String):
593+
%2 = integer_literal $Builtin.Int64, 0
594+
br bb1(%0, %2)
595+
596+
bb1(%4 : @owned $String, %5 : $Builtin.Int64):
597+
cond_br undef, bb14, bb2
598+
599+
bb2:
600+
%7 = integer_literal $Builtin.Int64, 1
601+
%8 = begin_borrow %4
602+
cond_br undef, bb4, bb3
603+
604+
bb3:
605+
br bb5
606+
607+
bb4:
608+
cond_br undef, bb7, bb8
609+
610+
bb5:
611+
cond_br undef, bb10, bb6
612+
613+
bb6:
614+
br bb9
615+
616+
bb7:
617+
br bb9
618+
619+
bb8:
620+
br bb12
621+
622+
bb9:
623+
br bb11
624+
625+
bb10:
626+
br bb11
627+
628+
bb11:
629+
end_borrow %8
630+
destroy_value %4
631+
br bb13
632+
633+
bb12:
634+
end_borrow %8
635+
destroy_value [dead_end] %4
636+
unreachable
637+
638+
bb13:
639+
%24 = copy_value %1
640+
br bb1(%24, %7)
641+
642+
bb14:
643+
destroy_value %4
644+
%27 = tuple ()
645+
return %27
646+
}
647+
648+
// Make sure that no unnecessary phis are inserted which would cause an ownership error.
649+
// CHECK-LABEL: sil [ossa] @test_ssa_updater_guaranteed :
650+
// CHECK: begin_borrow
651+
// CHECK: begin_borrow
652+
// CHECK-NOT: bb({{.*@reborrow.*}}):
653+
// CHECK: end_borrow
654+
// CHECK-LABEL: } // end sil function 'test_ssa_updater_guaranteed'
655+
sil [ossa] @test_ssa_updater_guaranteed : $@convention(thin) (@owned String) -> () {
656+
bb0(%0 : @owned $String):
657+
%2 = integer_literal $Builtin.Int64, 0
658+
%3 = begin_borrow %0
659+
br bb1(%3, %2)
660+
661+
bb1(%4 : @reborrow $String, %5 : $Builtin.Int64):
662+
%6 = borrowed %4 from (%0)
663+
cond_br undef, bb14, bb2
664+
665+
bb2:
666+
%7 = integer_literal $Builtin.Int64, 1
667+
%8 = begin_borrow %6
668+
cond_br undef, bb4, bb3
669+
670+
bb3:
671+
br bb5
672+
673+
bb4:
674+
cond_br undef, bb7, bb8
675+
676+
bb5:
677+
cond_br undef, bb10, bb6
678+
679+
bb6:
680+
br bb9
681+
682+
bb7:
683+
br bb9
684+
685+
bb8:
686+
br bb12
687+
688+
bb9:
689+
br bb11
690+
691+
bb10:
692+
br bb11
693+
694+
bb11:
695+
end_borrow %8
696+
end_borrow %6
697+
br bb13
698+
699+
bb12:
700+
end_borrow %8
701+
end_borrow %6
702+
destroy_value [dead_end] %0
703+
unreachable
704+
705+
bb13:
706+
%24 = begin_borrow %0
707+
br bb1(%24, %7)
708+
709+
bb14:
710+
end_borrow %6
711+
destroy_value %0
712+
%27 = tuple ()
713+
return %27
714+
}
715+

0 commit comments

Comments
 (0)