Skip to content

Commit 3953216

Browse files
committed
[TTI][RISCV] Deduplicate type-based VP costing
We have a lot of code in RISCVTTIImpl::getIntrinsicInstrCost for vp intrinsics, which just forward the cost to the underlying non-vp cost function. However I just also noticed that there is generic code in BasicTTIImpl's getIntrinsicInstrCost that does the same thing, added in #67178. The only difference is that BasicTTIImpl doesn't yet handle it for type-based costing. There doesn't seem to be any reason that it can't since it's just inspecting the argument types. This shuffles the VP costing up to handle both regular and type-based costing, and begins to deduplicate the VP specific costing in RISCVTTIImpl by moving them into BasicTTIImpl.h. It's not NFC since it picks up a couple of VP nodes that had slipped through the cracks. Future PRs can begin to move more of the code from RISCVTTIImpl to BasicTTIImpl.
1 parent f9125dd commit 3953216

File tree

3 files changed

+109
-153
lines changed

3 files changed

+109
-153
lines changed

llvm/include/llvm/CodeGen/BasicTTIImpl.h

Lines changed: 61 additions & 62 deletions
Original file line numberDiff line numberDiff line change
@@ -1563,6 +1563,67 @@ class BasicTTIImplBase : public TargetTransformInfoImplCRTPBase<T> {
15631563
if (Intrinsic::isTargetIntrinsic(IID))
15641564
return TargetTransformInfo::TCC_Basic;
15651565

1566+
// VP Intrinsics should have the same cost as their non-vp counterpart.
1567+
// TODO: Adjust the cost to make the vp intrinsic cheaper than its non-vp
1568+
// counterpart when the vector length argument is smaller than the maximum
1569+
// vector length.
1570+
// TODO: Support other kinds of VPIntrinsics
1571+
if (VPIntrinsic::isVPIntrinsic(ICA.getID())) {
1572+
std::optional<unsigned> FOp =
1573+
VPIntrinsic::getFunctionalOpcodeForVP(ICA.getID());
1574+
if (FOp) {
1575+
if (ICA.getID() == Intrinsic::vp_load) {
1576+
Align Alignment;
1577+
if (auto *VPI = dyn_cast_or_null<VPIntrinsic>(ICA.getInst()))
1578+
Alignment = VPI->getPointerAlignment().valueOrOne();
1579+
unsigned AS = 0;
1580+
if (ICA.getArgTypes().size() > 1)
1581+
if (auto *PtrTy = dyn_cast<PointerType>(ICA.getArgTypes()[0]))
1582+
AS = PtrTy->getAddressSpace();
1583+
return thisT()->getMemoryOpCost(*FOp, ICA.getReturnType(), Alignment,
1584+
AS, CostKind);
1585+
}
1586+
if (ICA.getID() == Intrinsic::vp_store) {
1587+
Align Alignment;
1588+
if (auto *VPI = dyn_cast_or_null<VPIntrinsic>(ICA.getInst()))
1589+
Alignment = VPI->getPointerAlignment().valueOrOne();
1590+
unsigned AS = 0;
1591+
if (ICA.getArgTypes().size() >= 2)
1592+
if (auto *PtrTy = dyn_cast<PointerType>(ICA.getArgTypes()[1]))
1593+
AS = PtrTy->getAddressSpace();
1594+
return thisT()->getMemoryOpCost(*FOp, ICA.getArgTypes()[0], Alignment,
1595+
AS, CostKind);
1596+
}
1597+
if (VPBinOpIntrinsic::isVPBinOp(ICA.getID())) {
1598+
return thisT()->getArithmeticInstrCost(*FOp, ICA.getReturnType(),
1599+
CostKind);
1600+
}
1601+
}
1602+
1603+
std::optional<Intrinsic::ID> FID =
1604+
VPIntrinsic::getFunctionalIntrinsicIDForVP(ICA.getID());
1605+
if (FID) {
1606+
// Non-vp version will have same arg types except mask and vector
1607+
// length.
1608+
assert(ICA.getArgTypes().size() >= 2 &&
1609+
"Expected VPIntrinsic to have Mask and Vector Length args and "
1610+
"types");
1611+
ArrayRef<Type *> NewTys = ArrayRef(ICA.getArgTypes()).drop_back(2);
1612+
1613+
// VPReduction intrinsics have a start value argument that their non-vp
1614+
// counterparts do not have, except for the fadd and fmul non-vp
1615+
// counterpart.
1616+
if (VPReductionIntrinsic::isVPReduction(ICA.getID()) &&
1617+
*FID != Intrinsic::vector_reduce_fadd &&
1618+
*FID != Intrinsic::vector_reduce_fmul)
1619+
NewTys = NewTys.drop_front();
1620+
1621+
IntrinsicCostAttributes NewICA(*FID, ICA.getReturnType(), NewTys,
1622+
ICA.getFlags());
1623+
return thisT()->getIntrinsicInstrCost(NewICA, CostKind);
1624+
}
1625+
}
1626+
15661627
if (ICA.isTypeBasedOnly())
15671628
return getTypeBasedIntrinsicInstrCost(ICA, CostKind);
15681629

@@ -1823,68 +1884,6 @@ class BasicTTIImplBase : public TargetTransformInfoImplCRTPBase<T> {
18231884
}
18241885
}
18251886

