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