1480093f4SDimitry Andric //===- VETargetTransformInfo.h - VE specific TTI ------*- C++ -*-===//
2480093f4SDimitry Andric //
3480093f4SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4480093f4SDimitry Andric // See https://llvm.org/LICENSE.txt for license information.
5480093f4SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6480093f4SDimitry Andric //
7480093f4SDimitry Andric //===----------------------------------------------------------------------===//
8480093f4SDimitry Andric /// \file
9480093f4SDimitry Andric /// This file a TargetTransformInfo::Concept conforming object specific to the
10480093f4SDimitry Andric /// VE target machine. It uses the target's detailed information to
11480093f4SDimitry Andric /// provide more precise answers to certain TTI queries, while letting the
12480093f4SDimitry Andric /// target independent and default TTI implementations handle the rest.
13480093f4SDimitry Andric ///
14480093f4SDimitry Andric //===----------------------------------------------------------------------===//
15480093f4SDimitry Andric
16480093f4SDimitry Andric #ifndef LLVM_LIB_TARGET_VE_VETARGETTRANSFORMINFO_H
17480093f4SDimitry Andric #define LLVM_LIB_TARGET_VE_VETARGETTRANSFORMINFO_H
18480093f4SDimitry Andric
19480093f4SDimitry Andric #include "VE.h"
20480093f4SDimitry Andric #include "VETargetMachine.h"
21480093f4SDimitry Andric #include "llvm/Analysis/TargetTransformInfo.h"
22480093f4SDimitry Andric #include "llvm/CodeGen/BasicTTIImpl.h"
23480093f4SDimitry Andric
getVectorElementType(llvm::Type * Ty)2481ad6265SDimitry Andric static llvm::Type *getVectorElementType(llvm::Type *Ty) {
2581ad6265SDimitry Andric return llvm::cast<llvm::FixedVectorType>(Ty)->getElementType();
2681ad6265SDimitry Andric }
2781ad6265SDimitry Andric
getLaneType(llvm::Type * Ty)2881ad6265SDimitry Andric static llvm::Type *getLaneType(llvm::Type *Ty) {
2981ad6265SDimitry Andric using namespace llvm;
3081ad6265SDimitry Andric if (!isa<VectorType>(Ty))
3181ad6265SDimitry Andric return Ty;
3281ad6265SDimitry Andric return getVectorElementType(Ty);
3381ad6265SDimitry Andric }
3481ad6265SDimitry Andric
isVectorLaneType(llvm::Type & ElemTy)3581ad6265SDimitry Andric static bool isVectorLaneType(llvm::Type &ElemTy) {
3681ad6265SDimitry Andric // check element sizes for vregs
3781ad6265SDimitry Andric if (ElemTy.isIntegerTy()) {
3881ad6265SDimitry Andric unsigned ScaBits = ElemTy.getScalarSizeInBits();
3981ad6265SDimitry Andric return ScaBits == 1 || ScaBits == 32 || ScaBits == 64;
4081ad6265SDimitry Andric }
4181ad6265SDimitry Andric if (ElemTy.isPointerTy()) {
4281ad6265SDimitry Andric return true;
4381ad6265SDimitry Andric }
4481ad6265SDimitry Andric if (ElemTy.isFloatTy() || ElemTy.isDoubleTy()) {
4581ad6265SDimitry Andric return true;
4681ad6265SDimitry Andric }
4781ad6265SDimitry Andric return false;
4881ad6265SDimitry Andric }
4981ad6265SDimitry Andric
50480093f4SDimitry Andric namespace llvm {
51480093f4SDimitry Andric
52480093f4SDimitry Andric class VETTIImpl : public BasicTTIImplBase<VETTIImpl> {
53480093f4SDimitry Andric using BaseT = BasicTTIImplBase<VETTIImpl>;
54480093f4SDimitry Andric friend BaseT;
55480093f4SDimitry Andric
56480093f4SDimitry Andric const VESubtarget *ST;
57480093f4SDimitry Andric const VETargetLowering *TLI;
58480093f4SDimitry Andric
getST()59480093f4SDimitry Andric const VESubtarget *getST() const { return ST; }
getTLI()60480093f4SDimitry Andric const VETargetLowering *getTLI() const { return TLI; }
61480093f4SDimitry Andric
enableVPU()62e8d8bef9SDimitry Andric bool enableVPU() const { return getST()->enableVPU(); }
63e8d8bef9SDimitry Andric
isSupportedReduction(Intrinsic::ID ReductionID)6481ad6265SDimitry Andric static bool isSupportedReduction(Intrinsic::ID ReductionID) {
6581ad6265SDimitry Andric #define VEC_VP_CASE(SUFFIX) \
6681ad6265SDimitry Andric case Intrinsic::vp_reduce_##SUFFIX: \
6781ad6265SDimitry Andric case Intrinsic::vector_reduce_##SUFFIX:
6881ad6265SDimitry Andric
6981ad6265SDimitry Andric switch (ReductionID) {
7081ad6265SDimitry Andric VEC_VP_CASE(add)
7181ad6265SDimitry Andric VEC_VP_CASE(and)
7281ad6265SDimitry Andric VEC_VP_CASE(or)
7381ad6265SDimitry Andric VEC_VP_CASE(xor)
7481ad6265SDimitry Andric VEC_VP_CASE(smax)
7581ad6265SDimitry Andric return true;
7681ad6265SDimitry Andric
7781ad6265SDimitry Andric default:
7881ad6265SDimitry Andric return false;
7981ad6265SDimitry Andric }
8081ad6265SDimitry Andric #undef VEC_VP_CASE
8181ad6265SDimitry Andric }
8281ad6265SDimitry Andric
83480093f4SDimitry Andric public:
VETTIImpl(const VETargetMachine * TM,const Function & F)84480093f4SDimitry Andric explicit VETTIImpl(const VETargetMachine *TM, const Function &F)
85*0fca6ea1SDimitry Andric : BaseT(TM, F.getDataLayout()), ST(TM->getSubtargetImpl(F)),
86480093f4SDimitry Andric TLI(ST->getTargetLowering()) {}
87480093f4SDimitry Andric
getNumberOfRegisters(unsigned ClassID)88e8d8bef9SDimitry Andric unsigned getNumberOfRegisters(unsigned ClassID) const {
89e8d8bef9SDimitry Andric bool VectorRegs = (ClassID == 1);
90e8d8bef9SDimitry Andric if (VectorRegs) {
91e8d8bef9SDimitry Andric // TODO report vregs once vector isel is stable.
92e8d8bef9SDimitry Andric return 0;
93e8d8bef9SDimitry Andric }
94480093f4SDimitry Andric
95e8d8bef9SDimitry Andric return 64;
96e8d8bef9SDimitry Andric }
97480093f4SDimitry Andric
getRegisterBitWidth(TargetTransformInfo::RegisterKind K)98fe6060f1SDimitry Andric TypeSize getRegisterBitWidth(TargetTransformInfo::RegisterKind K) const {
99fe6060f1SDimitry Andric switch (K) {
100fe6060f1SDimitry Andric case TargetTransformInfo::RGK_Scalar:
101fe6060f1SDimitry Andric return TypeSize::getFixed(64);
102fe6060f1SDimitry Andric case TargetTransformInfo::RGK_FixedWidthVector:
103e8d8bef9SDimitry Andric // TODO report vregs once vector isel is stable.
104fe6060f1SDimitry Andric return TypeSize::getFixed(0);
105fe6060f1SDimitry Andric case TargetTransformInfo::RGK_ScalableVector:
106fe6060f1SDimitry Andric return TypeSize::getScalable(0);
107e8d8bef9SDimitry Andric }
108fe6060f1SDimitry Andric
109fe6060f1SDimitry Andric llvm_unreachable("Unsupported register kind");
110fe6060f1SDimitry Andric }
111fe6060f1SDimitry Andric
112fe6060f1SDimitry Andric /// \returns How the target needs this vector-predicated operation to be
113fe6060f1SDimitry Andric /// transformed.
114fe6060f1SDimitry Andric TargetTransformInfo::VPLegalization
getVPLegalizationStrategy(const VPIntrinsic & PI)115fe6060f1SDimitry Andric getVPLegalizationStrategy(const VPIntrinsic &PI) const {
116fe6060f1SDimitry Andric using VPLegalization = TargetTransformInfo::VPLegalization;
117fe6060f1SDimitry Andric return VPLegalization(VPLegalization::Legal, VPLegalization::Legal);
118e8d8bef9SDimitry Andric }
119e8d8bef9SDimitry Andric
getMinVectorRegisterBitWidth()120e8d8bef9SDimitry Andric unsigned getMinVectorRegisterBitWidth() const {
121e8d8bef9SDimitry Andric // TODO report vregs once vector isel is stable.
122e8d8bef9SDimitry Andric return 0;
123e8d8bef9SDimitry Andric }
124fe6060f1SDimitry Andric
shouldBuildRelLookupTables()125fe6060f1SDimitry Andric bool shouldBuildRelLookupTables() const {
126fe6060f1SDimitry Andric // NEC nld doesn't support relative lookup tables. It shows following
127fe6060f1SDimitry Andric // errors. So, we disable it at the moment.
128fe6060f1SDimitry Andric // /opt/nec/ve/bin/nld: src/CMakeFiles/cxxabi_shared.dir/cxa_demangle.cpp
129fe6060f1SDimitry Andric // .o(.rodata+0x17b4): reloc against `.L.str.376': error 2
130fe6060f1SDimitry Andric // /opt/nec/ve/bin/nld: final link failed: Nonrepresentable section on
131fe6060f1SDimitry Andric // output
132fe6060f1SDimitry Andric return false;
133fe6060f1SDimitry Andric }
13481ad6265SDimitry Andric
13581ad6265SDimitry Andric // Load & Store {
isLegalMaskedLoad(Type * DataType,MaybeAlign Alignment)13681ad6265SDimitry Andric bool isLegalMaskedLoad(Type *DataType, MaybeAlign Alignment) {
13781ad6265SDimitry Andric return isVectorLaneType(*getLaneType(DataType));
13881ad6265SDimitry Andric }
isLegalMaskedStore(Type * DataType,MaybeAlign Alignment)13981ad6265SDimitry Andric bool isLegalMaskedStore(Type *DataType, MaybeAlign Alignment) {
14081ad6265SDimitry Andric return isVectorLaneType(*getLaneType(DataType));
14181ad6265SDimitry Andric }
isLegalMaskedGather(Type * DataType,MaybeAlign Alignment)14281ad6265SDimitry Andric bool isLegalMaskedGather(Type *DataType, MaybeAlign Alignment) {
14381ad6265SDimitry Andric return isVectorLaneType(*getLaneType(DataType));
14481ad6265SDimitry Andric };
isLegalMaskedScatter(Type * DataType,MaybeAlign Alignment)14581ad6265SDimitry Andric bool isLegalMaskedScatter(Type *DataType, MaybeAlign Alignment) {
14681ad6265SDimitry Andric return isVectorLaneType(*getLaneType(DataType));
14781ad6265SDimitry Andric }
14881ad6265SDimitry Andric // } Load & Store
14981ad6265SDimitry Andric
shouldExpandReduction(const IntrinsicInst * II)15081ad6265SDimitry Andric bool shouldExpandReduction(const IntrinsicInst *II) const {
15181ad6265SDimitry Andric if (!enableVPU())
15281ad6265SDimitry Andric return true;
15381ad6265SDimitry Andric return !isSupportedReduction(II->getIntrinsicID());
15481ad6265SDimitry Andric }
155480093f4SDimitry Andric };
156480093f4SDimitry Andric
157480093f4SDimitry Andric } // namespace llvm
158480093f4SDimitry Andric
159480093f4SDimitry Andric #endif // LLVM_LIB_TARGET_VE_VETARGETTRANSFORMINFO_H
160