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