Coverage Report

Created: 2024-01-17 10:31

/src/llvm-project/llvm/lib/Target/RISCV/RISCVSubtarget.cpp
Line
Count
Source (jump to first uncovered line)
1
//===-- RISCVSubtarget.cpp - RISC-V Subtarget Information -----------------===//
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
// This file implements the RISC-V specific subclass of TargetSubtargetInfo.
10
//
11
//===----------------------------------------------------------------------===//
12
13
#include "RISCVSubtarget.h"
14
#include "GISel/RISCVCallLowering.h"
15
#include "GISel/RISCVLegalizerInfo.h"
16
#include "GISel/RISCVRegisterBankInfo.h"
17
#include "RISCV.h"
18
#include "RISCVFrameLowering.h"
19
#include "RISCVMacroFusion.h"
20
#include "RISCVTargetMachine.h"
21
#include "llvm/MC/TargetRegistry.h"
22
#include "llvm/Support/ErrorHandling.h"
23
24
using namespace llvm;
25
26
#define DEBUG_TYPE "riscv-subtarget"
27
28
#define GET_SUBTARGETINFO_TARGET_DESC
29
#define GET_SUBTARGETINFO_CTOR
30
#include "RISCVGenSubtargetInfo.inc"
31
32
namespace llvm::RISCVTuneInfoTable {
33
34
#define GET_RISCVTuneInfoTable_IMPL
35
#include "RISCVGenSearchableTables.inc"
36
} // namespace llvm::RISCVTuneInfoTable
37
38
static cl::opt<bool> EnableSubRegLiveness("riscv-enable-subreg-liveness",
39
                                          cl::init(true), cl::Hidden);
40
41
static cl::opt<unsigned> RVVVectorLMULMax(
42
    "riscv-v-fixed-length-vector-lmul-max",
43
    cl::desc("The maximum LMUL value to use for fixed length vectors. "
44
             "Fractional LMUL values are not supported."),
45
    cl::init(8), cl::Hidden);
46
47
static cl::opt<bool> RISCVDisableUsingConstantPoolForLargeInts(
48
    "riscv-disable-using-constant-pool-for-large-ints",
49
    cl::desc("Disable using constant pool for large integers."),
50
    cl::init(false), cl::Hidden);
51
52
static cl::opt<unsigned> RISCVMaxBuildIntsCost(
53
    "riscv-max-build-ints-cost",
54
    cl::desc("The maximum cost used for building integers."), cl::init(0),
55
    cl::Hidden);
56
57
static cl::opt<bool> UseAA("riscv-use-aa", cl::init(true),
58
                           cl::desc("Enable the use of AA during codegen."));
59
60
static cl::opt<unsigned> RISCVMinimumJumpTableEntries(
61
    "riscv-min-jump-table-entries", cl::Hidden,
62
    cl::desc("Set minimum number of entries to use a jump table on RISCV"));
63
64
0
void RISCVSubtarget::anchor() {}
65
66
RISCVSubtarget &
67
RISCVSubtarget::initializeSubtargetDependencies(const Triple &TT, StringRef CPU,
68
                                                StringRef TuneCPU, StringRef FS,
69
1
                                                StringRef ABIName) {
70
  // Determine default and user-specified characteristics
71
1
  bool Is64Bit = TT.isArch64Bit();
72
1
  if (CPU.empty() || CPU == "generic")
73
1
    CPU = Is64Bit ? "generic-rv64" : "generic-rv32";
74
75
1
  if (TuneCPU.empty())
76
1
    TuneCPU = CPU;
77
78
1
  TuneInfo = RISCVTuneInfoTable::getRISCVTuneInfo(TuneCPU);
79
  // If there is no TuneInfo for this CPU, we fail back to generic.
80
1
  if (!TuneInfo)
81
0
    TuneInfo = RISCVTuneInfoTable::getRISCVTuneInfo("generic");
82
1
  assert(TuneInfo && "TuneInfo shouldn't be nullptr!");
83
84
0
  ParseSubtargetFeatures(CPU, TuneCPU, FS);
85
1
  TargetABI = RISCVABI::computeTargetABI(TT, getFeatureBits(), ABIName);
86
1
  RISCVFeatures::validate(TT, getFeatureBits());
87
1
  return *this;
88
1
}
89
90
RISCVSubtarget::RISCVSubtarget(const Triple &TT, StringRef CPU,
91
                               StringRef TuneCPU, StringRef FS,
92
                               StringRef ABIName, unsigned RVVVectorBitsMin,
93
                               unsigned RVVVectorBitsMax,
94
                               const TargetMachine &TM)
95
    : RISCVGenSubtargetInfo(TT, CPU, TuneCPU, FS),
96
      RVVVectorBitsMin(RVVVectorBitsMin), RVVVectorBitsMax(RVVVectorBitsMax),
97
      FrameLowering(
98
          initializeSubtargetDependencies(TT, CPU, TuneCPU, FS, ABIName)),
