xref: /freebsd/contrib/llvm-project/llvm/lib/Target/RISCV/RISCVTargetTransformInfo.cpp (revision c66ec88fed842fbaad62c30d510644ceb7bd2d71)
1 //===-- RISCVTargetTransformInfo.cpp - RISC-V specific TTI ----------------===//
2 //
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 //
7 //===----------------------------------------------------------------------===//
8 
9 #include "RISCVTargetTransformInfo.h"
10 #include "Utils/RISCVMatInt.h"
11 #include "llvm/Analysis/TargetTransformInfo.h"
12 #include "llvm/CodeGen/BasicTTIImpl.h"
13 #include "llvm/CodeGen/TargetLowering.h"
14 using namespace llvm;
15 
16 #define DEBUG_TYPE "riscvtti"
17 
18 int RISCVTTIImpl::getIntImmCost(const APInt &Imm, Type *Ty,
19                                 TTI::TargetCostKind CostKind) {
20   assert(Ty->isIntegerTy() &&
21          "getIntImmCost can only estimate cost of materialising integers");
22 
23   // We have a Zero register, so 0 is always free.
24   if (Imm == 0)
25     return TTI::TCC_Free;
26 
27   // Otherwise, we check how many instructions it will take to materialise.
28   const DataLayout &DL = getDataLayout();
29   return RISCVMatInt::getIntMatCost(Imm, DL.getTypeSizeInBits(Ty),
30                                     getST()->is64Bit());
31 }
32 
33 int RISCVTTIImpl::getIntImmCostInst(unsigned Opcode, unsigned Idx, const APInt &Imm,
34                                 Type *Ty, TTI::TargetCostKind CostKind) {
35   assert(Ty->isIntegerTy() &&
36          "getIntImmCost can only estimate cost of materialising integers");
37 
38   // We have a Zero register, so 0 is always free.
39   if (Imm == 0)
40     return TTI::TCC_Free;
41 
42   // Some instructions in RISC-V can take a 12-bit immediate. Some of these are
43   // commutative, in others the immediate comes from a specific argument index.
44   bool Takes12BitImm = false;
45   unsigned ImmArgIdx = ~0U;
46 
47   switch (Opcode) {
48   case Instruction::GetElementPtr:
49     // Never hoist any arguments to a GetElementPtr. CodeGenPrepare will
50     // split up large offsets in GEP into better parts than ConstantHoisting
51     // can.
52     return TTI::TCC_Free;
53   case Instruction::Add:
54   case Instruction::And:
55   case Instruction::Or:
56   case Instruction::Xor:
57   case Instruction::Mul:
58     Takes12BitImm = true;
59     break;
60   case Instruction::Sub:
61   case Instruction::Shl:
62   case Instruction::LShr:
63   case Instruction::AShr:
64     Takes12BitImm = true;
65     ImmArgIdx = 1;
66     break;
67   default:
68     break;
69   }
70 
71   if (Takes12BitImm) {
72     // Check immediate is the correct argument...
73     if (Instruction::isCommutative(Opcode) || Idx == ImmArgIdx) {
74       // ... and fits into the 12-bit immediate.
75       if (Imm.getMinSignedBits() <= 64 &&
76           getTLI()->isLegalAddImmediate(Imm.getSExtValue())) {
77         return TTI::TCC_Free;
78       }
79     }
80 
81     // Otherwise, use the full materialisation cost.
82     return getIntImmCost(Imm, Ty, CostKind);
83   }
84 
85   // By default, prevent hoisting.
86   return TTI::TCC_Free;
87 }
88 
89 int RISCVTTIImpl::getIntImmCostIntrin(Intrinsic::ID IID, unsigned Idx,
90                                       const APInt &Imm, Type *Ty,
91                                       TTI::TargetCostKind CostKind) {
92   // Prevent hoisting in unknown cases.
93   return TTI::TCC_Free;
94 }
95