1 //===-- LoongArchTargetMachine.cpp - Define TargetMachine for LoongArch ---===//
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
7 //===----------------------------------------------------------------------===//
9 // Implements the info about LoongArch target spec.
11 //===----------------------------------------------------------------------===//
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"
30 #define DEBUG_TYPE "loongarch"
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 initializeLoongArchPreRAExpandPseudoPass(*PR
);
38 initializeLoongArchDAGToDAGISelPass(*PR
);
42 EnableLoopDataPrefetch("loongarch-enable-loop-data-prefetch", cl::Hidden
,
43 cl::desc("Enable the loop data prefetch pass"),
46 static std::string
computeDataLayout(const Triple
&TT
) {
48 return "e-m:e-p:64:64-i64:64-i128:128-n64-S128";
49 assert(TT
.isArch32Bit() && "only LA32 and LA64 are currently supported");
50 return "e-m:e-p:32:32-i64:64-n32-S128";
53 static Reloc::Model
getEffectiveRelocModel(const Triple
&TT
,
54 std::optional
<Reloc::Model
> RM
) {
55 return RM
.value_or(Reloc::Static
);
58 static CodeModel::Model
59 getEffectiveLoongArchCodeModel(const Triple
&TT
,
60 std::optional
<CodeModel::Model
> CM
) {
62 return CodeModel::Small
;
65 case CodeModel::Small
:
67 case CodeModel::Medium
:
68 case CodeModel::Large
:
69 if (!TT
.isArch64Bit())
70 report_fatal_error("Medium/Large code model requires LA64");
74 "Only small, medium and large code models are allowed on LoongArch");
78 LoongArchTargetMachine::LoongArchTargetMachine(
79 const Target
&T
, const Triple
&TT
, StringRef CPU
, StringRef FS
,
80 const TargetOptions
&Options
, std::optional
<Reloc::Model
> RM
,
81 std::optional
<CodeModel::Model
> CM
, CodeGenOptLevel OL
, bool JIT
)
82 : LLVMTargetMachine(T
, computeDataLayout(TT
), TT
, CPU
, FS
, Options
,
83 getEffectiveRelocModel(TT
, RM
),
84 getEffectiveLoongArchCodeModel(TT
, CM
), OL
),
85 TLOF(std::make_unique
<TargetLoweringObjectFileELF
>()) {
89 LoongArchTargetMachine::~LoongArchTargetMachine() = default;
91 const LoongArchSubtarget
*
92 LoongArchTargetMachine::getSubtargetImpl(const Function
&F
) const {
93 Attribute CPUAttr
= F
.getFnAttribute("target-cpu");
94 Attribute TuneAttr
= F
.getFnAttribute("tune-cpu");
95 Attribute FSAttr
= F
.getFnAttribute("target-features");
98 CPUAttr
.isValid() ? CPUAttr
.getValueAsString().str() : TargetCPU
;
100 TuneAttr
.isValid() ? TuneAttr
.getValueAsString().str() : CPU
;
102 FSAttr
.isValid() ? FSAttr
.getValueAsString().str() : TargetFS
;
104 std::string Key
= CPU
+ TuneCPU
+ FS
;
105 auto &I
= SubtargetMap
[Key
];
107 // This needs to be done before we create a new subtarget since any
108 // creation will depend on the TM and the code generation flags on the
109 // function that reside in TargetOptions.
110 resetTargetOptions(F
);
111 auto ABIName
= Options
.MCOptions
.getABIName();
112 if (const MDString
*ModuleTargetABI
= dyn_cast_or_null
<MDString
>(
113 F
.getParent()->getModuleFlag("target-abi"))) {
114 auto TargetABI
= LoongArchABI::getTargetABI(ABIName
);
115 if (TargetABI
!= LoongArchABI::ABI_Unknown
&&
116 ModuleTargetABI
->getString() != ABIName
) {
117 report_fatal_error("-target-abi option != target-abi module flag");
119 ABIName
= ModuleTargetABI
->getString();
121 I
= std::make_unique
<LoongArchSubtarget
>(TargetTriple
, CPU
, TuneCPU
, FS
,
127 MachineFunctionInfo
*LoongArchTargetMachine::createMachineFunctionInfo(
128 BumpPtrAllocator
&Allocator
, const Function
&F
,
129 const TargetSubtargetInfo
*STI
) const {
130 return LoongArchMachineFunctionInfo::create
<LoongArchMachineFunctionInfo
>(
135 class LoongArchPassConfig
: public TargetPassConfig
{
137 LoongArchPassConfig(LoongArchTargetMachine
&TM
, PassManagerBase
&PM
)
138 : TargetPassConfig(TM
, PM
) {}
140 LoongArchTargetMachine
&getLoongArchTargetMachine() const {
141 return getTM
<LoongArchTargetMachine
>();
144 void addIRPasses() override
;
145 bool addInstSelector() override
;
146 void addPreEmitPass() override
;
147 void addPreEmitPass2() override
;
148 void addPreRegAlloc() override
;
153 LoongArchTargetMachine::createPassConfig(PassManagerBase
&PM
) {
154 return new LoongArchPassConfig(*this, PM
);
157 void LoongArchPassConfig::addIRPasses() {
158 // Run LoopDataPrefetch
160 // Run this before LSR to remove the multiplies involved in computing the
161 // pointer values N iterations ahead.
162 if (TM
->getOptLevel() != CodeGenOptLevel::None
&& EnableLoopDataPrefetch
)
163 addPass(createLoopDataPrefetchPass());
164 addPass(createAtomicExpandPass());
166 TargetPassConfig::addIRPasses();
169 bool LoongArchPassConfig::addInstSelector() {
170 addPass(createLoongArchISelDag(getLoongArchTargetMachine()));
176 LoongArchTargetMachine::getTargetTransformInfo(const Function
&F
) const {
177 return TargetTransformInfo(LoongArchTTIImpl(this, F
));
180 void LoongArchPassConfig::addPreEmitPass() { addPass(&BranchRelaxationPassID
); }
182 void LoongArchPassConfig::addPreEmitPass2() {
183 addPass(createLoongArchExpandPseudoPass());
184 // Schedule the expansion of AtomicPseudos at the last possible moment,
185 // avoiding the possibility for other passes to break the requirements for
186 // forward progress in the LL/SC block.
187 addPass(createLoongArchExpandAtomicPseudoPass());
190 void LoongArchPassConfig::addPreRegAlloc() {
191 addPass(createLoongArchPreRAExpandPseudoPass());