LLVM 20.0.0git
LoongArchTargetMachine.cpp
Go to the documentation of this file.
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
14#include "LoongArch.h"
20#include "llvm/CodeGen/Passes.h"
26#include <optional>
27
28using namespace llvm;
29
30#define DEBUG_TYPE "loongarch"
31
33 // Register the target.
42}
43
45 "loongarch-enable-dead-defs", cl::Hidden,
46 cl::desc("Enable the pass that removes dead"
47 " definitons and replaces stores to"
48 " them with stores to r0"),
49 cl::init(true));
50
51static cl::opt<bool>
52 EnableLoopDataPrefetch("loongarch-enable-loop-data-prefetch", cl::Hidden,
53 cl::desc("Enable the loop data prefetch pass"),
54 cl::init(false));
55
56static std::string computeDataLayout(const Triple &TT) {
57 if (TT.isArch64Bit())
58 return "e-m:e-p:64:64-i64:64-i128:128-n32:64-S128";
59 assert(TT.isArch32Bit() && "only LA32 and LA64 are currently supported");
60 return "e-m:e-p:32:32-i64:64-n32-S128";
61}
62
64 std::optional<Reloc::Model> RM) {
65 return RM.value_or(Reloc::Static);
66}
67
70 std::optional<CodeModel::Model> CM) {
71 if (!CM)
72 return CodeModel::Small;
73
74 switch (*CM) {
76 return *CM;
79 if (!TT.isArch64Bit())
80 report_fatal_error("Medium/Large code model requires LA64");
81 return *CM;
82 default:
84 "Only small, medium and large code models are allowed on LoongArch");
85 }
86}
87
89 const Target &T, const Triple &TT, StringRef CPU, StringRef FS,
90 const TargetOptions &Options, std::optional<Reloc::Model> RM,
91 std::optional<CodeModel::Model> CM, CodeGenOptLevel OL, bool JIT)
92 : LLVMTargetMachine(T, computeDataLayout(TT), TT, CPU, FS, Options,
95 TLOF(std::make_unique<TargetLoweringObjectFileELF>()) {
97}
98
100
101const LoongArchSubtarget *
103 Attribute CPUAttr = F.getFnAttribute("target-cpu");
104 Attribute TuneAttr = F.getFnAttribute("tune-cpu");
105 Attribute FSAttr = F.getFnAttribute("target-features");
106
107 std::string CPU =
108 CPUAttr.isValid() ? CPUAttr.getValueAsString().str() : TargetCPU;
109 std::string TuneCPU =
110 TuneAttr.isValid() ? TuneAttr.getValueAsString().str() : CPU;
111 std::string FS =
112 FSAttr.isValid() ? FSAttr.getValueAsString().str() : TargetFS;
113
114 std::string Key = CPU + TuneCPU + FS;
115 auto &I = SubtargetMap[Key];
116 if (!I) {
117 // This needs to be done before we create a new subtarget since any
118 // creation will depend on the TM and the code generation flags on the
119 // function that reside in TargetOptions.
121 auto ABIName = Options.MCOptions.getABIName();
122 if (const MDString *ModuleTargetABI = dyn_cast_or_null<MDString>(
123 F.getParent()->getModuleFlag("target-abi"))) {
124 auto TargetABI = LoongArchABI::getTargetABI(ABIName);
125 if (TargetABI != LoongArchABI::ABI_Unknown &&
126 ModuleTargetABI->getString() != ABIName) {
127 report_fatal_error("-target-abi option != target-abi module flag");
128 }
129 ABIName = ModuleTargetABI->getString();
130 }
131 I = std::make_unique<LoongArchSubtarget>(TargetTriple, CPU, TuneCPU, FS,
132 ABIName, *this);
133 }
134 return I.get();
135}
136
138 BumpPtrAllocator &Allocator, const Function &F,
139 const TargetSubtargetInfo *STI) const {
140 return LoongArchMachineFunctionInfo::create<LoongArchMachineFunctionInfo>(
141 Allocator, F, STI);
142}
143
144namespace {
145class LoongArchPassConfig : public TargetPassConfig {
146public:
147 LoongArchPassConfig(LoongArchTargetMachine &TM, PassManagerBase &PM)
148 : TargetPassConfig(TM, PM) {}
149
150 LoongArchTargetMachine &getLoongArchTargetMachine() const {
151 return getTM<LoongArchTargetMachine>();
152 }
153
154 void addIRPasses() override;
155 void addCodeGenPrepare() override;
156 bool addInstSelector() override;
157 void addPreEmitPass() override;
158 void addPreEmitPass2() override;
159 void addMachineSSAOptimization() override;
160 void addPreRegAlloc() override;
161 bool addRegAssignAndRewriteFast() override;
162 bool addRegAssignAndRewriteOptimized() override;
163};
164} // end namespace
165
168 return new LoongArchPassConfig(*this, PM);
169}
170
171void LoongArchPassConfig::addIRPasses() {
172 // Run LoopDataPrefetch
173 //
174 // Run this before LSR to remove the multiplies involved in computing the
175 // pointer values N iterations ahead.
176 if (TM->getOptLevel() != CodeGenOptLevel::None && EnableLoopDataPrefetch)
179
181}
182
183void LoongArchPassConfig::addCodeGenPrepare() {
184 if (getOptLevel() != CodeGenOptLevel::None)
187}
188
189bool LoongArchPassConfig::addInstSelector() {
190 addPass(createLoongArchISelDag(getLoongArchTargetMachine()));
191
192 return false;
193}
194
198}
199
200void LoongArchPassConfig::addPreEmitPass() { addPass(&BranchRelaxationPassID); }
201
202void LoongArchPassConfig::addPreEmitPass2() {
204 // Schedule the expansion of AtomicPseudos at the last possible moment,
205 // avoiding the possibility for other passes to break the requirements for
206 // forward progress in the LL/SC block.
208}
209
210void LoongArchPassConfig::addMachineSSAOptimization() {
212
213 if (TM->getTargetTriple().isLoongArch64()) {
215 }
216}
217
218void LoongArchPassConfig::addPreRegAlloc() {
220 if (TM->getOptLevel() != CodeGenOptLevel::None)
222}
223
224bool LoongArchPassConfig::addRegAssignAndRewriteFast() {
225 if (TM->getOptLevel() != CodeGenOptLevel::None &&
229}
230
231bool LoongArchPassConfig::addRegAssignAndRewriteOptimized() {
232 if (TM->getOptLevel() != CodeGenOptLevel::None &&
236}
static cl::opt< bool > EnableLoopDataPrefetch("aarch64-enable-loop-data-prefetch", cl::Hidden, cl::desc("Enable the loop data prefetch pass"), cl::init(true))
#define LLVM_EXTERNAL_VISIBILITY
Definition: Compiler.h:135
static GCMetadataPrinterRegistry::Add< ErlangGCPrinter > X("erlang", "erlang-compatible garbage collector")
static LVOptions Options
Definition: LVOptions.cpp:25
static std::string computeDataLayout()
static cl::opt< bool > EnableLoongArchDeadRegisterElimination("loongarch-enable-dead-defs", cl::Hidden, cl::desc("Enable the pass that removes dead" " definitons and replaces stores to" " them with stores to r0"), cl::init(true))
static cl::opt< bool > EnableLoopDataPrefetch("loongarch-enable-loop-data-prefetch", cl::Hidden, cl::desc("Enable the loop data prefetch pass"), cl::init(false))
static CodeModel::Model getEffectiveLoongArchCodeModel(const Triple &TT, std::optional< CodeModel::Model > CM)
static Reloc::Model getEffectiveRelocModel(const Triple &TT, std::optional< Reloc::Model > RM)
LLVM_EXTERNAL_VISIBILITY void LLVMInitializeLoongArchTarget()
This file a TargetTransformInfo::Concept conforming object specific to the LoongArch target machine.
#define F(x, y, z)
Definition: MD5.cpp:55
#define I(x, y, z)
Definition: MD5.cpp:58
static GCMetadataPrinterRegistry::Add< OcamlGCMetadataPrinter > Y("ocaml", "ocaml 3.10-compatible collector")
Basic Register Allocator
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
Target-Independent Code Generator Pass Configuration Options pass.
This pass exposes codegen information to IR-level passes.
StringRef getValueAsString() const
Return the attribute's value as a string.
Definition: Attributes.cpp:392
bool isValid() const
Return true if the attribute is any kind of attribute.
Definition: Attributes.h:203
Allocate memory in an ever growing pool, as if by bump-pointer.
Definition: Allocator.h:66
This class describes a target machine that is implemented with the LLVM target-independent code gener...
LoongArchTargetMachine(const Target &T, const Triple &TT, StringRef CPU, StringRef FS, const TargetOptions &Options, std::optional< Reloc::Model > RM, std::optional< CodeModel::Model > CM, CodeGenOptLevel OL, bool JIT)
const LoongArchSubtarget * getSubtargetImpl() const =delete
TargetPassConfig * createPassConfig(PassManagerBase &PM) override
Create a pass configuration object to be used by addPassToEmitX methods for generating a pipeline of ...
TargetTransformInfo getTargetTransformInfo(const Function &F) const override
Get a TargetTransformInfo implementation for the target.
MachineFunctionInfo * createMachineFunctionInfo(BumpPtrAllocator &Allocator, const Function &F, const TargetSubtargetInfo *STI) const override
Create the target's instance of MachineFunctionInfo.
StringRef getABIName() const
getABIName - If this returns a non-empty string this represents the textual name of the ABI that we w...
A single uniqued string.
Definition: Metadata.h:720
static PassRegistry * getPassRegistry()
getPassRegistry - Access the global registry object, which is automatically initialized at applicatio...
StringRef - Represent a constant reference to a string, i.e.
Definition: StringRef.h:50
std::string str() const
str - Get the contents as an std::string.
Definition: StringRef.h:215
Triple TargetTriple
Triple string, CPU name, and target feature strings the TargetMachine instance is created with.
Definition: TargetMachine.h:96
std::string TargetFS
Definition: TargetMachine.h:98
std::string TargetCPU
Definition: TargetMachine.h:97
std::unique_ptr< const MCSubtargetInfo > STI
TargetOptions Options
void resetTargetOptions(const Function &F) const
Reset the target options based on the function's attributes.
MCTargetOptions MCOptions
Machine level options.
Target-Independent Code Generator Pass Configuration Options.
virtual void addCodeGenPrepare()
Add pass to prepare the LLVM IR for code generation.
virtual bool addRegAssignAndRewriteFast()
Add core register allocator passes which do the actual register assignment and rewriting.
virtual void addIRPasses()
Add common target configurable passes that perform LLVM IR to IR transforms following machine indepen...
virtual void addMachineSSAOptimization()
addMachineSSAOptimization - Add standard passes that optimize machine instructions in SSA form.
virtual bool addRegAssignAndRewriteOptimized()
TargetSubtargetInfo - Generic base class for all target subtargets.
This pass provides access to the codegen interfaces that are needed for IR-level transformations.
Target - Wrapper for Target specific information.
Triple - Helper class for working with autoconf configuration names.
Definition: Triple.h:44
PassManagerBase - An abstract interface to allow code to add passes to a pass manager without having ...
ABI getTargetABI(StringRef ABIName)
initializer< Ty > init(const Ty &Val)
Definition: CommandLine.h:443
This is an optimization pass for GlobalISel generic memory operations.
Definition: AddressRanges.h:18
Target & getTheLoongArch64Target()
FunctionPass * createLoongArchExpandAtomicPseudoPass()
FunctionPass * createLoongArchDeadRegisterDefinitionsPass()
void initializeLoongArchDAGToDAGISelLegacyPass(PassRegistry &)
FunctionPass * createTypePromotionLegacyPass()
Create IR Type Promotion pass.
void initializeLoongArchPreRAExpandPseudoPass(PassRegistry &)
FunctionPass * createLoongArchISelDag(LoongArchTargetMachine &TM)
void initializeLoongArchMergeBaseOffsetOptPass(PassRegistry &)
char & BranchRelaxationPassID
BranchRelaxation - This pass replaces branches that need to jump further than is supported by a branc...
FunctionPass * createLoongArchOptWInstrsPass()
FunctionPass * createLoopDataPrefetchPass()
void report_fatal_error(Error Err, bool gen_crash_diag=true)
Report a serious error, calling any installed error handler.
Definition: Error.cpp:167
CodeGenOptLevel
Code generation optimization level.
Definition: CodeGen.h:54
Target & getTheLoongArch32Target()
FunctionPass * createLoongArchPreRAExpandPseudoPass()
void initializeLoongArchOptWInstrsPass(PassRegistry &)
FunctionPass * createLoongArchExpandPseudoPass()
FunctionPass * createAtomicExpandLegacyPass()
AtomicExpandPass - At IR level this pass replace atomic instructions with __atomic_* library calls,...
void initializeLoongArchDeadRegisterDefinitionsPass(PassRegistry &)
FunctionPass * createLoongArchMergeBaseOffsetOptPass()
Returns an instance of the Merge Base Offset Optimization pass.
Implement std::hash so that hash_code can be used in STL containers.
Definition: BitVector.h:858
MachineFunctionInfo - This class can be derived from and used by targets to hold private target-speci...
RegisterTargetMachine - Helper template for registering a target machine implementation,...