LLVM 24.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"
21#include "llvm/CodeGen/Passes.h"
28#include <optional>
29
30using namespace llvm;
31
32#define DEBUG_TYPE "loongarch"
33
49
51 "loongarch-enable-dead-defs", cl::Hidden,
52 cl::desc("Enable the pass that removes dead"
53 " definitons and replaces stores to"
54 " them with stores to r0"),
55 cl::init(true));
56
57static cl::opt<bool>
58 EnableLoopDataPrefetch("loongarch-enable-loop-data-prefetch", cl::Hidden,
59 cl::desc("Enable the loop data prefetch pass"),
60 cl::init(false));
61
62static cl::opt<bool>
63 EnableMergeBaseOffset("loongarch-enable-merge-offset",
64 cl::desc("Enable the merge base offset pass"),
65 cl::init(true), cl::Hidden);
66
67static cl::opt<bool>
68 EnableSinkFold("loongarch-enable-sink-fold",
69 cl::desc("Enable sinking and folding of instruction copies"),
70 cl::init(true), cl::Hidden);
71
72static Reloc::Model getEffectiveRelocModel(std::optional<Reloc::Model> RM) {
73 return RM.value_or(Reloc::Static);
74}
75
78 std::optional<CodeModel::Model> CM) {
79 if (!CM)
80 return TT.isArch64Bit() ? CodeModel::Medium : CodeModel::Small;
81
82 switch (*CM) {
85 return *CM;
87 if (!TT.isArch64Bit())
88 report_fatal_error("Large code model requires LA64");
89 return *CM;
90 default:
92 "Only small, medium and large code models are allowed on LoongArch");
93 }
94}
95
97 const Target &T, const Triple &TT, StringRef CPU, StringRef FS,
98 const TargetOptions &Options, std::optional<Reloc::Model> RM,
99 std::optional<CodeModel::Model> CM, CodeGenOptLevel OL, bool JIT)
100 : CodeGenTargetMachineImpl(T, TT.computeDataLayout(), TT, CPU, FS, Options,
103 TLOF(std::make_unique<LoongArchELFTargetObjectFile>()) {
104 initAsmInfo();
105}
106
108
109const LoongArchSubtarget *
111 Attribute CPUAttr = F.getFnAttribute("target-cpu");
112 Attribute TuneAttr = F.getFnAttribute("tune-cpu");
113 Attribute FSAttr = F.getFnAttribute("target-features");
114
115 std::string CPU =
116 CPUAttr.isValid() ? CPUAttr.getValueAsString().str() : TargetCPU;
117 std::string TuneCPU =
118 TuneAttr.isValid() ? TuneAttr.getValueAsString().str() : CPU;
119 std::string FS =
120 FSAttr.isValid() ? FSAttr.getValueAsString().str() : TargetFS;
121
122 std::string Key = CPU + TuneCPU + FS;
123 auto &I = SubtargetMap[Key];
124 if (!I) {
125 StringRef ABIName = getTargetABIName(*F.getParent());
126 I = std::make_unique<LoongArchSubtarget>(TargetTriple, CPU, TuneCPU, FS,
127 ABIName, *this);
128 }
129 return I.get();
130}
131
138
139namespace {
140class LoongArchPassConfig : public TargetPassConfig {
141public:
142 LoongArchPassConfig(LoongArchTargetMachine &TM, PassManagerBase &PM)
143 : TargetPassConfig(TM, PM) {
144 setEnableSinkAndFold(EnableSinkFold);
145 }
146
147 LoongArchTargetMachine &getLoongArchTargetMachine() const {
149 }
150
151 void addIRPasses() override;
152 void addCodeGenPrepare() override;
153 bool addInstSelector() override;
154 void addPreEmitPass() override;
155 void addPreEmitPass2() override;
156 void addMachineSSAOptimization() override;
157 void addPreRegAlloc() override;
158 bool addRegAssignAndRewriteFast() override;
159 bool addRegAssignAndRewriteOptimized() override;
160 void addMachineLateOptimization() override;
161};
162} // end namespace
163
166 return new LoongArchPassConfig(*this, PM);
167}
168
169void LoongArchPassConfig::addIRPasses() {
170 // Run LoopDataPrefetch
171 //
172 // Run this before LSR to remove the multiplies involved in computing the
173 // pointer values N iterations ahead.
174 if (TM->getOptLevel() != CodeGenOptLevel::None && EnableLoopDataPrefetch)
177
179}
180
181void LoongArchPassConfig::addCodeGenPrepare() {
182 if (getOptLevel() != CodeGenOptLevel::None)
185}
186
187bool LoongArchPassConfig::addInstSelector() {
188 addPass(createLoongArchISelDag(getLoongArchTargetMachine(), getOptLevel()));
189
190 return false;
191}
192
195 return TargetTransformInfo(std::make_unique<LoongArchTTIImpl>(this, F));
196}
197
198void LoongArchPassConfig::addPreEmitPass() { addPass(&BranchRelaxationPassID); }
199
200void LoongArchPassConfig::addPreEmitPass2() {
202 // Schedule the expansion of AtomicPseudos at the last possible moment,
203 // avoiding the possibility for other passes to break the requirements for
204 // forward progress in the LL/SC block.
206}
207
208void LoongArchPassConfig::addMachineSSAOptimization() {
210
211 if (TM->getTargetTriple().isLoongArch64()) {
213 }
214}
215
216void LoongArchPassConfig::addPreRegAlloc() {
218 if (TM->getOptLevel() != CodeGenOptLevel::None && EnableMergeBaseOffset)
220}
221
222bool LoongArchPassConfig::addRegAssignAndRewriteFast() {
223 if (TM->getOptLevel() != CodeGenOptLevel::None &&
227}
228
229bool LoongArchPassConfig::addRegAssignAndRewriteOptimized() {
230 if (TM->getOptLevel() != CodeGenOptLevel::None &&
234}
235
236void LoongArchPassConfig::addMachineLateOptimization() {
237 if (TM->getOptLevel() != CodeGenOptLevel::None)
240}
static cl::opt< bool > EnableSinkFold("aarch64-enable-sink-fold", cl::desc("Enable sinking and folding of instruction copies"), cl::init(true), cl::Hidden)
static cl::opt< bool > EnableLoopDataPrefetch("aarch64-enable-loop-data-prefetch", cl::Hidden, cl::desc("Enable the loop data prefetch pass"), cl::init(true))
static Reloc::Model getEffectiveRelocModel()
#define X(NUM, ENUM, NAME)
Definition ELF.h:857
#define LLVM_ABI
Definition Compiler.h:215
#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)
static cl::opt< bool > EnableSinkFold("loongarch-enable-sink-fold", cl::desc("Enable sinking and folding of instruction copies"), cl::init(true), cl::Hidden)
This file a TargetTransformInfoImplBase conforming object specific to the LoongArch target machine.
#define F(x, y, z)
Definition MD5.cpp:54
#define I(x, y, z)
Definition MD5.cpp:57
#define T
const GCNTargetMachine & getTM(const GCNSubtarget *STI)
static TableGen::Emitter::Opt Y("gen-skeleton-entry", EmitSkeleton, "Generate example skeleton entry")
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:105
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:261
CodeGenTargetMachineImpl(const Target &T, StringRef DataLayoutString, const Triple &TT, StringRef CPU, StringRef FS, const TargetOptions &Options, Reloc::Model RM, CodeModel::Model CM, CodeGenOptLevel OL)
This implementation is used for LoongArch ELF targets.
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.
static LLVM_ABI PassRegistry * getPassRegistry()
getPassRegistry - Access the global registry object, which is automatically initialized at applicatio...
Represent a constant reference to a string, i.e.
Definition StringRef.h:56
std::string str() const
Get the contents as an std::string.
Definition StringRef.h:222
Triple TargetTriple
Triple string, CPU name, and target feature strings the TargetMachine instance is created with.
StringRef getTargetABIName(const Module &M) const
Returns the effective target ABI name: the "target-abi" module flag if present, otherwise the -target...
std::unique_ptr< const MCSubtargetInfo > STI
TargetOptions 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 addMachineLateOptimization()
Add passes that optimize machine instructions after register allocation.
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:48
PassManagerBase - An abstract interface to allow code to add passes to a pass manager without having ...
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 &)
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()
void initializeLoongArchLateBranchOptPass(PassRegistry &)
LLVM_ABI FunctionPass * createLoopDataPrefetchPass()
LLVM_ABI void report_fatal_error(Error Err, bool gen_crash_diag=true)
Definition Error.cpp:163
CodeGenOptLevel
Code generation optimization level.
Definition CodeGen.h:149
LLVM_ATTRIBUTE_VISIBILITY_DEFAULT AnalysisKey InnerAnalysisManagerProxy< AnalysisManagerT, IRUnitT, ExtraArgTs... >::Key
Target & getTheLoongArch32Target()
FunctionPass * createLoongArchISelDag(LoongArchTargetMachine &TM, CodeGenOptLevel OptLevel)
FunctionPass * createLoongArchLateBranchOptPass()
FunctionPass * createLoongArchPreRAExpandPseudoPass()
void initializeLoongArchOptWInstrsPass(PassRegistry &)
FunctionPass * createLoongArchExpandPseudoPass()
LLVM_ABI FunctionPass * createAtomicExpandLegacyPass()
AtomicExpandPass - At IR level this pass replace atomic instructions with __atomic_* library calls,...
BumpPtrAllocatorImpl<> BumpPtrAllocator
The standard BumpPtrAllocator which just uses the default template parameters.
Definition Allocator.h:390
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:878
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,...