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