@@ -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 @@ static 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
@@ -2727,6 +2736,65 @@ static bool hoistFPAssociation(Instruction &I, Loop &L,
2727
2736
return true ;
2728
2737
}
2729
2738
2739
+ static bool hoistIntAssociation (Instruction &I, Loop &L,
2740
+ ICFLoopSafetyInfo &SafetyInfo,
2741
+ MemorySSAUpdater &MSSAU, AssumptionCache *AC,
2742
+ DominatorTree *DT) {
2743
+ using namespace PatternMatch ;
2744
+ Value *VariantOp = nullptr , *InvariantOp = nullptr ;
2745
+
2746
+ if (!match (&I, m_Mul (m_Value (VariantOp), m_Value (InvariantOp))))
2747
+ return false ;
2748
+ if (L.isLoopInvariant (VariantOp))
2749
+ std::swap (VariantOp, InvariantOp);
2750
+ if (L.isLoopInvariant (VariantOp) || !L.isLoopInvariant (InvariantOp))
2751
+ return false ;
2752
+ Value *Factor = InvariantOp;
2753
+
2754
+ // First, we need to make sure we should do the transformation.
2755
+ SmallVector<Use *> Changes;
2756
+ SmallVector<BinaryOperator *> Worklist;
2757
+ if (BinaryOperator *VariantBinOp = dyn_cast<BinaryOperator>(VariantOp))
2758
+ Worklist.push_back (VariantBinOp);
2759
+ while (!Worklist.empty ()) {
2760
+ BinaryOperator *BO = Worklist.pop_back_val ();
2761
+ if (!BO->hasOneUse ())
2762
+ return false ;
2763
+ BinaryOperator *Op0, *Op1;
2764
+ if (match (BO, m_Add (m_BinOp (Op0), m_BinOp (Op1)))) {
2765
+ Worklist.push_back (Op0);
2766
+ Worklist.push_back (Op1);
2767
+ continue ;
2768
+ }
2769
+ if (BO->getOpcode () != Instruction::Mul || L.isLoopInvariant (BO))
2770
+ return false ;
2771
+ Use &U0 = BO->getOperandUse (0 );
2772
+ Use &U1 = BO->getOperandUse (1 );
2773
+ if (L.isLoopInvariant (U0))
2774
+ Changes.push_back (&U0);
2775
+ else if (L.isLoopInvariant (U1))
2776
+ Changes.push_back (&U1);
2777
+ else
2778
+ return false ;
2779
+ if (Changes.size () > IntAssociationUpperLimit)
2780
+ return false ;
2781
+ }
2782
+ if (Changes.empty ())
2783
+ return false ;
2784
+
2785
+ // We know we should do it so let's do the transformation.
2786
+ auto *Preheader = L.getLoopPreheader ();
2787
+ assert (Preheader && " Loop is not in simplify form?" );
2788
+ IRBuilder<> Builder (Preheader->getTerminator ());
2789
+ for (auto *U : Changes) {
2790
+ assert (L.isLoopInvariant (U->get ()));
2791
+ U->set (Builder.CreateMul (U->get (), Factor, " factor.op.mul" ));
2792
+ }
2793
+ I.replaceAllUsesWith (VariantOp);
2794
+ eraseInstruction (I, SafetyInfo, MSSAU);
2795
+ return true ;
2796
+ }
2797
+
2730
2798
static bool hoistArithmetics (Instruction &I, Loop &L,
2731
2799
ICFLoopSafetyInfo &SafetyInfo,
2732
2800
MemorySSAUpdater &MSSAU, AssumptionCache *AC,
@@ -2760,6 +2828,12 @@ static bool hoistArithmetics(Instruction &I, Loop &L,
2760
2828
return true ;
2761
2829
}
2762
2830
2831
+ if (hoistIntAssociation (I, L, SafetyInfo, MSSAU, AC, DT)) {
2832
+ ++NumHoisted;
2833
+ ++NumIntAssociationsHoisted;
2834
+ return true ;
2835
+ }
2836
+
2763
2837
return false ;
2764
2838
}
2765
2839
0 commit comments