//===-- RISCVTargetMachine.cpp - Define TargetMachine for RISCV -----------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// // // Implements the info about RISCV target spec. // //===----------------------------------------------------------------------===// #include "RISCVTargetMachine.h" #include "RISCV.h" #include "RISCVTargetObjectFile.h" #include "RISCVTargetTransformInfo.h" #include "TargetInfo/RISCVTargetInfo.h" #include "llvm/ADT/STLExtras.h" #include "llvm/Analysis/TargetTransformInfo.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 X(getTheRISCV32Target()); RegisterTargetMachine Y(getTheRISCV64Target()); auto PR = PassRegistry::getPassRegistry(); initializeRISCVExpandPseudoPass(*PR); } static StringRef 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 RM) { if (!RM.hasValue()) return Reloc::Static; return *RM; } RISCVTargetMachine::RISCVTargetMachine(const Target &T, const Triple &TT, StringRef CPU, StringRef FS, const TargetOptions &Options, Optional RM, Optional CM, CodeGenOpt::Level OL, bool JIT) : LLVMTargetMachine(T, computeDataLayout(TT), TT, CPU, FS, Options, getEffectiveRelocModel(TT, RM), getEffectiveCodeModel(CM, CodeModel::Small), OL), TLOF(make_unique()), Subtarget(TT, CPU, FS, Options.MCOptions.getABIName(), *this) { initAsmInfo(); } TargetTransformInfo RISCVTargetMachine::getTargetTransformInfo(const Function &F) { return TargetTransformInfo(RISCVTTIImpl(this, F)); } namespace { class RISCVPassConfig : public TargetPassConfig { public: RISCVPassConfig(RISCVTargetMachine &TM, PassManagerBase &PM) : TargetPassConfig(TM, PM) {} RISCVTargetMachine &getRISCVTargetMachine() const { return getTM(); } void addIRPasses() override; bool addInstSelector() override; void addPreEmitPass() override; void addPreEmitPass2() 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::addPreEmitPass2() { // Schedule the expansion of AMOs at the last possible moment, avoiding the // possibility for other passes to break the requirements for forward // progress in the LR/SC block. addPass(createRISCVExpandPseudoPass()); } void RISCVPassConfig::addPreRegAlloc() { addPass(createRISCVMergeBaseOffsetOptPass()); }