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 return RM.value_or(Reloc::Static); 42 } 43 44 LoongArchTargetMachine::LoongArchTargetMachine( 45 const Target &T, const Triple &TT, StringRef CPU, StringRef FS, 46 const TargetOptions &Options, Optional<Reloc::Model> RM, 47 Optional<CodeModel::Model> CM, CodeGenOpt::Level OL, bool JIT) 48 : LLVMTargetMachine(T, computeDataLayout(TT), TT, CPU, FS, Options, 49 getEffectiveRelocModel(TT, RM), 50 getEffectiveCodeModel(CM, CodeModel::Small), OL), 51 TLOF(std::make_unique<TargetLoweringObjectFileELF>()) { 52 initAsmInfo(); 53 } 54 55 LoongArchTargetMachine::~LoongArchTargetMachine() = default; 56 57 const LoongArchSubtarget * 58 LoongArchTargetMachine::getSubtargetImpl(const Function &F) const { 59 Attribute CPUAttr = F.getFnAttribute("target-cpu"); 60 Attribute TuneAttr = F.getFnAttribute("tune-cpu"); 61 Attribute FSAttr = F.getFnAttribute("target-features"); 62 63 std::string CPU = 64 CPUAttr.isValid() ? CPUAttr.getValueAsString().str() : TargetCPU; 65 std::string TuneCPU = 66 TuneAttr.isValid() ? TuneAttr.getValueAsString().str() : CPU; 67 std::string FS = 68 FSAttr.isValid() ? FSAttr.getValueAsString().str() : TargetFS; 69 70 std::string Key = CPU + TuneCPU + FS; 71 auto &I = SubtargetMap[Key]; 72 if (!I) { 73 // This needs to be done before we create a new subtarget since any 74 // creation will depend on the TM and the code generation flags on the 75 // function that reside in TargetOptions. 76 resetTargetOptions(F); 77 auto ABIName = Options.MCOptions.getABIName(); 78 if (const MDString *ModuleTargetABI = dyn_cast_or_null<MDString>( 79 F.getParent()->getModuleFlag("target-abi"))) { 80 auto TargetABI = LoongArchABI::getTargetABI(ABIName); 81 if (TargetABI != LoongArchABI::ABI_Unknown && 82 ModuleTargetABI->getString() != ABIName) { 83 report_fatal_error("-target-abi option != target-abi module flag"); 84 } 85 ABIName = ModuleTargetABI->getString(); 86 } 87 I = std::make_unique<LoongArchSubtarget>(TargetTriple, CPU, TuneCPU, FS, 88 ABIName, *this); 89 } 90 return I.get(); 91 } 92 93 namespace { 94 class LoongArchPassConfig : public TargetPassConfig { 95 public: 96 LoongArchPassConfig(LoongArchTargetMachine &TM, PassManagerBase &PM) 97 : TargetPassConfig(TM, PM) {} 98 99 LoongArchTargetMachine &getLoongArchTargetMachine() const { 100 return getTM<LoongArchTargetMachine>(); 101 } 102 103 void addIRPasses() override; 104 bool addInstSelector() override; 105 }; 106 } // end namespace 107 108 TargetPassConfig * 109 LoongArchTargetMachine::createPassConfig(PassManagerBase &PM) { 110 return new LoongArchPassConfig(*this, PM); 111 } 112 113 void LoongArchPassConfig::addIRPasses() { 114 addPass(createAtomicExpandPass()); 115 116 TargetPassConfig::addIRPasses(); 117 } 118 119 bool LoongArchPassConfig::addInstSelector() { 120 addPass(createLoongArchISelDag(getLoongArchTargetMachine())); 121 122 return false; 123 } 124