1 | //===-- PowerPCSubtarget.cpp - PPC Subtarget Information ------------------===// |
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 | // This file implements the PPC specific subclass of TargetSubtargetInfo. |
10 | // |
11 | //===----------------------------------------------------------------------===// |
12 | |
13 | #include "PPCSubtarget.h" |
14 | #include "GISel/PPCCallLowering.h" |
15 | #include "GISel/PPCLegalizerInfo.h" |
16 | #include "GISel/PPCRegisterBankInfo.h" |
17 | #include "PPC.h" |
18 | #include "PPCRegisterInfo.h" |
19 | #include "PPCTargetMachine.h" |
20 | #include "llvm/CodeGen/GlobalISel/InstructionSelect.h" |
21 | #include "llvm/CodeGen/GlobalISel/InstructionSelector.h" |
22 | #include "llvm/CodeGen/MachineFunction.h" |
23 | #include "llvm/CodeGen/MachineScheduler.h" |
24 | #include "llvm/IR/Attributes.h" |
25 | #include "llvm/IR/Function.h" |
26 | #include "llvm/IR/GlobalValue.h" |
27 | #include "llvm/MC/TargetRegistry.h" |
28 | #include "llvm/Support/CommandLine.h" |
29 | #include "llvm/Target/TargetMachine.h" |
30 | #include <cstdlib> |
31 | |
32 | using namespace llvm; |
33 | |
34 | #define DEBUG_TYPE "ppc-subtarget" |
35 | |
36 | #define GET_SUBTARGETINFO_TARGET_DESC |
37 | #define GET_SUBTARGETINFO_CTOR |
38 | #include "PPCGenSubtargetInfo.inc" |
39 | |
40 | static cl::opt<bool> |
41 | UseSubRegLiveness("ppc-track-subreg-liveness" , |
42 | cl::desc("Enable subregister liveness tracking for PPC" ), |
43 | cl::init(true), cl::Hidden); |
44 | |
45 | static cl::opt<bool> |
46 | EnableMachinePipeliner("ppc-enable-pipeliner" , |
47 | cl::desc("Enable Machine Pipeliner for PPC" ), |
48 | cl::init(Val: false), cl::Hidden); |
49 | |
50 | PPCSubtarget &PPCSubtarget::initializeSubtargetDependencies(StringRef CPU, |
51 | StringRef TuneCPU, |
52 | StringRef FS) { |
53 | initializeEnvironment(); |
54 | initSubtargetFeatures(CPU, TuneCPU, FS); |
55 | return *this; |
56 | } |
57 | |
58 | PPCSubtarget::PPCSubtarget(const Triple &TT, const std::string &CPU, |
59 | const std::string &TuneCPU, const std::string &FS, |
60 | const PPCTargetMachine &TM) |
61 | : PPCGenSubtargetInfo(TT, CPU, TuneCPU, FS), TargetTriple(TT), |
62 | IsPPC64(TargetTriple.getArch() == Triple::ppc64 || |
63 | TargetTriple.getArch() == Triple::ppc64le), |
64 | TM(TM), FrameLowering(initializeSubtargetDependencies(CPU, TuneCPU, FS)), |
65 | InstrInfo(*this), TLInfo(TM, *this) { |
66 | CallLoweringInfo.reset(new PPCCallLowering(*getTargetLowering())); |
67 | Legalizer.reset(new PPCLegalizerInfo(*this)); |
68 | auto *RBI = new PPCRegisterBankInfo(*getRegisterInfo()); |
69 | RegBankInfo.reset(RBI); |
70 | |
71 | InstSelector.reset(createPPCInstructionSelector( |
72 | *static_cast<const PPCTargetMachine *>(&TM), *this, *RBI)); |
73 | } |
74 | |
75 | void PPCSubtarget::initializeEnvironment() { |
76 | StackAlignment = Align(16); |
77 | CPUDirective = PPC::DIR_NONE; |
78 | HasPOPCNTD = POPCNTD_Unavailable; |
79 | } |
80 | |
81 | void PPCSubtarget::initSubtargetFeatures(StringRef CPU, StringRef TuneCPU, |
82 | StringRef FS) { |
83 | // Determine default and user specified characteristics |
84 | std::string CPUName = std::string(CPU); |
85 | if (CPUName.empty() || CPU == "generic" ) { |
86 | // If cross-compiling with -march=ppc64le without -mcpu |
87 | if (TargetTriple.getArch() == Triple::ppc64le) |
88 | CPUName = "ppc64le" ; |
89 | else if (TargetTriple.getSubArch() == Triple::PPCSubArch_spe) |
90 | CPUName = "e500" ; |
91 | else |
92 | CPUName = "generic" ; |
93 | } |
94 | |
95 | // Determine the CPU to schedule for. |
96 | if (TuneCPU.empty()) TuneCPU = CPUName; |
97 | |
98 | // Initialize scheduling itinerary for the specified CPU. |
99 | InstrItins = getInstrItineraryForCPU(CPUName); |
100 | |
101 | // Parse features string. |
102 | ParseSubtargetFeatures(CPU: CPUName, TuneCPU, FS); |
103 | |
104 | // If the user requested use of 64-bit regs, but the cpu selected doesn't |
105 | // support it, ignore. |
106 | if (IsPPC64 && has64BitSupport()) |
107 | Use64BitRegs = true; |
108 | |
109 | if (TargetTriple.isPPC32SecurePlt()) |
110 | IsSecurePlt = true; |
111 | |
112 | if (HasSPE && IsPPC64) |
113 | report_fatal_error( reason: "SPE is only supported for 32-bit targets.\n" , gen_crash_diag: false); |
114 | if (HasSPE && (HasAltivec || HasVSX || HasFPU)) |
115 | report_fatal_error( |
116 | reason: "SPE and traditional floating point cannot both be enabled.\n" , gen_crash_diag: false); |
117 | |
118 | // If not SPE, set standard FPU |
119 | if (!HasSPE) |
120 | HasFPU = true; |
121 | |
122 | StackAlignment = getPlatformStackAlignment(); |
123 | |
124 | // Determine endianness. |
125 | IsLittleEndian = TM.isLittleEndian(); |
126 | |
127 | if (HasAIXSmallLocalExecTLS || HasAIXSmallLocalDynamicTLS) { |
128 | if (!TargetTriple.isOSAIX() || !IsPPC64) |
129 | report_fatal_error(reason: "The aix-small-local-[exec|dynamic]-tls attribute is " |
130 | "only supported on AIX in " |
131 | "64-bit mode.\n" , |
132 | gen_crash_diag: false); |
133 | // The aix-small-local-[exec|dynamic]-tls attribute should only be used with |
134 | // -data-sections, as having data sections turned off with this option |
135 | // is not ideal for performance. Moreover, the |
136 | // small-local-[exec|dynamic]-tls region is a limited resource, and should |
137 | // not be used for variables that may be replaced. |
138 | if (!TM.getDataSections()) |
139 | report_fatal_error(reason: "The aix-small-local-[exec|dynamic]-tls attribute can " |
140 | "only be specified with " |
141 | "-data-sections.\n" , |
142 | gen_crash_diag: false); |
143 | } |
144 | } |
145 | |
146 | bool PPCSubtarget::enableMachineScheduler() const { return true; } |
147 | |
148 | bool PPCSubtarget::enableMachinePipeliner() const { |
149 | return getSchedModel().hasInstrSchedModel() && EnableMachinePipeliner; |
150 | } |
151 | |
152 | bool PPCSubtarget::useDFAforSMS() const { return false; } |
153 | |
154 | // This overrides the PostRAScheduler bit in the SchedModel for each CPU. |
155 | bool PPCSubtarget::enablePostRAScheduler() const { return true; } |
156 | |
157 | PPCGenSubtargetInfo::AntiDepBreakMode PPCSubtarget::getAntiDepBreakMode() const { |
158 | return TargetSubtargetInfo::ANTIDEP_ALL; |
159 | } |
160 | |
161 | void PPCSubtarget::getCriticalPathRCs(RegClassVector &CriticalPathRCs) const { |
162 | CriticalPathRCs.clear(); |
163 | CriticalPathRCs.push_back(isPPC64() ? |
164 | &PPC::G8RCRegClass : &PPC::GPRCRegClass); |
165 | } |
166 | |
167 | void PPCSubtarget::overrideSchedPolicy(MachineSchedPolicy &Policy, |
168 | unsigned NumRegionInstrs) const { |
169 | // The GenericScheduler that we use defaults to scheduling bottom up only. |
170 | // We want to schedule from both the top and the bottom and so we set |
171 | // OnlyBottomUp to false. |
172 | // We want to do bi-directional scheduling since it provides a more balanced |
173 | // schedule leading to better performance. |
174 | Policy.OnlyBottomUp = false; |
175 | // Spilling is generally expensive on all PPC cores, so always enable |
176 | // register-pressure tracking. |
177 | Policy.ShouldTrackPressure = true; |
178 | } |
179 | |
180 | bool PPCSubtarget::useAA() const { |
181 | return true; |
182 | } |
183 | |
184 | bool PPCSubtarget::enableSubRegLiveness() const { |
185 | return UseSubRegLiveness; |
186 | } |
187 | |
188 | bool PPCSubtarget::isGVIndirectSymbol(const GlobalValue *GV) const { |
189 | if (isAIXABI()) { |
190 | if (const GlobalVariable *GVar = dyn_cast<GlobalVariable>(Val: GV)) |
191 | // On AIX the only symbols that aren't indirect are toc-data. |
192 | return !GVar->hasAttribute(Kind: "toc-data" ); |
193 | |
194 | return true; |
195 | } |
196 | |
197 | // Large code model always uses the TOC even for local symbols. |
198 | if (TM.getCodeModel() == CodeModel::Large) |
199 | return true; |
200 | |
201 | if (TM.shouldAssumeDSOLocal(GV)) |
202 | return false; |
203 | return true; |
204 | } |
205 | |
206 | CodeModel::Model PPCSubtarget::getCodeModel(const TargetMachine &TM, |
207 | const GlobalValue *GV) const { |
208 | // If there isn't an attribute to override the module code model |
209 | // this will be the effective code model. |
210 | CodeModel::Model ModuleModel = TM.getCodeModel(); |
211 | |
212 | // Initially support per global code model for AIX only. |
213 | if (!isAIXABI()) |
214 | return ModuleModel; |
215 | |
216 | // Only GlobalVariables carry an attribute which can override the module code |
217 | // model. |
218 | assert(GV && "Unexpected NULL GlobalValue" ); |
219 | const GlobalVariable *GlobalVar = |
220 | [](const GlobalValue *GV) -> const GlobalVariable * { |
221 | const GlobalVariable *Var = dyn_cast<GlobalVariable>(Val: GV); |
222 | if (Var) |
223 | return Var; |
224 | |
225 | const GlobalAlias *Alias = dyn_cast<GlobalAlias>(Val: GV); |
226 | if (Alias) |
227 | return dyn_cast<GlobalVariable>(Val: Alias->getAliaseeObject()); |
228 | |
229 | return nullptr; |
230 | }(GV); |
231 | |
232 | if (!GlobalVar) |
233 | return ModuleModel; |
234 | |
235 | std::optional<CodeModel::Model> MaybeCodeModel = GlobalVar->getCodeModel(); |
236 | if (MaybeCodeModel) { |
237 | CodeModel::Model CM = *MaybeCodeModel; |
238 | assert((CM == CodeModel::Small || CM == CodeModel::Large) && |
239 | "invalid code model for AIX" ); |
240 | return CM; |
241 | } |
242 | |
243 | return ModuleModel; |
244 | } |
245 | |
246 | bool PPCSubtarget::isELFv2ABI() const { return TM.isELFv2ABI(); } |
247 | bool PPCSubtarget::isPPC64() const { return TM.isPPC64(); } |
248 | |
249 | bool PPCSubtarget::isUsingPCRelativeCalls() const { |
250 | return isPPC64() && hasPCRelativeMemops() && isELFv2ABI() && |
251 | CodeModel::Medium == getTargetMachine().getCodeModel(); |
252 | } |
253 | |
254 | // GlobalISEL |
255 | const CallLowering *PPCSubtarget::getCallLowering() const { |
256 | return CallLoweringInfo.get(); |
257 | } |
258 | |
259 | const RegisterBankInfo *PPCSubtarget::getRegBankInfo() const { |
260 | return RegBankInfo.get(); |
261 | } |
262 | |
263 | const LegalizerInfo *PPCSubtarget::getLegalizerInfo() const { |
264 | return Legalizer.get(); |
265 | } |
266 | |
267 | InstructionSelector *PPCSubtarget::getInstructionSelector() const { |
268 | return InstSelector.get(); |
269 | } |
270 | |