@@ -332,20 +332,23 @@ hoistSpecialInstruction(std::unique_ptr<LoopNestSummary> &LoopSummary,
332
332
bool Changed = false ;
333
333
334
334
for (auto *Inst : Special) {
335
- auto *BI = dyn_cast<BeginAccessInst>(Inst);
336
- assert (BI && " Only BeginAccessInst are supported" );
337
- SmallVector<EndAccessInst *, 2 > Ends;
338
- getEndAccesses (BI, Ends);
339
- if (!hoistInstruction (DT, BI, Loop, Preheader)) {
335
+ if (!hoistInstruction (DT, Inst, Loop, Preheader)) {
340
336
continue ;
341
337
}
342
- LLVM_DEBUG (llvm::dbgs () << " Hoisted " << *BI);
343
- for (auto *instSink : Ends) {
344
- if (!sinkInstruction (DT, LoopSummary, instSink, LI)) {
345
- llvm_unreachable (" LICM: Could not perform must-sink instruction" );
338
+ if (auto *BI = dyn_cast<BeginAccessInst>(Inst)) {
339
+ SmallVector<EndAccessInst *, 2 > Ends;
340
+ getEndAccesses (BI, Ends);
341
+ LLVM_DEBUG (llvm::dbgs () << " Hoisted BeginAccess " << *BI);
342
+ for (auto *instSink : Ends) {
343
+ if (!sinkInstruction (DT, LoopSummary, instSink, LI)) {
344
+ llvm_unreachable (" LICM: Could not perform must-sink instruction" );
345
+ }
346
346
}
347
+ LLVM_DEBUG (llvm::errs () << " Successfully hosited and sank pair\n " );
348
+ } else {
349
+ auto *REA = static_cast <RefElementAddrInst *>(Inst);
350
+ LLVM_DEBUG (llvm::dbgs () << " Hoisted RefElementAddr " << *REA);
347
351
}
348
- LLVM_DEBUG (llvm::errs () << " Successfully hosited and sank pair\n " );
349
352
Changed = true ;
350
353
}
351
354
@@ -615,6 +618,11 @@ void LoopTreeOptimization::analyzeCurrentLoop(
615
618
checkSideEffects (Inst, MayWrites);
616
619
break ;
617
620
}
621
+ case SILInstructionKind::RefElementAddrInst: {
622
+ auto *REA = static_cast <RefElementAddrInst *>(&Inst);
623
+ SpecialHoist.insert (REA);
624
+ break ;
625
+ }
618
626
case swift::SILInstructionKind::CondFailInst: {
619
627
// We can (and must) hoist cond_fail instructions if the operand is
620
628
// invariant. We must hoist them so that we preserve memory safety. A
0 commit comments