1 //===-- RISCVTargetMachine.cpp - Define TargetMachine for RISCV -----------===// 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 RISCV target spec. 10 // 11 //===----------------------------------------------------------------------===// 12 13 #include "RISCVTargetMachine.h" 14 #include "RISCV.h" 15 #include "RISCVTargetObjectFile.h" 16 #include "RISCVTargetTransformInfo.h" 17 #include "TargetInfo/RISCVTargetInfo.h" 18 #include "llvm/ADT/STLExtras.h" 19 #include "llvm/Analysis/TargetTransformInfo.h" 20 #include "llvm/CodeGen/GlobalISel/IRTranslator.h" 21 #include "llvm/CodeGen/GlobalISel/InstructionSelect.h" 22 #include "llvm/CodeGen/GlobalISel/Legalizer.h" 23 #include "llvm/CodeGen/GlobalISel/RegBankSelect.h" 24 #include "llvm/CodeGen/Passes.h" 25 #include "llvm/CodeGen/TargetLoweringObjectFileImpl.h" 26 #include "llvm/CodeGen/TargetPassConfig.h" 27 #include "llvm/IR/LegacyPassManager.h" 28 #include "llvm/Support/FormattedStream.h" 29 #include "llvm/Support/TargetRegistry.h" 30 #include "llvm/Target/TargetOptions.h" 31 using namespace llvm; 32 33 extern "C" void LLVMInitializeRISCVTarget() { 34 RegisterTargetMachine<RISCVTargetMachine> X(getTheRISCV32Target()); 35 RegisterTargetMachine<RISCVTargetMachine> Y(getTheRISCV64Target()); 36 auto PR = PassRegistry::getPassRegistry(); 37 initializeGlobalISel(*PR); 38 initializeRISCVExpandPseudoPass(*PR); 39 } 40 41 static StringRef computeDataLayout(const Triple &TT) { 42 if (TT.isArch64Bit()) { 43 return "e-m:e-p:64:64-i64:64-i128:128-n64-S128"; 44 } else { 45 assert(TT.isArch32Bit() && "only RV32 and RV64 are currently supported"); 46 return "e-m:e-p:32:32-i64:64-n32-S128"; 47 } 48 } 49 50 static Reloc::Model getEffectiveRelocModel(const Triple &TT, 51 Optional<Reloc::Model> RM) { 52 if (!RM.hasValue()) 53 return Reloc::Static; 54 return *RM; 55 } 56 57 RISCVTargetMachine::RISCVTargetMachine(const Target &T, const Triple &TT, 58 StringRef CPU, StringRef FS, 59 const TargetOptions &Options, 60 Optional<Reloc::Model> RM, 61 Optional<CodeModel::Model> CM, 62 CodeGenOpt::Level OL, bool JIT) 63 : LLVMTargetMachine(T, computeDataLayout(TT), TT, CPU, FS, Options, 64 getEffectiveRelocModel(TT, RM), 65 getEffectiveCodeModel(CM, CodeModel::Small), OL), 66 TLOF(std::make_unique<RISCVELFTargetObjectFile>()), 67 Subtarget(TT, CPU, FS, Options.MCOptions.getABIName(), *this) { 68 initAsmInfo(); 69 } 70 71 TargetTransformInfo 72 RISCVTargetMachine::getTargetTransformInfo(const Function &F) { 73 return TargetTransformInfo(RISCVTTIImpl(this, F)); 74 } 75 76 namespace { 77 class RISCVPassConfig : public TargetPassConfig { 78 public: 79 RISCVPassConfig(RISCVTargetMachine &TM, PassManagerBase &PM) 80 : TargetPassConfig(TM, PM) {} 81 82 RISCVTargetMachine &getRISCVTargetMachine() const { 83 return getTM<RISCVTargetMachine>(); 84 } 85 86 void addIRPasses() override; 87 bool addInstSelector() override; 88 bool addIRTranslator() override; 89 bool addLegalizeMachineIR() override; 90 bool addRegBankSelect() override; 91 bool addGlobalInstructionSelect() override; 92 void addPreEmitPass() override; 93 void addPreEmitPass2() override; 94 void addPreRegAlloc() override; 95 }; 96 } 97 98 TargetPassConfig *RISCVTargetMachine::createPassConfig(PassManagerBase &PM) { 99 return new RISCVPassConfig(*this, PM); 100 } 101 102 void RISCVPassConfig::addIRPasses() { 103 addPass(createAtomicExpandPass()); 104 TargetPassConfig::addIRPasses(); 105 } 106 107 bool RISCVPassConfig::addInstSelector() { 108 addPass(createRISCVISelDag(getRISCVTargetMachine())); 109 110 return false; 111 } 112 113 bool RISCVPassConfig::addIRTranslator() { 114 addPass(new IRTranslator()); 115 return false; 116 } 117 118 bool RISCVPassConfig::addLegalizeMachineIR() { 119 addPass(new Legalizer()); 120 return false; 121 } 122 123 bool RISCVPassConfig::addRegBankSelect() { 124 addPass(new RegBankSelect()); 125 return false; 126 } 127 128 bool RISCVPassConfig::addGlobalInstructionSelect() { 129 addPass(new InstructionSelect()); 130 return false; 131 } 132 133 void RISCVPassConfig::addPreEmitPass() { addPass(&BranchRelaxationPassID); } 134 135 void RISCVPassConfig::addPreEmitPass2() { 136 // Schedule the expansion of AMOs at the last possible moment, avoiding the 137 // possibility for other passes to break the requirements for forward 138 // progress in the LR/SC block. 139 addPass(createRISCVExpandPseudoPass()); 140 } 141 142 void RISCVPassConfig::addPreRegAlloc() { 143 addPass(createRISCVMergeBaseOffsetOptPass()); 144 } 145