@@ -610,6 +610,22 @@ computeAvailableValuesFrom(SILBasicBlock::iterator StartingFrom,
610
610
}
611
611
}
612
612
613
+ // / If we are able to optimize \p Inst, return the source address that
614
+ // / instruction is loading from. If we can not optimize \p Inst, then just
615
+ // / return an empty SILValue.
616
+ static SILValue tryFindSrcAddrForLoad (SILInstruction *Inst) {
617
+ // We only handle load [copy], load [trivial] and copy_addr right now.
618
+ if (auto *LI = dyn_cast<LoadInst>(Inst))
619
+ return LI->getOperand ();
620
+
621
+ // If this is a CopyAddr, verify that the element type is loadable. If not,
622
+ // we can't explode to a load.
623
+ auto *CAI = dyn_cast<CopyAddrInst>(Inst);
624
+ if (!CAI || !CAI->getSrc ()->getType ().isLoadable (CAI->getModule ()))
625
+ return SILValue ();
626
+ return CAI->getSrc ();
627
+ }
628
+
613
629
// / At this point, we know that this element satisfies the definitive init
614
630
// / requirements, so we can try to promote loads to enable SSA-based dataflow
615
631
// / analysis. We know that accesses to this element only access this element,
@@ -623,33 +639,25 @@ bool AllocOptimize::promoteLoad(SILInstruction *Inst) {
623
639
// have to prove that something in this function is holding the weak value
624
640
// live across the promoted region and that isn't desired for a stable
625
641
// diagnostics pass this like one.
626
-
627
- // We only handle load and copy_addr right now.
628
- SILValue src;
629
- if (auto CAI = dyn_cast<CopyAddrInst>(Inst)) {
630
- // If this is a CopyAddr, verify that the element type is loadable. If not,
631
- // we can't explode to a load.
632
- src = CAI->getSrc ();
633
- if (!src->getType ().isLoadable (Module))
634
- return false ;
635
- } else if (auto load = dyn_cast<LoadInst>(Inst)) {
636
- src = load->getOperand ();
637
- } else {
642
+
643
+ // First attempt to find a source addr for our "load" instruction. If we fail
644
+ // to find a valid value, just return.
645
+ SILValue SrcAddr = tryFindSrcAddrForLoad (Inst);
646
+ if (!SrcAddr)
638
647
return false ;
639
- }
640
648
641
649
// If the box has escaped at this instruction, we can't safely promote the
642
650
// load.
643
651
if (hasEscapedAt (Inst))
644
652
return false ;
645
-
646
- SILType LoadTy = src ->getType ().getObjectType ();
647
-
653
+
654
+ SILType LoadTy = SrcAddr ->getType ().getObjectType ();
655
+
648
656
// If this is a load/copy_addr from a struct field that we want to promote,
649
657
// compute the access path down to the field so we can determine precise
650
658
// def/use behavior.
651
- unsigned FirstElt = computeSubelement (src , TheMemory);
652
-
659
+ unsigned FirstElt = computeSubelement (SrcAddr , TheMemory);
660
+
653
661
// If this is a load from within an enum projection, we can't promote it since
654
662
// we don't track subelements in a type that could be changing.
655
663
if (FirstElt == ~0U )
0 commit comments