123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151 |
- //===-- LoongArchTargetMachine.cpp - Define TargetMachine for LoongArch ---===//
- //
- // 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 LoongArch target spec.
- //
- //===----------------------------------------------------------------------===//
- #include "LoongArchTargetMachine.h"
- #include "LoongArch.h"
- #include "LoongArchMachineFunctionInfo.h"
- #include "MCTargetDesc/LoongArchBaseInfo.h"
- #include "TargetInfo/LoongArchTargetInfo.h"
- #include "llvm/CodeGen/Passes.h"
- #include "llvm/CodeGen/TargetLoweringObjectFileImpl.h"
- #include "llvm/CodeGen/TargetPassConfig.h"
- #include "llvm/MC/TargetRegistry.h"
- #include <optional>
- using namespace llvm;
- #define DEBUG_TYPE "loongarch"
- extern "C" LLVM_EXTERNAL_VISIBILITY void LLVMInitializeLoongArchTarget() {
- // Register the target.
- RegisterTargetMachine<LoongArchTargetMachine> X(getTheLoongArch32Target());
- RegisterTargetMachine<LoongArchTargetMachine> Y(getTheLoongArch64Target());
- auto *PR = PassRegistry::getPassRegistry();
- initializeLoongArchPreRAExpandPseudoPass(*PR);
- initializeLoongArchDAGToDAGISelPass(*PR);
- }
- static std::string computeDataLayout(const Triple &TT) {
- if (TT.isArch64Bit())
- return "e-m:e-p:64:64-i64:64-i128:128-n64-S128";
- assert(TT.isArch32Bit() && "only LA32 and LA64 are currently supported");
- return "e-m:e-p:32:32-i64:64-n32-S128";
- }
- static Reloc::Model getEffectiveRelocModel(const Triple &TT,
- std::optional<Reloc::Model> RM) {
- return RM.value_or(Reloc::Static);
- }
- LoongArchTargetMachine::LoongArchTargetMachine(
- const Target &T, const Triple &TT, StringRef CPU, StringRef FS,
- const TargetOptions &Options, std::optional<Reloc::Model> RM,
- std::optional<CodeModel::Model> CM, CodeGenOpt::Level OL, bool JIT)
- : LLVMTargetMachine(T, computeDataLayout(TT), TT, CPU, FS, Options,
- getEffectiveRelocModel(TT, RM),
- getEffectiveCodeModel(CM, CodeModel::Small), OL),
- TLOF(std::make_unique<TargetLoweringObjectFileELF>()) {
- initAsmInfo();
- }
- LoongArchTargetMachine::~LoongArchTargetMachine() = default;
- const LoongArchSubtarget *
- LoongArchTargetMachine::getSubtargetImpl(const Function &F) const {
- Attribute CPUAttr = F.getFnAttribute("target-cpu");
- Attribute TuneAttr = F.getFnAttribute("tune-cpu");
- Attribute FSAttr = F.getFnAttribute("target-features");
- std::string CPU =
- CPUAttr.isValid() ? CPUAttr.getValueAsString().str() : TargetCPU;
- std::string TuneCPU =
- TuneAttr.isValid() ? TuneAttr.getValueAsString().str() : CPU;
- std::string FS =
- FSAttr.isValid() ? FSAttr.getValueAsString().str() : TargetFS;
- std::string Key = CPU + TuneCPU + FS;
- auto &I = SubtargetMap[Key];
- if (!I) {
- // This needs to be done before we create a new subtarget since any
- // creation will depend on the TM and the code generation flags on the
- // function that reside in TargetOptions.
- resetTargetOptions(F);
- auto ABIName = Options.MCOptions.getABIName();
- if (const MDString *ModuleTargetABI = dyn_cast_or_null<MDString>(
- F.getParent()->getModuleFlag("target-abi"))) {
- auto TargetABI = LoongArchABI::getTargetABI(ABIName);
- if (TargetABI != LoongArchABI::ABI_Unknown &&
- ModuleTargetABI->getString() != ABIName) {
- report_fatal_error("-target-abi option != target-abi module flag");
- }
- ABIName = ModuleTargetABI->getString();
- }
- I = std::make_unique<LoongArchSubtarget>(TargetTriple, CPU, TuneCPU, FS,
- ABIName, *this);
- }
- return I.get();
- }
- MachineFunctionInfo *LoongArchTargetMachine::createMachineFunctionInfo(
- BumpPtrAllocator &Allocator, const Function &F,
- const TargetSubtargetInfo *STI) const {
- return LoongArchMachineFunctionInfo::create<LoongArchMachineFunctionInfo>(
- Allocator, F, STI);
- }
- namespace {
- class LoongArchPassConfig : public TargetPassConfig {
- public:
- LoongArchPassConfig(LoongArchTargetMachine &TM, PassManagerBase &PM)
- : TargetPassConfig(TM, PM) {}
- LoongArchTargetMachine &getLoongArchTargetMachine() const {
- return getTM<LoongArchTargetMachine>();
- }
- void addIRPasses() override;
- bool addInstSelector() override;
- void addPreEmitPass() override;
- void addPreEmitPass2() override;
- void addPreRegAlloc() override;
- };
- } // end namespace
- TargetPassConfig *
- LoongArchTargetMachine::createPassConfig(PassManagerBase &PM) {
- return new LoongArchPassConfig(*this, PM);
- }
- void LoongArchPassConfig::addIRPasses() {
- addPass(createAtomicExpandPass());
- TargetPassConfig::addIRPasses();
- }
- bool LoongArchPassConfig::addInstSelector() {
- addPass(createLoongArchISelDag(getLoongArchTargetMachine()));
- return false;
- }
- void LoongArchPassConfig::addPreEmitPass() { addPass(&BranchRelaxationPassID); }
- void LoongArchPassConfig::addPreEmitPass2() {
- // Schedule the expansion of AtomicPseudos at the last possible moment,
- // avoiding the possibility for other passes to break the requirements for
- // forward progress in the LL/SC block.
- addPass(createLoongArchExpandAtomicPseudoPass());
- }
- void LoongArchPassConfig::addPreRegAlloc() {
- addPass(createLoongArchPreRAExpandPseudoPass());
- }
|