24
24
#include " llvm/Analysis/VectorUtils.h"
25
25
#include " llvm/IR/Intrinsics.h"
26
26
#include " llvm/IR/PatternMatch.h"
27
+ #include < deque>
27
28
28
29
using namespace llvm ;
29
30
@@ -892,9 +893,10 @@ void VPlanTransforms::clearReductionWrapFlags(VPlan &Plan) {
892
893
}
893
894
}
894
895
895
- // / Try to simplify recipe \p R. Returns any new recipes introduced during
896
- // / simplification, as a candidate for further simplification.
897
- static VPRecipeBase *simplifyRecipe (VPRecipeBase &R, VPTypeAnalysis &TypeInfo) {
896
+ // / Try to simplify recipe \p R. Returns any new recipes introduced during
897
+ // / simplification, as candidates for further simplification.
898
+ static SmallVector<VPRecipeBase *>
899
+ simplifyRecipe (VPRecipeBase &R, VPTypeAnalysis &TypeInfo, VPlan &Plan) {
898
900
using namespace llvm ::VPlanPatternMatch;
899
901
900
902
if (auto *Blend = dyn_cast<VPBlendRecipe>(&R)) {
@@ -909,11 +911,11 @@ static VPRecipeBase *simplifyRecipe(VPRecipeBase &R, VPTypeAnalysis &TypeInfo) {
909
911
if (UniqueValues.size () == 1 ) {
910
912
Blend->replaceAllUsesWith (*UniqueValues.begin ());
911
913
Blend->eraseFromParent ();
912
- return nullptr ;
914
+ return {} ;
913
915
}
914
916
915
917
if (Blend->isNormalized ())
916
- return nullptr ;
918
+ return {} ;
917
919
918
920
// Normalize the blend so its first incomming value is used as the initial
919
921
// value with the others blended into it.
@@ -937,7 +939,7 @@ static VPRecipeBase *simplifyRecipe(VPRecipeBase &R, VPTypeAnalysis &TypeInfo) {
937
939
Blend->replaceAllUsesWith (NewBlend);
938
940
Blend->eraseFromParent ();
939
941
recursivelyDeleteDeadRecipes (DeadMask);
940
- return nullptr ;
942
+ return {} ;
941
943
}
942
944
943
945
VPValue *A;
@@ -986,25 +988,74 @@ static VPRecipeBase *simplifyRecipe(VPRecipeBase &R, VPTypeAnalysis &TypeInfo) {
986
988
assert (TypeInfo.inferScalarType (VPV) == TypeInfo2.inferScalarType (VPV));
987
989
}
988
990
#endif
989
- return VPC;
991
+ if (VPC)
992
+ return {VPC};
993
+ return {};
994
+ }
995
+
996
+ VPValue *X, *X1, *Y, *Z;
997
+ LLVMContext &Ctx = TypeInfo.getContext ();
998
+
999
+ // (X || !X) -> true.
1000
+ if (match (&R, m_c_BinaryOr (m_VPValue (X), m_Not (m_VPValue (X1)))) && X == X1) {
1001
+ VPValue *VPV = Plan.getOrAddLiveIn (ConstantInt::getTrue (Ctx));
1002
+ R.getVPSingleValue ()->replaceAllUsesWith (VPV);
1003
+ return {};
1004
+ }
1005
+
1006
+ // (X || true) -> true.
1007
+ if (match (&R, m_c_BinaryOr (m_VPValue (X), m_True ()))) {
1008
+ VPValue *VPV = Plan.getOrAddLiveIn (ConstantInt::getTrue (Ctx));
1009
+ R.getVPSingleValue ()->replaceAllUsesWith (VPV);
1010
+ return {};
990
1011
}
991
1012
992
- // Simplify (X && Y) || (X && !Y) -> X.
993
- // TODO: Split up into simpler, modular combines: (X && Y) || (X && Z) into X
994
- // && (Y || Z) and (X || !X) into true. This requires queuing newly created
995
- // recipes to be visited during simplification.
996
- VPValue *X, *Y, *X1, *Y1;
997
- if (match (&R,
998
- m_c_BinaryOr (m_LogicalAnd (m_VPValue (X), m_VPValue (Y)),
999
- m_LogicalAnd (m_VPValue (X1), m_Not (m_VPValue (Y1))))) &&
1000
- X == X1 && Y == Y1) {
1013
+ // (X || false) -> X.
1014
+ if (match (&R, m_c_BinaryOr (m_VPValue (X), m_False ()))) {
1001
1015
R.getVPSingleValue ()->replaceAllUsesWith (X);
1002
- return nullptr ;
1016
+ return {} ;
1003
1017
}
1004
1018
1005
- if (match (&R, m_c_Mul (m_VPValue (A), m_SpecificInt (1 ))))
1006
- R.getVPSingleValue ()->replaceAllUsesWith (A);
1007
- return nullptr ;
1019
+ // (X && !X) -> false.
1020
+ if (match (&R, m_LogicalAnd (m_VPValue (X), m_Not (m_VPValue (X1)))) && X == X1) {
1021
+ VPValue *VPV = Plan.getOrAddLiveIn (ConstantInt::getFalse (Ctx));
1022
+ R.getVPSingleValue ()->replaceAllUsesWith (VPV);
1023
+ return {};
1024
+ }
1025
+
1026
+ // (X && true) -> X.
1027
+ if (match (&R, m_LogicalAnd (m_VPValue (X), m_True ()))) {
1028
+ R.getVPSingleValue ()->replaceAllUsesWith (X);
1029
+ return {};
1030
+ }
1031
+
1032
+ // (X && false) -> false.
1033
+ if (match (&R, m_LogicalAnd (m_VPValue (X), m_False ()))) {
1034
+ VPValue *VPV = Plan.getOrAddLiveIn (ConstantInt::getFalse (Ctx));
1035
+ R.getVPSingleValue ()->replaceAllUsesWith (VPV);
1036
+ return {};
1037
+ }
1038
+
1039
+ // (X * 1) -> X.
1040
+ if (match (&R, m_c_Mul (m_VPValue (X), m_SpecificInt (1 )))) {
1041
+ R.getVPSingleValue ()->replaceAllUsesWith (X);
1042
+ return {};
1043
+ }
1044
+
1045
+ // (X && Y) || (X && Z) -> X && (Y || Z).
1046
+ if (match (&R, m_BinaryOr (m_LogicalAnd (m_VPValue (X), m_VPValue (Y)),
1047
+ m_LogicalAnd (m_VPValue (X1), m_VPValue (Z)))) &&
1048
+ X == X1) {
1049
+ VPBuilder Builder (&R);
1050
+ VPInstruction *YorZ = Builder.createOr (Y, Z, R.getDebugLoc ());
1051
+ VPInstruction *VPI = Builder.createLogicalAnd (X, YorZ, R.getDebugLoc ());
1052
+ R.getVPSingleValue ()->replaceAllUsesWith (VPI);
1053
+ // Order of simplification matters: simplify sub-recipes before root
1054
+ // recipes.
1055
+ return {YorZ, VPI};
1056
+ }
1057
+
1058
+ return {};
1008
1059
}
1009
1060
1010
1061
// / Try to simplify the recipes in \p Plan.
@@ -1013,10 +1064,14 @@ static void simplifyRecipes(VPlan &Plan, LLVMContext &Ctx) {
1013
1064
Plan.getEntry ());
1014
1065
VPTypeAnalysis TypeInfo (Plan.getCanonicalIV ()->getScalarType (), Ctx);
1015
1066
for (VPBasicBlock *VPBB : VPBlockUtils::blocksOnly<VPBasicBlock>(RPOT)) {
1067
+ std::deque<VPRecipeBase *> Worklist;
1016
1068
for (auto &R : make_early_inc_range (*VPBB)) {
1017
- VPRecipeBase *NewR = simplifyRecipe (R, TypeInfo);
1018
- while (NewR)
1019
- NewR = simplifyRecipe (*NewR, TypeInfo);
1069
+ Worklist.emplace_front (&R);
1070
+ while (!Worklist.empty ()) {
1071
+ VPRecipeBase *R = Worklist.front ();
1072
+ Worklist.pop_front ();
1073
+ append_range (Worklist, simplifyRecipe (*R, TypeInfo, Plan));
1074
+ }
1020
1075
}
1021
1076
}
1022
1077
}
0 commit comments