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