1826-
// VP Intrinsics should have the same cost as their non-vp counterpart.
1827-
// TODO: Adjust the cost to make the vp intrinsic cheaper than its non-vp
1828-
// counterpart when the vector length argument is smaller than the maximum
1829-
// vector length.
1830-
// TODO: Support other kinds of VPIntrinsics
1831-
if (VPIntrinsic::isVPIntrinsic(ICA.getID())) {
1832-
std::optional<unsigned> FOp =
1833-
VPIntrinsic::getFunctionalOpcodeForVP(ICA.getID());
1834-
if (FOp) {
1835-
if (ICA.getID() == Intrinsic::vp_load) {
1836-
Align Alignment;
1837-
if (auto *VPI = dyn_cast_or_null<VPIntrinsic>(ICA.getInst()))
1838-
Alignment = VPI->getPointerAlignment().valueOrOne();
1839-
unsigned AS = 0;
1840-
if (ICA.getArgs().size() > 1)
1841-
if (auto *PtrTy =
1842-
dyn_cast<PointerType>(ICA.getArgs()[0]->getType()))
1843-
AS = PtrTy->getAddressSpace();
1844-
return thisT()->getMemoryOpCost(*FOp, ICA.getReturnType(), Alignment,
1845-
AS, CostKind);
1846-
}
1847-
if (ICA.getID() == Intrinsic::vp_store) {
1848-
Align Alignment;
1849-
if (auto *VPI = dyn_cast_or_null<VPIntrinsic>(ICA.getInst()))
1850-
Alignment = VPI->getPointerAlignment().valueOrOne();
1851-
unsigned AS = 0;
1852-
if (ICA.getArgs().size() >= 2)
1853-
if (auto *PtrTy =
1854-
dyn_cast<PointerType>(ICA.getArgs()[1]->getType()))
1855-
AS = PtrTy->getAddressSpace();
1856-
return thisT()->getMemoryOpCost(*FOp, Args[0]->getType(), Alignment,
1857-
AS, CostKind);
1858-
}
1859-
if (VPBinOpIntrinsic::isVPBinOp(ICA.getID())) {
1860-
return thisT()->getArithmeticInstrCost(*FOp, ICA.getReturnType(),
1861-
CostKind);
1862-
}
1863-
}
1864-
1865-
std::optional<Intrinsic::ID> FID =
1866-
VPIntrinsic::getFunctionalIntrinsicIDForVP(ICA.getID());
1867-
if (FID) {
1868-
// Non-vp version will have same Args/Tys except mask and vector length.
1869-
assert(ICA.getArgs().size() >= 2 && ICA.getArgTypes().size() >= 2 &&
1870-
"Expected VPIntrinsic to have Mask and Vector Length args and "
1871-
"types");
1872-
ArrayRef<Type *> NewTys = ArrayRef(ICA.getArgTypes()).drop_back(2);
1873-
1874-
// VPReduction intrinsics have a start value argument that their non-vp
1875-
// counterparts do not have, except for the fadd and fmul non-vp
1876-
// counterpart.
1877-
if (VPReductionIntrinsic::isVPReduction(ICA.getID()) &&
1878-
*FID != Intrinsic::vector_reduce_fadd &&
1879-
*FID != Intrinsic::vector_reduce_fmul)
1880-
NewTys = NewTys.drop_front();
1881-
1882-
IntrinsicCostAttributes NewICA(*FID, ICA.getReturnType(), NewTys,
1883-
ICA.getFlags());
1884-
return thisT()->getIntrinsicInstrCost(NewICA, CostKind);
1885-
}
1886-
}
1887-
18881887
// Assume that we need to scalarize this intrinsic.)
18891888
// Compute the scalarization overhead based on Args for a vector
18901889
// intrinsic.

