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