1
0
mirror of https://github.com/RPCS3/llvm-mirror.git synced 2024-11-23 19:23:23 +01:00

[SLP] remove opcode field from reduction data class

This is NFC-intended and another step towards supporting
intrinsics as reduction candidates.

The remaining bits of the OperationData class do not make
much sense as-is, so I will try to improve that, but I'm
trying to take minimal steps because it's still not clear
how this was intended to work.
This commit is contained in:
Sanjay Patel 2021-01-16 13:51:55 -05:00
parent 8c16512468
commit 96dcca47c3

View File

@ -6430,40 +6430,15 @@ class HorizontalReduction {
// Use map vector to make stable output.
MapVector<Instruction *, Value *> ExtraArgs;
/// Contains info about operation, like its opcode, left and right operands.
/// This wraps functionality around a RecurKind (reduction kind).
/// TODO: Remove this class if callers can use the 'Kind' value directly?
class OperationData {
/// Opcode of the instruction.
unsigned Opcode = 0;
/// Kind of the reduction operation.
RecurKind Kind = RecurKind::None;
bool IsLeafValue = false;
/// Checks if the reduction operation can be vectorized.
bool isVectorizable() const {
switch (Kind) {
case RecurKind::Add:
return Opcode == Instruction::Add;
case RecurKind::Mul:
return Opcode == Instruction::Mul;
case RecurKind::Or:
return Opcode == Instruction::Or;
case RecurKind::And:
return Opcode == Instruction::And;
case RecurKind::Xor:
return Opcode == Instruction::Xor;
case RecurKind::FAdd:
return Opcode == Instruction::FAdd;
case RecurKind::FMul:
return Opcode == Instruction::FMul;
case RecurKind::SMax:
case RecurKind::SMin:
case RecurKind::UMax:
case RecurKind::UMin:
return Opcode == Instruction::ICmp;
default:
return false;
}
}
bool isVectorizable() const { return Kind != RecurKind::None; }
/// Creates reduction operation with the current opcode.
Value *createOp(IRBuilder<> &Builder, Value *LHS, Value *RHS,
@ -6505,19 +6480,17 @@ class HorizontalReduction {
public:
explicit OperationData() = default;
/// Construction for reduced values. They are identified by opcode only and
/// don't have associated LHS/RHS values.
explicit OperationData(Instruction &I) {
Opcode = I.getOpcode();
}
/// Constructor for reduced values. They are identified by the bool only.
explicit OperationData(Instruction &I) { IsLeafValue = true; }
/// Constructor for reduction operations with opcode and type.
OperationData(unsigned Opcode, RecurKind RdxKind)
: Opcode(Opcode), Kind(RdxKind) {
OperationData(RecurKind RdxKind) : Kind(RdxKind) {
assert(Kind != RecurKind::None && "Expected reduction operation.");
}
explicit operator bool() const { return Opcode; }
explicit operator bool() const {
return IsLeafValue || Kind != RecurKind::None;
}
/// Return true if this operation is any kind of minimum or maximum.
bool isMinMax() const {
@ -6580,8 +6553,7 @@ class HorizontalReduction {
/// Add all reduction operations for the reduction instruction \p I.
void addReductionOps(Instruction *I, ReductionOpsListType &ReductionOps) {
assert(Kind != RecurKind::None && !!*this &&
"Expected reduction operation.");
assert(Kind != RecurKind::None && "Expected reduction operation.");
if (isMinMax()) {
ReductionOps[0].emplace_back(cast<SelectInst>(I)->getCondition());
ReductionOps[1].emplace_back(I);
@ -6592,13 +6564,10 @@ class HorizontalReduction {
/// Checks if instruction is associative and can be vectorized.
bool isAssociative(Instruction *I) const {
assert(Kind != RecurKind::None && *this &&
"Expected reduction operation.");
if (RecurrenceDescriptor::isIntMinMaxRecurrenceKind(Kind)) {
assert(Opcode == Instruction::ICmp &&
"Only integer compare operation is expected.");
assert(Kind != RecurKind::None && "Expected reduction operation.");
if (RecurrenceDescriptor::isIntMinMaxRecurrenceKind(Kind))
return true;
}
return I->isAssociative();
}
@ -6610,9 +6579,7 @@ class HorizontalReduction {
/// Checks if two operation data are both a reduction op or both a reduced
/// value.
bool operator==(const OperationData &OD) const {
assert(((Kind != OD.Kind) || (Opcode != 0 && OD.Opcode != 0)) &&
"One of the comparing operations is incorrect.");
return Kind == OD.Kind && Opcode == OD.Opcode;
return Kind == OD.Kind && IsLeafValue == OD.IsLeafValue;
}
bool operator!=(const OperationData &OD) const { return !(*this == OD); }
@ -6696,28 +6663,28 @@ class HorizontalReduction {
TargetTransformInfo::ReductionFlags RdxFlags;
if (match(I, m_Add(m_Value(), m_Value())))
return OperationData(I->getOpcode(), RecurKind::Add);
return OperationData(RecurKind::Add);
if (match(I, m_Mul(m_Value(), m_Value())))
return OperationData(I->getOpcode(), RecurKind::Mul);
return OperationData(RecurKind::Mul);
if (match(I, m_And(m_Value(), m_Value())))
return OperationData(I->getOpcode(), RecurKind::And);
return OperationData(RecurKind::And);
if (match(I, m_Or(m_Value(), m_Value())))
return OperationData(I->getOpcode(), RecurKind::Or);
return OperationData(RecurKind::Or);
if (match(I, m_Xor(m_Value(), m_Value())))
return OperationData(I->getOpcode(), RecurKind::Xor);
return OperationData(RecurKind::Xor);
if (match(I, m_FAdd(m_Value(), m_Value())))
return OperationData(I->getOpcode(), RecurKind::FAdd);
return OperationData(RecurKind::FAdd);
if (match(I, m_FMul(m_Value(), m_Value())))
return OperationData(I->getOpcode(), RecurKind::FMul);
return OperationData(RecurKind::FMul);
if (match(I, m_SMax(m_Value(), m_Value())))
return OperationData(Instruction::ICmp, RecurKind::SMax);
return OperationData(RecurKind::SMax);
if (match(I, m_SMin(m_Value(), m_Value())))
return OperationData(Instruction::ICmp, RecurKind::SMin);
return OperationData(RecurKind::SMin);
if (match(I, m_UMax(m_Value(), m_Value())))
return OperationData(Instruction::ICmp, RecurKind::UMax);
return OperationData(RecurKind::UMax);
if (match(I, m_UMin(m_Value(), m_Value())))
return OperationData(Instruction::ICmp, RecurKind::UMin);
return OperationData(RecurKind::UMin);
if (auto *Select = dyn_cast<SelectInst>(I)) {
// Try harder: look for min/max pattern based on instructions producing
@ -6763,16 +6730,16 @@ class HorizontalReduction {
return OperationData(*I);
case CmpInst::ICMP_SGT:
case CmpInst::ICMP_SGE:
return OperationData(Instruction::ICmp, RecurKind::SMax);
return OperationData(RecurKind::SMax);
case CmpInst::ICMP_SLT:
case CmpInst::ICMP_SLE:
return OperationData(Instruction::ICmp, RecurKind::SMin);
return OperationData(RecurKind::SMin);
case CmpInst::ICMP_UGT:
case CmpInst::ICMP_UGE:
return OperationData(Instruction::ICmp, RecurKind::UMax);
return OperationData(RecurKind::UMax);
case CmpInst::ICMP_ULT:
case CmpInst::ICMP_ULE:
return OperationData(Instruction::ICmp, RecurKind::UMin);
return OperationData(RecurKind::UMin);
}
}
return OperationData(*I);