[X86] Better handling of impossibly large stack frames (#124217)
[llvm-project.git] / llvm / lib / Target / LoongArch / LoongArchTargetMachine.cpp
blob62b08be5435cda8f8d8f73311a551764f39e1401
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.
11 //===----------------------------------------------------------------------===//
13 #include "LoongArchTargetMachine.h"
14 #include "LoongArch.h"
15 #include "LoongArchMachineFunctionInfo.h"
16 #include "LoongArchTargetTransformInfo.h"
17 #include "MCTargetDesc/LoongArchBaseInfo.h"
18 #include "TargetInfo/LoongArchTargetInfo.h"
19 #include "llvm/Analysis/TargetTransformInfo.h"
20 #include "llvm/CodeGen/Passes.h"
21 #include "llvm/CodeGen/TargetLoweringObjectFileImpl.h"
22 #include "llvm/CodeGen/TargetPassConfig.h"
23 #include "llvm/MC/TargetRegistry.h"
24 #include "llvm/Support/CodeGen.h"
25 #include "llvm/Transforms/Scalar.h"
26 #include <optional>
28 using namespace llvm;
30 #define DEBUG_TYPE "loongarch"
32 extern "C" LLVM_EXTERNAL_VISIBILITY void LLVMInitializeLoongArchTarget() {
33 // Register the target.
34 RegisterTargetMachine<LoongArchTargetMachine> X(getTheLoongArch32Target());
35 RegisterTargetMachine<LoongArchTargetMachine> Y(getTheLoongArch64Target());
36 auto *PR = PassRegistry::getPassRegistry();
37 initializeLoongArchDeadRegisterDefinitionsPass(*PR);
38 initializeLoongArchMergeBaseOffsetOptPass(*PR);
39 initializeLoongArchOptWInstrsPass(*PR);
40 initializeLoongArchPreRAExpandPseudoPass(*PR);
41 initializeLoongArchExpandPseudoPass(*PR);
42 initializeLoongArchDAGToDAGISelLegacyPass(*PR);
45 static cl::opt<bool> EnableLoongArchDeadRegisterElimination(
46 "loongarch-enable-dead-defs", cl::Hidden,
47 cl::desc("Enable the pass that removes dead"
48 " definitons and replaces stores to"
49 " them with stores to r0"),
50 cl::init(true));
52 static cl::opt<bool>
53 EnableLoopDataPrefetch("loongarch-enable-loop-data-prefetch", cl::Hidden,
54 cl::desc("Enable the loop data prefetch pass"),
55 cl::init(false));
57 static std::string computeDataLayout(const Triple &TT) {
58 if (TT.isArch64Bit())
59 return "e-m:e-p:64:64-i64:64-i128:128-n32:64-S128";
60 assert(TT.isArch32Bit() && "only LA32 and LA64 are currently supported");
61 return "e-m:e-p:32:32-i64:64-n32-S128";
64 static Reloc::Model getEffectiveRelocModel(const Triple &TT,
65 std::optional<Reloc::Model> RM) {
66 return RM.value_or(Reloc::Static);
69 static CodeModel::Model
70 getEffectiveLoongArchCodeModel(const Triple &TT,
71 std::optional<CodeModel::Model> CM) {
72 if (!CM)
73 return CodeModel::Small;
75 switch (*CM) {
76 case CodeModel::Small:
77 return *CM;
78 case CodeModel::Medium:
79 case CodeModel::Large:
80 if (!TT.isArch64Bit())
81 report_fatal_error("Medium/Large code model requires LA64");
82 return *CM;
83 default:
84 report_fatal_error(
85 "Only small, medium and large code models are allowed on LoongArch");
89 LoongArchTargetMachine::LoongArchTargetMachine(
90 const Target &T, const Triple &TT, StringRef CPU, StringRef FS,
91 const TargetOptions &Options, std::optional<Reloc::Model> RM,
92 std::optional<CodeModel::Model> CM, CodeGenOptLevel OL, bool JIT)
93 : CodeGenTargetMachineImpl(T, computeDataLayout(TT), TT, CPU, FS, Options,
94 getEffectiveRelocModel(TT, RM),
95 getEffectiveLoongArchCodeModel(TT, CM), OL),
96 TLOF(std::make_unique<TargetLoweringObjectFileELF>()) {
97 initAsmInfo();
100 LoongArchTargetMachine::~LoongArchTargetMachine() = default;
102 const LoongArchSubtarget *
103 LoongArchTargetMachine::getSubtargetImpl(const Function &F) const {
104 Attribute CPUAttr = F.getFnAttribute("target-cpu");
105 Attribute TuneAttr = F.getFnAttribute("tune-cpu");
106 Attribute FSAttr = F.getFnAttribute("target-features");
108 std::string CPU =
109 CPUAttr.isValid() ? CPUAttr.getValueAsString().str() : TargetCPU;
110 std::string TuneCPU =
111 TuneAttr.isValid() ? TuneAttr.getValueAsString().str() : CPU;
112 std::string FS =
113 FSAttr.isValid() ? FSAttr.getValueAsString().str() : TargetFS;
115 std::string Key = CPU + TuneCPU + FS;
116 auto &I = SubtargetMap[Key];
117 if (!I) {
118 // This needs to be done before we create a new subtarget since any
119 // creation will depend on the TM and the code generation flags on the
120 // function that reside in TargetOptions.
121 resetTargetOptions(F);
122 auto ABIName = Options.MCOptions.getABIName();
123 if (const MDString *ModuleTargetABI = dyn_cast_or_null<MDString>(
124 F.getParent()->getModuleFlag("target-abi"))) {
125 auto TargetABI = LoongArchABI::getTargetABI(ABIName);
126 if (TargetABI != LoongArchABI::ABI_Unknown &&
127 ModuleTargetABI->getString() != ABIName) {
128 report_fatal_error("-target-abi option != target-abi module flag");
130 ABIName = ModuleTargetABI->getString();
132 I = std::make_unique<LoongArchSubtarget>(TargetTriple, CPU, TuneCPU, FS,
133 ABIName, *this);
135 return I.get();
138 MachineFunctionInfo *LoongArchTargetMachine::createMachineFunctionInfo(
139 BumpPtrAllocator &Allocator, const Function &F,
140 const TargetSubtargetInfo *STI) const {
141 return LoongArchMachineFunctionInfo::create<LoongArchMachineFunctionInfo>(
142 Allocator, F, STI);
145 namespace {
146 class LoongArchPassConfig : public TargetPassConfig {
147 public:
148 LoongArchPassConfig(LoongArchTargetMachine &TM, PassManagerBase &PM)
149 : TargetPassConfig(TM, PM) {}
151 LoongArchTargetMachine &getLoongArchTargetMachine() const {
152 return getTM<LoongArchTargetMachine>();
155 void addIRPasses() override;
156 void addCodeGenPrepare() override;
157 bool addInstSelector() override;
158 void addPreEmitPass() override;
159 void addPreEmitPass2() override;
160 void addMachineSSAOptimization() override;
161 void addPreRegAlloc() override;
162 bool addRegAssignAndRewriteFast() override;
163 bool addRegAssignAndRewriteOptimized() override;
165 } // end namespace
167 TargetPassConfig *
168 LoongArchTargetMachine::createPassConfig(PassManagerBase &PM) {
169 return new LoongArchPassConfig(*this, PM);
172 void LoongArchPassConfig::addIRPasses() {
173 // Run LoopDataPrefetch
175 // Run this before LSR to remove the multiplies involved in computing the
176 // pointer values N iterations ahead.
177 if (TM->getOptLevel() != CodeGenOptLevel::None && EnableLoopDataPrefetch)
178 addPass(createLoopDataPrefetchPass());
179 addPass(createAtomicExpandLegacyPass());
181 TargetPassConfig::addIRPasses();
184 void LoongArchPassConfig::addCodeGenPrepare() {
185 if (getOptLevel() != CodeGenOptLevel::None)
186 addPass(createTypePromotionLegacyPass());
187 TargetPassConfig::addCodeGenPrepare();
190 bool LoongArchPassConfig::addInstSelector() {
191 addPass(createLoongArchISelDag(getLoongArchTargetMachine()));
193 return false;
196 TargetTransformInfo
197 LoongArchTargetMachine::getTargetTransformInfo(const Function &F) const {
198 return TargetTransformInfo(LoongArchTTIImpl(this, F));
201 void LoongArchPassConfig::addPreEmitPass() { addPass(&BranchRelaxationPassID); }
203 void LoongArchPassConfig::addPreEmitPass2() {
204 addPass(createLoongArchExpandPseudoPass());
205 // Schedule the expansion of AtomicPseudos at the last possible moment,
206 // avoiding the possibility for other passes to break the requirements for
207 // forward progress in the LL/SC block.
208 addPass(createLoongArchExpandAtomicPseudoPass());
211 void LoongArchPassConfig::addMachineSSAOptimization() {
212 TargetPassConfig::addMachineSSAOptimization();
214 if (TM->getTargetTriple().isLoongArch64()) {
215 addPass(createLoongArchOptWInstrsPass());
219 void LoongArchPassConfig::addPreRegAlloc() {
220 addPass(createLoongArchPreRAExpandPseudoPass());
221 if (TM->getOptLevel() != CodeGenOptLevel::None)
222 addPass(createLoongArchMergeBaseOffsetOptPass());
225 bool LoongArchPassConfig::addRegAssignAndRewriteFast() {
226 if (TM->getOptLevel() != CodeGenOptLevel::None &&
227 EnableLoongArchDeadRegisterElimination)
228 addPass(createLoongArchDeadRegisterDefinitionsPass());
229 return TargetPassConfig::addRegAssignAndRewriteFast();
232 bool LoongArchPassConfig::addRegAssignAndRewriteOptimized() {
233 if (TM->getOptLevel() != CodeGenOptLevel::None &&
234 EnableLoongArchDeadRegisterElimination)
235 addPass(createLoongArchDeadRegisterDefinitionsPass());
236 return TargetPassConfig::addRegAssignAndRewriteOptimized();