LLVM 22.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"
27#include <optional>
28
29using namespace llvm;
30
31#define DEBUG_TYPE "loongarch"
32
35 // Register the target.
46}
47
49 "loongarch-enable-dead-defs", cl::Hidden,
50 cl::desc("Enable the pass that removes dead"
51 " definitons and replaces stores to"
52 " them with stores to r0"),
53 cl::init(true));
54
55static cl::opt<bool>
56 EnableLoopDataPrefetch("loongarch-enable-loop-data-prefetch", cl::Hidden,
57 cl::desc("Enable the loop data prefetch pass"),
58 cl::init(false));
59
60static std::string computeDataLayout(const Triple &TT) {
61 if (TT.isArch64Bit())
62 return "e-m:e-p:64:64-i64:64-i128:128-n32:64-S128";
63 assert(TT.isArch32Bit() && "only LA32 and LA64 are currently supported");
64 return "e-m:e-p:32:32-i64:64-n32-S128";
65}
66
68 std::optional<Reloc::Model> RM) {
69 return RM.value_or(Reloc::Static);
70}
71
74 std::optional<CodeModel::Model> CM) {
75 if (!CM)
76 return TT.isArch64Bit() ? CodeModel::Medium : CodeModel::Small;
77
78 switch (*CM) {
80 return *CM;
83 if (!TT.isArch64Bit())
84 report_fatal_error("Medium/Large code model requires LA64");
85 return *CM;
86 default:
88 "Only small, medium and large code models are allowed on LoongArch");
89 }
90}
91
93 const Target &T, const Triple &TT, StringRef CPU, StringRef FS,
94 const TargetOptions &Options, std::optional<Reloc::Model> RM,
95 std::optional<CodeModel::Model> CM, CodeGenOptLevel OL, bool JIT)
99 TLOF(std::make_unique<TargetLoweringObjectFileELF>()) {
100 initAsmInfo();
101}
102
104
105const LoongArchSubtarget *
107 Attribute CPUAttr = F.getFnAttribute("target-cpu");
108 Attribute TuneAttr = F.getFnAttribute("tune-cpu");
109 Attribute FSAttr = F.getFnAttribute("target-features");
110
111 std::string CPU =
112 CPUAttr.isValid() ? CPUAttr.getValueAsString().str() : TargetCPU;
113 std::string TuneCPU =
114 TuneAttr.isValid() ? TuneAttr.getValueAsString().str() : CPU;
115 std::string FS =
116 FSAttr.isValid() ? FSAttr.getValueAsString().str() : TargetFS;
117
118 std::string Key = CPU + TuneCPU + FS;
119 auto &I = SubtargetMap[Key];
120 if (!I) {
121 // This needs to be done before we create a new subtarget since any
122 // creation will depend on the TM and the code generation flags on the
123 // function that reside in TargetOptions.
125 auto ABIName = Options.MCOptions.getABIName();
126 if (const MDString *ModuleTargetABI = dyn_cast_or_null<MDString>(
127 F.getParent()->getModuleFlag("target-abi"))) {
128 auto TargetABI = LoongArchABI::getTargetABI(ABIName);
129 if (TargetABI != LoongArchABI::ABI_Unknown &&
130 ModuleTargetABI->getString() != ABIName) {
131 report_fatal_error("-target-abi option != target-abi module flag");
132 }
133 ABIName = ModuleTargetABI->getString();
134 }
135 I = std::make_unique<LoongArchSubtarget>(TargetTriple, CPU, TuneCPU, FS,
136 ABIName, *this);
137 }
138 return I.get();
139}
140
142 BumpPtrAllocator &Allocator, const Function &F,
143 const TargetSubtargetInfo *STI) const {
144 return LoongArchMachineFunctionInfo::create<LoongArchMachineFunctionInfo>(
145 Allocator, F, STI);
146}
147
148namespace {
149class LoongArchPassConfig : public TargetPassConfig {
150public:
151 LoongArchPassConfig(LoongArchTargetMachine &TM, PassManagerBase &PM)
152 : TargetPassConfig(TM, PM) {}
153
154 LoongArchTargetMachine &getLoongArchTargetMachine() const {
155 return getTM<LoongArchTargetMachine>();
156 }
157
158 void addIRPasses() override;
159 void addCodeGenPrepare() override;
160 bool addInstSelector() override;
161 void addPreEmitPass() override;
162 void addPreEmitPass2() override;
163 void addMachineSSAOptimization() override;
164 void addPreRegAlloc() override;
165 bool addRegAssignAndRewriteFast() override;
166 bool addRegAssignAndRewriteOptimized() override;
167};
168} // end namespace
169
172 return new LoongArchPassConfig(*this, PM);
173}
174
175void LoongArchPassConfig::addIRPasses() {
176 // Run LoopDataPrefetch
177 //
178 // Run this before LSR to remove the multiplies involved in computing the
179 // pointer values N iterations ahead.
180 if (TM->getOptLevel() != CodeGenOptLevel::None && EnableLoopDataPrefetch)
183
185}
186
187void LoongArchPassConfig::addCodeGenPrepare() {
188 if (getOptLevel() != CodeGenOptLevel::None)
191}
192
193bool LoongArchPassConfig::addInstSelector() {
194 addPass(createLoongArchISelDag(getLoongArchTargetMachine(), getOptLevel()));
195
196 return false;
197}
198
201 return TargetTransformInfo(std::make_unique<LoongArchTTIImpl>(this, F));
202}
203
204void LoongArchPassConfig::addPreEmitPass() { addPass(&BranchRelaxationPassID); }
205
206void LoongArchPassConfig::addPreEmitPass2() {
208 // Schedule the expansion of AtomicPseudos at the last possible moment,
209 // avoiding the possibility for other passes to break the requirements for
210 // forward progress in the LL/SC block.
212}
213
214void LoongArchPassConfig::addMachineSSAOptimization() {
216
217 if (TM->getTargetTriple().isLoongArch64()) {
219 }
220}
221
222void LoongArchPassConfig::addPreRegAlloc() {
224 if (TM->getOptLevel() != CodeGenOptLevel::None)
226}
227
228bool LoongArchPassConfig::addRegAssignAndRewriteFast() {
229 if (TM->getOptLevel() != CodeGenOptLevel::None &&
233}
234
235bool LoongArchPassConfig::addRegAssignAndRewriteOptimized() {
236 if (TM->getOptLevel() != CodeGenOptLevel::None &&
240}
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
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_ABI
Definition: Compiler.h:213
#define LLVM_EXTERNAL_VISIBILITY
Definition: Compiler.h:132
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))
LLVM_ABI LLVM_EXTERNAL_VISIBILITY void LLVMInitializeLoongArchTarget()
static CodeModel::Model getEffectiveLoongArchCodeModel(const Triple &TT, std::optional< CodeModel::Model > CM)
static Reloc::Model getEffectiveRelocModel(const Triple &TT, std::optional< Reloc::Model > RM)
This file a TargetTransformInfoImplBase 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
Target-Independent Code Generator Pass Configuration Options pass.
This pass exposes codegen information to IR-level passes.
LLVM_ABI StringRef getValueAsString() const
Return the attribute's value as a string.
Definition: Attributes.cpp:400
bool isValid() const
Return true if the attribute is any kind of attribute.
Definition: Attributes.h:223
Allocate memory in an ever growing pool, as if by bump-pointer.
Definition: Allocator.h:67
implements a set of functionality in the TargetMachine class for targets that make use of the indepen...
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.
LLVM_ABI 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 LLVM_ABI 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:55
std::string str() const
str - Get the contents as an std::string.
Definition: StringRef.h:233
Triple TargetTriple
Triple string, CPU name, and target feature strings the TargetMachine instance is created with.
std::string TargetFS
std::string TargetCPU
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:47
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:444
This is an optimization pass for GlobalISel generic memory operations.
Definition: AddressRanges.h:18
Target & getTheLoongArch64Target()
FunctionPass * createLoongArchExpandAtomicPseudoPass()
FunctionPass * createLoongArchDeadRegisterDefinitionsPass()
void initializeLoongArchDAGToDAGISelLegacyPass(PassRegistry &)
LLVM_ABI FunctionPass * createTypePromotionLegacyPass()
Create IR Type Promotion pass.
void initializeLoongArchPreRAExpandPseudoPass(PassRegistry &)
void initializeLoongArchMergeBaseOffsetOptPass(PassRegistry &)
void initializeLoongArchExpandAtomicPseudoPass(PassRegistry &)
LLVM_ABI char & BranchRelaxationPassID
BranchRelaxation - This pass replaces branches that need to jump further than is supported by a branc...
void initializeLoongArchExpandPseudoPass(PassRegistry &)
FunctionPass * createLoongArchOptWInstrsPass()
LLVM_ABI FunctionPass * createLoopDataPrefetchPass()
LLVM_ABI void report_fatal_error(Error Err, bool gen_crash_diag=true)
Definition: Error.cpp:167
CodeGenOptLevel
Code generation optimization level.
Definition: CodeGen.h:82
Target & getTheLoongArch32Target()
FunctionPass * createLoongArchISelDag(LoongArchTargetMachine &TM, CodeGenOptLevel OptLevel)
FunctionPass * createLoongArchPreRAExpandPseudoPass()
void initializeLoongArchOptWInstrsPass(PassRegistry &)
FunctionPass * createLoongArchExpandPseudoPass()
LLVM_ABI 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:856
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,...