[llvm-shlib] Fix the version naming style of libLLVM for Windows (#85710)
[llvm-project.git] / llvm / lib / Target / LoongArch / LoongArchTargetMachine.cpp
blob62ae1dea00d6f84bd9b7956a11bf01da4a373e9f
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.
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"
26 #include <optional>
28 using namespace llvm;
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);
41 static cl::opt<bool>
42 EnableLoopDataPrefetch("loongarch-enable-loop-data-prefetch", cl::Hidden,
43 cl::desc("Enable the loop data prefetch pass"),
44 cl::init(false));
46 static std::string computeDataLayout(const Triple &TT) {
47 if (TT.isArch64Bit())
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) {
61 if (!CM)
62 return CodeModel::Small;
64 switch (*CM) {
65 case CodeModel::Small:
66 return *CM;
67 case CodeModel::Medium:
68 case CodeModel::Large:
69 if (!TT.isArch64Bit())
70 report_fatal_error("Medium/Large code model requires LA64");
71 return *CM;
72 default:
73 report_fatal_error(
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>()) {
86 initAsmInfo();
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");
97 std::string CPU =
98 CPUAttr.isValid() ? CPUAttr.getValueAsString().str() : TargetCPU;
99 std::string TuneCPU =
100 TuneAttr.isValid() ? TuneAttr.getValueAsString().str() : CPU;
101 std::string FS =
102 FSAttr.isValid() ? FSAttr.getValueAsString().str() : TargetFS;
104 std::string Key = CPU + TuneCPU + FS;
105 auto &I = SubtargetMap[Key];
106 if (!I) {
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,
122 ABIName, *this);
124 return I.get();
127 MachineFunctionInfo *LoongArchTargetMachine::createMachineFunctionInfo(
128 BumpPtrAllocator &Allocator, const Function &F,
129 const TargetSubtargetInfo *STI) const {
130 return LoongArchMachineFunctionInfo::create<LoongArchMachineFunctionInfo>(
131 Allocator, F, STI);
134 namespace {
135 class LoongArchPassConfig : public TargetPassConfig {
136 public:
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;
150 } // end namespace
152 TargetPassConfig *
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()));
172 return false;
175 TargetTransformInfo
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());