@@ -110,6 +110,9 @@ STATISTIC(NumAddSubHoisted, "Number of add/subtract expressions reassociated "
110
110
" and hoisted out of the loop" );
111
111
STATISTIC (NumFPAssociationsHoisted, " Number of invariant FP expressions "
112
112
" reassociated and hoisted out of the loop" );
113
+ STATISTIC (NumIntAssociationsHoisted,
114
+ " Number of invariant int expressions "
115
+ " reassociated and hoisted out of the loop" );
113
116
114
117
// / Memory promotion is enabled by default.
115
118
static cl::opt<bool >
@@ -135,6 +138,12 @@ cl::opt<unsigned> FPAssociationUpperLimit(
135
138
" Set upper limit for the number of transformations performed "
136
139
" during a single round of hoisting the reassociated expressions." ));
137
140
141
+ cl::opt<unsigned > IntAssociationUpperLimit (
142
+ " licm-max-num-int-reassociations" , cl::init(5U ), cl::Hidden,
143
+ cl::desc(
144
+ " Set upper limit for the number of transformations performed "
145
+ " during a single round of hoisting the reassociated expressions." ));
146
+
138
147
// Experimental option to allow imprecision in LICM in pathological cases, in
139
148
// exchange for faster compile. This is to be removed if MemorySSA starts to
140
149
// address the same issue. LICM calls MemorySSAWalker's
@@ -2719,6 +2728,65 @@ static bool hoistFPAssociation(Instruction &I, Loop &L,
2719
2728
return true ;
2720
2729
}
2721
2730
2731
+ static bool hoistIntAssociation (Instruction &I, Loop &L,
2732
+ ICFLoopSafetyInfo &SafetyInfo,
2733
+ MemorySSAUpdater &MSSAU, AssumptionCache *AC,
2734
+ DominatorTree *DT) {
2735
+ using namespace PatternMatch ;
2736
+ Value *VariantOp = nullptr , *InvariantOp = nullptr ;
2737
+
2738
+ if (!match (&I, m_Mul (m_Value (VariantOp), m_Value (InvariantOp))))
2739
+ return false ;
2740
+ if (L.isLoopInvariant (VariantOp))
2741
+ std::swap (VariantOp, InvariantOp);
2742
+ if (L.isLoopInvariant (VariantOp) || !L.isLoopInvariant (InvariantOp))
2743
+ return false ;
2744
+ Value *Factor = InvariantOp;
2745
+
2746
+ // First, we need to make sure we should do the transformation.
2747
+ SmallVector<Use *> Changes;
2748
+ SmallVector<BinaryOperator *> Worklist;
2749
+ if (BinaryOperator *VariantBinOp = dyn_cast<BinaryOperator>(VariantOp))
2750
+ Worklist.push_back (VariantBinOp);
2751
+ while (!Worklist.empty ()) {
2752
+ BinaryOperator *BO = Worklist.pop_back_val ();
2753
+ if (!BO->hasOneUse ())
2754
+ return false ;
2755
+ BinaryOperator *Op0, *Op1;
2756
+ if (match (BO, m_Add (m_BinOp (Op0), m_BinOp (Op1)))) {
2757
+ Worklist.push_back (Op0);
2758
+ Worklist.push_back (Op1);
2759
+ continue ;
2760
+ }
2761
+ if (BO->getOpcode () != Instruction::Mul || L.isLoopInvariant (BO))
2762
+ return false ;
2763
+ Use &U0 = BO->getOperandUse (0 );
2764
+ Use &U1 = BO->getOperandUse (1 );
2765
+ if (L.isLoopInvariant (U0))
2766
+ Changes.push_back (&U0);
2767
+ else if (L.isLoopInvariant (U1))
2768
+ Changes.push_back (&U1);
2769
+ else
2770
+ return false ;
2771
+ if (Changes.size () > IntAssociationUpperLimit)
2772
+ return false ;
2773
+ }
2774
+ if (Changes.empty ())
2775
+ return false ;
2776
+
2777
+ // We know we should do it so let's do the transformation.
2778
+ auto *Preheader = L.getLoopPreheader ();
2779
+ assert (Preheader && " Loop is not in simplify form?" );
2780
+ IRBuilder<> Builder (Preheader->getTerminator ());
2781
+ for (auto *U : Changes) {
2782
+ assert (L.isLoopInvariant (U->get ()));
2783
+ U->set (Builder.CreateMul (U->get (), Factor, " factor.op.mul" ));
2784
+ }
2785
+ I.replaceAllUsesWith (VariantOp);
2786
+ eraseInstruction (I, SafetyInfo, MSSAU);
2787
+ return true ;
2788
+ }
2789
+
2722
2790
static bool hoistArithmetics (Instruction &I, Loop &L,
2723
2791
ICFLoopSafetyInfo &SafetyInfo,
2724
2792
MemorySSAUpdater &MSSAU, AssumptionCache *AC,
@@ -2752,6 +2820,12 @@ static bool hoistArithmetics(Instruction &I, Loop &L,
2752
2820
return true ;
2753
2821
}
2754
2822
2823
+ if (hoistIntAssociation (I, L, SafetyInfo, MSSAU, AC, DT)) {
2824
+ ++NumHoisted;
2825
+ ++NumIntAssociationsHoisted;
2826
+ return true ;
2827
+ }
2828
+
2755
2829
return false ;
2756
2830
}
2757
2831
0 commit comments