mirror of
https://github.com/llvm/llvm-project.git
synced 2025-04-17 08:06:40 +00:00
[VPlan] Make VPReductionRecipe a VPRecipeWithIRFlags. NFC (#130881)
This patch change the parent of the VPReductionRecipe from VPSingleDefRecipe to VPRecipeWithIRFlags and also print/get/drop/control flags by the VPRecipeWithIRFlags. This will remove the dependency of the underlying instruction. This patch also add a new function `setFastMathFlags()` to the VPRecipeWithIRFlags because the entire reduction chain may contains multiple instructions. And the underlying instruction may not contains the corresponding flags for this reduction. Split from #113903.
This commit is contained in:
parent
00cad3ed22
commit
ed19620b8c
@ -711,6 +711,8 @@ public:
|
||||
R->getVPDefID() == VPRecipeBase::VPWidenGEPSC ||
|
||||
R->getVPDefID() == VPRecipeBase::VPWidenCastSC ||
|
||||
R->getVPDefID() == VPRecipeBase::VPWidenIntrinsicSC ||
|
||||
R->getVPDefID() == VPRecipeBase::VPReductionSC ||
|
||||
R->getVPDefID() == VPRecipeBase::VPReductionEVLSC ||
|
||||
R->getVPDefID() == VPRecipeBase::VPReplicateSC ||
|
||||
R->getVPDefID() == VPRecipeBase::VPReverseVectorPointerSC ||
|
||||
R->getVPDefID() == VPRecipeBase::VPVectorPointerSC;
|
||||
@ -2236,7 +2238,7 @@ public:
|
||||
/// A recipe to represent inloop reduction operations, performing a reduction on
|
||||
/// a vector operand into a scalar value, and adding the result to a chain.
|
||||
/// The Operands are {ChainOp, VecOp, [Condition]}.
|
||||
class VPReductionRecipe : public VPSingleDefRecipe {
|
||||
class VPReductionRecipe : public VPRecipeWithIRFlags {
|
||||
/// The recurrence decriptor for the reduction in question.
|
||||
const RecurrenceDescriptor &RdxDesc;
|
||||
bool IsOrdered;
|
||||
@ -2247,12 +2249,17 @@ protected:
|
||||
VPReductionRecipe(const unsigned char SC, const RecurrenceDescriptor &R,
|
||||
Instruction *I, ArrayRef<VPValue *> Operands,
|
||||
VPValue *CondOp, bool IsOrdered, DebugLoc DL)
|
||||
: VPSingleDefRecipe(SC, Operands, I, DL), RdxDesc(R),
|
||||
IsOrdered(IsOrdered) {
|
||||
: VPRecipeWithIRFlags(SC, Operands,
|
||||
isa_and_nonnull<FPMathOperator>(I)
|
||||
? R.getFastMathFlags()
|
||||
: FastMathFlags(),
|
||||
DL),
|
||||
RdxDesc(R), IsOrdered(IsOrdered) {
|
||||
if (CondOp) {
|
||||
IsConditional = true;
|
||||
addOperand(CondOp);
|
||||
}
|
||||
setUnderlyingValue(I);
|
||||
}
|
||||
|
||||
public:
|
||||
@ -2318,12 +2325,13 @@ public:
|
||||
/// The Operands are {ChainOp, VecOp, EVL, [Condition]}.
|
||||
class VPReductionEVLRecipe : public VPReductionRecipe {
|
||||
public:
|
||||
VPReductionEVLRecipe(VPReductionRecipe &R, VPValue &EVL, VPValue *CondOp)
|
||||
VPReductionEVLRecipe(VPReductionRecipe &R, VPValue &EVL, VPValue *CondOp,
|
||||
DebugLoc DL = {})
|
||||
: VPReductionRecipe(
|
||||
VPDef::VPReductionEVLSC, R.getRecurrenceDescriptor(),
|
||||
cast_or_null<Instruction>(R.getUnderlyingValue()),
|
||||
ArrayRef<VPValue *>({R.getChainOp(), R.getVecOp(), &EVL}), CondOp,
|
||||
R.isOrdered(), R.getDebugLoc()) {}
|
||||
R.isOrdered(), DL) {}
|
||||
|
||||
~VPReductionEVLRecipe() override = default;
|
||||
|
||||
|
@ -2290,7 +2290,7 @@ void VPReductionRecipe::execute(VPTransformState &State) {
|
||||
"In-loop AnyOf reductions aren't currently supported");
|
||||
// Propagate the fast-math flags carried by the underlying instruction.
|
||||
IRBuilderBase::FastMathFlagGuard FMFGuard(State.Builder);
|
||||
State.Builder.setFastMathFlags(RdxDesc.getFastMathFlags());
|
||||
State.Builder.setFastMathFlags(getFastMathFlags());
|
||||
State.setDebugLocFrom(getDebugLoc());
|
||||
Value *NewVecOp = State.get(getVecOp());
|
||||
if (VPValue *Cond = getCondOp()) {
|
||||
@ -2337,7 +2337,7 @@ void VPReductionEVLRecipe::execute(VPTransformState &State) {
|
||||
// Propagate the fast-math flags carried by the underlying instruction.
|
||||
IRBuilderBase::FastMathFlagGuard FMFGuard(Builder);
|
||||
const RecurrenceDescriptor &RdxDesc = getRecurrenceDescriptor();
|
||||
Builder.setFastMathFlags(RdxDesc.getFastMathFlags());
|
||||
Builder.setFastMathFlags(getFastMathFlags());
|
||||
|
||||
RecurKind Kind = RdxDesc.getRecurrenceKind();
|
||||
Value *Prev = State.get(getChainOp(), /*IsScalar*/ true);
|
||||
@ -2374,6 +2374,7 @@ InstructionCost VPReductionRecipe::computeCost(ElementCount VF,
|
||||
Type *ElementTy = Ctx.Types.inferScalarType(this);
|
||||
auto *VectorTy = cast<VectorType>(toVectorTy(ElementTy, VF));
|
||||
unsigned Opcode = RdxDesc.getOpcode();
|
||||
FastMathFlags FMFs = getFastMathFlags();
|
||||
|
||||
// TODO: Support any-of and in-loop reductions.
|
||||
assert(
|
||||
@ -2393,12 +2394,12 @@ InstructionCost VPReductionRecipe::computeCost(ElementCount VF,
|
||||
Ctx.TTI.getArithmeticInstrCost(Opcode, ElementTy, Ctx.CostKind);
|
||||
if (RecurrenceDescriptor::isMinMaxRecurrenceKind(RdxKind)) {
|
||||
Intrinsic::ID Id = getMinMaxReductionIntrinsicOp(RdxKind);
|
||||
return Cost + Ctx.TTI.getMinMaxReductionCost(
|
||||
Id, VectorTy, RdxDesc.getFastMathFlags(), Ctx.CostKind);
|
||||
return Cost +
|
||||
Ctx.TTI.getMinMaxReductionCost(Id, VectorTy, FMFs, Ctx.CostKind);
|
||||
}
|
||||
|
||||
return Cost + Ctx.TTI.getArithmeticReductionCost(
|
||||
Opcode, VectorTy, RdxDesc.getFastMathFlags(), Ctx.CostKind);
|
||||
return Cost + Ctx.TTI.getArithmeticReductionCost(Opcode, VectorTy, FMFs,
|
||||
Ctx.CostKind);
|
||||
}
|
||||
|
||||
#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
|
||||
@ -2409,8 +2410,7 @@ void VPReductionRecipe::print(raw_ostream &O, const Twine &Indent,
|
||||
O << " = ";
|
||||
getChainOp()->printAsOperand(O, SlotTracker);
|
||||
O << " +";
|
||||
if (isa<FPMathOperator>(getUnderlyingInstr()))
|
||||
O << getUnderlyingInstr()->getFastMathFlags();
|
||||
printFlags(O);
|
||||
O << " reduce." << Instruction::getOpcodeName(RdxDesc.getOpcode()) << " (";
|
||||
getVecOp()->printAsOperand(O, SlotTracker);
|
||||
if (isConditional()) {
|
||||
@ -2431,8 +2431,7 @@ void VPReductionEVLRecipe::print(raw_ostream &O, const Twine &Indent,
|
||||
O << " = ";
|
||||
getChainOp()->printAsOperand(O, SlotTracker);
|
||||
O << " +";
|
||||
if (isa<FPMathOperator>(getUnderlyingInstr()))
|
||||
O << getUnderlyingInstr()->getFastMathFlags();
|
||||
printFlags(O);
|
||||
O << " vp.reduce." << Instruction::getOpcodeName(RdxDesc.getOpcode()) << " (";
|
||||
getVecOp()->printAsOperand(O, SlotTracker);
|
||||
O << ", ";
|
||||
|
@ -1165,22 +1165,27 @@ TEST_F(VPRecipeTest, MayHaveSideEffectsAndMayReadWriteMemory) {
|
||||
}
|
||||
|
||||
{
|
||||
auto *Add = BinaryOperator::CreateAdd(PoisonValue::get(Int32),
|
||||
PoisonValue::get(Int32));
|
||||
VPValue *ChainOp = Plan.getOrAddLiveIn(ConstantInt::get(Int32, 1));
|
||||
VPValue *VecOp = Plan.getOrAddLiveIn(ConstantInt::get(Int32, 2));
|
||||
VPValue *CondOp = Plan.getOrAddLiveIn(ConstantInt::get(Int32, 3));
|
||||
VPReductionRecipe Recipe(RecurrenceDescriptor(), nullptr, ChainOp, CondOp,
|
||||
VPReductionRecipe Recipe(RecurrenceDescriptor(), Add, ChainOp, CondOp,
|
||||
VecOp, false);
|
||||
EXPECT_FALSE(Recipe.mayHaveSideEffects());
|
||||
EXPECT_FALSE(Recipe.mayReadFromMemory());
|
||||
EXPECT_FALSE(Recipe.mayWriteToMemory());
|
||||
EXPECT_FALSE(Recipe.mayReadOrWriteMemory());
|
||||
delete Add;
|
||||
}
|
||||
|
||||
{
|
||||
auto *Add = BinaryOperator::CreateAdd(PoisonValue::get(Int32),
|
||||
PoisonValue::get(Int32));
|
||||
VPValue *ChainOp = Plan.getOrAddLiveIn(ConstantInt::get(Int32, 1));
|
||||
VPValue *VecOp = Plan.getOrAddLiveIn(ConstantInt::get(Int32, 2));
|
||||
VPValue *CondOp = Plan.getOrAddLiveIn(ConstantInt::get(Int32, 3));
|
||||
VPReductionRecipe Recipe(RecurrenceDescriptor(), nullptr, ChainOp, CondOp,
|
||||
VPReductionRecipe Recipe(RecurrenceDescriptor(), Add, ChainOp, CondOp,
|
||||
VecOp, false);
|
||||
VPValue *EVL = Plan.getOrAddLiveIn(ConstantInt::get(Int32, 4));
|
||||
VPReductionEVLRecipe EVLRecipe(Recipe, *EVL, CondOp);
|
||||
@ -1188,6 +1193,7 @@ TEST_F(VPRecipeTest, MayHaveSideEffectsAndMayReadWriteMemory) {
|
||||
EXPECT_FALSE(EVLRecipe.mayReadFromMemory());
|
||||
EXPECT_FALSE(EVLRecipe.mayWriteToMemory());
|
||||
EXPECT_FALSE(EVLRecipe.mayReadOrWriteMemory());
|
||||
delete Add;
|
||||
}
|
||||
|
||||
{
|
||||
@ -1529,28 +1535,34 @@ TEST_F(VPRecipeTest, dumpRecipeUnnamedVPValuesNotInPlanOrBlock) {
|
||||
|
||||
TEST_F(VPRecipeTest, CastVPReductionRecipeToVPUser) {
|
||||
IntegerType *Int32 = IntegerType::get(C, 32);
|
||||
auto *Add = BinaryOperator::CreateAdd(PoisonValue::get(Int32),
|
||||
PoisonValue::get(Int32));
|
||||
VPValue *ChainOp = getPlan().getOrAddLiveIn(ConstantInt::get(Int32, 1));
|
||||
VPValue *VecOp = getPlan().getOrAddLiveIn(ConstantInt::get(Int32, 2));
|
||||
VPValue *CondOp = getPlan().getOrAddLiveIn(ConstantInt::get(Int32, 3));
|
||||
VPReductionRecipe Recipe(RecurrenceDescriptor(), nullptr, ChainOp, CondOp,
|
||||
VecOp, false);
|
||||
VPReductionRecipe Recipe(RecurrenceDescriptor(), Add, ChainOp, CondOp, VecOp,
|
||||
false);
|
||||
EXPECT_TRUE(isa<VPUser>(&Recipe));
|
||||
VPRecipeBase *BaseR = &Recipe;
|
||||
EXPECT_TRUE(isa<VPUser>(BaseR));
|
||||
delete Add;
|
||||
}
|
||||
|
||||
TEST_F(VPRecipeTest, CastVPReductionEVLRecipeToVPUser) {
|
||||
IntegerType *Int32 = IntegerType::get(C, 32);
|
||||
auto *Add = BinaryOperator::CreateAdd(PoisonValue::get(Int32),
|
||||
PoisonValue::get(Int32));
|
||||
VPValue *ChainOp = getPlan().getOrAddLiveIn(ConstantInt::get(Int32, 1));
|
||||
VPValue *VecOp = getPlan().getOrAddLiveIn(ConstantInt::get(Int32, 2));
|
||||
VPValue *CondOp = getPlan().getOrAddLiveIn(ConstantInt::get(Int32, 3));
|
||||
VPReductionRecipe Recipe(RecurrenceDescriptor(), nullptr, ChainOp, CondOp,
|
||||
VecOp, false);
|
||||
VPReductionRecipe Recipe(RecurrenceDescriptor(), Add, ChainOp, CondOp, VecOp,
|
||||
false);
|
||||
VPValue *EVL = getPlan().getOrAddLiveIn(ConstantInt::get(Int32, 0));
|
||||
VPReductionEVLRecipe EVLRecipe(Recipe, *EVL, CondOp);
|
||||
EXPECT_TRUE(isa<VPUser>(&EVLRecipe));
|
||||
VPRecipeBase *BaseR = &EVLRecipe;
|
||||
EXPECT_TRUE(isa<VPUser>(BaseR));
|
||||
delete Add;
|
||||
}
|
||||
} // namespace
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user