xref: /freebsd/contrib/llvm-project/llvm/lib/Target/Lanai/LanaiTargetTransformInfo.h (revision 0fca6ea1d4eea4c934cfff25ac9ee8ad6fe95583)
10b57cec5SDimitry Andric //===-- LanaiTargetTransformInfo.h - Lanai specific TTI ---------*- C++ -*-===//
20b57cec5SDimitry Andric //
30b57cec5SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
40b57cec5SDimitry Andric // See https://llvm.org/LICENSE.txt for license information.
50b57cec5SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
60b57cec5SDimitry Andric //
70b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
80b57cec5SDimitry Andric //
90b57cec5SDimitry Andric // This file a TargetTransformInfo::Concept conforming object specific to the
100b57cec5SDimitry Andric // Lanai target machine. It uses the target's detailed information to
110b57cec5SDimitry Andric // provide more precise answers to certain TTI queries, while letting the
120b57cec5SDimitry Andric // target independent and default TTI implementations handle the rest.
130b57cec5SDimitry Andric //
140b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
150b57cec5SDimitry Andric 
160b57cec5SDimitry Andric #ifndef LLVM_LIB_TARGET_LANAI_LANAITARGETTRANSFORMINFO_H
170b57cec5SDimitry Andric #define LLVM_LIB_TARGET_LANAI_LANAITARGETTRANSFORMINFO_H
180b57cec5SDimitry Andric 
190b57cec5SDimitry Andric #include "Lanai.h"
200b57cec5SDimitry Andric #include "LanaiSubtarget.h"
210b57cec5SDimitry Andric #include "LanaiTargetMachine.h"
220b57cec5SDimitry Andric #include "llvm/Analysis/TargetTransformInfo.h"
230b57cec5SDimitry Andric #include "llvm/CodeGen/BasicTTIImpl.h"
240b57cec5SDimitry Andric #include "llvm/CodeGen/TargetLowering.h"
250b57cec5SDimitry Andric #include "llvm/Support/MathExtras.h"
260b57cec5SDimitry Andric 
270b57cec5SDimitry Andric namespace llvm {
280b57cec5SDimitry Andric class LanaiTTIImpl : public BasicTTIImplBase<LanaiTTIImpl> {
290b57cec5SDimitry Andric   typedef BasicTTIImplBase<LanaiTTIImpl> BaseT;
300b57cec5SDimitry Andric   typedef TargetTransformInfo TTI;
310b57cec5SDimitry Andric   friend BaseT;
320b57cec5SDimitry Andric 
330b57cec5SDimitry Andric   const LanaiSubtarget *ST;
340b57cec5SDimitry Andric   const LanaiTargetLowering *TLI;
350b57cec5SDimitry Andric 
getST()360b57cec5SDimitry Andric   const LanaiSubtarget *getST() const { return ST; }
getTLI()370b57cec5SDimitry Andric   const LanaiTargetLowering *getTLI() const { return TLI; }
380b57cec5SDimitry Andric 
390b57cec5SDimitry Andric public:
LanaiTTIImpl(const LanaiTargetMachine * TM,const Function & F)400b57cec5SDimitry Andric   explicit LanaiTTIImpl(const LanaiTargetMachine *TM, const Function &F)
41*0fca6ea1SDimitry Andric       : BaseT(TM, F.getDataLayout()), ST(TM->getSubtargetImpl(F)),
420b57cec5SDimitry Andric         TLI(ST->getTargetLowering()) {}
430b57cec5SDimitry Andric 
shouldBuildLookupTables()440b57cec5SDimitry Andric   bool shouldBuildLookupTables() const { return false; }
450b57cec5SDimitry Andric 
getPopcntSupport(unsigned TyWidth)460b57cec5SDimitry Andric   TargetTransformInfo::PopcntSupportKind getPopcntSupport(unsigned TyWidth) {
470b57cec5SDimitry Andric     if (TyWidth == 32)
480b57cec5SDimitry Andric       return TTI::PSK_FastHardware;
490b57cec5SDimitry Andric     return TTI::PSK_Software;
500b57cec5SDimitry Andric   }
510b57cec5SDimitry Andric 
getIntImmCost(const APInt & Imm,Type * Ty,TTI::TargetCostKind CostKind)52fe6060f1SDimitry Andric   InstructionCost getIntImmCost(const APInt &Imm, Type *Ty,
53fe6060f1SDimitry Andric                                 TTI::TargetCostKind CostKind) {
540b57cec5SDimitry Andric     assert(Ty->isIntegerTy());
55349cc55cSDimitry Andric     unsigned BitSize = Ty->getPrimitiveSizeInBits();
56349cc55cSDimitry Andric     // There is no cost model for constants with a bit size of 0. Return
57349cc55cSDimitry Andric     // TCC_Free here, so that constant hoisting will ignore this constant.
58349cc55cSDimitry Andric     if (BitSize == 0)
59349cc55cSDimitry Andric       return TTI::TCC_Free;
60349cc55cSDimitry Andric     // No cost model for operations on integers larger than 64 bit implemented
61349cc55cSDimitry Andric     // yet.
62349cc55cSDimitry Andric     if (BitSize > 64)
63349cc55cSDimitry Andric       return TTI::TCC_Free;
64349cc55cSDimitry Andric 
650b57cec5SDimitry Andric     if (Imm == 0)
660b57cec5SDimitry Andric       return TTI::TCC_Free;
670b57cec5SDimitry Andric     if (isInt<16>(Imm.getSExtValue()))
680b57cec5SDimitry Andric       return TTI::TCC_Basic;
690b57cec5SDimitry Andric     if (isInt<21>(Imm.getZExtValue()))
700b57cec5SDimitry Andric       return TTI::TCC_Basic;
710b57cec5SDimitry Andric     if (isInt<32>(Imm.getSExtValue())) {
720b57cec5SDimitry Andric       if ((Imm.getSExtValue() & 0xFFFF) == 0)
730b57cec5SDimitry Andric         return TTI::TCC_Basic;
740b57cec5SDimitry Andric       return 2 * TTI::TCC_Basic;
750b57cec5SDimitry Andric     }
760b57cec5SDimitry Andric 
770b57cec5SDimitry Andric     return 4 * TTI::TCC_Basic;
780b57cec5SDimitry Andric   }
790b57cec5SDimitry Andric 
80fe6060f1SDimitry Andric   InstructionCost getIntImmCostInst(unsigned Opc, unsigned Idx,
81fe6060f1SDimitry Andric                                     const APInt &Imm, Type *Ty,
82e8d8bef9SDimitry Andric                                     TTI::TargetCostKind CostKind,
83e8d8bef9SDimitry Andric                                     Instruction *Inst = nullptr) {
845ffd83dbSDimitry Andric     return getIntImmCost(Imm, Ty, CostKind);
850b57cec5SDimitry Andric   }
860b57cec5SDimitry Andric 
getIntImmCostIntrin(Intrinsic::ID IID,unsigned Idx,const APInt & Imm,Type * Ty,TTI::TargetCostKind CostKind)87fe6060f1SDimitry Andric   InstructionCost getIntImmCostIntrin(Intrinsic::ID IID, unsigned Idx,
88fe6060f1SDimitry Andric                                       const APInt &Imm, Type *Ty,
89fe6060f1SDimitry Andric                                       TTI::TargetCostKind CostKind) {
905ffd83dbSDimitry Andric     return getIntImmCost(Imm, Ty, CostKind);
910b57cec5SDimitry Andric   }
920b57cec5SDimitry Andric 
93fe6060f1SDimitry Andric   InstructionCost getArithmeticInstrCost(
94349cc55cSDimitry Andric       unsigned Opcode, Type *Ty, TTI::TargetCostKind CostKind,
95bdd1243dSDimitry Andric       TTI::OperandValueInfo Op1Info = {TTI::OK_AnyValue, TTI::OP_None},
96bdd1243dSDimitry Andric       TTI::OperandValueInfo Op2Info = {TTI::OK_AnyValue, TTI::OP_None},
97*0fca6ea1SDimitry Andric       ArrayRef<const Value *> Args = std::nullopt,
98480093f4SDimitry Andric       const Instruction *CxtI = nullptr) {
990b57cec5SDimitry Andric     int ISD = TLI->InstructionOpcodeToISD(Opcode);
1000b57cec5SDimitry Andric 
1010b57cec5SDimitry Andric     switch (ISD) {
1020b57cec5SDimitry Andric     default:
103bdd1243dSDimitry Andric       return BaseT::getArithmeticInstrCost(Opcode, Ty, CostKind, Op1Info,
104bdd1243dSDimitry Andric                                            Op2Info);
1050b57cec5SDimitry Andric     case ISD::MUL:
1060b57cec5SDimitry Andric     case ISD::SDIV:
1070b57cec5SDimitry Andric     case ISD::UDIV:
1080b57cec5SDimitry Andric     case ISD::UREM:
1090b57cec5SDimitry Andric       // This increases the cost associated with multiplication and division
1100b57cec5SDimitry Andric       // to 64 times what the baseline arithmetic cost is. The arithmetic
1110b57cec5SDimitry Andric       // instruction cost was arbitrarily chosen to reduce the desirability
1120b57cec5SDimitry Andric       // of emitting arithmetic instructions that are emulated in software.
1130b57cec5SDimitry Andric       // TODO: Investigate the performance impact given specialized lowerings.
114bdd1243dSDimitry Andric       return 64 * BaseT::getArithmeticInstrCost(Opcode, Ty, CostKind, Op1Info,
115bdd1243dSDimitry Andric                                                 Op2Info);
1160b57cec5SDimitry Andric     }
1170b57cec5SDimitry Andric   }
1180b57cec5SDimitry Andric };
1190b57cec5SDimitry Andric 
1200b57cec5SDimitry Andric } // end namespace llvm
1210b57cec5SDimitry Andric 
1220b57cec5SDimitry Andric #endif // LLVM_LIB_TARGET_LANAI_LANAITARGETTRANSFORMINFO_H
123