llvm/lib/Target/RISCV/RISCVTargetTransformInfo.cpp

Lines changed: 0 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -1104,32 +1104,6 @@ RISCVTTIImpl::getIntrinsicInstrCost(const IntrinsicCostAttributes &ICA,
11041104
return Cost * LT.first;
11051105
break;
11061106
}
1107-
// vp integer arithmetic ops.
1108-
case Intrinsic::vp_add:
1109-
case Intrinsic::vp_and:
1110-
case Intrinsic::vp_ashr:
1111-
case Intrinsic::vp_lshr:
1112-
case Intrinsic::vp_mul:
1113-
case Intrinsic::vp_or:
1114-
case Intrinsic::vp_sdiv:
1115-
case Intrinsic::vp_shl:
1116-
case Intrinsic::vp_srem:
1117-
case Intrinsic::vp_sub:
1118-
case Intrinsic::vp_udiv:
1119-
case Intrinsic::vp_urem:
1120-
case Intrinsic::vp_xor:
1121-
// vp float arithmetic ops.
1122-
case Intrinsic::vp_fadd:
1123-
case Intrinsic::vp_fsub:
1124-
case Intrinsic::vp_fmul:
1125-
case Intrinsic::vp_fdiv:
1126-
case Intrinsic::vp_frem: {
1127-
std::optional<unsigned> FOp =
1128-
VPIntrinsic::getFunctionalOpcodeForVP(ICA.getID());
1129-
assert(FOp.has_value());
1130-
return getArithmeticInstrCost(*FOp, ICA.getReturnType(), CostKind);
1131-
break;
1132-
}
11331107
// vp int cast ops.
11341108
case Intrinsic::vp_trunc:
11351109
case Intrinsic::vp_zext:
@@ -1163,23 +1137,6 @@ RISCVTTIImpl::getIntrinsicInstrCost(const IntrinsicCostAttributes &ICA,
11631137
return getCmpSelInstrCost(*FOp, ICA.getArgTypes()[0], ICA.getReturnType(),
11641138
UI->getPredicate(), CostKind);
11651139
}
1166-
// vp load/store
1167-
case Intrinsic::vp_load:
1168-
case Intrinsic::vp_store: {
1169-
if (!ICA.getInst())
1170-
break;
1171-
Intrinsic::ID IID = ICA.getID();
1172-
std::optional<unsigned> FOp = VPIntrinsic::getFunctionalOpcodeForVP(IID);
1173-
assert(FOp.has_value());
1174-
auto *UI = cast<VPIntrinsic>(ICA.getInst());
1175-
if (ICA.getID() == Intrinsic::vp_load)
1176-
return getMemoryOpCost(
1177-
*FOp, ICA.getReturnType(), UI->getPointerAlignment(),
1178-
UI->getOperand(0)->getType()->getPointerAddressSpace(), CostKind);
1179-
return getMemoryOpCost(
1180-
*FOp, ICA.getArgTypes()[0], UI->getPointerAlignment(),
1181-
UI->getOperand(1)->getType()->getPointerAddressSpace(), CostKind);
1182-
}
11831140
case Intrinsic::vp_select: {
11841141
Intrinsic::ID IID = ICA.getID();
11851142
std::optional<unsigned> FOp = VPIntrinsic::getFunctionalOpcodeForVP(IID);

0 commit comments

Comments
 (0)