@@ -173,11 +173,11 @@ class SelectOptimizeImpl {
173
173
return getTrueValue (/* HonorInverts=*/ false );
174
174
if (auto *Sel = dyn_cast<SelectInst>(I))
175
175
return Sel->getFalseValue ();
176
- // Or(zext) case - return the operand which is not the zext.
177
- if (auto *BO = dyn_cast<BinaryOperator>(I)) {
178
- // Return non-dependant on condition operand
176
+ // We are on the branch where the condition is zero, which means BinOp
177
+ // does not perform any computation, and we can simply return the operand
178
+ // that is not related to the condition
179
+ if (auto *BO = dyn_cast<BinaryOperator>(I))
179
180
return BO->getOperand (1 - CondIdx);
180
- }
181
181
182
182
llvm_unreachable (" Unhandled case in getFalseValue" );
183
183
}
@@ -199,7 +199,7 @@ class SelectOptimizeImpl {
199
199
}
200
200
// If getTrue(False)Value() return nullptr, it means we are dealing with
201
201
// select-like instructions on the branch where the actual computation is
202
- // happening In that case the cost is equal to the cost of computation +
202
+ // happening. In that case the cost is equal to the cost of computation +
203
203
// cost of non-dependant on condition operand
204
204
InstructionCost Cost = TTI->getArithmeticInstrCost (
205
205
getI ()->getOpcode (), I->getType (), TargetTransformInfo::TCK_Latency,
@@ -208,9 +208,8 @@ class SelectOptimizeImpl {
208
208
auto TotalCost = Scaled64::get (*Cost.getValue ());
209
209
if (auto *OpI = dyn_cast<Instruction>(I->getOperand (1 - CondIdx))) {
210
210
auto It = InstCostMap.find (OpI);
211
- if (It != InstCostMap.end ()) {
211
+ if (It != InstCostMap.end ())
212
212
TotalCost += It->second .NonPredCost ;
213
- }
214
213
}
215
214
return TotalCost;
216
215
}
@@ -774,65 +773,69 @@ void SelectOptimizeImpl::collectSelectGroups(BasicBlock &BB,
774
773
SmallPtrSet<Instruction *, 2 > SeenCmp;
775
774
std::map<Value *, SelectLikeInfo> SelectInfo;
776
775
777
- BasicBlock::iterator BBIt = BB.begin ();
778
- while (BBIt != BB.end ()) {
779
- Instruction *I = &*BBIt++;
776
+ auto ProcessSelectInfo = [&SeenCmp, &SelectInfo](Instruction *I) -> void {
780
777
if (auto *Cmp = dyn_cast<CmpInst>(I)) {
781
778
SeenCmp.insert (Cmp);
782
- continue ;
779
+ return ;
783
780
}
784
781
785
782
Value *Cond;
786
783
if (match (I, m_OneUse (m_ZExt (m_Value (Cond)))) &&
787
784
Cond->getType ()->isIntegerTy (1 )) {
788
785
bool Inverted = match (Cond, m_Not (m_Value (Cond)));
789
786
SelectInfo[I] = {Cond, true , Inverted, 0 };
790
- continue ;
787
+ return ;
791
788
}
792
789
793
790
if (match (I, m_Not (m_Value (Cond)))) {
794
791
SelectInfo[I] = {Cond, true , true , 0 };
795
- continue ;
792
+ return ;
796
793
}
797
794
798
795
// Select instruction are what we are usually looking for.
799
796
if (match (I, m_Select (m_Value (Cond), m_Value (), m_Value ()))) {
800
797
bool Inverted = match (Cond, m_Not (m_Value (Cond)));
801
798
SelectInfo[I] = {Cond, false , Inverted, 0 };
802
- continue ;
799
+ return ;
803
800
}
804
801
805
- // An Or(zext(i1 X), Y) can also be treated like a select, with condition
802
+ // An Or(zext(i1 X), Y) can also be treated like a select, with condition X
803
+ // and values Y|1 and Y.
806
804
if (auto *BO = dyn_cast<BinaryOperator>(I)) {
807
805
if (BO->getType ()->isIntegerTy (1 ) || BO->getOpcode () != Instruction::Or)
808
- continue ;
806
+ return ;
809
807
810
808
for (unsigned Idx = 0 ; Idx < 2 ; Idx++) {
811
809
auto *Op = BO->getOperand (Idx);
812
- if (SelectInfo.count (Op) && SelectInfo[Op].IsAuxiliary ) {
813
- Cond = SelectInfo[Op].Cond ;
814
- bool Inverted = SelectInfo[Op].IsInverted ;
815
- SelectInfo[I] = {Cond, false , Inverted, Idx};
810
+ auto It = SelectInfo.find (Op);
811
+ if (It != SelectInfo.end () && It->second .IsAuxiliary ) {
812
+ SelectInfo[I] = {It->second .Cond , false , It->second .IsInverted , Idx};
816
813
break ;
817
814
}
818
815
}
819
- continue ;
820
816
}
821
- }
817
+ };
822
818
823
- BBIt = BB.begin ();
819
+ bool AlreadyProcessed = false ;
820
+ BasicBlock::iterator BBIt = BB.begin ();
824
821
while (BBIt != BB.end ()) {
825
822
Instruction *I = &*BBIt++;
826
- if (!SelectInfo.count (I) || SelectInfo[I].IsAuxiliary )
823
+ if (!AlreadyProcessed)
824
+ ProcessSelectInfo (I);
825
+ else
826
+ AlreadyProcessed = false ;
827
+
828
+ auto It = SelectInfo.find (I);
829
+ if (It == SelectInfo.end () || It->second .IsAuxiliary )
827
830
continue ;
828
831
829
832
if (!TTI->shouldTreatInstructionLikeSelect (I))
830
833
continue ;
831
834
832
- Value *Cond = SelectInfo[I] .Cond ;
835
+ Value *Cond = It-> second .Cond ;
833
836
SelectGroup SIGroup{Cond};
834
- SIGroup.Selects .emplace_back (I, SelectInfo[I] .IsInverted ,
835
- SelectInfo[I] .ConditionIdx );
837
+ SIGroup.Selects .emplace_back (I, It-> second .IsInverted ,
838
+ It-> second .ConditionIdx );
836
839
837
840
if (!Cond->getType ()->isIntegerTy (1 ))
838
841
continue ;
@@ -844,20 +847,26 @@ void SelectOptimizeImpl::collectSelectGroups(BasicBlock &BB,
844
847
845
848
while (BBIt != BB.end ()) {
846
849
Instruction *NI = &*BBIt;
850
+ ProcessSelectInfo (NI);
847
851
// Debug/pseudo instructions should be skipped and not prevent the
848
852
// formation of a select group.
849
853
if (NI->isDebugOrPseudoInst ()) {
850
854
++BBIt;
851
855
continue ;
852
856
}
853
857
854
- if (!SelectInfo.count (NI))
858
+ It = SelectInfo.find (NI);
859
+ if (It == SelectInfo.end ()) {
860
+ AlreadyProcessed = true ;
855
861
break ;
862
+ }
856
863
857
864
// Auxiliary with same condition
858
- auto [CurrCond, IsAux, IsRev, CondIdx] = SelectInfo[NI];
859
- if (Cond != CurrCond)
865
+ auto [CurrCond, IsAux, IsRev, CondIdx] = It->second ;
866
+ if (Cond != CurrCond) {
867
+ AlreadyProcessed = true ;
860
868
break ;
869
+ }
861
870
862
871
if (!IsAux)
863
872
SIGroup.Selects .emplace_back (NI, IsRev, CondIdx);
0 commit comments