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