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/Analysis/TargetTransformInfo.h" 21 #include "llvm/CodeGen/GlobalISel/CSEInfo.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/Passes/PassBuilder.h" 37 #include "llvm/Support/Compiler.h" 38 #include "llvm/Target/TargetOptions.h" 39 #include "llvm/Transforms/IPO.h" 40 #include "llvm/Transforms/Scalar.h" 41 #include "llvm/Transforms/Vectorize/EVLIndVarSimplify.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 " definitions 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> EnablePostMISchedLoadStoreClustering( 103 "riscv-postmisched-load-store-clustering", cl::Hidden, 104 cl::desc("Enable PostRA load and store clustering in the machine scheduler"), 105 cl::init(true)); 106 107 static cl::opt<bool> 108 EnableVLOptimizer("riscv-enable-vl-optimizer", 109 cl::desc("Enable the RISC-V VL Optimizer pass"), 110 cl::init(true), cl::Hidden); 111 112 static cl::opt<bool> DisableVectorMaskMutation( 113 "riscv-disable-vector-mask-mutation", 114 cl::desc("Disable the vector mask scheduling mutation"), cl::init(false), 115 cl::Hidden); 116 117 static cl::opt<bool> 118 EnableMachinePipeliner("riscv-enable-pipeliner", 119 cl::desc("Enable Machine Pipeliner for RISC-V"), 120 cl::init(false), cl::Hidden); 121 122 extern "C" LLVM_ABI LLVM_EXTERNAL_VISIBILITY void LLVMInitializeRISCVTarget() { 123 RegisterTargetMachine<RISCVTargetMachine> X(getTheRISCV32Target()); 124 RegisterTargetMachine<RISCVTargetMachine> Y(getTheRISCV64Target()); 125 auto *PR = PassRegistry::getPassRegistry(); 126 initializeGlobalISel(*PR); 127 initializeRISCVO0PreLegalizerCombinerPass(*PR); 128 initializeRISCVPreLegalizerCombinerPass(*PR); 129 initializeRISCVPostLegalizerCombinerPass(*PR); 130 initializeKCFIPass(*PR); 131 initializeRISCVDeadRegisterDefinitionsPass(*PR); 132 initializeRISCVLateBranchOptPass(*PR); 133 initializeRISCVMakeCompressibleOptPass(*PR); 134 initializeRISCVGatherScatterLoweringPass(*PR); 135 initializeRISCVCodeGenPreparePass(*PR); 136 initializeRISCVPostRAExpandPseudoPass(*PR); 137 initializeRISCVMergeBaseOffsetOptPass(*PR); 138 initializeRISCVOptWInstrsPass(*PR); 139 initializeRISCVFoldMemOffsetPass(*PR); 140 initializeRISCVPreRAExpandPseudoPass(*PR); 141 initializeRISCVExpandPseudoPass(*PR); 142 initializeRISCVVectorPeepholePass(*PR); 143 initializeRISCVVLOptimizerPass(*PR); 144 initializeRISCVVMV0EliminationPass(*PR); 145 initializeRISCVInsertVSETVLIPass(*PR); 146 initializeRISCVInsertReadWriteCSRPass(*PR); 147 initializeRISCVInsertWriteVXRMPass(*PR); 148 initializeRISCVDAGToDAGISelLegacyPass(*PR); 149 initializeRISCVMoveMergePass(*PR); 150 initializeRISCVPushPopOptPass(*PR); 151 initializeRISCVIndirectBranchTrackingPass(*PR); 152 initializeRISCVLoadStoreOptPass(*PR); 153 initializeRISCVExpandAtomicPseudoPass(*PR); 154 initializeRISCVRedundantCopyEliminationPass(*PR); 155 initializeRISCVAsmPrinterPass(*PR); 156 } 157 158 static StringRef computeDataLayout(const Triple &TT, 159 const TargetOptions &Options) { 160 StringRef ABIName = Options.MCOptions.getABIName(); 161 if (TT.isArch64Bit()) { 162 if (ABIName == "lp64e") 163 return "e-m:e-p:64:64-i64:64-i128:128-n32:64-S64"; 164 165 return "e-m:e-p:64:64-i64:64-i128:128-n32:64-S128"; 166 } 167 assert(TT.isArch32Bit() && "only RV32 and RV64 are currently supported"); 168 169 if (ABIName == "ilp32e") 170 return "e-m:e-p:32:32-i64:64-n32-S32"; 171 172 return "e-m:e-p:32:32-i64:64-n32-S128"; 173 } 174 175 static Reloc::Model getEffectiveRelocModel(const Triple &TT, 176 std::optional<Reloc::Model> RM) { 177 return RM.value_or(Reloc::Static); 178 } 179 180 RISCVTargetMachine::RISCVTargetMachine(const Target &T, const Triple &TT, 181 StringRef CPU, StringRef FS, 182 const TargetOptions &Options, 183 std::optional<Reloc::Model> RM, 184 std::optional<CodeModel::Model> CM, 185 CodeGenOptLevel OL, bool JIT) 186 : CodeGenTargetMachineImpl(T, computeDataLayout(TT, Options), TT, CPU, FS, 187 Options, getEffectiveRelocModel(TT, RM), 188 getEffectiveCodeModel(CM, CodeModel::Small), OL), 189 TLOF(std::make_unique<RISCVELFTargetObjectFile>()) { 190 initAsmInfo(); 191 192 // RISC-V supports the MachineOutliner. 193 setMachineOutliner(true); 194 setSupportsDefaultOutlining(true); 195 196 if (TT.isOSFuchsia() && !TT.isArch64Bit()) 197 report_fatal_error("Fuchsia is only supported for 64-bit"); 198 199 setCFIFixup(true); 200 } 201 202 const RISCVSubtarget * 203 RISCVTargetMachine::getSubtargetImpl(const Function &F) const { 204 Attribute CPUAttr = F.getFnAttribute("target-cpu"); 205 Attribute TuneAttr = F.getFnAttribute("tune-cpu"); 206 Attribute FSAttr = F.getFnAttribute("target-features"); 207 208 std::string CPU = 209 CPUAttr.isValid() ? CPUAttr.getValueAsString().str() : TargetCPU; 210 std::string TuneCPU = 211 TuneAttr.isValid() ? TuneAttr.getValueAsString().str() : CPU; 212 std::string FS = 213 FSAttr.isValid() ? FSAttr.getValueAsString().str() : TargetFS; 214 215 unsigned RVVBitsMin = RVVVectorBitsMinOpt; 216 unsigned RVVBitsMax = RVVVectorBitsMaxOpt; 217 218 Attribute VScaleRangeAttr = F.getFnAttribute(Attribute::VScaleRange); 219 if (VScaleRangeAttr.isValid()) { 220 if (!RVVVectorBitsMinOpt.getNumOccurrences()) 221 RVVBitsMin = VScaleRangeAttr.getVScaleRangeMin() * RISCV::RVVBitsPerBlock; 222 std::optional<unsigned> VScaleMax = VScaleRangeAttr.getVScaleRangeMax(); 223 if (VScaleMax.has_value() && !RVVVectorBitsMaxOpt.getNumOccurrences()) 224 RVVBitsMax = *VScaleMax * RISCV::RVVBitsPerBlock; 225 } 226 227 if (RVVBitsMin != -1U) { 228 // FIXME: Change to >= 32 when VLEN = 32 is supported. 229 assert((RVVBitsMin == 0 || (RVVBitsMin >= 64 && RVVBitsMin <= 65536 && 230 isPowerOf2_32(RVVBitsMin))) && 231 "V or Zve* extension requires vector length to be in the range of " 232 "64 to 65536 and a power 2!"); 233 assert((RVVBitsMax >= RVVBitsMin || RVVBitsMax == 0) && 234 "Minimum V extension vector length should not be larger than its " 235 "maximum!"); 236 } 237 assert((RVVBitsMax == 0 || (RVVBitsMax >= 64 && RVVBitsMax <= 65536 && 238 isPowerOf2_32(RVVBitsMax))) && 239 "V or Zve* extension requires vector length to be in the range of " 240 "64 to 65536 and a power 2!"); 241 242 if (RVVBitsMin != -1U) { 243 if (RVVBitsMax != 0) { 244 RVVBitsMin = std::min(RVVBitsMin, RVVBitsMax); 245 RVVBitsMax = std::max(RVVBitsMin, RVVBitsMax); 246 } 247 248 RVVBitsMin = llvm::bit_floor( 249 (RVVBitsMin < 64 || RVVBitsMin > 65536) ? 0 : RVVBitsMin); 250 } 251 RVVBitsMax = 252 llvm::bit_floor((RVVBitsMax < 64 || RVVBitsMax > 65536) ? 0 : RVVBitsMax); 253 254 SmallString<512> Key; 255 raw_svector_ostream(Key) << "RVVMin" << RVVBitsMin << "RVVMax" << RVVBitsMax 256 << CPU << TuneCPU << FS; 257 auto &I = SubtargetMap[Key]; 258 if (!I) { 259 // This needs to be done before we create a new subtarget since any 260 // creation will depend on the TM and the code generation flags on the 261 // function that reside in TargetOptions. 262 resetTargetOptions(F); 263 auto ABIName = Options.MCOptions.getABIName(); 264 if (const MDString *ModuleTargetABI = dyn_cast_or_null<MDString>( 265 F.getParent()->getModuleFlag("target-abi"))) { 266 auto TargetABI = RISCVABI::getTargetABI(ABIName); 267 if (TargetABI != RISCVABI::ABI_Unknown && 268 ModuleTargetABI->getString() != ABIName) { 269 report_fatal_error("-target-abi option != target-abi module flag"); 270 } 271 ABIName = ModuleTargetABI->getString(); 272 } 273 I = std::make_unique<RISCVSubtarget>( 274 TargetTriple, CPU, TuneCPU, FS, ABIName, RVVBitsMin, RVVBitsMax, *this); 275 } 276 return I.get(); 277 } 278 279 MachineFunctionInfo *RISCVTargetMachine::createMachineFunctionInfo( 280 BumpPtrAllocator &Allocator, const Function &F, 281 const TargetSubtargetInfo *STI) const { 282 return RISCVMachineFunctionInfo::create<RISCVMachineFunctionInfo>( 283 Allocator, F, static_cast<const RISCVSubtarget *>(STI)); 284 } 285 286 TargetTransformInfo 287 RISCVTargetMachine::getTargetTransformInfo(const Function &F) const { 288 return TargetTransformInfo(std::make_unique<RISCVTTIImpl>(this, F)); 289 } 290 291 // A RISC-V hart has a single byte-addressable address space of 2^XLEN bytes 292 // for all memory accesses, so it is reasonable to assume that an 293 // implementation has no-op address space casts. If an implementation makes a 294 // change to this, they can override it here. 295 bool RISCVTargetMachine::isNoopAddrSpaceCast(unsigned SrcAS, 296 unsigned DstAS) const { 297 return true; 298 } 299 300 ScheduleDAGInstrs * 301 RISCVTargetMachine::createMachineScheduler(MachineSchedContext *C) const { 302 ScheduleDAGMILive *DAG = createSchedLive(C); 303 if (EnableMISchedLoadStoreClustering) { 304 DAG->addMutation(createLoadClusterDAGMutation( 305 DAG->TII, DAG->TRI, /*ReorderWhileClustering=*/true)); 306 DAG->addMutation(createStoreClusterDAGMutation( 307 DAG->TII, DAG->TRI, /*ReorderWhileClustering=*/true)); 308 } 309 310 const RISCVSubtarget &ST = C->MF->getSubtarget<RISCVSubtarget>(); 311 if (!DisableVectorMaskMutation && ST.hasVInstructions()) 312 DAG->addMutation(createRISCVVectorMaskDAGMutation(DAG->TRI)); 313 314 return DAG; 315 } 316 317 ScheduleDAGInstrs * 318 RISCVTargetMachine::createPostMachineScheduler(MachineSchedContext *C) const { 319 ScheduleDAGMI *DAG = createSchedPostRA(C); 320 if (EnablePostMISchedLoadStoreClustering) { 321 DAG->addMutation(createLoadClusterDAGMutation( 322 DAG->TII, DAG->TRI, /*ReorderWhileClustering=*/true)); 323 DAG->addMutation(createStoreClusterDAGMutation( 324 DAG->TII, DAG->TRI, /*ReorderWhileClustering=*/true)); 325 } 326 327 return DAG; 328 } 329 330 namespace { 331 332 class RVVRegisterRegAlloc : public RegisterRegAllocBase<RVVRegisterRegAlloc> { 333 public: 334 RVVRegisterRegAlloc(const char *N, const char *D, FunctionPassCtor C) 335 : RegisterRegAllocBase(N, D, C) {} 336 }; 337 338 static bool onlyAllocateRVVReg(const TargetRegisterInfo &TRI, 339 const MachineRegisterInfo &MRI, 340 const Register Reg) { 341 const TargetRegisterClass *RC = MRI.getRegClass(Reg); 342 return RISCVRegisterInfo::isRVVRegClass(RC); 343 } 344 345 static FunctionPass *useDefaultRegisterAllocator() { return nullptr; } 346 347 static llvm::once_flag InitializeDefaultRVVRegisterAllocatorFlag; 348 349 /// -riscv-rvv-regalloc=<fast|basic|greedy> command line option. 350 /// This option could designate the rvv register allocator only. 351 /// For example: -riscv-rvv-regalloc=basic 352 static cl::opt<RVVRegisterRegAlloc::FunctionPassCtor, false, 353 RegisterPassParser<RVVRegisterRegAlloc>> 354 RVVRegAlloc("riscv-rvv-regalloc", cl::Hidden, 355 cl::init(&useDefaultRegisterAllocator), 356 cl::desc("Register allocator to use for RVV register.")); 357 358 static void initializeDefaultRVVRegisterAllocatorOnce() { 359 RegisterRegAlloc::FunctionPassCtor Ctor = RVVRegisterRegAlloc::getDefault(); 360 361 if (!Ctor) { 362 Ctor = RVVRegAlloc; 363 RVVRegisterRegAlloc::setDefault(RVVRegAlloc); 364 } 365 } 366 367 static FunctionPass *createBasicRVVRegisterAllocator() { 368 return createBasicRegisterAllocator(onlyAllocateRVVReg); 369 } 370 371 static FunctionPass *createGreedyRVVRegisterAllocator() { 372 return createGreedyRegisterAllocator(onlyAllocateRVVReg); 373 } 374 375 static FunctionPass *createFastRVVRegisterAllocator() { 376 return createFastRegisterAllocator(onlyAllocateRVVReg, false); 377 } 378 379 static RVVRegisterRegAlloc basicRegAllocRVVReg("basic", 380 "basic register allocator", 381 createBasicRVVRegisterAllocator); 382 static RVVRegisterRegAlloc 383 greedyRegAllocRVVReg("greedy", "greedy register allocator", 384 createGreedyRVVRegisterAllocator); 385 386 static RVVRegisterRegAlloc fastRegAllocRVVReg("fast", "fast register allocator", 387 createFastRVVRegisterAllocator); 388 389 class RISCVPassConfig : public TargetPassConfig { 390 public: 391 RISCVPassConfig(RISCVTargetMachine &TM, PassManagerBase &PM) 392 : TargetPassConfig(TM, PM) { 393 if (TM.getOptLevel() != CodeGenOptLevel::None) 394 substitutePass(&PostRASchedulerID, &PostMachineSchedulerID); 395 setEnableSinkAndFold(EnableSinkFold); 396 EnableLoopTermFold = true; 397 } 398 399 RISCVTargetMachine &getRISCVTargetMachine() const { 400 return getTM<RISCVTargetMachine>(); 401 } 402 403 void addIRPasses() override; 404 bool addPreISel() override; 405 void addCodeGenPrepare() override; 406 bool addInstSelector() override; 407 bool addIRTranslator() override; 408 void addPreLegalizeMachineIR() override; 409 bool addLegalizeMachineIR() override; 410 void addPreRegBankSelect() override; 411 bool addRegBankSelect() override; 412 bool addGlobalInstructionSelect() override; 413 void addPreEmitPass() override; 414 void addPreEmitPass2() override; 415 void addPreSched2() override; 416 void addMachineSSAOptimization() override; 417 FunctionPass *createRVVRegAllocPass(bool Optimized); 418 bool addRegAssignAndRewriteFast() override; 419 bool addRegAssignAndRewriteOptimized() override; 420 void addPreRegAlloc() override; 421 void addPostRegAlloc() override; 422 void addFastRegAlloc() override; 423 424 std::unique_ptr<CSEConfigBase> getCSEConfig() const override; 425 }; 426 } // namespace 427 428 TargetPassConfig *RISCVTargetMachine::createPassConfig(PassManagerBase &PM) { 429 return new RISCVPassConfig(*this, PM); 430 } 431 432 std::unique_ptr<CSEConfigBase> RISCVPassConfig::getCSEConfig() const { 433 return getStandardCSEConfigForOpt(TM->getOptLevel()); 434 } 435 436 FunctionPass *RISCVPassConfig::createRVVRegAllocPass(bool Optimized) { 437 // Initialize the global default. 438 llvm::call_once(InitializeDefaultRVVRegisterAllocatorFlag, 439 initializeDefaultRVVRegisterAllocatorOnce); 440 441 RegisterRegAlloc::FunctionPassCtor Ctor = RVVRegisterRegAlloc::getDefault(); 442 if (Ctor != useDefaultRegisterAllocator) 443 return Ctor(); 444 445 if (Optimized) 446 return createGreedyRVVRegisterAllocator(); 447 448 return createFastRVVRegisterAllocator(); 449 } 450 451 bool RISCVPassConfig::addRegAssignAndRewriteFast() { 452 addPass(createRVVRegAllocPass(false)); 453 addPass(createRISCVInsertVSETVLIPass()); 454 if (TM->getOptLevel() != CodeGenOptLevel::None && 455 EnableRISCVDeadRegisterElimination) 456 addPass(createRISCVDeadRegisterDefinitionsPass()); 457 return TargetPassConfig::addRegAssignAndRewriteFast(); 458 } 459 460 bool RISCVPassConfig::addRegAssignAndRewriteOptimized() { 461 addPass(createRVVRegAllocPass(true)); 462 addPass(createVirtRegRewriter(false)); 463 addPass(createRISCVInsertVSETVLIPass()); 464 if (TM->getOptLevel() != CodeGenOptLevel::None && 465 EnableRISCVDeadRegisterElimination) 466 addPass(createRISCVDeadRegisterDefinitionsPass()); 467 return TargetPassConfig::addRegAssignAndRewriteOptimized(); 468 } 469 470 void RISCVPassConfig::addIRPasses() { 471 addPass(createAtomicExpandLegacyPass()); 472 addPass(createRISCVZacasABIFixPass()); 473 474 if (getOptLevel() != CodeGenOptLevel::None) { 475 if (EnableLoopDataPrefetch) 476 addPass(createLoopDataPrefetchPass()); 477 478 addPass(createRISCVGatherScatterLoweringPass()); 479 addPass(createInterleavedAccessPass()); 480 addPass(createRISCVCodeGenPreparePass()); 481 } 482 483 TargetPassConfig::addIRPasses(); 484 } 485 486 bool RISCVPassConfig::addPreISel() { 487 if (TM->getOptLevel() != CodeGenOptLevel::None) { 488 // Add a barrier before instruction selection so that we will not get 489 // deleted block address after enabling default outlining. See D99707 for 490 // more details. 491 addPass(createBarrierNoopPass()); 492 } 493 494 if ((TM->getOptLevel() != CodeGenOptLevel::None && 495 EnableGlobalMerge == cl::BOU_UNSET) || 496 EnableGlobalMerge == cl::BOU_TRUE) { 497 // FIXME: Like AArch64, we disable extern global merging by default due to 498 // concerns it might regress some workloads. Unlike AArch64, we don't 499 // currently support enabling the pass in an "OnlyOptimizeForSize" mode. 500 // Investigating and addressing both items are TODO. 501 addPass(createGlobalMergePass(TM, /* MaxOffset */ 2047, 502 /* OnlyOptimizeForSize */ false, 503 /* MergeExternalByDefault */ true)); 504 } 505 506 return false; 507 } 508 509 void RISCVPassConfig::addCodeGenPrepare() { 510 if (getOptLevel() != CodeGenOptLevel::None) 511 addPass(createTypePromotionLegacyPass()); 512 TargetPassConfig::addCodeGenPrepare(); 513 } 514 515 bool RISCVPassConfig::addInstSelector() { 516 addPass(createRISCVISelDag(getRISCVTargetMachine(), getOptLevel())); 517 518 return false; 519 } 520 521 bool RISCVPassConfig::addIRTranslator() { 522 addPass(new IRTranslator(getOptLevel())); 523 return false; 524 } 525 526 void RISCVPassConfig::addPreLegalizeMachineIR() { 527 if (getOptLevel() == CodeGenOptLevel::None) { 528 addPass(createRISCVO0PreLegalizerCombiner()); 529 } else { 530 addPass(createRISCVPreLegalizerCombiner()); 531 } 532 } 533 534 bool RISCVPassConfig::addLegalizeMachineIR() { 535 addPass(new Legalizer()); 536 return false; 537 } 538 539 void RISCVPassConfig::addPreRegBankSelect() { 540 if (getOptLevel() != CodeGenOptLevel::None) 541 addPass(createRISCVPostLegalizerCombiner()); 542 } 543 544 bool RISCVPassConfig::addRegBankSelect() { 545 addPass(new RegBankSelect()); 546 return false; 547 } 548 549 bool RISCVPassConfig::addGlobalInstructionSelect() { 550 addPass(new InstructionSelect(getOptLevel())); 551 return false; 552 } 553 554 void RISCVPassConfig::addPreSched2() { 555 addPass(createRISCVPostRAExpandPseudoPass()); 556 557 // Emit KCFI checks for indirect calls. 558 addPass(createKCFIPass()); 559 if (TM->getOptLevel() != CodeGenOptLevel::None) 560 addPass(createRISCVLoadStoreOptPass()); 561 } 562 563 void RISCVPassConfig::addPreEmitPass() { 564 // TODO: It would potentially be better to schedule copy propagation after 565 // expanding pseudos (in addPreEmitPass2). However, performing copy 566 // propagation after the machine outliner (which runs after addPreEmitPass) 567 // currently leads to incorrect code-gen, where copies to registers within 568 // outlined functions are removed erroneously. 569 if (TM->getOptLevel() >= CodeGenOptLevel::Default && 570 EnableRISCVCopyPropagation) 571 addPass(createMachineCopyPropagationPass(true)); 572 if (TM->getOptLevel() >= CodeGenOptLevel::Default) 573 addPass(createRISCVLateBranchOptPass()); 574 // The IndirectBranchTrackingPass inserts lpad and could have changed the 575 // basic block alignment. It must be done before Branch Relaxation to 576 // prevent the adjusted offset exceeding the branch range. 577 addPass(createRISCVIndirectBranchTrackingPass()); 578 addPass(&BranchRelaxationPassID); 579 addPass(createRISCVMakeCompressibleOptPass()); 580 } 581 582 void RISCVPassConfig::addPreEmitPass2() { 583 if (TM->getOptLevel() != CodeGenOptLevel::None) { 584 addPass(createRISCVMoveMergePass()); 585 // Schedule PushPop Optimization before expansion of Pseudo instruction, 586 // ensuring return instruction is detected correctly. 587 addPass(createRISCVPushPopOptimizationPass()); 588 } 589 addPass(createRISCVExpandPseudoPass()); 590 591 // Schedule the expansion of AMOs at the last possible moment, avoiding the 592 // possibility for other passes to break the requirements for forward 593 // progress in the LR/SC block. 594 addPass(createRISCVExpandAtomicPseudoPass()); 595 596 // KCFI indirect call checks are lowered to a bundle. 597 addPass(createUnpackMachineBundles([&](const MachineFunction &MF) { 598 return MF.getFunction().getParent()->getModuleFlag("kcfi"); 599 })); 600 } 601 602 void RISCVPassConfig::addMachineSSAOptimization() { 603 addPass(createRISCVVectorPeepholePass()); 604 addPass(createRISCVFoldMemOffsetPass()); 605 606 TargetPassConfig::addMachineSSAOptimization(); 607 608 if (EnableMachineCombiner) 609 addPass(&MachineCombinerID); 610 611 if (TM->getTargetTriple().isRISCV64()) { 612 addPass(createRISCVOptWInstrsPass()); 613 } 614 } 615 616 void RISCVPassConfig::addPreRegAlloc() { 617 addPass(createRISCVPreRAExpandPseudoPass()); 618 if (TM->getOptLevel() != CodeGenOptLevel::None) { 619 addPass(createRISCVMergeBaseOffsetOptPass()); 620 if (EnableVLOptimizer) 621 addPass(createRISCVVLOptimizerPass()); 622 } 623 624 addPass(createRISCVInsertReadWriteCSRPass()); 625 addPass(createRISCVInsertWriteVXRMPass()); 626 addPass(createRISCVLandingPadSetupPass()); 627 628 if (TM->getOptLevel() != CodeGenOptLevel::None && EnableMachinePipeliner) 629 addPass(&MachinePipelinerID); 630 631 addPass(createRISCVVMV0EliminationPass()); 632 } 633 634 void RISCVPassConfig::addFastRegAlloc() { 635 addPass(&InitUndefID); 636 TargetPassConfig::addFastRegAlloc(); 637 } 638 639 640 void RISCVPassConfig::addPostRegAlloc() { 641 if (TM->getOptLevel() != CodeGenOptLevel::None && 642 EnableRedundantCopyElimination) 643 addPass(createRISCVRedundantCopyEliminationPass()); 644 } 645 646 void RISCVTargetMachine::registerPassBuilderCallbacks(PassBuilder &PB) { 647 PB.registerLateLoopOptimizationsEPCallback([=](LoopPassManager &LPM, 648 OptimizationLevel Level) { 649 LPM.addPass(LoopIdiomVectorizePass(LoopIdiomVectorizeStyle::Predicated)); 650 }); 651 652 PB.registerVectorizerEndEPCallback( 653 [](FunctionPassManager &FPM, OptimizationLevel Level) { 654 if (Level.isOptimizingForSpeed()) 655 FPM.addPass(createFunctionToLoopPassAdaptor(EVLIndVarSimplifyPass())); 656 }); 657 } 658 659 yaml::MachineFunctionInfo * 660 RISCVTargetMachine::createDefaultFuncInfoYAML() const { 661 return new yaml::RISCVMachineFunctionInfo(); 662 } 663 664 yaml::MachineFunctionInfo * 665 RISCVTargetMachine::convertFuncInfoToYAML(const MachineFunction &MF) const { 666 const auto *MFI = MF.getInfo<RISCVMachineFunctionInfo>(); 667 return new yaml::RISCVMachineFunctionInfo(*MFI); 668 } 669 670 bool RISCVTargetMachine::parseMachineFunctionInfo( 671 const yaml::MachineFunctionInfo &MFI, PerFunctionMIParsingState &PFS, 672 SMDiagnostic &Error, SMRange &SourceRange) const { 673 const auto &YamlMFI = 674 static_cast<const yaml::RISCVMachineFunctionInfo &>(MFI); 675 PFS.MF.getInfo<RISCVMachineFunctionInfo>()->initializeBaseYamlFields(YamlMFI); 676 return false; 677 } 678