xref: /aosp_15_r20/external/llvm/lib/Target/PowerPC/PPCTargetMachine.cpp (revision 9880d6810fe72a1726cb53787c6711e909410d58)
1*9880d681SAndroid Build Coastguard Worker //===-- PPCTargetMachine.cpp - Define TargetMachine for PowerPC -----------===//
2*9880d681SAndroid Build Coastguard Worker //
3*9880d681SAndroid Build Coastguard Worker //                     The LLVM Compiler Infrastructure
4*9880d681SAndroid Build Coastguard Worker //
5*9880d681SAndroid Build Coastguard Worker // This file is distributed under the University of Illinois Open Source
6*9880d681SAndroid Build Coastguard Worker // License. See LICENSE.TXT for details.
7*9880d681SAndroid Build Coastguard Worker //
8*9880d681SAndroid Build Coastguard Worker //===----------------------------------------------------------------------===//
9*9880d681SAndroid Build Coastguard Worker //
10*9880d681SAndroid Build Coastguard Worker // Top-level implementation for the PowerPC target.
11*9880d681SAndroid Build Coastguard Worker //
12*9880d681SAndroid Build Coastguard Worker //===----------------------------------------------------------------------===//
13*9880d681SAndroid Build Coastguard Worker 
14*9880d681SAndroid Build Coastguard Worker #include "PPCTargetMachine.h"
15*9880d681SAndroid Build Coastguard Worker #include "PPC.h"
16*9880d681SAndroid Build Coastguard Worker #include "PPCTargetObjectFile.h"
17*9880d681SAndroid Build Coastguard Worker #include "PPCTargetTransformInfo.h"
18*9880d681SAndroid Build Coastguard Worker #include "llvm/CodeGen/LiveVariables.h"
19*9880d681SAndroid Build Coastguard Worker #include "llvm/CodeGen/Passes.h"
20*9880d681SAndroid Build Coastguard Worker #include "llvm/CodeGen/TargetPassConfig.h"
21*9880d681SAndroid Build Coastguard Worker #include "llvm/IR/Function.h"
22*9880d681SAndroid Build Coastguard Worker #include "llvm/IR/LegacyPassManager.h"
23*9880d681SAndroid Build Coastguard Worker #include "llvm/MC/MCStreamer.h"
24*9880d681SAndroid Build Coastguard Worker #include "llvm/Support/CommandLine.h"
25*9880d681SAndroid Build Coastguard Worker #include "llvm/Support/FormattedStream.h"
26*9880d681SAndroid Build Coastguard Worker #include "llvm/Support/TargetRegistry.h"
27*9880d681SAndroid Build Coastguard Worker #include "llvm/Target/TargetOptions.h"
28*9880d681SAndroid Build Coastguard Worker #include "llvm/Transforms/Scalar.h"
29*9880d681SAndroid Build Coastguard Worker using namespace llvm;
30*9880d681SAndroid Build Coastguard Worker 
31*9880d681SAndroid Build Coastguard Worker static cl::
32*9880d681SAndroid Build Coastguard Worker opt<bool> DisableCTRLoops("disable-ppc-ctrloops", cl::Hidden,
33*9880d681SAndroid Build Coastguard Worker                         cl::desc("Disable CTR loops for PPC"));
34*9880d681SAndroid Build Coastguard Worker 
35*9880d681SAndroid Build Coastguard Worker static cl::
36*9880d681SAndroid Build Coastguard Worker opt<bool> DisablePreIncPrep("disable-ppc-preinc-prep", cl::Hidden,
37*9880d681SAndroid Build Coastguard Worker                             cl::desc("Disable PPC loop preinc prep"));
38*9880d681SAndroid Build Coastguard Worker 
39*9880d681SAndroid Build Coastguard Worker static cl::opt<bool>
40*9880d681SAndroid Build Coastguard Worker VSXFMAMutateEarly("schedule-ppc-vsx-fma-mutation-early",
41*9880d681SAndroid Build Coastguard Worker   cl::Hidden, cl::desc("Schedule VSX FMA instruction mutation early"));
42*9880d681SAndroid Build Coastguard Worker 
43*9880d681SAndroid Build Coastguard Worker static cl::
44*9880d681SAndroid Build Coastguard Worker opt<bool> DisableVSXSwapRemoval("disable-ppc-vsx-swap-removal", cl::Hidden,
45*9880d681SAndroid Build Coastguard Worker                                 cl::desc("Disable VSX Swap Removal for PPC"));
46*9880d681SAndroid Build Coastguard Worker 
47*9880d681SAndroid Build Coastguard Worker static cl::
48*9880d681SAndroid Build Coastguard Worker opt<bool> DisableQPXLoadSplat("disable-ppc-qpx-load-splat", cl::Hidden,
49*9880d681SAndroid Build Coastguard Worker                               cl::desc("Disable QPX load splat simplification"));
50*9880d681SAndroid Build Coastguard Worker 
51*9880d681SAndroid Build Coastguard Worker static cl::
52*9880d681SAndroid Build Coastguard Worker opt<bool> DisableMIPeephole("disable-ppc-peephole", cl::Hidden,
53*9880d681SAndroid Build Coastguard Worker                             cl::desc("Disable machine peepholes for PPC"));
54*9880d681SAndroid Build Coastguard Worker 
55*9880d681SAndroid Build Coastguard Worker static cl::opt<bool>
56*9880d681SAndroid Build Coastguard Worker EnableGEPOpt("ppc-gep-opt", cl::Hidden,
57*9880d681SAndroid Build Coastguard Worker              cl::desc("Enable optimizations on complex GEPs"),
58*9880d681SAndroid Build Coastguard Worker              cl::init(true));
59*9880d681SAndroid Build Coastguard Worker 
60*9880d681SAndroid Build Coastguard Worker static cl::opt<bool>
61*9880d681SAndroid Build Coastguard Worker EnablePrefetch("enable-ppc-prefetching",
62*9880d681SAndroid Build Coastguard Worker                   cl::desc("disable software prefetching on PPC"),
63*9880d681SAndroid Build Coastguard Worker                   cl::init(false), cl::Hidden);
64*9880d681SAndroid Build Coastguard Worker 
65*9880d681SAndroid Build Coastguard Worker static cl::opt<bool>
66*9880d681SAndroid Build Coastguard Worker EnableExtraTOCRegDeps("enable-ppc-extra-toc-reg-deps",
67*9880d681SAndroid Build Coastguard Worker                       cl::desc("Add extra TOC register dependencies"),
68*9880d681SAndroid Build Coastguard Worker                       cl::init(true), cl::Hidden);
69*9880d681SAndroid Build Coastguard Worker 
70*9880d681SAndroid Build Coastguard Worker static cl::opt<bool>
71*9880d681SAndroid Build Coastguard Worker EnableMachineCombinerPass("ppc-machine-combiner",
72*9880d681SAndroid Build Coastguard Worker                           cl::desc("Enable the machine combiner pass"),
73*9880d681SAndroid Build Coastguard Worker                           cl::init(true), cl::Hidden);
74*9880d681SAndroid Build Coastguard Worker 
LLVMInitializePowerPCTarget()75*9880d681SAndroid Build Coastguard Worker extern "C" void LLVMInitializePowerPCTarget() {
76*9880d681SAndroid Build Coastguard Worker   // Register the targets
77*9880d681SAndroid Build Coastguard Worker   RegisterTargetMachine<PPC32TargetMachine> A(ThePPC32Target);
78*9880d681SAndroid Build Coastguard Worker   RegisterTargetMachine<PPC64TargetMachine> B(ThePPC64Target);
79*9880d681SAndroid Build Coastguard Worker   RegisterTargetMachine<PPC64TargetMachine> C(ThePPC64LETarget);
80*9880d681SAndroid Build Coastguard Worker 
81*9880d681SAndroid Build Coastguard Worker   PassRegistry &PR = *PassRegistry::getPassRegistry();
82*9880d681SAndroid Build Coastguard Worker   initializePPCBoolRetToIntPass(PR);
83*9880d681SAndroid Build Coastguard Worker }
84*9880d681SAndroid Build Coastguard Worker 
85*9880d681SAndroid Build Coastguard Worker /// Return the datalayout string of a subtarget.
getDataLayoutString(const Triple & T)86*9880d681SAndroid Build Coastguard Worker static std::string getDataLayoutString(const Triple &T) {
87*9880d681SAndroid Build Coastguard Worker   bool is64Bit = T.getArch() == Triple::ppc64 || T.getArch() == Triple::ppc64le;
88*9880d681SAndroid Build Coastguard Worker   std::string Ret;
89*9880d681SAndroid Build Coastguard Worker 
90*9880d681SAndroid Build Coastguard Worker   // Most PPC* platforms are big endian, PPC64LE is little endian.
91*9880d681SAndroid Build Coastguard Worker   if (T.getArch() == Triple::ppc64le)
92*9880d681SAndroid Build Coastguard Worker     Ret = "e";
93*9880d681SAndroid Build Coastguard Worker   else
94*9880d681SAndroid Build Coastguard Worker     Ret = "E";
95*9880d681SAndroid Build Coastguard Worker 
96*9880d681SAndroid Build Coastguard Worker   Ret += DataLayout::getManglingComponent(T);
97*9880d681SAndroid Build Coastguard Worker 
98*9880d681SAndroid Build Coastguard Worker   // PPC32 has 32 bit pointers. The PS3 (OS Lv2) is a PPC64 machine with 32 bit
99*9880d681SAndroid Build Coastguard Worker   // pointers.
100*9880d681SAndroid Build Coastguard Worker   if (!is64Bit || T.getOS() == Triple::Lv2)
101*9880d681SAndroid Build Coastguard Worker     Ret += "-p:32:32";
102*9880d681SAndroid Build Coastguard Worker 
103*9880d681SAndroid Build Coastguard Worker   // Note, the alignment values for f64 and i64 on ppc64 in Darwin
104*9880d681SAndroid Build Coastguard Worker   // documentation are wrong; these are correct (i.e. "what gcc does").
105*9880d681SAndroid Build Coastguard Worker   if (is64Bit || !T.isOSDarwin())
106*9880d681SAndroid Build Coastguard Worker     Ret += "-i64:64";
107*9880d681SAndroid Build Coastguard Worker   else
108*9880d681SAndroid Build Coastguard Worker     Ret += "-f64:32:64";
109*9880d681SAndroid Build Coastguard Worker 
110*9880d681SAndroid Build Coastguard Worker   // PPC64 has 32 and 64 bit registers, PPC32 has only 32 bit ones.
111*9880d681SAndroid Build Coastguard Worker   if (is64Bit)
112*9880d681SAndroid Build Coastguard Worker     Ret += "-n32:64";
113*9880d681SAndroid Build Coastguard Worker   else
114*9880d681SAndroid Build Coastguard Worker     Ret += "-n32";
115*9880d681SAndroid Build Coastguard Worker 
116*9880d681SAndroid Build Coastguard Worker   return Ret;
117*9880d681SAndroid Build Coastguard Worker }
118*9880d681SAndroid Build Coastguard Worker 
computeFSAdditions(StringRef FS,CodeGenOpt::Level OL,const Triple & TT)119*9880d681SAndroid Build Coastguard Worker static std::string computeFSAdditions(StringRef FS, CodeGenOpt::Level OL,
120*9880d681SAndroid Build Coastguard Worker                                       const Triple &TT) {
121*9880d681SAndroid Build Coastguard Worker   std::string FullFS = FS;
122*9880d681SAndroid Build Coastguard Worker 
123*9880d681SAndroid Build Coastguard Worker   // Make sure 64-bit features are available when CPUname is generic
124*9880d681SAndroid Build Coastguard Worker   if (TT.getArch() == Triple::ppc64 || TT.getArch() == Triple::ppc64le) {
125*9880d681SAndroid Build Coastguard Worker     if (!FullFS.empty())
126*9880d681SAndroid Build Coastguard Worker       FullFS = "+64bit," + FullFS;
127*9880d681SAndroid Build Coastguard Worker     else
128*9880d681SAndroid Build Coastguard Worker       FullFS = "+64bit";
129*9880d681SAndroid Build Coastguard Worker   }
130*9880d681SAndroid Build Coastguard Worker 
131*9880d681SAndroid Build Coastguard Worker   if (OL >= CodeGenOpt::Default) {
132*9880d681SAndroid Build Coastguard Worker     if (!FullFS.empty())
133*9880d681SAndroid Build Coastguard Worker       FullFS = "+crbits," + FullFS;
134*9880d681SAndroid Build Coastguard Worker     else
135*9880d681SAndroid Build Coastguard Worker       FullFS = "+crbits";
136*9880d681SAndroid Build Coastguard Worker   }
137*9880d681SAndroid Build Coastguard Worker 
138*9880d681SAndroid Build Coastguard Worker   if (OL != CodeGenOpt::None) {
139*9880d681SAndroid Build Coastguard Worker     if (!FullFS.empty())
140*9880d681SAndroid Build Coastguard Worker       FullFS = "+invariant-function-descriptors," + FullFS;
141*9880d681SAndroid Build Coastguard Worker     else
142*9880d681SAndroid Build Coastguard Worker       FullFS = "+invariant-function-descriptors";
143*9880d681SAndroid Build Coastguard Worker   }
144*9880d681SAndroid Build Coastguard Worker 
145*9880d681SAndroid Build Coastguard Worker   return FullFS;
146*9880d681SAndroid Build Coastguard Worker }
147*9880d681SAndroid Build Coastguard Worker 
createTLOF(const Triple & TT)148*9880d681SAndroid Build Coastguard Worker static std::unique_ptr<TargetLoweringObjectFile> createTLOF(const Triple &TT) {
149*9880d681SAndroid Build Coastguard Worker   // If it isn't a Mach-O file then it's going to be a linux ELF
150*9880d681SAndroid Build Coastguard Worker   // object file.
151*9880d681SAndroid Build Coastguard Worker   if (TT.isOSDarwin())
152*9880d681SAndroid Build Coastguard Worker     return make_unique<TargetLoweringObjectFileMachO>();
153*9880d681SAndroid Build Coastguard Worker 
154*9880d681SAndroid Build Coastguard Worker   return make_unique<PPC64LinuxTargetObjectFile>();
155*9880d681SAndroid Build Coastguard Worker }
156*9880d681SAndroid Build Coastguard Worker 
computeTargetABI(const Triple & TT,const TargetOptions & Options)157*9880d681SAndroid Build Coastguard Worker static PPCTargetMachine::PPCABI computeTargetABI(const Triple &TT,
158*9880d681SAndroid Build Coastguard Worker                                                  const TargetOptions &Options) {
159*9880d681SAndroid Build Coastguard Worker   if (Options.MCOptions.getABIName().startswith("elfv1"))
160*9880d681SAndroid Build Coastguard Worker     return PPCTargetMachine::PPC_ABI_ELFv1;
161*9880d681SAndroid Build Coastguard Worker   else if (Options.MCOptions.getABIName().startswith("elfv2"))
162*9880d681SAndroid Build Coastguard Worker     return PPCTargetMachine::PPC_ABI_ELFv2;
163*9880d681SAndroid Build Coastguard Worker 
164*9880d681SAndroid Build Coastguard Worker   assert(Options.MCOptions.getABIName().empty() &&
165*9880d681SAndroid Build Coastguard Worker          "Unknown target-abi option!");
166*9880d681SAndroid Build Coastguard Worker 
167*9880d681SAndroid Build Coastguard Worker   if (!TT.isMacOSX()) {
168*9880d681SAndroid Build Coastguard Worker     switch (TT.getArch()) {
169*9880d681SAndroid Build Coastguard Worker     case Triple::ppc64le:
170*9880d681SAndroid Build Coastguard Worker       return PPCTargetMachine::PPC_ABI_ELFv2;
171*9880d681SAndroid Build Coastguard Worker     case Triple::ppc64:
172*9880d681SAndroid Build Coastguard Worker       return PPCTargetMachine::PPC_ABI_ELFv1;
173*9880d681SAndroid Build Coastguard Worker     default:
174*9880d681SAndroid Build Coastguard Worker       // Fallthrough.
175*9880d681SAndroid Build Coastguard Worker       ;
176*9880d681SAndroid Build Coastguard Worker     }
177*9880d681SAndroid Build Coastguard Worker   }
178*9880d681SAndroid Build Coastguard Worker   return PPCTargetMachine::PPC_ABI_UNKNOWN;
179*9880d681SAndroid Build Coastguard Worker }
180*9880d681SAndroid Build Coastguard Worker 
getEffectiveRelocModel(const Triple & TT,Optional<Reloc::Model> RM)181*9880d681SAndroid Build Coastguard Worker static Reloc::Model getEffectiveRelocModel(const Triple &TT,
182*9880d681SAndroid Build Coastguard Worker                                            Optional<Reloc::Model> RM) {
183*9880d681SAndroid Build Coastguard Worker   if (!RM.hasValue()) {
184*9880d681SAndroid Build Coastguard Worker     if (TT.isOSDarwin())
185*9880d681SAndroid Build Coastguard Worker       return Reloc::DynamicNoPIC;
186*9880d681SAndroid Build Coastguard Worker     return Reloc::Static;
187*9880d681SAndroid Build Coastguard Worker   }
188*9880d681SAndroid Build Coastguard Worker   return *RM;
189*9880d681SAndroid Build Coastguard Worker }
190*9880d681SAndroid Build Coastguard Worker 
191*9880d681SAndroid Build Coastguard Worker // The FeatureString here is a little subtle. We are modifying the feature
192*9880d681SAndroid Build Coastguard Worker // string with what are (currently) non-function specific overrides as it goes
193*9880d681SAndroid Build Coastguard Worker // into the LLVMTargetMachine constructor and then using the stored value in the
194*9880d681SAndroid Build Coastguard Worker // Subtarget constructor below it.
PPCTargetMachine(const Target & T,const Triple & TT,StringRef CPU,StringRef FS,const TargetOptions & Options,Optional<Reloc::Model> RM,CodeModel::Model CM,CodeGenOpt::Level OL)195*9880d681SAndroid Build Coastguard Worker PPCTargetMachine::PPCTargetMachine(const Target &T, const Triple &TT,
196*9880d681SAndroid Build Coastguard Worker                                    StringRef CPU, StringRef FS,
197*9880d681SAndroid Build Coastguard Worker                                    const TargetOptions &Options,
198*9880d681SAndroid Build Coastguard Worker                                    Optional<Reloc::Model> RM,
199*9880d681SAndroid Build Coastguard Worker                                    CodeModel::Model CM, CodeGenOpt::Level OL)
200*9880d681SAndroid Build Coastguard Worker     : LLVMTargetMachine(T, getDataLayoutString(TT), TT, CPU,
201*9880d681SAndroid Build Coastguard Worker                         computeFSAdditions(FS, OL, TT), Options,
202*9880d681SAndroid Build Coastguard Worker                         getEffectiveRelocModel(TT, RM), CM, OL),
203*9880d681SAndroid Build Coastguard Worker       TLOF(createTLOF(getTargetTriple())),
204*9880d681SAndroid Build Coastguard Worker       TargetABI(computeTargetABI(TT, Options)),
205*9880d681SAndroid Build Coastguard Worker       Subtarget(TargetTriple, CPU, computeFSAdditions(FS, OL, TT), *this) {
206*9880d681SAndroid Build Coastguard Worker 
207*9880d681SAndroid Build Coastguard Worker   // For the estimates, convergence is quadratic, so we essentially double the
208*9880d681SAndroid Build Coastguard Worker   // number of digits correct after every iteration. For both FRE and FRSQRTE,
209*9880d681SAndroid Build Coastguard Worker   // the minimum architected relative accuracy is 2^-5. When hasRecipPrec(),
210*9880d681SAndroid Build Coastguard Worker   // this is 2^-14. IEEE float has 23 digits and double has 52 digits.
211*9880d681SAndroid Build Coastguard Worker   unsigned RefinementSteps = Subtarget.hasRecipPrec() ? 1 : 3,
212*9880d681SAndroid Build Coastguard Worker            RefinementSteps64 = RefinementSteps + 1;
213*9880d681SAndroid Build Coastguard Worker 
214*9880d681SAndroid Build Coastguard Worker   this->Options.Reciprocals.setDefaults("sqrtf", true, RefinementSteps);
215*9880d681SAndroid Build Coastguard Worker   this->Options.Reciprocals.setDefaults("vec-sqrtf", true, RefinementSteps);
216*9880d681SAndroid Build Coastguard Worker   this->Options.Reciprocals.setDefaults("divf", true, RefinementSteps);
217*9880d681SAndroid Build Coastguard Worker   this->Options.Reciprocals.setDefaults("vec-divf", true, RefinementSteps);
218*9880d681SAndroid Build Coastguard Worker 
219*9880d681SAndroid Build Coastguard Worker   this->Options.Reciprocals.setDefaults("sqrtd", true, RefinementSteps64);
220*9880d681SAndroid Build Coastguard Worker   this->Options.Reciprocals.setDefaults("vec-sqrtd", true, RefinementSteps64);
221*9880d681SAndroid Build Coastguard Worker   this->Options.Reciprocals.setDefaults("divd", true, RefinementSteps64);
222*9880d681SAndroid Build Coastguard Worker   this->Options.Reciprocals.setDefaults("vec-divd", true, RefinementSteps64);
223*9880d681SAndroid Build Coastguard Worker 
224*9880d681SAndroid Build Coastguard Worker   initAsmInfo();
225*9880d681SAndroid Build Coastguard Worker }
226*9880d681SAndroid Build Coastguard Worker 
~PPCTargetMachine()227*9880d681SAndroid Build Coastguard Worker PPCTargetMachine::~PPCTargetMachine() {}
228*9880d681SAndroid Build Coastguard Worker 
anchor()229*9880d681SAndroid Build Coastguard Worker void PPC32TargetMachine::anchor() { }
230*9880d681SAndroid Build Coastguard Worker 
PPC32TargetMachine(const Target & T,const Triple & TT,StringRef CPU,StringRef FS,const TargetOptions & Options,Optional<Reloc::Model> RM,CodeModel::Model CM,CodeGenOpt::Level OL)231*9880d681SAndroid Build Coastguard Worker PPC32TargetMachine::PPC32TargetMachine(const Target &T, const Triple &TT,
232*9880d681SAndroid Build Coastguard Worker                                        StringRef CPU, StringRef FS,
233*9880d681SAndroid Build Coastguard Worker                                        const TargetOptions &Options,
234*9880d681SAndroid Build Coastguard Worker                                        Optional<Reloc::Model> RM,
235*9880d681SAndroid Build Coastguard Worker                                        CodeModel::Model CM,
236*9880d681SAndroid Build Coastguard Worker                                        CodeGenOpt::Level OL)
237*9880d681SAndroid Build Coastguard Worker     : PPCTargetMachine(T, TT, CPU, FS, Options, RM, CM, OL) {}
238*9880d681SAndroid Build Coastguard Worker 
anchor()239*9880d681SAndroid Build Coastguard Worker void PPC64TargetMachine::anchor() { }
240*9880d681SAndroid Build Coastguard Worker 
PPC64TargetMachine(const Target & T,const Triple & TT,StringRef CPU,StringRef FS,const TargetOptions & Options,Optional<Reloc::Model> RM,CodeModel::Model CM,CodeGenOpt::Level OL)241*9880d681SAndroid Build Coastguard Worker PPC64TargetMachine::PPC64TargetMachine(const Target &T, const Triple &TT,
242*9880d681SAndroid Build Coastguard Worker                                        StringRef CPU, StringRef FS,
243*9880d681SAndroid Build Coastguard Worker                                        const TargetOptions &Options,
244*9880d681SAndroid Build Coastguard Worker                                        Optional<Reloc::Model> RM,
245*9880d681SAndroid Build Coastguard Worker                                        CodeModel::Model CM,
246*9880d681SAndroid Build Coastguard Worker                                        CodeGenOpt::Level OL)
247*9880d681SAndroid Build Coastguard Worker     : PPCTargetMachine(T, TT, CPU, FS, Options, RM, CM, OL) {}
248*9880d681SAndroid Build Coastguard Worker 
249*9880d681SAndroid Build Coastguard Worker const PPCSubtarget *
getSubtargetImpl(const Function & F) const250*9880d681SAndroid Build Coastguard Worker PPCTargetMachine::getSubtargetImpl(const Function &F) const {
251*9880d681SAndroid Build Coastguard Worker   Attribute CPUAttr = F.getFnAttribute("target-cpu");
252*9880d681SAndroid Build Coastguard Worker   Attribute FSAttr = F.getFnAttribute("target-features");
253*9880d681SAndroid Build Coastguard Worker 
254*9880d681SAndroid Build Coastguard Worker   std::string CPU = !CPUAttr.hasAttribute(Attribute::None)
255*9880d681SAndroid Build Coastguard Worker                         ? CPUAttr.getValueAsString().str()
256*9880d681SAndroid Build Coastguard Worker                         : TargetCPU;
257*9880d681SAndroid Build Coastguard Worker   std::string FS = !FSAttr.hasAttribute(Attribute::None)
258*9880d681SAndroid Build Coastguard Worker                        ? FSAttr.getValueAsString().str()
259*9880d681SAndroid Build Coastguard Worker                        : TargetFS;
260*9880d681SAndroid Build Coastguard Worker 
261*9880d681SAndroid Build Coastguard Worker   // FIXME: This is related to the code below to reset the target options,
262*9880d681SAndroid Build Coastguard Worker   // we need to know whether or not the soft float flag is set on the
263*9880d681SAndroid Build Coastguard Worker   // function before we can generate a subtarget. We also need to use
264*9880d681SAndroid Build Coastguard Worker   // it as a key for the subtarget since that can be the only difference
265*9880d681SAndroid Build Coastguard Worker   // between two functions.
266*9880d681SAndroid Build Coastguard Worker   bool SoftFloat =
267*9880d681SAndroid Build Coastguard Worker       F.getFnAttribute("use-soft-float").getValueAsString() == "true";
268*9880d681SAndroid Build Coastguard Worker   // If the soft float attribute is set on the function turn on the soft float
269*9880d681SAndroid Build Coastguard Worker   // subtarget feature.
270*9880d681SAndroid Build Coastguard Worker   if (SoftFloat)
271*9880d681SAndroid Build Coastguard Worker     FS += FS.empty() ? "+soft-float" : ",+soft-float";
272*9880d681SAndroid Build Coastguard Worker 
273*9880d681SAndroid Build Coastguard Worker   auto &I = SubtargetMap[CPU + FS];
274*9880d681SAndroid Build Coastguard Worker   if (!I) {
275*9880d681SAndroid Build Coastguard Worker     // This needs to be done before we create a new subtarget since any
276*9880d681SAndroid Build Coastguard Worker     // creation will depend on the TM and the code generation flags on the
277*9880d681SAndroid Build Coastguard Worker     // function that reside in TargetOptions.
278*9880d681SAndroid Build Coastguard Worker     resetTargetOptions(F);
279*9880d681SAndroid Build Coastguard Worker     I = llvm::make_unique<PPCSubtarget>(
280*9880d681SAndroid Build Coastguard Worker         TargetTriple, CPU,
281*9880d681SAndroid Build Coastguard Worker         // FIXME: It would be good to have the subtarget additions here
282*9880d681SAndroid Build Coastguard Worker         // not necessary. Anything that turns them on/off (overrides) ends
283*9880d681SAndroid Build Coastguard Worker         // up being put at the end of the feature string, but the defaults
284*9880d681SAndroid Build Coastguard Worker         // shouldn't require adding them. Fixing this means pulling Feature64Bit
285*9880d681SAndroid Build Coastguard Worker         // out of most of the target cpus in the .td file and making it set only
286*9880d681SAndroid Build Coastguard Worker         // as part of initialization via the TargetTriple.
287*9880d681SAndroid Build Coastguard Worker         computeFSAdditions(FS, getOptLevel(), getTargetTriple()), *this);
288*9880d681SAndroid Build Coastguard Worker   }
289*9880d681SAndroid Build Coastguard Worker   return I.get();
290*9880d681SAndroid Build Coastguard Worker }
291*9880d681SAndroid Build Coastguard Worker 
292*9880d681SAndroid Build Coastguard Worker //===----------------------------------------------------------------------===//
293*9880d681SAndroid Build Coastguard Worker // Pass Pipeline Configuration
294*9880d681SAndroid Build Coastguard Worker //===----------------------------------------------------------------------===//
295*9880d681SAndroid Build Coastguard Worker 
296*9880d681SAndroid Build Coastguard Worker namespace {
297*9880d681SAndroid Build Coastguard Worker /// PPC Code Generator Pass Configuration Options.
298*9880d681SAndroid Build Coastguard Worker class PPCPassConfig : public TargetPassConfig {
299*9880d681SAndroid Build Coastguard Worker public:
PPCPassConfig(PPCTargetMachine * TM,PassManagerBase & PM)300*9880d681SAndroid Build Coastguard Worker   PPCPassConfig(PPCTargetMachine *TM, PassManagerBase &PM)
301*9880d681SAndroid Build Coastguard Worker     : TargetPassConfig(TM, PM) {}
302*9880d681SAndroid Build Coastguard Worker 
getPPCTargetMachine() const303*9880d681SAndroid Build Coastguard Worker   PPCTargetMachine &getPPCTargetMachine() const {
304*9880d681SAndroid Build Coastguard Worker     return getTM<PPCTargetMachine>();
305*9880d681SAndroid Build Coastguard Worker   }
306*9880d681SAndroid Build Coastguard Worker 
307*9880d681SAndroid Build Coastguard Worker   void addIRPasses() override;
308*9880d681SAndroid Build Coastguard Worker   bool addPreISel() override;
309*9880d681SAndroid Build Coastguard Worker   bool addILPOpts() override;
310*9880d681SAndroid Build Coastguard Worker   bool addInstSelector() override;
311*9880d681SAndroid Build Coastguard Worker   void addMachineSSAOptimization() override;
312*9880d681SAndroid Build Coastguard Worker   void addPreRegAlloc() override;
313*9880d681SAndroid Build Coastguard Worker   void addPreSched2() override;
314*9880d681SAndroid Build Coastguard Worker   void addPreEmitPass() override;
315*9880d681SAndroid Build Coastguard Worker };
316*9880d681SAndroid Build Coastguard Worker } // namespace
317*9880d681SAndroid Build Coastguard Worker 
createPassConfig(PassManagerBase & PM)318*9880d681SAndroid Build Coastguard Worker TargetPassConfig *PPCTargetMachine::createPassConfig(PassManagerBase &PM) {
319*9880d681SAndroid Build Coastguard Worker   return new PPCPassConfig(this, PM);
320*9880d681SAndroid Build Coastguard Worker }
321*9880d681SAndroid Build Coastguard Worker 
addIRPasses()322*9880d681SAndroid Build Coastguard Worker void PPCPassConfig::addIRPasses() {
323*9880d681SAndroid Build Coastguard Worker   if (TM->getOptLevel() != CodeGenOpt::None)
324*9880d681SAndroid Build Coastguard Worker     addPass(createPPCBoolRetToIntPass());
325*9880d681SAndroid Build Coastguard Worker   addPass(createAtomicExpandPass(&getPPCTargetMachine()));
326*9880d681SAndroid Build Coastguard Worker 
327*9880d681SAndroid Build Coastguard Worker   // For the BG/Q (or if explicitly requested), add explicit data prefetch
328*9880d681SAndroid Build Coastguard Worker   // intrinsics.
329*9880d681SAndroid Build Coastguard Worker   bool UsePrefetching = TM->getTargetTriple().getVendor() == Triple::BGQ &&
330*9880d681SAndroid Build Coastguard Worker                         getOptLevel() != CodeGenOpt::None;
331*9880d681SAndroid Build Coastguard Worker   if (EnablePrefetch.getNumOccurrences() > 0)
332*9880d681SAndroid Build Coastguard Worker     UsePrefetching = EnablePrefetch;
333*9880d681SAndroid Build Coastguard Worker   if (UsePrefetching)
334*9880d681SAndroid Build Coastguard Worker     addPass(createLoopDataPrefetchPass());
335*9880d681SAndroid Build Coastguard Worker 
336*9880d681SAndroid Build Coastguard Worker   if (TM->getOptLevel() >= CodeGenOpt::Default && EnableGEPOpt) {
337*9880d681SAndroid Build Coastguard Worker     // Call SeparateConstOffsetFromGEP pass to extract constants within indices
338*9880d681SAndroid Build Coastguard Worker     // and lower a GEP with multiple indices to either arithmetic operations or
339*9880d681SAndroid Build Coastguard Worker     // multiple GEPs with single index.
340*9880d681SAndroid Build Coastguard Worker     addPass(createSeparateConstOffsetFromGEPPass(TM, true));
341*9880d681SAndroid Build Coastguard Worker     // Call EarlyCSE pass to find and remove subexpressions in the lowered
342*9880d681SAndroid Build Coastguard Worker     // result.
343*9880d681SAndroid Build Coastguard Worker     addPass(createEarlyCSEPass());
344*9880d681SAndroid Build Coastguard Worker     // Do loop invariant code motion in case part of the lowered result is
345*9880d681SAndroid Build Coastguard Worker     // invariant.
346*9880d681SAndroid Build Coastguard Worker     addPass(createLICMPass());
347*9880d681SAndroid Build Coastguard Worker   }
348*9880d681SAndroid Build Coastguard Worker 
349*9880d681SAndroid Build Coastguard Worker   TargetPassConfig::addIRPasses();
350*9880d681SAndroid Build Coastguard Worker }
351*9880d681SAndroid Build Coastguard Worker 
addPreISel()352*9880d681SAndroid Build Coastguard Worker bool PPCPassConfig::addPreISel() {
353*9880d681SAndroid Build Coastguard Worker   if (!DisablePreIncPrep && getOptLevel() != CodeGenOpt::None)
354*9880d681SAndroid Build Coastguard Worker     addPass(createPPCLoopPreIncPrepPass(getPPCTargetMachine()));
355*9880d681SAndroid Build Coastguard Worker 
356*9880d681SAndroid Build Coastguard Worker   if (!DisableCTRLoops && getOptLevel() != CodeGenOpt::None)
357*9880d681SAndroid Build Coastguard Worker     addPass(createPPCCTRLoops(getPPCTargetMachine()));
358*9880d681SAndroid Build Coastguard Worker 
359*9880d681SAndroid Build Coastguard Worker   return false;
360*9880d681SAndroid Build Coastguard Worker }
361*9880d681SAndroid Build Coastguard Worker 
addILPOpts()362*9880d681SAndroid Build Coastguard Worker bool PPCPassConfig::addILPOpts() {
363*9880d681SAndroid Build Coastguard Worker   addPass(&EarlyIfConverterID);
364*9880d681SAndroid Build Coastguard Worker 
365*9880d681SAndroid Build Coastguard Worker   if (EnableMachineCombinerPass)
366*9880d681SAndroid Build Coastguard Worker     addPass(&MachineCombinerID);
367*9880d681SAndroid Build Coastguard Worker 
368*9880d681SAndroid Build Coastguard Worker   return true;
369*9880d681SAndroid Build Coastguard Worker }
370*9880d681SAndroid Build Coastguard Worker 
addInstSelector()371*9880d681SAndroid Build Coastguard Worker bool PPCPassConfig::addInstSelector() {
372*9880d681SAndroid Build Coastguard Worker   // Install an instruction selector.
373*9880d681SAndroid Build Coastguard Worker   addPass(createPPCISelDag(getPPCTargetMachine()));
374*9880d681SAndroid Build Coastguard Worker 
375*9880d681SAndroid Build Coastguard Worker #ifndef NDEBUG
376*9880d681SAndroid Build Coastguard Worker   if (!DisableCTRLoops && getOptLevel() != CodeGenOpt::None)
377*9880d681SAndroid Build Coastguard Worker     addPass(createPPCCTRLoopsVerify());
378*9880d681SAndroid Build Coastguard Worker #endif
379*9880d681SAndroid Build Coastguard Worker 
380*9880d681SAndroid Build Coastguard Worker   addPass(createPPCVSXCopyPass());
381*9880d681SAndroid Build Coastguard Worker   return false;
382*9880d681SAndroid Build Coastguard Worker }
383*9880d681SAndroid Build Coastguard Worker 
addMachineSSAOptimization()384*9880d681SAndroid Build Coastguard Worker void PPCPassConfig::addMachineSSAOptimization() {
385*9880d681SAndroid Build Coastguard Worker   TargetPassConfig::addMachineSSAOptimization();
386*9880d681SAndroid Build Coastguard Worker   // For little endian, remove where possible the vector swap instructions
387*9880d681SAndroid Build Coastguard Worker   // introduced at code generation to normalize vector element order.
388*9880d681SAndroid Build Coastguard Worker   if (TM->getTargetTriple().getArch() == Triple::ppc64le &&
389*9880d681SAndroid Build Coastguard Worker       !DisableVSXSwapRemoval)
390*9880d681SAndroid Build Coastguard Worker     addPass(createPPCVSXSwapRemovalPass());
391*9880d681SAndroid Build Coastguard Worker   // Target-specific peephole cleanups performed after instruction
392*9880d681SAndroid Build Coastguard Worker   // selection.
393*9880d681SAndroid Build Coastguard Worker   if (!DisableMIPeephole) {
394*9880d681SAndroid Build Coastguard Worker     addPass(createPPCMIPeepholePass());
395*9880d681SAndroid Build Coastguard Worker     addPass(&DeadMachineInstructionElimID);
396*9880d681SAndroid Build Coastguard Worker   }
397*9880d681SAndroid Build Coastguard Worker }
398*9880d681SAndroid Build Coastguard Worker 
addPreRegAlloc()399*9880d681SAndroid Build Coastguard Worker void PPCPassConfig::addPreRegAlloc() {
400*9880d681SAndroid Build Coastguard Worker   if (getOptLevel() != CodeGenOpt::None) {
401*9880d681SAndroid Build Coastguard Worker     initializePPCVSXFMAMutatePass(*PassRegistry::getPassRegistry());
402*9880d681SAndroid Build Coastguard Worker     insertPass(VSXFMAMutateEarly ? &RegisterCoalescerID : &MachineSchedulerID,
403*9880d681SAndroid Build Coastguard Worker                &PPCVSXFMAMutateID);
404*9880d681SAndroid Build Coastguard Worker   }
405*9880d681SAndroid Build Coastguard Worker 
406*9880d681SAndroid Build Coastguard Worker   // FIXME: We probably don't need to run these for -fPIE.
407*9880d681SAndroid Build Coastguard Worker   if (getPPCTargetMachine().isPositionIndependent()) {
408*9880d681SAndroid Build Coastguard Worker     // FIXME: LiveVariables should not be necessary here!
409*9880d681SAndroid Build Coastguard Worker     // PPCTLSDYnamicCallPass uses LiveIntervals which previously dependet on
410*9880d681SAndroid Build Coastguard Worker     // LiveVariables. This (unnecessary) dependency has been removed now,
411*9880d681SAndroid Build Coastguard Worker     // however a stage-2 clang build fails without LiveVariables computed here.
412*9880d681SAndroid Build Coastguard Worker     addPass(&LiveVariablesID, false);
413*9880d681SAndroid Build Coastguard Worker     addPass(createPPCTLSDynamicCallPass());
414*9880d681SAndroid Build Coastguard Worker   }
415*9880d681SAndroid Build Coastguard Worker   if (EnableExtraTOCRegDeps)
416*9880d681SAndroid Build Coastguard Worker     addPass(createPPCTOCRegDepsPass());
417*9880d681SAndroid Build Coastguard Worker }
418*9880d681SAndroid Build Coastguard Worker 
addPreSched2()419*9880d681SAndroid Build Coastguard Worker void PPCPassConfig::addPreSched2() {
420*9880d681SAndroid Build Coastguard Worker   if (getOptLevel() != CodeGenOpt::None) {
421*9880d681SAndroid Build Coastguard Worker     addPass(&IfConverterID);
422*9880d681SAndroid Build Coastguard Worker 
423*9880d681SAndroid Build Coastguard Worker     // This optimization must happen after anything that might do store-to-load
424*9880d681SAndroid Build Coastguard Worker     // forwarding. Here we're after RA (and, thus, when spills are inserted)
425*9880d681SAndroid Build Coastguard Worker     // but before post-RA scheduling.
426*9880d681SAndroid Build Coastguard Worker     if (!DisableQPXLoadSplat)
427*9880d681SAndroid Build Coastguard Worker       addPass(createPPCQPXLoadSplatPass());
428*9880d681SAndroid Build Coastguard Worker   }
429*9880d681SAndroid Build Coastguard Worker }
430*9880d681SAndroid Build Coastguard Worker 
addPreEmitPass()431*9880d681SAndroid Build Coastguard Worker void PPCPassConfig::addPreEmitPass() {
432*9880d681SAndroid Build Coastguard Worker   if (getOptLevel() != CodeGenOpt::None)
433*9880d681SAndroid Build Coastguard Worker     addPass(createPPCEarlyReturnPass(), false);
434*9880d681SAndroid Build Coastguard Worker   // Must run branch selection immediately preceding the asm printer.
435*9880d681SAndroid Build Coastguard Worker   addPass(createPPCBranchSelectionPass(), false);
436*9880d681SAndroid Build Coastguard Worker }
437*9880d681SAndroid Build Coastguard Worker 
getTargetIRAnalysis()438*9880d681SAndroid Build Coastguard Worker TargetIRAnalysis PPCTargetMachine::getTargetIRAnalysis() {
439*9880d681SAndroid Build Coastguard Worker   return TargetIRAnalysis([this](const Function &F) {
440*9880d681SAndroid Build Coastguard Worker     return TargetTransformInfo(PPCTTIImpl(this, F));
441*9880d681SAndroid Build Coastguard Worker   });
442*9880d681SAndroid Build Coastguard Worker }
443