]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - contrib/llvm-project/llvm/lib/Target/RISCV/RISCVTargetTransformInfo.cpp
MFC r355940:
[FreeBSD/FreeBSD.git] / contrib / llvm-project / llvm / lib / Target / RISCV / RISCVTargetTransformInfo.cpp
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   assert(Ty->isIntegerTy() &&
20          "getIntImmCost can only estimate cost of materialising integers");
21
22   // We have a Zero register, so 0 is always free.
23   if (Imm == 0)
24     return TTI::TCC_Free;
25
26   // Otherwise, we check how many instructions it will take to materialise.
27   const DataLayout &DL = getDataLayout();
28   return RISCVMatInt::getIntMatCost(Imm, DL.getTypeSizeInBits(Ty),
29                                     getST()->is64Bit());
30 }
31
32 int RISCVTTIImpl::getIntImmCost(unsigned Opcode, unsigned Idx, const APInt &Imm,
33                                 Type *Ty) {
34   assert(Ty->isIntegerTy() &&
35          "getIntImmCost can only estimate cost of materialising integers");
36
37   // We have a Zero register, so 0 is always free.
38   if (Imm == 0)
39     return TTI::TCC_Free;
40
41   // Some instructions in RISC-V can take a 12-bit immediate. Some of these are
42   // commutative, in others the immediate comes from a specific argument index.
43   bool Takes12BitImm = false;
44   unsigned ImmArgIdx = ~0U;
45
46   switch (Opcode) {
47   case Instruction::GetElementPtr:
48     // Never hoist any arguments to a GetElementPtr. CodeGenPrepare will
49     // split up large offsets in GEP into better parts than ConstantHoisting
50     // can.
51     return TTI::TCC_Free;
52   case Instruction::Add:
53   case Instruction::And:
54   case Instruction::Or:
55   case Instruction::Xor:
56   case Instruction::Mul:
57     Takes12BitImm = true;
58     break;
59   case Instruction::Sub:
60   case Instruction::Shl:
61   case Instruction::LShr:
62   case Instruction::AShr:
63     Takes12BitImm = true;
64     ImmArgIdx = 1;
65     break;
66   default:
67     break;
68   }
69
70   if (Takes12BitImm) {
71     // Check immediate is the correct argument...
72     if (Instruction::isCommutative(Opcode) || Idx == ImmArgIdx) {
73       // ... and fits into the 12-bit immediate.
74       if (Imm.getMinSignedBits() <= 64 &&
75           getTLI()->isLegalAddImmediate(Imm.getSExtValue())) {
76         return TTI::TCC_Free;
77       }
78     }
79
80     // Otherwise, use the full materialisation cost.
81     return getIntImmCost(Imm, Ty);
82   }
83
84   // By default, prevent hoisting.
85   return TTI::TCC_Free;
86 }
87
88 int RISCVTTIImpl::getIntImmCost(Intrinsic::ID IID, unsigned Idx,
89                                 const APInt &Imm, Type *Ty) {
90   // Prevent hoisting in unknown cases.
91   return TTI::TCC_Free;
92 }