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 "RISCVTargetObjectFile.h"
18 #include "RISCVTargetTransformInfo.h"
19 #include "TargetInfo/RISCVTargetInfo.h"
20 #include "llvm/ADT/STLExtras.h"
21 #include "llvm/Analysis/TargetTransformInfo.h"
22 #include "llvm/CodeGen/GlobalISel/IRTranslator.h"
23 #include "llvm/CodeGen/GlobalISel/InstructionSelect.h"
24 #include "llvm/CodeGen/GlobalISel/Legalizer.h"
25 #include "llvm/CodeGen/GlobalISel/RegBankSelect.h"
26 #include "llvm/CodeGen/MIRParser/MIParser.h"
27 #include "llvm/CodeGen/MIRYamlMapping.h"
28 #include "llvm/CodeGen/MachineScheduler.h"
29 #include "llvm/CodeGen/MacroFusion.h"
30 #include "llvm/CodeGen/Passes.h"
31 #include "llvm/CodeGen/RegAllocRegistry.h"
32 #include "llvm/CodeGen/TargetLoweringObjectFileImpl.h"
33 #include "llvm/CodeGen/TargetPassConfig.h"
34 #include "llvm/InitializePasses.h"
35 #include "llvm/MC/TargetRegistry.h"
36 #include "llvm/Support/FormattedStream.h"
37 #include "llvm/Target/TargetOptions.h"
38 #include "llvm/Transforms/IPO.h"
39 #include "llvm/Transforms/Scalar.h"
40 #include <optional>
41 using namespace llvm;
42 
43 static cl::opt<bool> EnableRedundantCopyElimination(
44     "riscv-enable-copyelim",
45     cl::desc("Enable the redundant copy elimination pass"), cl::init(true),
46     cl::Hidden);
47 
48 // FIXME: Unify control over GlobalMerge.
49 static cl::opt<cl::boolOrDefault>
50     EnableGlobalMerge("riscv-enable-global-merge", cl::Hidden,
51                       cl::desc("Enable the global merge pass"));
52 
53 static cl::opt<bool>
54     EnableMachineCombiner("riscv-enable-machine-combiner",
55                           cl::desc("Enable the machine combiner pass"),
56                           cl::init(true), cl::Hidden);
57 
58 static cl::opt<unsigned> RVVVectorBitsMaxOpt(
59     "riscv-v-vector-bits-max",
60     cl::desc("Assume V extension vector registers are at most this big, "
61              "with zero meaning no maximum size is assumed."),
62     cl::init(0), cl::Hidden);
63 
64 static cl::opt<int> RVVVectorBitsMinOpt(
65     "riscv-v-vector-bits-min",
66     cl::desc("Assume V extension vector registers are at least this big, "
67              "with zero meaning no minimum size is assumed. A value of -1 "
68              "means use Zvl*b extension. This is primarily used to enable "
69              "autovectorization with fixed width vectors."),
70     cl::init(-1), cl::Hidden);
71 
72 static cl::opt<bool> EnableRISCVCopyPropagation(
73     "riscv-enable-copy-propagation",
74     cl::desc("Enable the copy propagation with RISC-V copy instr"),
75     cl::init(true), cl::Hidden);
76 
77 static cl::opt<bool> EnableRISCVDeadRegisterElimination(
78     "riscv-enable-dead-defs", cl::Hidden,
79     cl::desc("Enable the pass that removes dead"
80              " definitons and replaces stores to"
81              " them with stores to x0"),
82     cl::init(true));
83 
84 static cl::opt<bool>
85     EnableSinkFold("riscv-enable-sink-fold",
86                    cl::desc("Enable sinking and folding of instruction copies"),
87                    cl::init(false), cl::Hidden);
88 
89 static cl::opt<bool>
90     EnableLoopDataPrefetch("riscv-enable-loop-data-prefetch", cl::Hidden,
91                            cl::desc("Enable the loop data prefetch pass"),
92                            cl::init(true));
93 
94 static cl::opt<bool>
95     EnableSplitRegAlloc("riscv-split-regalloc", cl::Hidden,
96                         cl::desc("Enable Split RegisterAlloc for RVV"),
97                         cl::init(true));
98 
99 static cl::opt<bool> EnableMISchedLoadClustering(
100     "riscv-misched-load-clustering", cl::Hidden,
101     cl::desc("Enable load clustering in the machine scheduler"),
102     cl::init(false));
103 
LLVMInitializeRISCVTarget()104 extern "C" LLVM_EXTERNAL_VISIBILITY void LLVMInitializeRISCVTarget() {
105   RegisterTargetMachine<RISCVTargetMachine> X(getTheRISCV32Target());
106   RegisterTargetMachine<RISCVTargetMachine> Y(getTheRISCV64Target());
107   auto *PR = PassRegistry::getPassRegistry();
108   initializeGlobalISel(*PR);
109   initializeRISCVO0PreLegalizerCombinerPass(*PR);
110   initializeRISCVPreLegalizerCombinerPass(*PR);
111   initializeRISCVPostLegalizerCombinerPass(*PR);
112   initializeKCFIPass(*PR);
113   initializeRISCVDeadRegisterDefinitionsPass(*PR);
114   initializeRISCVMakeCompressibleOptPass(*PR);
115   initializeRISCVGatherScatterLoweringPass(*PR);
116   initializeRISCVCodeGenPreparePass(*PR);
117   initializeRISCVPostRAExpandPseudoPass(*PR);
118   initializeRISCVMergeBaseOffsetOptPass(*PR);
119   initializeRISCVOptWInstrsPass(*PR);
120   initializeRISCVPreRAExpandPseudoPass(*PR);
121   initializeRISCVExpandPseudoPass(*PR);
122   initializeRISCVFoldMasksPass(*PR);
123   initializeRISCVInsertVSETVLIPass(*PR);
124   initializeRISCVInsertReadWriteCSRPass(*PR);
125   initializeRISCVInsertWriteVXRMPass(*PR);
126   initializeRISCVDAGToDAGISelPass(*PR);
127   initializeRISCVInitUndefPass(*PR);
128   initializeRISCVMoveMergePass(*PR);
129   initializeRISCVPushPopOptPass(*PR);
130 }
131 
computeDataLayout(const Triple & TT,const TargetOptions & Options)132 static StringRef computeDataLayout(const Triple &TT,
133                                    const TargetOptions &Options) {
134   StringRef ABIName = Options.MCOptions.getABIName();
135   if (TT.isArch64Bit()) {
136     if (ABIName == "lp64e")
137       return "e-m:e-p:64:64-i64:64-i128:128-n32:64-S64";
138 
139     return "e-m:e-p:64:64-i64:64-i128:128-n32:64-S128";
140   }
141   assert(TT.isArch32Bit() && "only RV32 and RV64 are currently supported");
142 
143   if (ABIName == "ilp32e")
144     return "e-m:e-p:32:32-i64:64-n32-S32";
145 
146   return "e-m:e-p:32:32-i64:64-n32-S128";
147 }
148 
getEffectiveRelocModel(const Triple & TT,std::optional<Reloc::Model> RM)149 static Reloc::Model getEffectiveRelocModel(const Triple &TT,
150                                            std::optional<Reloc::Model> RM) {
151   return RM.value_or(Reloc::Static);
152 }
153 
RISCVTargetMachine(const Target & T,const Triple & TT,StringRef CPU,StringRef FS,const TargetOptions & Options,std::optional<Reloc::Model> RM,std::optional<CodeModel::Model> CM,CodeGenOptLevel OL,bool JIT)154 RISCVTargetMachine::RISCVTargetMachine(const Target &T, const Triple &TT,
155                                        StringRef CPU, StringRef FS,
156                                        const TargetOptions &Options,
157                                        std::optional<Reloc::Model> RM,
158                                        std::optional<CodeModel::Model> CM,
159                                        CodeGenOptLevel OL, bool JIT)
160     : LLVMTargetMachine(T, computeDataLayout(TT, Options), TT, CPU, FS, Options,
161                         getEffectiveRelocModel(TT, RM),
162                         getEffectiveCodeModel(CM, CodeModel::Small), OL),
163       TLOF(std::make_unique<RISCVELFTargetObjectFile>()) {
164   initAsmInfo();
165 
166   // RISC-V supports the MachineOutliner.
167   setMachineOutliner(true);
168   setSupportsDefaultOutlining(true);
169 
170   if (TT.isOSFuchsia() && !TT.isArch64Bit())
171     report_fatal_error("Fuchsia is only supported for 64-bit");
172 }
173 
174 const RISCVSubtarget *
getSubtargetImpl(const Function & F) const175 RISCVTargetMachine::getSubtargetImpl(const Function &F) const {
176   Attribute CPUAttr = F.getFnAttribute("target-cpu");
177   Attribute TuneAttr = F.getFnAttribute("tune-cpu");
178   Attribute FSAttr = F.getFnAttribute("target-features");
179 
180   std::string CPU =
181       CPUAttr.isValid() ? CPUAttr.getValueAsString().str() : TargetCPU;
182   std::string TuneCPU =
183       TuneAttr.isValid() ? TuneAttr.getValueAsString().str() : CPU;
184   std::string FS =
185       FSAttr.isValid() ? FSAttr.getValueAsString().str() : TargetFS;
186 
187   unsigned RVVBitsMin = RVVVectorBitsMinOpt;
188   unsigned RVVBitsMax = RVVVectorBitsMaxOpt;
189 
190   Attribute VScaleRangeAttr = F.getFnAttribute(Attribute::VScaleRange);
191   if (VScaleRangeAttr.isValid()) {
192     if (!RVVVectorBitsMinOpt.getNumOccurrences())
193       RVVBitsMin = VScaleRangeAttr.getVScaleRangeMin() * RISCV::RVVBitsPerBlock;
194     std::optional<unsigned> VScaleMax = VScaleRangeAttr.getVScaleRangeMax();
195     if (VScaleMax.has_value() && !RVVVectorBitsMaxOpt.getNumOccurrences())
196       RVVBitsMax = *VScaleMax * RISCV::RVVBitsPerBlock;
197   }
198 
199   if (RVVBitsMin != -1U) {
200     // FIXME: Change to >= 32 when VLEN = 32 is supported.
201     assert((RVVBitsMin == 0 || (RVVBitsMin >= 64 && RVVBitsMin <= 65536 &&
202                                 isPowerOf2_32(RVVBitsMin))) &&
203            "V or Zve* extension requires vector length to be in the range of "
204            "64 to 65536 and a power 2!");
205     assert((RVVBitsMax >= RVVBitsMin || RVVBitsMax == 0) &&
206            "Minimum V extension vector length should not be larger than its "
207            "maximum!");
208   }
209   assert((RVVBitsMax == 0 || (RVVBitsMax >= 64 && RVVBitsMax <= 65536 &&
210                               isPowerOf2_32(RVVBitsMax))) &&
211          "V or Zve* extension requires vector length to be in the range of "
212          "64 to 65536 and a power 2!");
213 
214   if (RVVBitsMin != -1U) {
215     if (RVVBitsMax != 0) {
216       RVVBitsMin = std::min(RVVBitsMin, RVVBitsMax);
217       RVVBitsMax = std::max(RVVBitsMin, RVVBitsMax);
218     }
219 
220     RVVBitsMin = llvm::bit_floor(
221         (RVVBitsMin < 64 || RVVBitsMin > 65536) ? 0 : RVVBitsMin);
222   }
223   RVVBitsMax =
224       llvm::bit_floor((RVVBitsMax < 64 || RVVBitsMax > 65536) ? 0 : RVVBitsMax);
225 
226   SmallString<512> Key;
227   raw_svector_ostream(Key) << "RVVMin" << RVVBitsMin << "RVVMax" << RVVBitsMax
228                            << CPU << TuneCPU << FS;
229   auto &I = SubtargetMap[Key];
230   if (!I) {
231     // This needs to be done before we create a new subtarget since any
232     // creation will depend on the TM and the code generation flags on the
233     // function that reside in TargetOptions.
234     resetTargetOptions(F);
235     auto ABIName = Options.MCOptions.getABIName();
236     if (const MDString *ModuleTargetABI = dyn_cast_or_null<MDString>(
237             F.getParent()->getModuleFlag("target-abi"))) {
238       auto TargetABI = RISCVABI::getTargetABI(ABIName);
239       if (TargetABI != RISCVABI::ABI_Unknown &&
240           ModuleTargetABI->getString() != ABIName) {
241         report_fatal_error("-target-abi option != target-abi module flag");
242       }
243       ABIName = ModuleTargetABI->getString();
244     }
245     I = std::make_unique<RISCVSubtarget>(
246         TargetTriple, CPU, TuneCPU, FS, ABIName, RVVBitsMin, RVVBitsMax, *this);
247   }
248   return I.get();
249 }
250 
createMachineFunctionInfo(BumpPtrAllocator & Allocator,const Function & F,const TargetSubtargetInfo * STI) const251 MachineFunctionInfo *RISCVTargetMachine::createMachineFunctionInfo(
252     BumpPtrAllocator &Allocator, const Function &F,
253     const TargetSubtargetInfo *STI) const {
254   return RISCVMachineFunctionInfo::create<RISCVMachineFunctionInfo>(Allocator,
255                                                                     F, STI);
256 }
257 
258 TargetTransformInfo
getTargetTransformInfo(const Function & F) const259 RISCVTargetMachine::getTargetTransformInfo(const Function &F) const {
260   return TargetTransformInfo(RISCVTTIImpl(this, F));
261 }
262 
263 // A RISC-V hart has a single byte-addressable address space of 2^XLEN bytes
264 // for all memory accesses, so it is reasonable to assume that an
265 // implementation has no-op address space casts. If an implementation makes a
266 // change to this, they can override it here.
isNoopAddrSpaceCast(unsigned SrcAS,unsigned DstAS) const267 bool RISCVTargetMachine::isNoopAddrSpaceCast(unsigned SrcAS,
268                                              unsigned DstAS) const {
269   return true;
270 }
271 
272 namespace {
273 
274 class RVVRegisterRegAlloc : public RegisterRegAllocBase<RVVRegisterRegAlloc> {
275 public:
RVVRegisterRegAlloc(const char * N,const char * D,FunctionPassCtor C)276   RVVRegisterRegAlloc(const char *N, const char *D, FunctionPassCtor C)
277       : RegisterRegAllocBase(N, D, C) {}
278 };
279 
onlyAllocateRVVReg(const TargetRegisterInfo & TRI,const TargetRegisterClass & RC)280 static bool onlyAllocateRVVReg(const TargetRegisterInfo &TRI,
281                                const TargetRegisterClass &RC) {
282   return RISCV::VRRegClass.hasSubClassEq(&RC) ||
283          RISCV::VRM2RegClass.hasSubClassEq(&RC) ||
284          RISCV::VRM4RegClass.hasSubClassEq(&RC) ||
285          RISCV::VRM8RegClass.hasSubClassEq(&RC) ||
286          RISCV::VRN2M1RegClass.hasSubClassEq(&RC) ||
287          RISCV::VRN2M2RegClass.hasSubClassEq(&RC) ||
288          RISCV::VRN2M4RegClass.hasSubClassEq(&RC) ||
289          RISCV::VRN3M1RegClass.hasSubClassEq(&RC) ||
290          RISCV::VRN3M2RegClass.hasSubClassEq(&RC) ||
291          RISCV::VRN4M1RegClass.hasSubClassEq(&RC) ||
292          RISCV::VRN4M2RegClass.hasSubClassEq(&RC) ||
293          RISCV::VRN5M1RegClass.hasSubClassEq(&RC) ||
294          RISCV::VRN6M1RegClass.hasSubClassEq(&RC) ||
295          RISCV::VRN7M1RegClass.hasSubClassEq(&RC) ||
296          RISCV::VRN8M1RegClass.hasSubClassEq(&RC);
297 }
298 
useDefaultRegisterAllocator()299 static FunctionPass *useDefaultRegisterAllocator() { return nullptr; }
300 
301 static llvm::once_flag InitializeDefaultRVVRegisterAllocatorFlag;
302 
303 /// -riscv-rvv-regalloc=<fast|basic|greedy> command line option.
304 /// This option could designate the rvv register allocator only.
305 /// For example: -riscv-rvv-regalloc=basic
306 static cl::opt<RVVRegisterRegAlloc::FunctionPassCtor, false,
307                RegisterPassParser<RVVRegisterRegAlloc>>
308     RVVRegAlloc("riscv-rvv-regalloc", cl::Hidden,
309                 cl::init(&useDefaultRegisterAllocator),
310                 cl::desc("Register allocator to use for RVV register."));
311 
initializeDefaultRVVRegisterAllocatorOnce()312 static void initializeDefaultRVVRegisterAllocatorOnce() {
313   RegisterRegAlloc::FunctionPassCtor Ctor = RVVRegisterRegAlloc::getDefault();
314 
315   if (!Ctor) {
316     Ctor = RVVRegAlloc;
317     RVVRegisterRegAlloc::setDefault(RVVRegAlloc);
318   }
319 }
320 
createBasicRVVRegisterAllocator()321 static FunctionPass *createBasicRVVRegisterAllocator() {
322   return createBasicRegisterAllocator(onlyAllocateRVVReg);
323 }
324 
createGreedyRVVRegisterAllocator()325 static FunctionPass *createGreedyRVVRegisterAllocator() {
326   return createGreedyRegisterAllocator(onlyAllocateRVVReg);
327 }
328 
createFastRVVRegisterAllocator()329 static FunctionPass *createFastRVVRegisterAllocator() {
330   return createFastRegisterAllocator(onlyAllocateRVVReg, false);
331 }
332 
333 static RVVRegisterRegAlloc basicRegAllocRVVReg("basic",
334                                                "basic register allocator",
335                                                createBasicRVVRegisterAllocator);
336 static RVVRegisterRegAlloc
337     greedyRegAllocRVVReg("greedy", "greedy register allocator",
338                          createGreedyRVVRegisterAllocator);
339 
340 static RVVRegisterRegAlloc fastRegAllocRVVReg("fast", "fast register allocator",
341                                               createFastRVVRegisterAllocator);
342 
343 class RISCVPassConfig : public TargetPassConfig {
344 public:
RISCVPassConfig(RISCVTargetMachine & TM,PassManagerBase & PM)345   RISCVPassConfig(RISCVTargetMachine &TM, PassManagerBase &PM)
346       : TargetPassConfig(TM, PM) {
347     if (TM.getOptLevel() != CodeGenOptLevel::None)
348       substitutePass(&PostRASchedulerID, &PostMachineSchedulerID);
349     setEnableSinkAndFold(EnableSinkFold);
350   }
351 
getRISCVTargetMachine() const352   RISCVTargetMachine &getRISCVTargetMachine() const {
353     return getTM<RISCVTargetMachine>();
354   }
355 
356   ScheduleDAGInstrs *
createMachineScheduler(MachineSchedContext * C) const357   createMachineScheduler(MachineSchedContext *C) const override {
358     const RISCVSubtarget &ST = C->MF->getSubtarget<RISCVSubtarget>();
359     ScheduleDAGMILive *DAG = nullptr;
360     if (EnableMISchedLoadClustering) {
361       DAG = createGenericSchedLive(C);
362       DAG->addMutation(createLoadClusterDAGMutation(
363           DAG->TII, DAG->TRI, /*ReorderWhileClustering=*/true));
364     }
365     const auto &MacroFusions = ST.getMacroFusions();
366     if (!MacroFusions.empty()) {
367       DAG = DAG ? DAG : createGenericSchedLive(C);
368       DAG->addMutation(createMacroFusionDAGMutation(MacroFusions));
369     }
370     return DAG;
371   }
372 
373   ScheduleDAGInstrs *
createPostMachineScheduler(MachineSchedContext * C) const374   createPostMachineScheduler(MachineSchedContext *C) const override {
375     const RISCVSubtarget &ST = C->MF->getSubtarget<RISCVSubtarget>();
376     const auto &MacroFusions = ST.getMacroFusions();
377     if (!MacroFusions.empty()) {
378       ScheduleDAGMI *DAG = createGenericSchedPostRA(C);
379       DAG->addMutation(createMacroFusionDAGMutation(MacroFusions));
380       return DAG;
381     }
382     return nullptr;
383   }
384 
385   void addIRPasses() override;
386   bool addPreISel() override;
387   bool addInstSelector() override;
388   bool addIRTranslator() override;
389   void addPreLegalizeMachineIR() override;
390   bool addLegalizeMachineIR() override;
391   void addPreRegBankSelect() override;
392   bool addRegBankSelect() override;
393   bool addGlobalInstructionSelect() override;
394   void addPreEmitPass() override;
395   void addPreEmitPass2() override;
396   void addPreSched2() override;
397   void addMachineSSAOptimization() override;
398   FunctionPass *createRVVRegAllocPass(bool Optimized);
399   bool addRegAssignAndRewriteFast() override;
400   bool addRegAssignAndRewriteOptimized() override;
401   void addPreRegAlloc() override;
402   void addPostRegAlloc() override;
403   void addOptimizedRegAlloc() override;
404   void addFastRegAlloc() override;
405 };
406 } // namespace
407 
createPassConfig(PassManagerBase & PM)408 TargetPassConfig *RISCVTargetMachine::createPassConfig(PassManagerBase &PM) {
409   return new RISCVPassConfig(*this, PM);
410 }
411 
createRVVRegAllocPass(bool Optimized)412 FunctionPass *RISCVPassConfig::createRVVRegAllocPass(bool Optimized) {
413   // Initialize the global default.
414   llvm::call_once(InitializeDefaultRVVRegisterAllocatorFlag,
415                   initializeDefaultRVVRegisterAllocatorOnce);
416 
417   RegisterRegAlloc::FunctionPassCtor Ctor = RVVRegisterRegAlloc::getDefault();
418   if (Ctor != useDefaultRegisterAllocator)
419     return Ctor();
420 
421   if (Optimized)
422     return createGreedyRVVRegisterAllocator();
423 
424   return createFastRVVRegisterAllocator();
425 }
426 
addRegAssignAndRewriteFast()427 bool RISCVPassConfig::addRegAssignAndRewriteFast() {
428   if (EnableSplitRegAlloc)
429     addPass(createRVVRegAllocPass(false));
430   return TargetPassConfig::addRegAssignAndRewriteFast();
431 }
432 
addRegAssignAndRewriteOptimized()433 bool RISCVPassConfig::addRegAssignAndRewriteOptimized() {
434   if (EnableSplitRegAlloc) {
435     addPass(createRVVRegAllocPass(true));
436     addPass(createVirtRegRewriter(false));
437   }
438   return TargetPassConfig::addRegAssignAndRewriteOptimized();
439 }
440 
addIRPasses()441 void RISCVPassConfig::addIRPasses() {
442   addPass(createAtomicExpandPass());
443 
444   if (getOptLevel() != CodeGenOptLevel::None) {
445     if (EnableLoopDataPrefetch)
446       addPass(createLoopDataPrefetchPass());
447 
448     addPass(createRISCVGatherScatterLoweringPass());
449     addPass(createInterleavedAccessPass());
450     addPass(createRISCVCodeGenPreparePass());
451   }
452 
453   TargetPassConfig::addIRPasses();
454 }
455 
addPreISel()456 bool RISCVPassConfig::addPreISel() {
457   if (TM->getOptLevel() != CodeGenOptLevel::None) {
458     // Add a barrier before instruction selection so that we will not get
459     // deleted block address after enabling default outlining. See D99707 for
460     // more details.
461     addPass(createBarrierNoopPass());
462   }
463 
464   if (EnableGlobalMerge == cl::BOU_TRUE) {
465     addPass(createGlobalMergePass(TM, /* MaxOffset */ 2047,
466                                   /* OnlyOptimizeForSize */ false,
467                                   /* MergeExternalByDefault */ true));
468   }
469 
470   return false;
471 }
472 
addInstSelector()473 bool RISCVPassConfig::addInstSelector() {
474   addPass(createRISCVISelDag(getRISCVTargetMachine(), getOptLevel()));
475 
476   return false;
477 }
478 
addIRTranslator()479 bool RISCVPassConfig::addIRTranslator() {
480   addPass(new IRTranslator(getOptLevel()));
481   return false;
482 }
483 
addPreLegalizeMachineIR()484 void RISCVPassConfig::addPreLegalizeMachineIR() {
485   if (getOptLevel() == CodeGenOptLevel::None) {
486     addPass(createRISCVO0PreLegalizerCombiner());
487   } else {
488     addPass(createRISCVPreLegalizerCombiner());
489   }
490 }
491 
addLegalizeMachineIR()492 bool RISCVPassConfig::addLegalizeMachineIR() {
493   addPass(new Legalizer());
494   return false;
495 }
496 
addPreRegBankSelect()497 void RISCVPassConfig::addPreRegBankSelect() {
498   if (getOptLevel() != CodeGenOptLevel::None)
499     addPass(createRISCVPostLegalizerCombiner());
500 }
501 
addRegBankSelect()502 bool RISCVPassConfig::addRegBankSelect() {
503   addPass(new RegBankSelect());
504   return false;
505 }
506 
addGlobalInstructionSelect()507 bool RISCVPassConfig::addGlobalInstructionSelect() {
508   addPass(new InstructionSelect(getOptLevel()));
509   return false;
510 }
511 
addPreSched2()512 void RISCVPassConfig::addPreSched2() {
513   addPass(createRISCVPostRAExpandPseudoPass());
514 
515   // Emit KCFI checks for indirect calls.
516   addPass(createKCFIPass());
517 }
518 
addPreEmitPass()519 void RISCVPassConfig::addPreEmitPass() {
520   addPass(&BranchRelaxationPassID);
521   addPass(createRISCVMakeCompressibleOptPass());
522 
523   // TODO: It would potentially be better to schedule copy propagation after
524   // expanding pseudos (in addPreEmitPass2). However, performing copy
525   // propagation after the machine outliner (which runs after addPreEmitPass)
526   // currently leads to incorrect code-gen, where copies to registers within
527   // outlined functions are removed erroneously.
528   if (TM->getOptLevel() >= CodeGenOptLevel::Default &&
529       EnableRISCVCopyPropagation)
530     addPass(createMachineCopyPropagationPass(true));
531 }
532 
addPreEmitPass2()533 void RISCVPassConfig::addPreEmitPass2() {
534   if (TM->getOptLevel() != CodeGenOptLevel::None) {
535     addPass(createRISCVMoveMergePass());
536     // Schedule PushPop Optimization before expansion of Pseudo instruction,
537     // ensuring return instruction is detected correctly.
538     addPass(createRISCVPushPopOptimizationPass());
539   }
540   addPass(createRISCVExpandPseudoPass());
541 
542   // Schedule the expansion of AMOs at the last possible moment, avoiding the
543   // possibility for other passes to break the requirements for forward
544   // progress in the LR/SC block.
545   addPass(createRISCVExpandAtomicPseudoPass());
546 
547   // KCFI indirect call checks are lowered to a bundle.
548   addPass(createUnpackMachineBundles([&](const MachineFunction &MF) {
549     return MF.getFunction().getParent()->getModuleFlag("kcfi");
550   }));
551 }
552 
addMachineSSAOptimization()553 void RISCVPassConfig::addMachineSSAOptimization() {
554   addPass(createRISCVFoldMasksPass());
555 
556   TargetPassConfig::addMachineSSAOptimization();
557 
558   if (EnableMachineCombiner)
559     addPass(&MachineCombinerID);
560 
561   if (TM->getTargetTriple().isRISCV64()) {
562     addPass(createRISCVOptWInstrsPass());
563   }
564 }
565 
addPreRegAlloc()566 void RISCVPassConfig::addPreRegAlloc() {
567   addPass(createRISCVPreRAExpandPseudoPass());
568   if (TM->getOptLevel() != CodeGenOptLevel::None)
569     addPass(createRISCVMergeBaseOffsetOptPass());
570   addPass(createRISCVInsertVSETVLIPass());
571   if (TM->getOptLevel() != CodeGenOptLevel::None &&
572       EnableRISCVDeadRegisterElimination)
573     addPass(createRISCVDeadRegisterDefinitionsPass());
574   addPass(createRISCVInsertReadWriteCSRPass());
575   addPass(createRISCVInsertWriteVXRMPass());
576 }
577 
addOptimizedRegAlloc()578 void RISCVPassConfig::addOptimizedRegAlloc() {
579   insertPass(&DetectDeadLanesID, &RISCVInitUndefID);
580 
581   TargetPassConfig::addOptimizedRegAlloc();
582 }
583 
addFastRegAlloc()584 void RISCVPassConfig::addFastRegAlloc() {
585   addPass(createRISCVInitUndefPass());
586   TargetPassConfig::addFastRegAlloc();
587 }
588 
589 
addPostRegAlloc()590 void RISCVPassConfig::addPostRegAlloc() {
591   if (TM->getOptLevel() != CodeGenOptLevel::None &&
592       EnableRedundantCopyElimination)
593     addPass(createRISCVRedundantCopyEliminationPass());
594 }
595 
596 yaml::MachineFunctionInfo *
createDefaultFuncInfoYAML() const597 RISCVTargetMachine::createDefaultFuncInfoYAML() const {
598   return new yaml::RISCVMachineFunctionInfo();
599 }
600 
601 yaml::MachineFunctionInfo *
convertFuncInfoToYAML(const MachineFunction & MF) const602 RISCVTargetMachine::convertFuncInfoToYAML(const MachineFunction &MF) const {
603   const auto *MFI = MF.getInfo<RISCVMachineFunctionInfo>();
604   return new yaml::RISCVMachineFunctionInfo(*MFI);
605 }
606 
parseMachineFunctionInfo(const yaml::MachineFunctionInfo & MFI,PerFunctionMIParsingState & PFS,SMDiagnostic & Error,SMRange & SourceRange) const607 bool RISCVTargetMachine::parseMachineFunctionInfo(
608     const yaml::MachineFunctionInfo &MFI, PerFunctionMIParsingState &PFS,
609     SMDiagnostic &Error, SMRange &SourceRange) const {
610   const auto &YamlMFI =
611       static_cast<const yaml::RISCVMachineFunctionInfo &>(MFI);
612   PFS.MF.getInfo<RISCVMachineFunctionInfo>()->initializeBaseYamlFields(YamlMFI);
613   return false;
614 }
615