/src/llvm-project/llvm/lib/Target/PowerPC/PPCSubtarget.cpp
Line | Count | Source (jump to first uncovered line) |
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(false), cl::Hidden); |
49 | | |
50 | | PPCSubtarget &PPCSubtarget::initializeSubtargetDependencies(StringRef CPU, |
51 | | StringRef TuneCPU, |
52 | 25 | StringRef FS) { |
53 | 25 | initializeEnvironment(); |
54 | 25 | initSubtargetFeatures(CPU, TuneCPU, FS); |
55 | 25 | return *this; |
56 | 25 | } |
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 | 25 | InstrInfo(*this), TLInfo(TM, *this) { |
66 | 25 | CallLoweringInfo.reset(new PPCCallLowering(*getTargetLowering())); |
67 | 25 | Legalizer.reset(new PPCLegalizerInfo(*this)); |
68 | 25 | auto *RBI = new PPCRegisterBankInfo(*getRegisterInfo()); |
69 | 25 | RegBankInfo.reset(RBI); |
70 | | |
71 | 25 | InstSelector.reset(createPPCInstructionSelector( |
72 | 25 | *static_cast<const PPCTargetMachine *>(&TM), *this, *RBI)); |
73 | 25 | } |
74 | | |
75 | 25 | void PPCSubtarget::initializeEnvironment() { |
76 | 25 | StackAlignment = Align(16); |
77 | 25 | CPUDirective = PPC::DIR_NONE; |
78 | 25 | HasPOPCNTD = POPCNTD_Unavailable; |
79 | 25 | } |
80 | | |
81 | | void PPCSubtarget::initSubtargetFeatures(StringRef CPU, StringRef TuneCPU, |
82 | 25 | StringRef FS) { |
83 | | // Determine default and user specified characteristics |
84 | 25 | std::string CPUName = std::string(CPU); |
85 | 25 | if (CPUName.empty() || CPU == "generic") { |
86 | | // If cross-compiling with -march=ppc64le without -mcpu |
87 | 7 | if (TargetTriple.getArch() == Triple::ppc64le) |
88 | 0 | CPUName = "ppc64le"; |
89 | 7 | else if (TargetTriple.getSubArch() == Triple::PPCSubArch_spe) |
90 | 0 | CPUName = "e500"; |
91 | 7 | else |
92 | 7 | CPUName = "generic"; |
93 | 7 | } |
94 | | |
95 | | // Determine the CPU to schedule for. |
96 | 25 | if (TuneCPU.empty()) TuneCPU = CPUName; |
97 | | |
98 | | // Initialize scheduling itinerary for the specified CPU. |
99 | 25 | InstrItins = getInstrItineraryForCPU(CPUName); |
100 | | |
101 | | // Parse features string. |
102 | 25 | ParseSubtargetFeatures(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 | 25 | if (IsPPC64 && has64BitSupport()) |
107 | 25 | Use64BitRegs = true; |
108 | | |
109 | 25 | if (TargetTriple.isPPC32SecurePlt()) |
110 | 0 | IsSecurePlt = true; |
111 | | |
112 | 25 | if (HasSPE && IsPPC64) |
113 | 0 | report_fatal_error( "SPE is only supported for 32-bit targets.\n", false); |
114 | 25 | if (HasSPE && (HasAltivec || HasVSX || HasFPU)) |
115 | 0 | report_fatal_error( |
116 | 0 | "SPE and traditional floating point cannot both be enabled.\n", false); |
117 | | |
118 | | // If not SPE, set standard FPU |
119 | 25 | if (!HasSPE) |
120 | 25 | HasFPU = true; |
121 | | |
122 | 25 | StackAlignment = getPlatformStackAlignment(); |
123 | | |
124 | | // Determine endianness. |
125 | 25 | IsLittleEndian = TM.isLittleEndian(); |
126 | | |
127 | 25 | if (HasAIXSmallLocalExecTLS && (!TargetTriple.isOSAIX() || !IsPPC64)) |
128 | 0 | report_fatal_error( |
129 | 0 | "The aix-small-local-exec-tls attribute is only supported on AIX in " |
130 | 0 | "64-bit mode.\n", false); |
131 | 25 | } |
132 | | |
133 | 2.39M | bool PPCSubtarget::enableMachineScheduler() const { return true; } |
134 | | |
135 | 30.3k | bool PPCSubtarget::enableMachinePipeliner() const { |
136 | 30.3k | return getSchedModel().hasInstrSchedModel() && EnableMachinePipeliner; |
137 | 30.3k | } |
138 | | |
139 | 0 | bool PPCSubtarget::useDFAforSMS() const { return false; } |
140 | | |
141 | | // This overrides the PostRAScheduler bit in the SchedModel for each CPU. |
142 | 30.4k | bool PPCSubtarget::enablePostRAScheduler() const { return true; } |
143 | | |
144 | 0 | PPCGenSubtargetInfo::AntiDepBreakMode PPCSubtarget::getAntiDepBreakMode() const { |
145 | 0 | return TargetSubtargetInfo::ANTIDEP_ALL; |
146 | 0 | } |
147 | | |
148 | 0 | void PPCSubtarget::getCriticalPathRCs(RegClassVector &CriticalPathRCs) const { |
149 | 0 | CriticalPathRCs.clear(); |
150 | 0 | CriticalPathRCs.push_back(isPPC64() ? |
151 | 0 | &PPC::G8RCRegClass : &PPC::GPRCRegClass); |
152 | 0 | } |
153 | | |
154 | | void PPCSubtarget::overrideSchedPolicy(MachineSchedPolicy &Policy, |
155 | 66.3k | unsigned NumRegionInstrs) const { |
156 | | // The GenericScheduler that we use defaults to scheduling bottom up only. |
157 | | // We want to schedule from both the top and the bottom and so we set |
158 | | // OnlyBottomUp to false. |
159 | | // We want to do bi-directional scheduling since it provides a more balanced |
160 | | // schedule leading to better performance. |
161 | 66.3k | Policy.OnlyBottomUp = false; |
162 | | // Spilling is generally expensive on all PPC cores, so always enable |
163 | | // register-pressure tracking. |
164 | 66.3k | Policy.ShouldTrackPressure = true; |
165 | 66.3k | } |
166 | | |
167 | 2.22M | bool PPCSubtarget::useAA() const { |
168 | 2.22M | return true; |
169 | 2.22M | } |
170 | | |
171 | 30.4k | bool PPCSubtarget::enableSubRegLiveness() const { |
172 | 30.4k | return UseSubRegLiveness; |
173 | 30.4k | } |
174 | | |
175 | 46.8k | bool PPCSubtarget::isGVIndirectSymbol(const GlobalValue *GV) const { |
176 | | // Large code model always uses the TOC even for local symbols. |
177 | 46.8k | if (TM.getCodeModel() == CodeModel::Large) |
178 | 0 | return true; |
179 | 46.8k | if (TM.shouldAssumeDSOLocal(*GV->getParent(), GV)) |
180 | 636 | return false; |
181 | 46.1k | return true; |
182 | 46.8k | } |
183 | | |
184 | 642k | bool PPCSubtarget::isELFv2ABI() const { return TM.isELFv2ABI(); } |
185 | 8.13M | bool PPCSubtarget::isPPC64() const { return TM.isPPC64(); } |
186 | | |
187 | 989k | bool PPCSubtarget::isUsingPCRelativeCalls() const { |
188 | 989k | return isPPC64() && hasPCRelativeMemops() && isELFv2ABI() && |
189 | 989k | CodeModel::Medium == getTargetMachine().getCodeModel(); |
190 | 989k | } |
191 | | |
192 | | // GlobalISEL |
193 | 0 | const CallLowering *PPCSubtarget::getCallLowering() const { |
194 | 0 | return CallLoweringInfo.get(); |
195 | 0 | } |
196 | | |
197 | 1.23k | const RegisterBankInfo *PPCSubtarget::getRegBankInfo() const { |
198 | 1.23k | return RegBankInfo.get(); |
199 | 1.23k | } |
200 | | |
201 | 0 | const LegalizerInfo *PPCSubtarget::getLegalizerInfo() const { |
202 | 0 | return Legalizer.get(); |
203 | 0 | } |
204 | | |
205 | 0 | InstructionSelector *PPCSubtarget::getInstructionSelector() const { |
206 | 0 | return InstSelector.get(); |
207 | 0 | } |