xref: /freebsd/contrib/llvm-project/llvm/lib/Target/RISCV/RISCVTargetMachine.cpp (revision 19fae0f66023a97a9b464b3beeeabb2081f575b3)
1 //===-- RISCVTargetMachine.cpp - Define TargetMachine for RISCV -----------===//
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 // Implements the info about RISCV target spec.
10 //
11 //===----------------------------------------------------------------------===//
12 
13 #include "RISCVTargetMachine.h"
14 #include "MCTargetDesc/RISCVBaseInfo.h"
15 #include "RISCV.h"
16 #include "RISCVMachineFunctionInfo.h"
17 #include "RISCVMacroFusion.h"
18 #include "RISCVTargetObjectFile.h"
19 #include "RISCVTargetTransformInfo.h"
20 #include "TargetInfo/RISCVTargetInfo.h"
21 #include "llvm/ADT/STLExtras.h"
22 #include "llvm/Analysis/TargetTransformInfo.h"
23 #include "llvm/CodeGen/GlobalISel/IRTranslator.h"
24 #include "llvm/CodeGen/GlobalISel/InstructionSelect.h"
25 #include "llvm/CodeGen/GlobalISel/Legalizer.h"
26 #include "llvm/CodeGen/GlobalISel/RegBankSelect.h"
27 #include "llvm/CodeGen/MIRParser/MIParser.h"
28 #include "llvm/CodeGen/MIRYamlMapping.h"
29 #include "llvm/CodeGen/Passes.h"
30 #include "llvm/CodeGen/TargetLoweringObjectFileImpl.h"
31 #include "llvm/CodeGen/TargetPassConfig.h"
32 #include "llvm/IR/LegacyPassManager.h"
33 #include "llvm/InitializePasses.h"
34 #include "llvm/MC/TargetRegistry.h"
35 #include "llvm/Support/FormattedStream.h"
36 #include "llvm/Target/TargetOptions.h"
37 #include "llvm/Transforms/IPO.h"
38 #include <optional>
39 using namespace llvm;
40 
41 static cl::opt<bool> EnableRedundantCopyElimination(
42     "riscv-enable-copyelim",
43     cl::desc("Enable the redundant copy elimination pass"), cl::init(true),
44     cl::Hidden);
45 
46 // FIXME: Unify control over GlobalMerge.
47 static cl::opt<cl::boolOrDefault>
48     EnableGlobalMerge("riscv-enable-global-merge", cl::Hidden,
49                       cl::desc("Enable the global merge pass"));
50 
51 static cl::opt<bool>
52     EnableMachineCombiner("riscv-enable-machine-combiner",
53                           cl::desc("Enable the machine combiner pass"),
54                           cl::init(true), cl::Hidden);
55 
56 static cl::opt<unsigned> RVVVectorBitsMaxOpt(
57     "riscv-v-vector-bits-max",
58     cl::desc("Assume V extension vector registers are at most this big, "
59              "with zero meaning no maximum size is assumed."),
60     cl::init(0), cl::Hidden);
61 
62 static cl::opt<int> RVVVectorBitsMinOpt(
63     "riscv-v-vector-bits-min",
64     cl::desc("Assume V extension vector registers are at least this big, "
65              "with zero meaning no minimum size is assumed. A value of -1 "
66              "means use Zvl*b extension. This is primarily used to enable "
67              "autovectorization with fixed width vectors."),
68     cl::init(-1), cl::Hidden);
69 
70 extern "C" LLVM_EXTERNAL_VISIBILITY void LLVMInitializeRISCVTarget() {
71   RegisterTargetMachine<RISCVTargetMachine> X(getTheRISCV32Target());
72   RegisterTargetMachine<RISCVTargetMachine> Y(getTheRISCV64Target());
73   auto *PR = PassRegistry::getPassRegistry();
74   initializeGlobalISel(*PR);
75   initializeRISCVMakeCompressibleOptPass(*PR);
76   initializeRISCVGatherScatterLoweringPass(*PR);
77   initializeRISCVCodeGenPreparePass(*PR);
78   initializeRISCVMergeBaseOffsetOptPass(*PR);
79   initializeRISCVSExtWRemovalPass(*PR);
80   initializeRISCVStripWSuffixPass(*PR);
81   initializeRISCVPreRAExpandPseudoPass(*PR);
82   initializeRISCVExpandPseudoPass(*PR);
83   initializeRISCVInsertVSETVLIPass(*PR);
84   initializeRISCVDAGToDAGISelPass(*PR);
85 }
86 
87 static StringRef computeDataLayout(const Triple &TT) {
88   if (TT.isArch64Bit())
89     return "e-m:e-p:64:64-i64:64-i128:128-n32:64-S128";
90   assert(TT.isArch32Bit() && "only RV32 and RV64 are currently supported");
91   return "e-m:e-p:32:32-i64:64-n32-S128";
92 }
93 
94 static Reloc::Model getEffectiveRelocModel(const Triple &TT,
95                                            std::optional<Reloc::Model> RM) {
96   return RM.value_or(Reloc::Static);
97 }
98 
99 RISCVTargetMachine::RISCVTargetMachine(const Target &T, const Triple &TT,
100                                        StringRef CPU, StringRef FS,
101                                        const TargetOptions &Options,
102                                        std::optional<Reloc::Model> RM,
103                                        std::optional<CodeModel::Model> CM,
104                                        CodeGenOpt::Level OL, bool JIT)
105     : LLVMTargetMachine(T, computeDataLayout(TT), TT, CPU, FS, Options,
106                         getEffectiveRelocModel(TT, RM),
107                         getEffectiveCodeModel(CM, CodeModel::Small), OL),
108       TLOF(std::make_unique<RISCVELFTargetObjectFile>()) {
109   initAsmInfo();
110 
111   // RISC-V supports the MachineOutliner.
112   setMachineOutliner(true);
113   setSupportsDefaultOutlining(true);
114 }
115 
116 const RISCVSubtarget *
117 RISCVTargetMachine::getSubtargetImpl(const Function &F) const {
118   Attribute CPUAttr = F.getFnAttribute("target-cpu");
119   Attribute TuneAttr = F.getFnAttribute("tune-cpu");
120   Attribute FSAttr = F.getFnAttribute("target-features");
121 
122   std::string CPU =
123       CPUAttr.isValid() ? CPUAttr.getValueAsString().str() : TargetCPU;
124   std::string TuneCPU =
125       TuneAttr.isValid() ? TuneAttr.getValueAsString().str() : CPU;
126   std::string FS =
127       FSAttr.isValid() ? FSAttr.getValueAsString().str() : TargetFS;
128 
129   unsigned RVVBitsMin = RVVVectorBitsMinOpt;
130   unsigned RVVBitsMax = RVVVectorBitsMaxOpt;
131 
132   Attribute VScaleRangeAttr = F.getFnAttribute(Attribute::VScaleRange);
133   if (VScaleRangeAttr.isValid()) {
134     if (!RVVVectorBitsMinOpt.getNumOccurrences())
135       RVVBitsMin = VScaleRangeAttr.getVScaleRangeMin() * RISCV::RVVBitsPerBlock;
136     std::optional<unsigned> VScaleMax = VScaleRangeAttr.getVScaleRangeMax();
137     if (VScaleMax.has_value() && !RVVVectorBitsMaxOpt.getNumOccurrences())
138       RVVBitsMax = *VScaleMax * RISCV::RVVBitsPerBlock;
139   }
140 
141   if (RVVBitsMin != -1U) {
142     // FIXME: Change to >= 32 when VLEN = 32 is supported.
143     assert((RVVBitsMin == 0 || (RVVBitsMin >= 64 && RVVBitsMin <= 65536 &&
144                                 isPowerOf2_32(RVVBitsMin))) &&
145            "V or Zve* extension requires vector length to be in the range of "
146            "64 to 65536 and a power 2!");
147     assert((RVVBitsMax >= RVVBitsMin || RVVBitsMax == 0) &&
148            "Minimum V extension vector length should not be larger than its "
149            "maximum!");
150   }
151   assert((RVVBitsMax == 0 || (RVVBitsMax >= 64 && RVVBitsMax <= 65536 &&
152                               isPowerOf2_32(RVVBitsMax))) &&
153          "V or Zve* extension requires vector length to be in the range of "
154          "64 to 65536 and a power 2!");
155 
156   if (RVVBitsMin != -1U) {
157     if (RVVBitsMax != 0) {
158       RVVBitsMin = std::min(RVVBitsMin, RVVBitsMax);
159       RVVBitsMax = std::max(RVVBitsMin, RVVBitsMax);
160     }
161 
162     RVVBitsMin =
163         PowerOf2Floor((RVVBitsMin < 64 || RVVBitsMin > 65536) ? 0 : RVVBitsMin);
164   }
165   RVVBitsMax =
166       PowerOf2Floor((RVVBitsMax < 64 || RVVBitsMax > 65536) ? 0 : RVVBitsMax);
167 
168   SmallString<512> Key;
169   Key += "RVVMin";
170   Key += std::to_string(RVVBitsMin);
171   Key += "RVVMax";
172   Key += std::to_string(RVVBitsMax);
173   Key += CPU;
174   Key += TuneCPU;
175   Key += FS;
176   auto &I = SubtargetMap[Key];
177   if (!I) {
178     // This needs to be done before we create a new subtarget since any
179     // creation will depend on the TM and the code generation flags on the
180     // function that reside in TargetOptions.
181     resetTargetOptions(F);
182     auto ABIName = Options.MCOptions.getABIName();
183     if (const MDString *ModuleTargetABI = dyn_cast_or_null<MDString>(
184             F.getParent()->getModuleFlag("target-abi"))) {
185       auto TargetABI = RISCVABI::getTargetABI(ABIName);
186       if (TargetABI != RISCVABI::ABI_Unknown &&
187           ModuleTargetABI->getString() != ABIName) {
188         report_fatal_error("-target-abi option != target-abi module flag");
189       }
190       ABIName = ModuleTargetABI->getString();
191     }
192     I = std::make_unique<RISCVSubtarget>(
193         TargetTriple, CPU, TuneCPU, FS, ABIName, RVVBitsMin, RVVBitsMax, *this);
194   }
195   return I.get();
196 }
197 
198 MachineFunctionInfo *RISCVTargetMachine::createMachineFunctionInfo(
199     BumpPtrAllocator &Allocator, const Function &F,
200     const TargetSubtargetInfo *STI) const {
201   return RISCVMachineFunctionInfo::create<RISCVMachineFunctionInfo>(Allocator,
202                                                                     F, STI);
203 }
204 
205 TargetTransformInfo
206 RISCVTargetMachine::getTargetTransformInfo(const Function &F) const {
207   return TargetTransformInfo(RISCVTTIImpl(this, F));
208 }
209 
210 // A RISC-V hart has a single byte-addressable address space of 2^XLEN bytes
211 // for all memory accesses, so it is reasonable to assume that an
212 // implementation has no-op address space casts. If an implementation makes a
213 // change to this, they can override it here.
214 bool RISCVTargetMachine::isNoopAddrSpaceCast(unsigned SrcAS,
215                                              unsigned DstAS) const {
216   return true;
217 }
218 
219 namespace {
220 class RISCVPassConfig : public TargetPassConfig {
221 public:
222   RISCVPassConfig(RISCVTargetMachine &TM, PassManagerBase &PM)
223       : TargetPassConfig(TM, PM) {}
224 
225   RISCVTargetMachine &getRISCVTargetMachine() const {
226     return getTM<RISCVTargetMachine>();
227   }
228 
229   ScheduleDAGInstrs *
230   createMachineScheduler(MachineSchedContext *C) const override {
231     const RISCVSubtarget &ST = C->MF->getSubtarget<RISCVSubtarget>();
232     if (ST.hasMacroFusion()) {
233       ScheduleDAGMILive *DAG = createGenericSchedLive(C);
234       DAG->addMutation(createRISCVMacroFusionDAGMutation());
235       return DAG;
236     }
237     return nullptr;
238   }
239 
240   ScheduleDAGInstrs *
241   createPostMachineScheduler(MachineSchedContext *C) const override {
242     const RISCVSubtarget &ST = C->MF->getSubtarget<RISCVSubtarget>();
243     if (ST.hasMacroFusion()) {
244       ScheduleDAGMI *DAG = createGenericSchedPostRA(C);
245       DAG->addMutation(createRISCVMacroFusionDAGMutation());
246       return DAG;
247     }
248     return nullptr;
249   }
250 
251   void addIRPasses() override;
252   bool addPreISel() override;
253   bool addInstSelector() override;
254   bool addIRTranslator() override;
255   bool addLegalizeMachineIR() override;
256   bool addRegBankSelect() override;
257   bool addGlobalInstructionSelect() override;
258   void addPreEmitPass() override;
259   void addPreEmitPass2() override;
260   void addPreSched2() override;
261   void addMachineSSAOptimization() override;
262   void addPreRegAlloc() override;
263   void addPostRegAlloc() override;
264 };
265 } // namespace
266 
267 TargetPassConfig *RISCVTargetMachine::createPassConfig(PassManagerBase &PM) {
268   return new RISCVPassConfig(*this, PM);
269 }
270 
271 void RISCVPassConfig::addIRPasses() {
272   addPass(createAtomicExpandPass());
273 
274   if (getOptLevel() != CodeGenOpt::None)
275     addPass(createRISCVGatherScatterLoweringPass());
276 
277   if (getOptLevel() != CodeGenOpt::None)
278     addPass(createRISCVCodeGenPreparePass());
279 
280   TargetPassConfig::addIRPasses();
281 }
282 
283 bool RISCVPassConfig::addPreISel() {
284   if (TM->getOptLevel() != CodeGenOpt::None) {
285     // Add a barrier before instruction selection so that we will not get
286     // deleted block address after enabling default outlining. See D99707 for
287     // more details.
288     addPass(createBarrierNoopPass());
289   }
290 
291   if (EnableGlobalMerge == cl::BOU_TRUE) {
292     addPass(createGlobalMergePass(TM, /* MaxOffset */ 2047,
293                                   /* OnlyOptimizeForSize */ false,
294                                   /* MergeExternalByDefault */ true));
295   }
296 
297   return false;
298 }
299 
300 bool RISCVPassConfig::addInstSelector() {
301   addPass(createRISCVISelDag(getRISCVTargetMachine(), getOptLevel()));
302 
303   return false;
304 }
305 
306 bool RISCVPassConfig::addIRTranslator() {
307   addPass(new IRTranslator(getOptLevel()));
308   return false;
309 }
310 
311 bool RISCVPassConfig::addLegalizeMachineIR() {
312   addPass(new Legalizer());
313   return false;
314 }
315 
316 bool RISCVPassConfig::addRegBankSelect() {
317   addPass(new RegBankSelect());
318   return false;
319 }
320 
321 bool RISCVPassConfig::addGlobalInstructionSelect() {
322   addPass(new InstructionSelect(getOptLevel()));
323   return false;
324 }
325 
326 void RISCVPassConfig::addPreSched2() {}
327 
328 void RISCVPassConfig::addPreEmitPass() {
329   addPass(&BranchRelaxationPassID);
330   addPass(createRISCVMakeCompressibleOptPass());
331 }
332 
333 void RISCVPassConfig::addPreEmitPass2() {
334   addPass(createRISCVExpandPseudoPass());
335   // Schedule the expansion of AMOs at the last possible moment, avoiding the
336   // possibility for other passes to break the requirements for forward
337   // progress in the LR/SC block.
338   addPass(createRISCVExpandAtomicPseudoPass());
339 }
340 
341 void RISCVPassConfig::addMachineSSAOptimization() {
342   TargetPassConfig::addMachineSSAOptimization();
343   if (EnableMachineCombiner)
344     addPass(&MachineCombinerID);
345 
346   if (TM->getTargetTriple().getArch() == Triple::riscv64) {
347     addPass(createRISCVSExtWRemovalPass());
348     addPass(createRISCVStripWSuffixPass());
349   }
350 }
351 
352 void RISCVPassConfig::addPreRegAlloc() {
353   addPass(createRISCVPreRAExpandPseudoPass());
354   if (TM->getOptLevel() != CodeGenOpt::None)
355     addPass(createRISCVMergeBaseOffsetOptPass());
356   addPass(createRISCVInsertVSETVLIPass());
357 }
358 
359 void RISCVPassConfig::addPostRegAlloc() {
360   if (TM->getOptLevel() != CodeGenOpt::None && EnableRedundantCopyElimination)
361     addPass(createRISCVRedundantCopyEliminationPass());
362 }
363 
364 yaml::MachineFunctionInfo *
365 RISCVTargetMachine::createDefaultFuncInfoYAML() const {
366   return new yaml::RISCVMachineFunctionInfo();
367 }
368 
369 yaml::MachineFunctionInfo *
370 RISCVTargetMachine::convertFuncInfoToYAML(const MachineFunction &MF) const {
371   const auto *MFI = MF.getInfo<RISCVMachineFunctionInfo>();
372   return new yaml::RISCVMachineFunctionInfo(*MFI);
373 }
374 
375 bool RISCVTargetMachine::parseMachineFunctionInfo(
376     const yaml::MachineFunctionInfo &MFI, PerFunctionMIParsingState &PFS,
377     SMDiagnostic &Error, SMRange &SourceRange) const {
378   const auto &YamlMFI =
379       static_cast<const yaml::RISCVMachineFunctionInfo &>(MFI);
380   PFS.MF.getInfo<RISCVMachineFunctionInfo>()->initializeBaseYamlFields(YamlMFI);
381   return false;
382 }
383