99
1
      InstrInfo(*this), RegInfo(getHwMode()), TLInfo(TM, *this) {
100
1
  CallLoweringInfo.reset(new RISCVCallLowering(*getTargetLowering()));
101
1
  Legalizer.reset(new RISCVLegalizerInfo(*this));
102
103
1
  auto *RBI = new RISCVRegisterBankInfo(getHwMode());
104
1
  RegBankInfo.reset(RBI);
105
1
  InstSelector.reset(createRISCVInstructionSelector(
106
1
      *static_cast<const RISCVTargetMachine *>(&TM), *this, *RBI));
107
1
}
108
109
0
const CallLowering *RISCVSubtarget::getCallLowering() const {
110
0
  return CallLoweringInfo.get();
111
0
}
112
113
0
InstructionSelector *RISCVSubtarget::getInstructionSelector() const {
114
0
  return InstSelector.get();
115
0
}
116
117
0
const LegalizerInfo *RISCVSubtarget::getLegalizerInfo() const {
118
0
  return Legalizer.get();
119
0
}
120
121
0
const RegisterBankInfo *RISCVSubtarget::getRegBankInfo() const {
122
0
  return RegBankInfo.get();
123
0
}
124
125
16.0k
bool RISCVSubtarget::useConstantPoolForLargeInts() const {
126
16.0k
  return !RISCVDisableUsingConstantPoolForLargeInts;
127
16.0k
}
128
129
16.0k
unsigned RISCVSubtarget::getMaxBuildIntsCost() const {
130
  // Loading integer from constant pool needs two instructions (the reason why
131
  // the minimum cost is 2): an address calculation instruction and a load
132
  // instruction. Usually, address calculation and instructions used for
133
  // building integers (addi, slli, etc.) can be done in one cycle, so here we
134
  // set the default cost to (LoadLatency + 1) if no threshold is provided.
135
16.0k
  return RISCVMaxBuildIntsCost == 0
136
16.0k
             ? getSchedModel().LoadLatency + 1
137
16.0k
             : std::max<unsigned>(2, RISCVMaxBuildIntsCost);
138
16.0k
}
139
140
0
unsigned RISCVSubtarget::getMaxRVVVectorSizeInBits() const {
141
0
  assert(hasVInstructions() &&
142
0
         "Tried to get vector length without Zve or V extension support!");
143
144
  // ZvlLen specifies the minimum required vlen. The upper bound provided by
145
  // riscv-v-vector-bits-max should be no less than it.
146
0
  if (RVVVectorBitsMax != 0 && RVVVectorBitsMax < ZvlLen)
147
0
    report_fatal_error("riscv-v-vector-bits-max specified is lower "
148
0
                       "than the Zvl*b limitation");
149
150
0
  return RVVVectorBitsMax;
151
0
}
152
153
0
unsigned RISCVSubtarget::getMinRVVVectorSizeInBits() const {
154
0
  assert(hasVInstructions() &&
155
0
         "Tried to get vector length without Zve or V extension support!");
156
157
0
  if (RVVVectorBitsMin == -1U)
158
0
    return ZvlLen;
159
160
  // ZvlLen specifies the minimum required vlen. The lower bound provided by
161
  // riscv-v-vector-bits-min should be no less than it.
162
0
  if (RVVVectorBitsMin != 0 && RVVVectorBitsMin < ZvlLen)
163
0
    report_fatal_error("riscv-v-vector-bits-min specified is lower "
164
0
                       "than the Zvl*b limitation");
165
166
0
  return RVVVectorBitsMin;
167
0
}
168
169
0
unsigned RISCVSubtarget::getMaxLMULForFixedLengthVectors() const {
170
0
  assert(hasVInstructions() &&
171
0
         "Tried to get vector length without Zve or V extension support!");
172
0
  assert(RVVVectorLMULMax <= 8 &&
173
0
         llvm::has_single_bit<uint32_t>(RVVVectorLMULMax) &&
174
0
         "V extension requires a LMUL to be at most 8 and a power of 2!");
175
0
  return llvm::bit_floor(std::clamp<unsigned>(RVVVectorLMULMax, 1, 8));
176
0
}
177
178
390k
bool RISCVSubtarget::useRVVForFixedLengthVectors() const {
179
390k
  return hasVInstructions() && getMinRVVVectorSizeInBits() != 0;
180
390k
}
181
182
6.24k
bool RISCVSubtarget::enableSubRegLiveness() const {
183
  // FIXME: Enable subregister liveness by default for RVV to better handle
184
  // LMUL>1 and segment load/store.
185
6.24k
  return EnableSubRegLiveness;
186
6.24k
}
187
188
void RISCVSubtarget::getPostRAMutations(
189
0
    std::vector<std::unique_ptr<ScheduleDAGMutation>> &Mutations) const {
190
0
  Mutations.push_back(createRISCVMacroFusionDAGMutation());
191
0
}
192
193
  /// Enable use of alias analysis during code generation (during MI
194
  /// scheduling, DAGCombine, etc.).
195
1.46M
bool RISCVSubtarget::useAA() const { return UseAA; }
196
197
0
unsigned RISCVSubtarget::getMinimumJumpTableEntries() const {
198
0
  return RISCVMinimumJumpTableEntries.getNumOccurrences() > 0
199
0
             ? RISCVMinimumJumpTableEntries
200
0
             : TuneInfo->MinimumJumpTableEntries;
201
0
}