1 //===-- RISCVTargetMachine.cpp - Define TargetMachine for RISCV -----------===// 2 // 3 // The LLVM Compiler Infrastructure 4 // 5 // This file is distributed under the University of Illinois Open Source 6 // License. See LICENSE.TXT for details. 7 // 8 //===----------------------------------------------------------------------===// 9 // 10 // Implements the info about RISCV target spec. 11 // 12 //===----------------------------------------------------------------------===// 13 14 #include "RISCV.h" 15 #include "RISCVTargetMachine.h" 16 #include "RISCVTargetObjectFile.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 std::string 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 static CodeModel::Model getEffectiveCodeModel(Optional<CodeModel::Model> CM) { 51 if (CM) 52 return *CM; 53 return CodeModel::Small; 54 } 55 56 RISCVTargetMachine::RISCVTargetMachine(const Target &T, const Triple &TT, 57 StringRef CPU, StringRef FS, 58 const TargetOptions &Options, 59 Optional<Reloc::Model> RM, 60 Optional<CodeModel::Model> CM, 61 CodeGenOpt::Level OL, bool JIT) 62 : LLVMTargetMachine(T, computeDataLayout(TT), TT, CPU, FS, Options, 63 getEffectiveRelocModel(TT, RM), 64 getEffectiveCodeModel(CM), OL), 65 TLOF(make_unique<RISCVELFTargetObjectFile>()), 66 Subtarget(TT, CPU, FS, *this) { 67 initAsmInfo(); 68 } 69 70 namespace { 71 class RISCVPassConfig : public TargetPassConfig { 72 public: 73 RISCVPassConfig(RISCVTargetMachine &TM, PassManagerBase &PM) 74 : TargetPassConfig(TM, PM) {} 75 76 RISCVTargetMachine &getRISCVTargetMachine() const { 77 return getTM<RISCVTargetMachine>(); 78 } 79 80 void addIRPasses() override; 81 bool addInstSelector() override; 82 void addPreEmitPass() override; 83 void addPreEmitPass2() override; 84 void addPreRegAlloc() override; 85 }; 86 } 87 88 TargetPassConfig *RISCVTargetMachine::createPassConfig(PassManagerBase &PM) { 89 return new RISCVPassConfig(*this, PM); 90 } 91 92 void RISCVPassConfig::addIRPasses() { 93 addPass(createAtomicExpandPass()); 94 TargetPassConfig::addIRPasses(); 95 } 96 97 bool RISCVPassConfig::addInstSelector() { 98 addPass(createRISCVISelDag(getRISCVTargetMachine())); 99 100 return false; 101 } 102 103 void RISCVPassConfig::addPreEmitPass() { addPass(&BranchRelaxationPassID); } 104 105 void RISCVPassConfig::addPreEmitPass2() { 106 // Schedule the expansion of AMOs at the last possible moment, avoiding the 107 // possibility for other passes to break the requirements for forward 108 // progress in the LR/SC block. 109 addPass(createRISCVExpandPseudoPass()); 110 } 111 112 void RISCVPassConfig::addPreRegAlloc() { 113 addPass(createRISCVMergeBaseOffsetOptPass()); 114 } 115