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