@@ -481,14 +481,17 @@ class RLEContext {
481
481
// / walked, i.e. when the we generate the genset and killset.
482
482
llvm::DenseSet<SILBasicBlock *> BBWithLoads;
483
483
484
+ // / If set, RLE ignores loads from that array type.
485
+ NominalTypeDecl *ArrayType;
486
+
484
487
#ifndef NDEBUG
485
488
SILPrintContext printCtx;
486
489
#endif
487
490
488
491
public:
489
492
RLEContext (SILFunction *F, SILPassManager *PM, AliasAnalysis *AA,
490
493
TypeExpansionAnalysis *TE, PostOrderFunctionInfo *PO,
491
- EpilogueARCFunctionInfo *EAFI);
494
+ EpilogueARCFunctionInfo *EAFI, bool disableArrayLoads );
492
495
493
496
RLEContext (const RLEContext &) = delete ;
494
497
RLEContext (RLEContext &&) = default ;
@@ -555,6 +558,17 @@ class RLEContext {
555
558
// / Transitively collect all the values that make up this location and
556
559
// / create a SILArgument out of them.
557
560
SILValue computePredecessorLocationValue (SILBasicBlock *BB, LSLocation &L);
561
+
562
+ // / Returns the LoadInst if \p Inst is a load inst we want to handle.
563
+ LoadInst *isLoadInstToHandle (SILInstruction *Inst) {
564
+ if (auto *LI = dyn_cast<LoadInst>(Inst)) {
565
+ if (!ArrayType ||
566
+ LI->getType ().getNominalOrBoundGenericNominal () != ArrayType) {
567
+ return LI;
568
+ }
569
+ }
570
+ return nullptr ;
571
+ }
558
572
};
559
573
560
574
} // end anonymous namespace
@@ -1054,7 +1068,7 @@ void BlockState::processInstructionWithKind(RLEContext &Ctx,
1054
1068
1055
1069
// This is a LoadInst. Let's see if we can find a previous loaded, stored
1056
1070
// value to use instead of this load.
1057
- if (auto *LI = dyn_cast<LoadInst> (Inst)) {
1071
+ if (auto *LI = Ctx. isLoadInstToHandle (Inst)) {
1058
1072
processLoadInst (Ctx, LI, Kind);
1059
1073
return ;
1060
1074
}
@@ -1174,8 +1188,10 @@ void BlockState::dump(RLEContext &Ctx) {
1174
1188
1175
1189
RLEContext::RLEContext (SILFunction *F, SILPassManager *PM, AliasAnalysis *AA,
1176
1190
TypeExpansionAnalysis *TE, PostOrderFunctionInfo *PO,
1177
- EpilogueARCFunctionInfo *EAFI)
1178
- : Fn(F), PM(PM), AA(AA), TE(TE), PO(PO), EAFI(EAFI)
1191
+ EpilogueARCFunctionInfo *EAFI, bool disableArrayLoads)
1192
+ : Fn(F), PM(PM), AA(AA), TE(TE), PO(PO), EAFI(EAFI),
1193
+ ArrayType(disableArrayLoads ?
1194
+ F->getModule ().getASTContext().getArrayDecl() : nullptr)
1179
1195
#ifndef NDEBUG
1180
1196
,
1181
1197
printCtx (llvm::dbgs(), /* Verbose=*/ false, /* Sorted=*/ true)
@@ -1612,6 +1628,14 @@ namespace {
1612
1628
1613
1629
class RedundantLoadElimination : public SILFunctionTransform {
1614
1630
1631
+ private:
1632
+ bool disableArrayLoads;
1633
+
1634
+ public:
1635
+
1636
+ RedundantLoadElimination (bool disableArrayLoads)
1637
+ : disableArrayLoads(disableArrayLoads) { }
1638
+
1615
1639
// / The entry point to the transformation.
1616
1640
void run () override {
1617
1641
SILFunction *F = getFunction ();
@@ -1623,7 +1647,7 @@ class RedundantLoadElimination : public SILFunctionTransform {
1623
1647
auto *PO = PM->getAnalysis <PostOrderAnalysis>()->get (F);
1624
1648
auto *EAFI = PM->getAnalysis <EpilogueARCAnalysis>()->get (F);
1625
1649
1626
- RLEContext RLE (F, PM, AA, TE, PO, EAFI);
1650
+ RLEContext RLE (F, PM, AA, TE, PO, EAFI, disableArrayLoads );
1627
1651
if (RLE.run ()) {
1628
1652
invalidateAnalysis (SILAnalysis::InvalidationKind::Instructions);
1629
1653
}
@@ -1632,6 +1656,10 @@ class RedundantLoadElimination : public SILFunctionTransform {
1632
1656
1633
1657
} // end anonymous namespace
1634
1658
1659
+ SILTransform *swift::createEarlyRedundantLoadElimination () {
1660
+ return new RedundantLoadElimination (/* disableArrayLoads=*/ true );
1661
+ }
1662
+
1635
1663
SILTransform *swift::createRedundantLoadElimination () {
1636
- return new RedundantLoadElimination ();
1664
+ return new RedundantLoadElimination (/* disableArrayLoads= */ false );
1637
1665
}
0 commit comments