1 //===-- LoongArchTargetMachine.cpp - Define TargetMachine for LoongArch ---===// 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 LoongArch target spec. 10 // 11 //===----------------------------------------------------------------------===// 12 13 #include "LoongArchTargetMachine.h" 14 #include "LoongArch.h" 15 #include "MCTargetDesc/LoongArchBaseInfo.h" 16 #include "TargetInfo/LoongArchTargetInfo.h" 17 #include "llvm/CodeGen/Passes.h" 18 #include "llvm/CodeGen/TargetLoweringObjectFileImpl.h" 19 #include "llvm/CodeGen/TargetPassConfig.h" 20 #include "llvm/MC/TargetRegistry.h" 21 22 using namespace llvm; 23 24 #define DEBUG_TYPE "loongarch" 25 26 extern "C" LLVM_EXTERNAL_VISIBILITY void LLVMInitializeLoongArchTarget() { 27 // Register the target. 28 RegisterTargetMachine<LoongArchTargetMachine> X(getTheLoongArch32Target()); 29 RegisterTargetMachine<LoongArchTargetMachine> Y(getTheLoongArch64Target()); 30 } 31 32 static std::string computeDataLayout(const Triple &TT) { 33 if (TT.isArch64Bit()) 34 return "e-m:e-p:64:64-i64:64-i128:128-n64-S128"; 35 assert(TT.isArch32Bit() && "only LA32 and LA64 are currently supported"); 36 return "e-m:e-p:32:32-i64:64-n32-S128"; 37 } 38 39 static Reloc::Model getEffectiveRelocModel(const Triple &TT, 40 Optional<Reloc::Model> RM) { 41 if (!RM.hasValue()) 42 return Reloc::Static; 43 return *RM; 44 } 45 46 LoongArchTargetMachine::LoongArchTargetMachine( 47 const Target &T, const Triple &TT, StringRef CPU, StringRef FS, 48 const TargetOptions &Options, Optional<Reloc::Model> RM, 49 Optional<CodeModel::Model> CM, CodeGenOpt::Level OL, bool JIT) 50 : LLVMTargetMachine(T, computeDataLayout(TT), TT, CPU, FS, Options, 51 getEffectiveRelocModel(TT, RM), 52 getEffectiveCodeModel(CM, CodeModel::Small), OL), 53 TLOF(std::make_unique<TargetLoweringObjectFileELF>()) { 54 initAsmInfo(); 55 } 56 57 LoongArchTargetMachine::~LoongArchTargetMachine() = default; 58 59 const LoongArchSubtarget * 60 LoongArchTargetMachine::getSubtargetImpl(const Function &F) const { 61 Attribute CPUAttr = F.getFnAttribute("target-cpu"); 62 Attribute TuneAttr = F.getFnAttribute("tune-cpu"); 63 Attribute FSAttr = F.getFnAttribute("target-features"); 64 65 std::string CPU = 66 CPUAttr.isValid() ? CPUAttr.getValueAsString().str() : TargetCPU; 67 std::string TuneCPU = 68 TuneAttr.isValid() ? TuneAttr.getValueAsString().str() : CPU; 69 std::string FS = 70 FSAttr.isValid() ? FSAttr.getValueAsString().str() : TargetFS; 71 72 std::string Key = CPU + TuneCPU + FS; 73 auto &I = SubtargetMap[Key]; 74 if (!I) { 75 // This needs to be done before we create a new subtarget since any 76 // creation will depend on the TM and the code generation flags on the 77 // function that reside in TargetOptions. 78 resetTargetOptions(F); 79 auto ABIName = Options.MCOptions.getABIName(); 80 if (const MDString *ModuleTargetABI = dyn_cast_or_null<MDString>( 81 F.getParent()->getModuleFlag("target-abi"))) { 82 auto TargetABI = LoongArchABI::getTargetABI(ABIName); 83 if (TargetABI != LoongArchABI::ABI_Unknown && 84 ModuleTargetABI->getString() != ABIName) { 85 report_fatal_error("-target-abi option != target-abi module flag"); 86 } 87 ABIName = ModuleTargetABI->getString(); 88 } 89 I = std::make_unique<LoongArchSubtarget>(TargetTriple, CPU, TuneCPU, FS, 90 ABIName, *this); 91 } 92 return I.get(); 93 } 94 95 namespace { 96 class LoongArchPassConfig : public TargetPassConfig { 97 public: 98 LoongArchPassConfig(LoongArchTargetMachine &TM, PassManagerBase &PM) 99 : TargetPassConfig(TM, PM) {} 100 101 LoongArchTargetMachine &getLoongArchTargetMachine() const { 102 return getTM<LoongArchTargetMachine>(); 103 } 104 105 bool addInstSelector() override; 106 }; 107 } // namespace 108 109 TargetPassConfig * 110 LoongArchTargetMachine::createPassConfig(PassManagerBase &PM) { 111 return new LoongArchPassConfig(*this, PM); 112 } 113 114 bool LoongArchPassConfig::addInstSelector() { 115 addPass(createLoongArchISelDag(getLoongArchTargetMachine())); 116 117 return false; 118 } 119