1351278Sdim//===-- RISCVTargetTransformInfo.cpp - RISC-V specific TTI ----------------===//
2351278Sdim//
3351278Sdim// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4351278Sdim// See https://llvm.org/LICENSE.txt for license information.
5351278Sdim// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6351278Sdim//
7351278Sdim//===----------------------------------------------------------------------===//
8351278Sdim
9351278Sdim#include "RISCVTargetTransformInfo.h"
10351278Sdim#include "Utils/RISCVMatInt.h"
11351278Sdim#include "llvm/Analysis/TargetTransformInfo.h"
12351278Sdim#include "llvm/CodeGen/BasicTTIImpl.h"
13351278Sdim#include "llvm/CodeGen/TargetLowering.h"
14351278Sdimusing namespace llvm;
15351278Sdim
16351278Sdim#define DEBUG_TYPE "riscvtti"
17351278Sdim
18351278Sdimint RISCVTTIImpl::getIntImmCost(const APInt &Imm, Type *Ty) {
19351278Sdim  assert(Ty->isIntegerTy() &&
20351278Sdim         "getIntImmCost can only estimate cost of materialising integers");
21351278Sdim
22351278Sdim  // We have a Zero register, so 0 is always free.
23351278Sdim  if (Imm == 0)
24351278Sdim    return TTI::TCC_Free;
25351278Sdim
26351278Sdim  // Otherwise, we check how many instructions it will take to materialise.
27351278Sdim  const DataLayout &DL = getDataLayout();
28351278Sdim  return RISCVMatInt::getIntMatCost(Imm, DL.getTypeSizeInBits(Ty),
29351278Sdim                                    getST()->is64Bit());
30351278Sdim}
31351278Sdim
32360784Sdimint RISCVTTIImpl::getIntImmCostInst(unsigned Opcode, unsigned Idx, const APInt &Imm,
33351278Sdim                                Type *Ty) {
34351278Sdim  assert(Ty->isIntegerTy() &&
35351278Sdim         "getIntImmCost can only estimate cost of materialising integers");
36351278Sdim
37351278Sdim  // We have a Zero register, so 0 is always free.
38351278Sdim  if (Imm == 0)
39351278Sdim    return TTI::TCC_Free;
40351278Sdim
41351278Sdim  // Some instructions in RISC-V can take a 12-bit immediate. Some of these are
42351278Sdim  // commutative, in others the immediate comes from a specific argument index.
43351278Sdim  bool Takes12BitImm = false;
44351278Sdim  unsigned ImmArgIdx = ~0U;
45351278Sdim
46351278Sdim  switch (Opcode) {
47351278Sdim  case Instruction::GetElementPtr:
48351278Sdim    // Never hoist any arguments to a GetElementPtr. CodeGenPrepare will
49351278Sdim    // split up large offsets in GEP into better parts than ConstantHoisting
50351278Sdim    // can.
51351278Sdim    return TTI::TCC_Free;
52351278Sdim  case Instruction::Add:
53351278Sdim  case Instruction::And:
54351278Sdim  case Instruction::Or:
55351278Sdim  case Instruction::Xor:
56351278Sdim  case Instruction::Mul:
57351278Sdim    Takes12BitImm = true;
58351278Sdim    break;
59351278Sdim  case Instruction::Sub:
60351278Sdim  case Instruction::Shl:
61351278Sdim  case Instruction::LShr:
62351278Sdim  case Instruction::AShr:
63351278Sdim    Takes12BitImm = true;
64351278Sdim    ImmArgIdx = 1;
65351278Sdim    break;
66351278Sdim  default:
67351278Sdim    break;
68351278Sdim  }
69351278Sdim
70351278Sdim  if (Takes12BitImm) {
71351278Sdim    // Check immediate is the correct argument...
72351278Sdim    if (Instruction::isCommutative(Opcode) || Idx == ImmArgIdx) {
73351278Sdim      // ... and fits into the 12-bit immediate.
74351278Sdim      if (Imm.getMinSignedBits() <= 64 &&
75351278Sdim          getTLI()->isLegalAddImmediate(Imm.getSExtValue())) {
76351278Sdim        return TTI::TCC_Free;
77351278Sdim      }
78351278Sdim    }
79351278Sdim
80351278Sdim    // Otherwise, use the full materialisation cost.
81351278Sdim    return getIntImmCost(Imm, Ty);
82351278Sdim  }
83351278Sdim
84351278Sdim  // By default, prevent hoisting.
85351278Sdim  return TTI::TCC_Free;
86351278Sdim}
87351278Sdim
88360784Sdimint RISCVTTIImpl::getIntImmCostIntrin(Intrinsic::ID IID, unsigned Idx,
89360784Sdim                                      const APInt &Imm, Type *Ty) {
90351278Sdim  // Prevent hoisting in unknown cases.
91351278Sdim  return TTI::TCC_Free;
92351278Sdim}
93