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