Skip to content

Commit 714673c

Browse files
committed
VPlan: introduce worklist in simplifyRecipes
In order to break up patterns in simplifyRecipes, and increase its simplification power, introudce a worklist keeping a running list of candidates for simplification, as a prelude to breaking up patterns in simplifyRecipe.
1 parent 4f07508 commit 714673c

File tree

1 file changed

+26
-12
lines changed

1 file changed

+26
-12
lines changed

llvm/lib/Transforms/Vectorize/VPlanTransforms.cpp

Lines changed: 26 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -892,8 +892,9 @@ void VPlanTransforms::clearReductionWrapFlags(VPlan &Plan) {
892892
}
893893
}
894894

895-
/// Try to simplify recipe \p R.
896-
static void simplifyRecipe(VPRecipeBase &R, VPTypeAnalysis &TypeInfo) {
895+
/// Try to simplify recipe \p R. Returns candidates for further simplification.
896+
static SmallVector<VPRecipeBase *> simplifyRecipe(VPRecipeBase &R,
897+
VPTypeAnalysis &TypeInfo) {
897898
using namespace llvm::VPlanPatternMatch;
898899

899900
if (auto *Blend = dyn_cast<VPBlendRecipe>(&R)) {
@@ -908,11 +909,11 @@ static void simplifyRecipe(VPRecipeBase &R, VPTypeAnalysis &TypeInfo) {
908909
if (UniqueValues.size() == 1) {
909910
Blend->replaceAllUsesWith(*UniqueValues.begin());
910911
Blend->eraseFromParent();
911-
return;
912+
return {};
912913
}
913914

914915
if (Blend->isNormalized())
915-
return;
916+
return {};
916917

917918
// Normalize the blend so its first incomming value is used as the initial
918919
// value with the others blended into it.
@@ -936,26 +937,27 @@ static void simplifyRecipe(VPRecipeBase &R, VPTypeAnalysis &TypeInfo) {
936937
Blend->replaceAllUsesWith(NewBlend);
937938
Blend->eraseFromParent();
938939
recursivelyDeleteDeadRecipes(DeadMask);
939-
return;
940+
return {};
940941
}
941942

942943
VPValue *A;
943944
if (match(&R, m_Trunc(m_ZExtOrSExt(m_VPValue(A))))) {
944945
VPValue *Trunc = R.getVPSingleValue();
945946
Type *TruncTy = TypeInfo.inferScalarType(Trunc);
946947
Type *ATy = TypeInfo.inferScalarType(A);
948+
VPWidenCastRecipe *VPC = nullptr;
947949
if (TruncTy == ATy) {
948950
Trunc->replaceAllUsesWith(A);
949951
} else {
950952
// Don't replace a scalarizing recipe with a widened cast.
951953
if (isa<VPReplicateRecipe>(&R))
952-
return;
954+
return {};
953955
if (ATy->getScalarSizeInBits() < TruncTy->getScalarSizeInBits()) {
954956

955957
unsigned ExtOpcode = match(R.getOperand(0), m_SExt(m_VPValue()))
956958
? Instruction::SExt
957959
: Instruction::ZExt;
958-
auto *VPC =
960+
VPC =
959961
new VPWidenCastRecipe(Instruction::CastOps(ExtOpcode), A, TruncTy);
960962
if (auto *UnderlyingExt = R.getOperand(0)->getUnderlyingValue()) {
961963
// UnderlyingExt has distinct return type, used to retain legacy cost.
@@ -964,7 +966,7 @@ static void simplifyRecipe(VPRecipeBase &R, VPTypeAnalysis &TypeInfo) {
964966
VPC->insertBefore(&R);
965967
Trunc->replaceAllUsesWith(VPC);
966968
} else if (ATy->getScalarSizeInBits() > TruncTy->getScalarSizeInBits()) {
967-
auto *VPC = new VPWidenCastRecipe(Instruction::Trunc, A, TruncTy);
969+
VPC = new VPWidenCastRecipe(Instruction::Trunc, A, TruncTy);
968970
VPC->insertBefore(&R);
969971
Trunc->replaceAllUsesWith(VPC);
970972
}
@@ -984,6 +986,9 @@ static void simplifyRecipe(VPRecipeBase &R, VPTypeAnalysis &TypeInfo) {
984986
assert(TypeInfo.inferScalarType(VPV) == TypeInfo2.inferScalarType(VPV));
985987
}
986988
#endif
989+
if (VPC)
990+
return {VPC};
991+
return {};
987992
}
988993

989994
// Simplify (X && Y) || (X && !Y) -> X.
@@ -996,11 +1001,12 @@ static void simplifyRecipe(VPRecipeBase &R, VPTypeAnalysis &TypeInfo) {
9961001
m_LogicalAnd(m_VPValue(X1), m_Not(m_VPValue(Y1))))) &&
9971002
X == X1 && Y == Y1) {
9981003
R.getVPSingleValue()->replaceAllUsesWith(X);
999-
return;
1004+
return {};
10001005
}
10011006

10021007
if (match(&R, m_c_Mul(m_VPValue(A), m_SpecificInt(1))))
1003-
return R.getVPSingleValue()->replaceAllUsesWith(A);
1008+
R.getVPSingleValue()->replaceAllUsesWith(A);
1009+
return {};
10041010
}
10051011

10061012
/// Try to simplify the recipes in \p Plan.
@@ -1009,8 +1015,16 @@ static void simplifyRecipes(VPlan &Plan, LLVMContext &Ctx) {
10091015
Plan.getEntry());
10101016
VPTypeAnalysis TypeInfo(Plan.getCanonicalIV()->getScalarType(), Ctx);
10111017
for (VPBasicBlock *VPBB : VPBlockUtils::blocksOnly<VPBasicBlock>(RPOT)) {
1012-
for (VPRecipeBase &R : make_early_inc_range(*VPBB)) {
1013-
simplifyRecipe(R, TypeInfo);
1018+
// Populate a Worklist, as simplifyRecipe might return a new recipe that we
1019+
// need to re-process.
1020+
SmallVector<VPRecipeBase *> Worklist;
1021+
for (auto &R : VPBB->getRecipeList())
1022+
Worklist.push_back(&R);
1023+
1024+
while (!Worklist.empty()) {
1025+
VPRecipeBase *R = Worklist.pop_back_val();
1026+
for (VPRecipeBase *Cand : simplifyRecipe(*R, TypeInfo))
1027+
Worklist.push_back(Cand);
10141028
}
10151029
}
10161030
}

0 commit comments

Comments
 (0)