Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
freebsd
GitHub Repository: freebsd/freebsd-src
Path: blob/main/contrib/llvm-project/llvm/lib/Target/LoongArch/LoongArchTargetMachine.cpp
35294 views
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
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>
27
28
using namespace llvm;
29
30
#define DEBUG_TYPE "loongarch"
31
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
initializeLoongArchOptWInstrsPass(*PR);
39
initializeLoongArchPreRAExpandPseudoPass(*PR);
40
initializeLoongArchDAGToDAGISelLegacyPass(*PR);
41
}
42
43
static cl::opt<bool> EnableLoongArchDeadRegisterElimination(
44
"loongarch-enable-dead-defs", cl::Hidden,
45
cl::desc("Enable the pass that removes dead"
46
" definitons and replaces stores to"
47
" them with stores to r0"),
48
cl::init(true));
49
50
static cl::opt<bool>
51
EnableLoopDataPrefetch("loongarch-enable-loop-data-prefetch", cl::Hidden,
52
cl::desc("Enable the loop data prefetch pass"),
53
cl::init(false));
54
55
static std::string computeDataLayout(const Triple &TT) {
56
if (TT.isArch64Bit())
57
return "e-m:e-p:64:64-i64:64-i128:128-n32:64-S128";
58
assert(TT.isArch32Bit() && "only LA32 and LA64 are currently supported");
59
return "e-m:e-p:32:32-i64:64-n32-S128";
60
}
61
62
static Reloc::Model getEffectiveRelocModel(const Triple &TT,
63
std::optional<Reloc::Model> RM) {
64
return RM.value_or(Reloc::Static);
65
}
66
67
static CodeModel::Model
68
getEffectiveLoongArchCodeModel(const Triple &TT,
69
std::optional<CodeModel::Model> CM) {
70
if (!CM)
71
return CodeModel::Small;
72
73
switch (*CM) {
74
case CodeModel::Small:
75
return *CM;
76
case CodeModel::Medium:
77
case CodeModel::Large:
78
if (!TT.isArch64Bit())
79
report_fatal_error("Medium/Large code model requires LA64");
80
return *CM;
81
default:
82
report_fatal_error(
83
"Only small, medium and large code models are allowed on LoongArch");
84
}
85
}
86
87
LoongArchTargetMachine::LoongArchTargetMachine(
88
const Target &T, const Triple &TT, StringRef CPU, StringRef FS,
89
const TargetOptions &Options, std::optional<Reloc::Model> RM,
90
std::optional<CodeModel::Model> CM, CodeGenOptLevel OL, bool JIT)
91
: LLVMTargetMachine(T, computeDataLayout(TT), TT, CPU, FS, Options,
92
getEffectiveRelocModel(TT, RM),
93
getEffectiveLoongArchCodeModel(TT, CM), OL),
94
TLOF(std::make_unique<TargetLoweringObjectFileELF>()) {
95
initAsmInfo();
96
}
97
98
LoongArchTargetMachine::~LoongArchTargetMachine() = default;
99
100
const LoongArchSubtarget *
101
LoongArchTargetMachine::getSubtargetImpl(const Function &F) const {
102
Attribute CPUAttr = F.getFnAttribute("target-cpu");
103
Attribute TuneAttr = F.getFnAttribute("tune-cpu");
104
Attribute FSAttr = F.getFnAttribute("target-features");
105
106
std::string CPU =
107
CPUAttr.isValid() ? CPUAttr.getValueAsString().str() : TargetCPU;
108
std::string TuneCPU =
109
TuneAttr.isValid() ? TuneAttr.getValueAsString().str() : CPU;
110
std::string FS =
111
FSAttr.isValid() ? FSAttr.getValueAsString().str() : TargetFS;
112
113
std::string Key = CPU + TuneCPU + FS;
114
auto &I = SubtargetMap[Key];
115
if (!I) {
116
// This needs to be done before we create a new subtarget since any
117
// creation will depend on the TM and the code generation flags on the
118
// function that reside in TargetOptions.
119
resetTargetOptions(F);
120
auto ABIName = Options.MCOptions.getABIName();
121
if (const MDString *ModuleTargetABI = dyn_cast_or_null<MDString>(
122
F.getParent()->getModuleFlag("target-abi"))) {
123
auto TargetABI = LoongArchABI::getTargetABI(ABIName);
124
if (TargetABI != LoongArchABI::ABI_Unknown &&
125
ModuleTargetABI->getString() != ABIName) {
126
report_fatal_error("-target-abi option != target-abi module flag");
127
}
128
ABIName = ModuleTargetABI->getString();
129
}
130
I = std::make_unique<LoongArchSubtarget>(TargetTriple, CPU, TuneCPU, FS,
131
ABIName, *this);
132
}
133
return I.get();
134
}
135
136
MachineFunctionInfo *LoongArchTargetMachine::createMachineFunctionInfo(
137
BumpPtrAllocator &Allocator, const Function &F,
138
const TargetSubtargetInfo *STI) const {
139
return LoongArchMachineFunctionInfo::create<LoongArchMachineFunctionInfo>(
140
Allocator, F, STI);
141
}
142
143
namespace {
144
class LoongArchPassConfig : public TargetPassConfig {
145
public:
146
LoongArchPassConfig(LoongArchTargetMachine &TM, PassManagerBase &PM)
147
: TargetPassConfig(TM, PM) {}
148
149
LoongArchTargetMachine &getLoongArchTargetMachine() const {
150
return getTM<LoongArchTargetMachine>();
151
}
152
153
void addIRPasses() override;
154
void addCodeGenPrepare() override;
155
bool addInstSelector() override;
156
void addPreEmitPass() override;
157
void addPreEmitPass2() override;
158
void addMachineSSAOptimization() override;
159
void addPreRegAlloc() override;
160
bool addRegAssignAndRewriteFast() override;
161
bool addRegAssignAndRewriteOptimized() override;
162
};
163
} // end namespace
164
165
TargetPassConfig *
166
LoongArchTargetMachine::createPassConfig(PassManagerBase &PM) {
167
return new LoongArchPassConfig(*this, PM);
168
}
169
170
void LoongArchPassConfig::addIRPasses() {
171
// Run LoopDataPrefetch
172
//
173
// Run this before LSR to remove the multiplies involved in computing the
174
// pointer values N iterations ahead.
175
if (TM->getOptLevel() != CodeGenOptLevel::None && EnableLoopDataPrefetch)
176
addPass(createLoopDataPrefetchPass());
177
addPass(createAtomicExpandLegacyPass());
178
179
TargetPassConfig::addIRPasses();
180
}
181
182
void LoongArchPassConfig::addCodeGenPrepare() {
183
if (getOptLevel() != CodeGenOptLevel::None)
184
addPass(createTypePromotionLegacyPass());
185
TargetPassConfig::addCodeGenPrepare();
186
}
187
188
bool LoongArchPassConfig::addInstSelector() {
189
addPass(createLoongArchISelDag(getLoongArchTargetMachine()));
190
191
return false;
192
}
193
194
TargetTransformInfo
195
LoongArchTargetMachine::getTargetTransformInfo(const Function &F) const {
196
return TargetTransformInfo(LoongArchTTIImpl(this, F));
197
}
198
199
void LoongArchPassConfig::addPreEmitPass() { addPass(&BranchRelaxationPassID); }
200
201
void LoongArchPassConfig::addPreEmitPass2() {
202
addPass(createLoongArchExpandPseudoPass());
203
// Schedule the expansion of AtomicPseudos at the last possible moment,
204
// avoiding the possibility for other passes to break the requirements for
205
// forward progress in the LL/SC block.
206
addPass(createLoongArchExpandAtomicPseudoPass());
207
}
208
209
void LoongArchPassConfig::addMachineSSAOptimization() {
210
TargetPassConfig::addMachineSSAOptimization();
211
212
if (TM->getTargetTriple().isLoongArch64()) {
213
addPass(createLoongArchOptWInstrsPass());
214
}
215
}
216
217
void LoongArchPassConfig::addPreRegAlloc() {
218
addPass(createLoongArchPreRAExpandPseudoPass());
219
}
220
221
bool LoongArchPassConfig::addRegAssignAndRewriteFast() {
222
if (TM->getOptLevel() != CodeGenOptLevel::None &&
223
EnableLoongArchDeadRegisterElimination)
224
addPass(createLoongArchDeadRegisterDefinitionsPass());
225
return TargetPassConfig::addRegAssignAndRewriteFast();
226
}
227
228
bool LoongArchPassConfig::addRegAssignAndRewriteOptimized() {
229
if (TM->getOptLevel() != CodeGenOptLevel::None &&
230
EnableLoongArchDeadRegisterElimination)
231
addPass(createLoongArchDeadRegisterDefinitionsPass());
232
return TargetPassConfig::addRegAssignAndRewriteOptimized();
233
}
234
235