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
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 cl::opt<bool>
61 EnableMergeBaseOffset("loongarch-enable-merge-offset",
62 cl::desc("Enable the merge base offset pass"),
63 cl::init(true), cl::Hidden);
64
66 std::optional<Reloc::Model> RM) {
67 return RM.value_or(Reloc::Static);
68}
69
72 std::optional<CodeModel::Model> CM) {
73 if (!CM)
74 return TT.isArch64Bit() ? CodeModel::Medium : CodeModel::Small;
75
76 switch (*CM) {
78 return *CM;
81 if (!TT.isArch64Bit())
82 report_fatal_error("Medium/Large code model requires LA64");
83 return *CM;
84 default:
86 "Only small, medium and large code models are allowed on LoongArch");
87 }
88}
89
91 const Target &T, const Triple &TT, StringRef CPU, StringRef FS,
92 const TargetOptions &Options, std::optional<Reloc::Model> RM,
93 std::optional<CodeModel::Model> CM, CodeGenOptLevel OL, bool JIT)
94 : CodeGenTargetMachineImpl(T, TT.computeDataLayout(), TT, CPU, FS, Options,
97 TLOF(std::make_unique<TargetLoweringObjectFileELF>()) {
99}
100
102
103const LoongArchSubtarget *
105 Attribute CPUAttr = F.getFnAttribute("target-cpu");
106 Attribute TuneAttr = F.getFnAttribute("tune-cpu");
107 Attribute FSAttr = F.getFnAttribute("target-features");
108
109 std::string CPU =
110 CPUAttr.isValid() ? CPUAttr.getValueAsString().str() : TargetCPU;
111 std::string TuneCPU =
112 TuneAttr.isValid() ? TuneAttr.getValueAsString().str() : CPU;
113 std::string FS =
114 FSAttr.isValid() ? FSAttr.getValueAsString().str() : TargetFS;
115
116 std::string Key = CPU + TuneCPU + FS;
117 auto &I = SubtargetMap[Key];
118 if (!I) {
119 // This needs to be done before we create a new subtarget since any
120 // creation will depend on the TM and the code generation flags on the
121 // function that reside in TargetOptions.
123 auto ABIName = Options.MCOptions.getABIName();
124 if (const MDString *ModuleTargetABI = dyn_cast_or_null<MDString>(
125 F.getParent()->getModuleFlag("target-abi"))) {
126 auto TargetABI = LoongArchABI::getTargetABI(ABIName);
127 if (TargetABI != LoongArchABI::ABI_Unknown &&
128 ModuleTargetABI->getString() != ABIName) {
129 report_fatal_error("-target-abi option != target-abi module flag");
130 }
131 ABIName = ModuleTargetABI->getString();
132 }
133 I = std::make_unique<LoongArchSubtarget>(TargetTriple, CPU, TuneCPU, FS,
134 ABIName, *this);
135 }
136 return I.get();
137}
138
145
146namespace {
147class LoongArchPassConfig : public TargetPassConfig {
148public:
149 LoongArchPassConfig(LoongArchTargetMachine &TM, PassManagerBase &PM)
150 : TargetPassConfig(TM, PM) {}
151
152 LoongArchTargetMachine &getLoongArchTargetMachine() const {
154 }
155
156 void addIRPasses() override;
157 void addCodeGenPrepare() override;
158 bool addInstSelector() override;
159 void addPreEmitPass() override;
160 void addPreEmitPass2() override;
161 void addMachineSSAOptimization() override;
162 void addPreRegAlloc() override;
163 bool addRegAssignAndRewriteFast() override;
164 bool addRegAssignAndRewriteOptimized() override;
165};
166} // end namespace
167
170 return new LoongArchPassConfig(*this, PM);
171}
172
173void LoongArchPassConfig::addIRPasses() {
174 // Run LoopDataPrefetch
175 //
176 // Run this before LSR to remove the multiplies involved in computing the
177 // pointer values N iterations ahead.
178 if (TM->getOptLevel() != CodeGenOptLevel::None && EnableLoopDataPrefetch)
181
183}
184
185void LoongArchPassConfig::addCodeGenPrepare() {
186 if (getOptLevel() != CodeGenOptLevel::None)
189}
190
191bool LoongArchPassConfig::addInstSelector() {
192 addPass(createLoongArchISelDag(getLoongArchTargetMachine(), getOptLevel()));
193
194 return false;
195}
196
199 return TargetTransformInfo(std::make_unique<LoongArchTTIImpl>(this, F));
200}
201
202void LoongArchPassConfig::addPreEmitPass() { addPass(&BranchRelaxationPassID); }
203
204void LoongArchPassConfig::addPreEmitPass2() {
206 // Schedule the expansion of AtomicPseudos at the last possible moment,
207 // avoiding the possibility for other passes to break the requirements for
208 // forward progress in the LL/SC block.
210}
211
212void LoongArchPassConfig::addMachineSSAOptimization() {
214
215 if (TM->getTargetTriple().isLoongArch64()) {
217 }
218}
219
220void LoongArchPassConfig::addPreRegAlloc() {
222 if (TM->getOptLevel() != CodeGenOptLevel::None && EnableMergeBaseOffset)
224}
225
226bool LoongArchPassConfig::addRegAssignAndRewriteFast() {
227 if (TM->getOptLevel() != CodeGenOptLevel::None &&
231}
232
233bool LoongArchPassConfig::addRegAssignAndRewriteOptimized() {
234 if (TM->getOptLevel() != CodeGenOptLevel::None &&
238}
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 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 > EnableMergeBaseOffset("loongarch-enable-merge-offset", cl::desc("Enable the merge base offset pass"), cl::init(true), cl::Hidden)
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)
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
#define T
const GCNTargetMachine & getTM(const GCNSubtarget *STI)
static TableGen::Emitter::Opt Y("gen-skeleton-entry", EmitSkeleton, "Generate example skeleton entry")
static TableGen::Emitter::OptClass< SkeletonEmitter > X("gen-skeleton-class", "Generate example skeleton class")
Target-Independent Code Generator Pass Configuration Options pass.
This pass exposes codegen information to IR-level passes.
Functions, function parameters, and return types can have attributes to indicate how they should be t...
Definition Attributes.h:69
LLVM_ABI StringRef getValueAsString() const
Return the attribute's value as a string.
bool isValid() const
Return true if the attribute is any kind of attribute.
Definition Attributes.h:223
CodeGenTargetMachineImpl(const Target &T, StringRef DataLayoutString, const Triple &TT, StringRef CPU, StringRef FS, const TargetOptions &Options, Reloc::Model RM, CodeModel::Model CM, CodeGenOptLevel OL)
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.
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:225
Triple TargetTriple
Triple string, CPU name, and target feature strings the TargetMachine instance is created with.
std::unique_ptr< const MCSubtargetInfo > STI
TargetOptions Options
void resetTargetOptions(const Function &F) const
Reset the target options based on the function's attributes.
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)
This is an optimization pass for GlobalISel generic memory operations.
Target & getTheLoongArch64Target()
FunctionPass * createLoongArchExpandAtomicPseudoPass()
FunctionPass * createLoongArchDeadRegisterDefinitionsPass()
void initializeLoongArchDAGToDAGISelLegacyPass(PassRegistry &)
LLVM_ABI FunctionPass * createTypePromotionLegacyPass()
Create IR Type Promotion pass.
void initializeLoongArchPreRAExpandPseudoPass(PassRegistry &)
auto dyn_cast_or_null(const Y &Val)
Definition Casting.h:759
void initializeLoongArchMergeBaseOffsetOptPass(PassRegistry &)
static Reloc::Model getEffectiveRelocModel(std::optional< Reloc::Model > RM)
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
BumpPtrAllocatorImpl BumpPtrAllocator
The standard BumpPtrAllocator which just uses the default template parameters.
Definition Allocator.h:383
CodeGenOptLevel
Code generation optimization level.
Definition CodeGen.h:82
LLVM_ATTRIBUTE_VISIBILITY_DEFAULT AnalysisKey InnerAnalysisManagerProxy< AnalysisManagerT, IRUnitT, ExtraArgTs... >::Key
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:870
MachineFunctionInfo - This class can be derived from and used by targets to hold private target-speci...
static FuncInfoTy * create(BumpPtrAllocator &Allocator, const Function &F, const SubtargetTy *STI)
Factory function: default behavior is to call new using the supplied allocator.
RegisterTargetMachine - Helper template for registering a target machine implementation,...