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 "LoongArchMachineFunctionInfo.h" 16 #include "MCTargetDesc/LoongArchBaseInfo.h" 17 #include "TargetInfo/LoongArchTargetInfo.h" 18 #include "llvm/CodeGen/Passes.h" 19 #include "llvm/CodeGen/TargetLoweringObjectFileImpl.h" 20 #include "llvm/CodeGen/TargetPassConfig.h" 21 #include "llvm/MC/TargetRegistry.h" 22 #include <optional> 23 24 using namespace llvm; 25 26 #define DEBUG_TYPE "loongarch" 27 28 extern "C" LLVM_EXTERNAL_VISIBILITY void LLVMInitializeLoongArchTarget() { 29 // Register the target. 30 RegisterTargetMachine<LoongArchTargetMachine> X(getTheLoongArch32Target()); 31 RegisterTargetMachine<LoongArchTargetMachine> Y(getTheLoongArch64Target()); 32 auto *PR = PassRegistry::getPassRegistry(); 33 initializeLoongArchPreRAExpandPseudoPass(*PR); 34 initializeLoongArchDAGToDAGISelPass(*PR); 35 } 36 37 static std::string computeDataLayout(const Triple &TT) { 38 if (TT.isArch64Bit()) 39 return "e-m:e-p:64:64-i64:64-i128:128-n64-S128"; 40 assert(TT.isArch32Bit() && "only LA32 and LA64 are currently supported"); 41 return "e-m:e-p:32:32-i64:64-n32-S128"; 42 } 43 44 static Reloc::Model getEffectiveRelocModel(const Triple &TT, 45 std::optional<Reloc::Model> RM) { 46 return RM.value_or(Reloc::Static); 47 } 48 49 LoongArchTargetMachine::LoongArchTargetMachine( 50 const Target &T, const Triple &TT, StringRef CPU, StringRef FS, 51 const TargetOptions &Options, std::optional<Reloc::Model> RM, 52 std::optional<CodeModel::Model> CM, CodeGenOpt::Level OL, bool JIT) 53 : LLVMTargetMachine(T, computeDataLayout(TT), TT, CPU, FS, Options, 54 getEffectiveRelocModel(TT, RM), 55 getEffectiveCodeModel(CM, CodeModel::Small), OL), 56 TLOF(std::make_unique<TargetLoweringObjectFileELF>()) { 57 initAsmInfo(); 58 } 59 60 LoongArchTargetMachine::~LoongArchTargetMachine() = default; 61 62 const LoongArchSubtarget * 63 LoongArchTargetMachine::getSubtargetImpl(const Function &F) const { 64 Attribute CPUAttr = F.getFnAttribute("target-cpu"); 65 Attribute TuneAttr = F.getFnAttribute("tune-cpu"); 66 Attribute FSAttr = F.getFnAttribute("target-features"); 67 68 std::string CPU = 69 CPUAttr.isValid() ? CPUAttr.getValueAsString().str() : TargetCPU; 70 std::string TuneCPU = 71 TuneAttr.isValid() ? TuneAttr.getValueAsString().str() : CPU; 72 std::string FS = 73 FSAttr.isValid() ? FSAttr.getValueAsString().str() : TargetFS; 74 75 std::string Key = CPU + TuneCPU + FS; 76 auto &I = SubtargetMap[Key]; 77 if (!I) { 78 // This needs to be done before we create a new subtarget since any 79 // creation will depend on the TM and the code generation flags on the 80 // function that reside in TargetOptions. 81 resetTargetOptions(F); 82 auto ABIName = Options.MCOptions.getABIName(); 83 if (const MDString *ModuleTargetABI = dyn_cast_or_null<MDString>( 84 F.getParent()->getModuleFlag("target-abi"))) { 85 auto TargetABI = LoongArchABI::getTargetABI(ABIName); 86 if (TargetABI != LoongArchABI::ABI_Unknown && 87 ModuleTargetABI->getString() != ABIName) { 88 report_fatal_error("-target-abi option != target-abi module flag"); 89 } 90 ABIName = ModuleTargetABI->getString(); 91 } 92 I = std::make_unique<LoongArchSubtarget>(TargetTriple, CPU, TuneCPU, FS, 93 ABIName, *this); 94 } 95 return I.get(); 96 } 97 98 MachineFunctionInfo *LoongArchTargetMachine::createMachineFunctionInfo( 99 BumpPtrAllocator &Allocator, const Function &F, 100 const TargetSubtargetInfo *STI) const { 101 return LoongArchMachineFunctionInfo::create<LoongArchMachineFunctionInfo>( 102 Allocator, F, STI); 103 } 104 105 namespace { 106 class LoongArchPassConfig : public TargetPassConfig { 107 public: 108 LoongArchPassConfig(LoongArchTargetMachine &TM, PassManagerBase &PM) 109 : TargetPassConfig(TM, PM) {} 110 111 LoongArchTargetMachine &getLoongArchTargetMachine() const { 112 return getTM<LoongArchTargetMachine>(); 113 } 114 115 void addIRPasses() override; 116 bool addInstSelector() override; 117 void addPreEmitPass() override; 118 void addPreEmitPass2() override; 119 void addPreRegAlloc() override; 120 }; 121 } // end namespace 122 123 TargetPassConfig * 124 LoongArchTargetMachine::createPassConfig(PassManagerBase &PM) { 125 return new LoongArchPassConfig(*this, PM); 126 } 127 128 void LoongArchPassConfig::addIRPasses() { 129 addPass(createAtomicExpandPass()); 130 131 TargetPassConfig::addIRPasses(); 132 } 133 134 bool LoongArchPassConfig::addInstSelector() { 135 addPass(createLoongArchISelDag(getLoongArchTargetMachine())); 136 137 return false; 138 } 139 140 void LoongArchPassConfig::addPreEmitPass() { addPass(&BranchRelaxationPassID); } 141 142 void LoongArchPassConfig::addPreEmitPass2() { 143 // Schedule the expansion of AtomicPseudos at the last possible moment, 144 // avoiding the possibility for other passes to break the requirements for 145 // forward progress in the LL/SC block. 146 addPass(createLoongArchExpandAtomicPseudoPass()); 147 } 148 149 void LoongArchPassConfig::addPreRegAlloc() { 150 addPass(createLoongArchPreRAExpandPseudoPass()); 151 } 152