Skip to content

Commit e9bf7a6

Browse files
committed
[SLP] reduce code duplication for min/max vs. other reductions; NFCI
1 parent 4e2ce22 commit e9bf7a6

File tree

1 file changed

+31
-77
lines changed

1 file changed

+31
-77
lines changed

llvm/lib/Transforms/Vectorize/SLPVectorizer.cpp

Lines changed: 31 additions & 77 deletions
Original file line numberDiff line numberDiff line change
@@ -6076,38 +6076,36 @@ class HorizontalReduction {
60766076

60776077
explicit operator bool() const { return Opcode; }
60786078

6079-
/// Get the index of the first operand.
6080-
unsigned getFirstOperandIndex() const {
6081-
assert(!!*this && "The opcode is not set.");
6079+
/// Return true if this operation is any kind of minimum or maximum.
6080+
bool isMinMax() const {
60826081
switch (Kind) {
6082+
case RK_Arithmetic:
6083+
return false;
60836084
case RK_Min:
6084-
case RK_UMin:
60856085
case RK_Max:
6086+
case RK_UMin:
60866087
case RK_UMax:
6087-
return 1;
6088-
case RK_Arithmetic:
6088+
return true;
60896089
case RK_None:
60906090
break;
60916091
}
6092-
return 0;
6092+
llvm_unreachable("Reduction kind is not set");
6093+
}
6094+
6095+
/// Get the index of the first operand.
6096+
unsigned getFirstOperandIndex() const {
6097+
assert(!!*this && "The opcode is not set.");
6098+
// We allow calling this before 'Kind' is set, so handle that specially.
6099+
if (Kind == RK_None)
6100+
return 0;
6101+
return isMinMax() ? 1 : 0;
60936102
}
60946103

60956104
/// Total number of operands in the reduction operation.
60966105
unsigned getNumberOfOperands() const {
60976106
assert(Kind != RK_None && !!*this && LHS && RHS &&
60986107
"Expected reduction operation.");
6099-
switch (Kind) {
6100-
case RK_Arithmetic:
6101-
return 2;
6102-
case RK_Min:
6103-
case RK_UMin:
6104-
case RK_Max:
6105-
case RK_UMax:
6106-
return 3;
6107-
case RK_None:
6108-
break;
6109-
}
6110-
llvm_unreachable("Reduction kind is not set");
6108+
return isMinMax() ? 3 : 2;
61116109
}
61126110

61136111
/// Checks if the operation has the same parent as \p P.
@@ -6116,79 +6114,46 @@ class HorizontalReduction {
61166114
"Expected reduction operation.");
61176115
if (!IsRedOp)
61186116
return I->getParent() == P;
6119-
switch (Kind) {
6120-
case RK_Arithmetic:
6121-
// Arithmetic reduction operation must be used once only.
6122-
return I->getParent() == P;
6123-
case RK_Min:
6124-
case RK_UMin:
6125-
case RK_Max:
6126-
case RK_UMax: {
6117+
if (isMinMax()) {
61276118
// SelectInst must be used twice while the condition op must have single
61286119
// use only.
61296120
auto *Cmp = cast<Instruction>(cast<SelectInst>(I)->getCondition());
61306121
return I->getParent() == P && Cmp && Cmp->getParent() == P;
61316122
}
6132-
case RK_None:
6133-
break;
6134-
}
6135-
llvm_unreachable("Reduction kind is not set");
6123+
// Arithmetic reduction operation must be used once only.
6124+
return I->getParent() == P;
61366125
}
6126+
61376127
/// Expected number of uses for reduction operations/reduced values.
61386128
bool hasRequiredNumberOfUses(Instruction *I, bool IsReductionOp) const {
61396129
assert(Kind != RK_None && !!*this && LHS && RHS &&
61406130
"Expected reduction operation.");
6141-
switch (Kind) {
6142-
case RK_Arithmetic:
6143-
return I->hasOneUse();
6144-
case RK_Min:
6145-
case RK_UMin:
6146-
case RK_Max:
6147-
case RK_UMax:
6131+
if (isMinMax())
61486132
return I->hasNUses(2) &&
61496133
(!IsReductionOp ||
61506134
cast<SelectInst>(I)->getCondition()->hasOneUse());
6151-
case RK_None:
6152-
break;
6153-
}
6154-
llvm_unreachable("Reduction kind is not set");
6135+
return I->hasOneUse();
61556136
}
61566137

61576138
/// Initializes the list of reduction operations.
61586139
void initReductionOps(ReductionOpsListType &ReductionOps) {
61596140
assert(Kind != RK_None && !!*this && LHS && RHS &&
61606141
"Expected reduction operation.");
6161-
switch (Kind) {
6162-
case RK_Arithmetic:
6163-
ReductionOps.assign(1, ReductionOpsType());
6164-
break;
6165-
case RK_Min:
6166-
case RK_UMin:
6167-
case RK_Max:
6168-
case RK_UMax:
6142+
if (isMinMax())
61696143
ReductionOps.assign(2, ReductionOpsType());
6170-
break;
6171-
case RK_None:
6172-
llvm_unreachable("Reduction kind is not set");
6173-
}
6144+
else
6145+
ReductionOps.assign(1, ReductionOpsType());
61746146
}
6147+
61756148
/// Add all reduction operations for the reduction instruction \p I.
61766149
void addReductionOps(Instruction *I, ReductionOpsListType &ReductionOps) {
61776150
assert(Kind != RK_None && !!*this && LHS && RHS &&
61786151
"Expected reduction operation.");
6179-
switch (Kind) {
6180-
case RK_Arithmetic:
6181-
ReductionOps[0].emplace_back(I);
6182-
break;
6183-
case RK_Min:
6184-
case RK_UMin:
6185-
case RK_Max:
6186-
case RK_UMax:
6152+
if (isMinMax()) {
61876153
ReductionOps[0].emplace_back(cast<SelectInst>(I)->getCondition());
61886154
ReductionOps[1].emplace_back(I);
6189-
break;
6190-
case RK_None:
6191-
llvm_unreachable("Reduction kind is not set");
6155+
} else {
6156+
ReductionOps[0].emplace_back(I);
61926157
}
61936158
}
61946159

@@ -6246,18 +6211,7 @@ class HorizontalReduction {
62466211
Value *getLHS() const { return LHS; }
62476212
Value *getRHS() const { return RHS; }
62486213
Type *getConditionType() const {
6249-
switch (Kind) {
6250-
case RK_Arithmetic:
6251-
return nullptr;
6252-
case RK_Min:
6253-
case RK_Max:
6254-
case RK_UMin:
6255-
case RK_UMax:
6256-
return CmpInst::makeCmpResultType(LHS->getType());
6257-
case RK_None:
6258-
break;
6259-
}
6260-
llvm_unreachable("Reduction kind is not set");
6214+
return isMinMax() ? CmpInst::makeCmpResultType(LHS->getType()) : nullptr;
62616215
}
62626216

62636217
/// Creates reduction operation with the current opcode with the IR flags

0 commit comments

Comments
 (0)