//===-- RISCVTargetMachine.cpp - Define TargetMachine for RISCV -----------===// // // The LLVM Compiler Infrastructure // // This file is distributed under the University of Illinois Open Source // License. See LICENSE.TXT for details. // //===----------------------------------------------------------------------===// // // Implements the info about RISCV target spec. // //===----------------------------------------------------------------------===// #include "RISCV.h" #include "RISCVTargetMachine.h" #include "RISCVTargetObjectFile.h" #include "llvm/ADT/STLExtras.h" #include "llvm/CodeGen/Passes.h" #include "llvm/CodeGen/TargetLoweringObjectFileImpl.h" #include "llvm/CodeGen/TargetPassConfig.h" #include "llvm/IR/LegacyPassManager.h" #include "llvm/Support/FormattedStream.h" #include "llvm/Support/TargetRegistry.h" #include "llvm/Target/TargetOptions.h" using namespace llvm; extern "C" void LLVMInitializeRISCVTarget() { RegisterTargetMachine<RISCVTargetMachine> X(getTheRISCV32Target()); RegisterTargetMachine<RISCVTargetMachine> Y(getTheRISCV64Target()); } static std::string computeDataLayout(const Triple &TT) { if (TT.isArch64Bit()) { return "e-m:e-p:64:64-i64:64-i128:128-n64-S128"; } else { assert(TT.isArch32Bit() && "only RV32 and RV64 are currently supported"); return "e-m:e-p:32:32-i64:64-n32-S128"; } } static Reloc::Model getEffectiveRelocModel(const Triple &TT, Optional<Reloc::Model> RM) { if (!RM.hasValue()) return Reloc::Static; return *RM; } static CodeModel::Model getEffectiveCodeModel(Optional<CodeModel::Model> CM) { if (CM) return *CM; return CodeModel::Small; } RISCVTargetMachine::RISCVTargetMachine(const Target &T, const Triple &TT, StringRef CPU, StringRef FS, const TargetOptions &Options, Optional<Reloc::Model> RM, Optional<CodeModel::Model> CM, CodeGenOpt::Level OL, bool JIT) : LLVMTargetMachine(T, computeDataLayout(TT), TT, CPU, FS, Options, getEffectiveRelocModel(TT, RM), getEffectiveCodeModel(CM), OL), TLOF(make_unique<RISCVELFTargetObjectFile>()), Subtarget(TT, CPU, FS, *this) { initAsmInfo(); } namespace { class RISCVPassConfig : public TargetPassConfig { public: RISCVPassConfig(RISCVTargetMachine &TM, PassManagerBase &PM) : TargetPassConfig(TM, PM) {} RISCVTargetMachine &getRISCVTargetMachine() const { return getTM<RISCVTargetMachine>(); } void addIRPasses() override; bool addInstSelector() override; void addPreEmitPass() override; void addPreRegAlloc() override; }; } TargetPassConfig *RISCVTargetMachine::createPassConfig(PassManagerBase &PM) { return new RISCVPassConfig(*this, PM); } void RISCVPassConfig::addIRPasses() { addPass(createAtomicExpandPass()); TargetPassConfig::addIRPasses(); } bool RISCVPassConfig::addInstSelector() { addPass(createRISCVISelDag(getRISCVTargetMachine())); return false; } void RISCVPassConfig::addPreEmitPass() { addPass(&BranchRelaxationPassID); } void RISCVPassConfig::addPreRegAlloc() { addPass(createRISCVMergeBaseOffsetOptPass()); }