xref: /freebsd/contrib/llvm-project/llvm/lib/Target/PowerPC/PPCTargetMachine.cpp (revision 0b57cec536236d46e3dba9bd041533462f33dbb7)
1*0b57cec5SDimitry Andric //===-- PPCTargetMachine.cpp - Define TargetMachine for PowerPC -----------===//
2*0b57cec5SDimitry Andric //
3*0b57cec5SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4*0b57cec5SDimitry Andric // See https://llvm.org/LICENSE.txt for license information.
5*0b57cec5SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6*0b57cec5SDimitry Andric //
7*0b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
8*0b57cec5SDimitry Andric //
9*0b57cec5SDimitry Andric // Top-level implementation for the PowerPC target.
10*0b57cec5SDimitry Andric //
11*0b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
12*0b57cec5SDimitry Andric 
13*0b57cec5SDimitry Andric #include "PPCTargetMachine.h"
14*0b57cec5SDimitry Andric #include "MCTargetDesc/PPCMCTargetDesc.h"
15*0b57cec5SDimitry Andric #include "PPC.h"
16*0b57cec5SDimitry Andric #include "PPCMachineScheduler.h"
17*0b57cec5SDimitry Andric #include "PPCSubtarget.h"
18*0b57cec5SDimitry Andric #include "PPCTargetObjectFile.h"
19*0b57cec5SDimitry Andric #include "PPCTargetTransformInfo.h"
20*0b57cec5SDimitry Andric #include "TargetInfo/PowerPCTargetInfo.h"
21*0b57cec5SDimitry Andric #include "llvm/ADT/Optional.h"
22*0b57cec5SDimitry Andric #include "llvm/ADT/STLExtras.h"
23*0b57cec5SDimitry Andric #include "llvm/ADT/StringRef.h"
24*0b57cec5SDimitry Andric #include "llvm/ADT/Triple.h"
25*0b57cec5SDimitry Andric #include "llvm/Analysis/TargetTransformInfo.h"
26*0b57cec5SDimitry Andric #include "llvm/CodeGen/Passes.h"
27*0b57cec5SDimitry Andric #include "llvm/CodeGen/TargetPassConfig.h"
28*0b57cec5SDimitry Andric #include "llvm/CodeGen/MachineScheduler.h"
29*0b57cec5SDimitry Andric #include "llvm/IR/Attributes.h"
30*0b57cec5SDimitry Andric #include "llvm/IR/DataLayout.h"
31*0b57cec5SDimitry Andric #include "llvm/IR/Function.h"
32*0b57cec5SDimitry Andric #include "llvm/Pass.h"
33*0b57cec5SDimitry Andric #include "llvm/Support/CodeGen.h"
34*0b57cec5SDimitry Andric #include "llvm/Support/CommandLine.h"
35*0b57cec5SDimitry Andric #include "llvm/Support/TargetRegistry.h"
36*0b57cec5SDimitry Andric #include "llvm/Target/TargetLoweringObjectFile.h"
37*0b57cec5SDimitry Andric #include "llvm/Target/TargetOptions.h"
38*0b57cec5SDimitry Andric #include "llvm/Transforms/Scalar.h"
39*0b57cec5SDimitry Andric #include <cassert>
40*0b57cec5SDimitry Andric #include <memory>
41*0b57cec5SDimitry Andric #include <string>
42*0b57cec5SDimitry Andric 
43*0b57cec5SDimitry Andric using namespace llvm;
44*0b57cec5SDimitry Andric 
45*0b57cec5SDimitry Andric 
46*0b57cec5SDimitry Andric static cl::opt<bool>
47*0b57cec5SDimitry Andric     EnableBranchCoalescing("enable-ppc-branch-coalesce", cl::Hidden,
48*0b57cec5SDimitry Andric                            cl::desc("enable coalescing of duplicate branches for PPC"));
49*0b57cec5SDimitry Andric static cl::
50*0b57cec5SDimitry Andric opt<bool> DisableCTRLoops("disable-ppc-ctrloops", cl::Hidden,
51*0b57cec5SDimitry Andric                         cl::desc("Disable CTR loops for PPC"));
52*0b57cec5SDimitry Andric 
53*0b57cec5SDimitry Andric static cl::
54*0b57cec5SDimitry Andric opt<bool> DisablePreIncPrep("disable-ppc-preinc-prep", cl::Hidden,
55*0b57cec5SDimitry Andric                             cl::desc("Disable PPC loop preinc prep"));
56*0b57cec5SDimitry Andric 
57*0b57cec5SDimitry Andric static cl::opt<bool>
58*0b57cec5SDimitry Andric VSXFMAMutateEarly("schedule-ppc-vsx-fma-mutation-early",
59*0b57cec5SDimitry Andric   cl::Hidden, cl::desc("Schedule VSX FMA instruction mutation early"));
60*0b57cec5SDimitry Andric 
61*0b57cec5SDimitry Andric static cl::
62*0b57cec5SDimitry Andric opt<bool> DisableVSXSwapRemoval("disable-ppc-vsx-swap-removal", cl::Hidden,
63*0b57cec5SDimitry Andric                                 cl::desc("Disable VSX Swap Removal for PPC"));
64*0b57cec5SDimitry Andric 
65*0b57cec5SDimitry Andric static cl::
66*0b57cec5SDimitry Andric opt<bool> DisableQPXLoadSplat("disable-ppc-qpx-load-splat", cl::Hidden,
67*0b57cec5SDimitry Andric                               cl::desc("Disable QPX load splat simplification"));
68*0b57cec5SDimitry Andric 
69*0b57cec5SDimitry Andric static cl::
70*0b57cec5SDimitry Andric opt<bool> DisableMIPeephole("disable-ppc-peephole", cl::Hidden,
71*0b57cec5SDimitry Andric                             cl::desc("Disable machine peepholes for PPC"));
72*0b57cec5SDimitry Andric 
73*0b57cec5SDimitry Andric static cl::opt<bool>
74*0b57cec5SDimitry Andric EnableGEPOpt("ppc-gep-opt", cl::Hidden,
75*0b57cec5SDimitry Andric              cl::desc("Enable optimizations on complex GEPs"),
76*0b57cec5SDimitry Andric              cl::init(true));
77*0b57cec5SDimitry Andric 
78*0b57cec5SDimitry Andric static cl::opt<bool>
79*0b57cec5SDimitry Andric EnablePrefetch("enable-ppc-prefetching",
80*0b57cec5SDimitry Andric                   cl::desc("disable software prefetching on PPC"),
81*0b57cec5SDimitry Andric                   cl::init(false), cl::Hidden);
82*0b57cec5SDimitry Andric 
83*0b57cec5SDimitry Andric static cl::opt<bool>
84*0b57cec5SDimitry Andric EnableExtraTOCRegDeps("enable-ppc-extra-toc-reg-deps",
85*0b57cec5SDimitry Andric                       cl::desc("Add extra TOC register dependencies"),
86*0b57cec5SDimitry Andric                       cl::init(true), cl::Hidden);
87*0b57cec5SDimitry Andric 
88*0b57cec5SDimitry Andric static cl::opt<bool>
89*0b57cec5SDimitry Andric EnableMachineCombinerPass("ppc-machine-combiner",
90*0b57cec5SDimitry Andric                           cl::desc("Enable the machine combiner pass"),
91*0b57cec5SDimitry Andric                           cl::init(true), cl::Hidden);
92*0b57cec5SDimitry Andric 
93*0b57cec5SDimitry Andric static cl::opt<bool>
94*0b57cec5SDimitry Andric   ReduceCRLogical("ppc-reduce-cr-logicals",
95*0b57cec5SDimitry Andric                   cl::desc("Expand eligible cr-logical binary ops to branches"),
96*0b57cec5SDimitry Andric                   cl::init(false), cl::Hidden);
97*0b57cec5SDimitry Andric extern "C" void LLVMInitializePowerPCTarget() {
98*0b57cec5SDimitry Andric   // Register the targets
99*0b57cec5SDimitry Andric   RegisterTargetMachine<PPCTargetMachine> A(getThePPC32Target());
100*0b57cec5SDimitry Andric   RegisterTargetMachine<PPCTargetMachine> B(getThePPC64Target());
101*0b57cec5SDimitry Andric   RegisterTargetMachine<PPCTargetMachine> C(getThePPC64LETarget());
102*0b57cec5SDimitry Andric 
103*0b57cec5SDimitry Andric   PassRegistry &PR = *PassRegistry::getPassRegistry();
104*0b57cec5SDimitry Andric #ifndef NDEBUG
105*0b57cec5SDimitry Andric   initializePPCCTRLoopsVerifyPass(PR);
106*0b57cec5SDimitry Andric #endif
107*0b57cec5SDimitry Andric   initializePPCLoopPreIncPrepPass(PR);
108*0b57cec5SDimitry Andric   initializePPCTOCRegDepsPass(PR);
109*0b57cec5SDimitry Andric   initializePPCEarlyReturnPass(PR);
110*0b57cec5SDimitry Andric   initializePPCVSXCopyPass(PR);
111*0b57cec5SDimitry Andric   initializePPCVSXFMAMutatePass(PR);
112*0b57cec5SDimitry Andric   initializePPCVSXSwapRemovalPass(PR);
113*0b57cec5SDimitry Andric   initializePPCReduceCRLogicalsPass(PR);
114*0b57cec5SDimitry Andric   initializePPCBSelPass(PR);
115*0b57cec5SDimitry Andric   initializePPCBranchCoalescingPass(PR);
116*0b57cec5SDimitry Andric   initializePPCQPXLoadSplatPass(PR);
117*0b57cec5SDimitry Andric   initializePPCBoolRetToIntPass(PR);
118*0b57cec5SDimitry Andric   initializePPCExpandISELPass(PR);
119*0b57cec5SDimitry Andric   initializePPCPreEmitPeepholePass(PR);
120*0b57cec5SDimitry Andric   initializePPCTLSDynamicCallPass(PR);
121*0b57cec5SDimitry Andric   initializePPCMIPeepholePass(PR);
122*0b57cec5SDimitry Andric }
123*0b57cec5SDimitry Andric 
124*0b57cec5SDimitry Andric /// Return the datalayout string of a subtarget.
125*0b57cec5SDimitry Andric static std::string getDataLayoutString(const Triple &T) {
126*0b57cec5SDimitry Andric   bool is64Bit = T.getArch() == Triple::ppc64 || T.getArch() == Triple::ppc64le;
127*0b57cec5SDimitry Andric   std::string Ret;
128*0b57cec5SDimitry Andric 
129*0b57cec5SDimitry Andric   // Most PPC* platforms are big endian, PPC64LE is little endian.
130*0b57cec5SDimitry Andric   if (T.getArch() == Triple::ppc64le)
131*0b57cec5SDimitry Andric     Ret = "e";
132*0b57cec5SDimitry Andric   else
133*0b57cec5SDimitry Andric     Ret = "E";
134*0b57cec5SDimitry Andric 
135*0b57cec5SDimitry Andric   Ret += DataLayout::getManglingComponent(T);
136*0b57cec5SDimitry Andric 
137*0b57cec5SDimitry Andric   // PPC32 has 32 bit pointers. The PS3 (OS Lv2) is a PPC64 machine with 32 bit
138*0b57cec5SDimitry Andric   // pointers.
139*0b57cec5SDimitry Andric   if (!is64Bit || T.getOS() == Triple::Lv2)
140*0b57cec5SDimitry Andric     Ret += "-p:32:32";
141*0b57cec5SDimitry Andric 
142*0b57cec5SDimitry Andric   // Note, the alignment values for f64 and i64 on ppc64 in Darwin
143*0b57cec5SDimitry Andric   // documentation are wrong; these are correct (i.e. "what gcc does").
144*0b57cec5SDimitry Andric   if (is64Bit || !T.isOSDarwin())
145*0b57cec5SDimitry Andric     Ret += "-i64:64";
146*0b57cec5SDimitry Andric   else
147*0b57cec5SDimitry Andric     Ret += "-f64:32:64";
148*0b57cec5SDimitry Andric 
149*0b57cec5SDimitry Andric   // PPC64 has 32 and 64 bit registers, PPC32 has only 32 bit ones.
150*0b57cec5SDimitry Andric   if (is64Bit)
151*0b57cec5SDimitry Andric     Ret += "-n32:64";
152*0b57cec5SDimitry Andric   else
153*0b57cec5SDimitry Andric     Ret += "-n32";
154*0b57cec5SDimitry Andric 
155*0b57cec5SDimitry Andric   return Ret;
156*0b57cec5SDimitry Andric }
157*0b57cec5SDimitry Andric 
158*0b57cec5SDimitry Andric static std::string computeFSAdditions(StringRef FS, CodeGenOpt::Level OL,
159*0b57cec5SDimitry Andric                                       const Triple &TT) {
160*0b57cec5SDimitry Andric   std::string FullFS = FS;
161*0b57cec5SDimitry Andric 
162*0b57cec5SDimitry Andric   // Make sure 64-bit features are available when CPUname is generic
163*0b57cec5SDimitry Andric   if (TT.getArch() == Triple::ppc64 || TT.getArch() == Triple::ppc64le) {
164*0b57cec5SDimitry Andric     if (!FullFS.empty())
165*0b57cec5SDimitry Andric       FullFS = "+64bit," + FullFS;
166*0b57cec5SDimitry Andric     else
167*0b57cec5SDimitry Andric       FullFS = "+64bit";
168*0b57cec5SDimitry Andric   }
169*0b57cec5SDimitry Andric 
170*0b57cec5SDimitry Andric   if (OL >= CodeGenOpt::Default) {
171*0b57cec5SDimitry Andric     if (!FullFS.empty())
172*0b57cec5SDimitry Andric       FullFS = "+crbits," + FullFS;
173*0b57cec5SDimitry Andric     else
174*0b57cec5SDimitry Andric       FullFS = "+crbits";
175*0b57cec5SDimitry Andric   }
176*0b57cec5SDimitry Andric 
177*0b57cec5SDimitry Andric   if (OL != CodeGenOpt::None) {
178*0b57cec5SDimitry Andric     if (!FullFS.empty())
179*0b57cec5SDimitry Andric       FullFS = "+invariant-function-descriptors," + FullFS;
180*0b57cec5SDimitry Andric     else
181*0b57cec5SDimitry Andric       FullFS = "+invariant-function-descriptors";
182*0b57cec5SDimitry Andric   }
183*0b57cec5SDimitry Andric 
184*0b57cec5SDimitry Andric   return FullFS;
185*0b57cec5SDimitry Andric }
186*0b57cec5SDimitry Andric 
187*0b57cec5SDimitry Andric static std::unique_ptr<TargetLoweringObjectFile> createTLOF(const Triple &TT) {
188*0b57cec5SDimitry Andric   // If it isn't a Mach-O file then it's going to be a linux ELF
189*0b57cec5SDimitry Andric   // object file.
190*0b57cec5SDimitry Andric   if (TT.isOSDarwin())
191*0b57cec5SDimitry Andric     return llvm::make_unique<TargetLoweringObjectFileMachO>();
192*0b57cec5SDimitry Andric 
193*0b57cec5SDimitry Andric   return llvm::make_unique<PPC64LinuxTargetObjectFile>();
194*0b57cec5SDimitry Andric }
195*0b57cec5SDimitry Andric 
196*0b57cec5SDimitry Andric static PPCTargetMachine::PPCABI computeTargetABI(const Triple &TT,
197*0b57cec5SDimitry Andric                                                  const TargetOptions &Options) {
198*0b57cec5SDimitry Andric   if (TT.isOSDarwin())
199*0b57cec5SDimitry Andric     report_fatal_error("Darwin is no longer supported for PowerPC");
200*0b57cec5SDimitry Andric 
201*0b57cec5SDimitry Andric   if (Options.MCOptions.getABIName().startswith("elfv1"))
202*0b57cec5SDimitry Andric     return PPCTargetMachine::PPC_ABI_ELFv1;
203*0b57cec5SDimitry Andric   else if (Options.MCOptions.getABIName().startswith("elfv2"))
204*0b57cec5SDimitry Andric     return PPCTargetMachine::PPC_ABI_ELFv2;
205*0b57cec5SDimitry Andric 
206*0b57cec5SDimitry Andric   assert(Options.MCOptions.getABIName().empty() &&
207*0b57cec5SDimitry Andric          "Unknown target-abi option!");
208*0b57cec5SDimitry Andric 
209*0b57cec5SDimitry Andric   if (TT.isMacOSX())
210*0b57cec5SDimitry Andric     return PPCTargetMachine::PPC_ABI_UNKNOWN;
211*0b57cec5SDimitry Andric 
212*0b57cec5SDimitry Andric   switch (TT.getArch()) {
213*0b57cec5SDimitry Andric   case Triple::ppc64le:
214*0b57cec5SDimitry Andric     return PPCTargetMachine::PPC_ABI_ELFv2;
215*0b57cec5SDimitry Andric   case Triple::ppc64:
216*0b57cec5SDimitry Andric     if (TT.getEnvironment() == llvm::Triple::ELFv2)
217*0b57cec5SDimitry Andric       return PPCTargetMachine::PPC_ABI_ELFv2;
218*0b57cec5SDimitry Andric     return PPCTargetMachine::PPC_ABI_ELFv1;
219*0b57cec5SDimitry Andric   default:
220*0b57cec5SDimitry Andric     return PPCTargetMachine::PPC_ABI_UNKNOWN;
221*0b57cec5SDimitry Andric   }
222*0b57cec5SDimitry Andric }
223*0b57cec5SDimitry Andric 
224*0b57cec5SDimitry Andric static Reloc::Model getEffectiveRelocModel(const Triple &TT,
225*0b57cec5SDimitry Andric                                            Optional<Reloc::Model> RM) {
226*0b57cec5SDimitry Andric   if (RM.hasValue())
227*0b57cec5SDimitry Andric     return *RM;
228*0b57cec5SDimitry Andric 
229*0b57cec5SDimitry Andric   // Darwin defaults to dynamic-no-pic.
230*0b57cec5SDimitry Andric   if (TT.isOSDarwin())
231*0b57cec5SDimitry Andric     return Reloc::DynamicNoPIC;
232*0b57cec5SDimitry Andric 
233*0b57cec5SDimitry Andric   // Big Endian PPC is PIC by default.
234*0b57cec5SDimitry Andric   if (TT.getArch() == Triple::ppc64)
235*0b57cec5SDimitry Andric     return Reloc::PIC_;
236*0b57cec5SDimitry Andric 
237*0b57cec5SDimitry Andric   // Rest are static by default.
238*0b57cec5SDimitry Andric   return Reloc::Static;
239*0b57cec5SDimitry Andric }
240*0b57cec5SDimitry Andric 
241*0b57cec5SDimitry Andric static CodeModel::Model getEffectivePPCCodeModel(const Triple &TT,
242*0b57cec5SDimitry Andric                                                  Optional<CodeModel::Model> CM,
243*0b57cec5SDimitry Andric                                                  bool JIT) {
244*0b57cec5SDimitry Andric   if (CM) {
245*0b57cec5SDimitry Andric     if (*CM == CodeModel::Tiny)
246*0b57cec5SDimitry Andric       report_fatal_error("Target does not support the tiny CodeModel", false);
247*0b57cec5SDimitry Andric     if (*CM == CodeModel::Kernel)
248*0b57cec5SDimitry Andric       report_fatal_error("Target does not support the kernel CodeModel", false);
249*0b57cec5SDimitry Andric     return *CM;
250*0b57cec5SDimitry Andric   }
251*0b57cec5SDimitry Andric   if (!TT.isOSDarwin() && !JIT &&
252*0b57cec5SDimitry Andric       (TT.getArch() == Triple::ppc64 || TT.getArch() == Triple::ppc64le))
253*0b57cec5SDimitry Andric     return CodeModel::Medium;
254*0b57cec5SDimitry Andric   return CodeModel::Small;
255*0b57cec5SDimitry Andric }
256*0b57cec5SDimitry Andric 
257*0b57cec5SDimitry Andric 
258*0b57cec5SDimitry Andric static ScheduleDAGInstrs *createPPCMachineScheduler(MachineSchedContext *C) {
259*0b57cec5SDimitry Andric   const PPCSubtarget &ST = C->MF->getSubtarget<PPCSubtarget>();
260*0b57cec5SDimitry Andric   ScheduleDAGMILive *DAG =
261*0b57cec5SDimitry Andric     new ScheduleDAGMILive(C, ST.usePPCPreRASchedStrategy() ?
262*0b57cec5SDimitry Andric                           llvm::make_unique<PPCPreRASchedStrategy>(C) :
263*0b57cec5SDimitry Andric                           llvm::make_unique<GenericScheduler>(C));
264*0b57cec5SDimitry Andric   // add DAG Mutations here.
265*0b57cec5SDimitry Andric   DAG->addMutation(createCopyConstrainDAGMutation(DAG->TII, DAG->TRI));
266*0b57cec5SDimitry Andric   return DAG;
267*0b57cec5SDimitry Andric }
268*0b57cec5SDimitry Andric 
269*0b57cec5SDimitry Andric static ScheduleDAGInstrs *createPPCPostMachineScheduler(
270*0b57cec5SDimitry Andric   MachineSchedContext *C) {
271*0b57cec5SDimitry Andric   const PPCSubtarget &ST = C->MF->getSubtarget<PPCSubtarget>();
272*0b57cec5SDimitry Andric   ScheduleDAGMI *DAG =
273*0b57cec5SDimitry Andric     new ScheduleDAGMI(C, ST.usePPCPostRASchedStrategy() ?
274*0b57cec5SDimitry Andric                       llvm::make_unique<PPCPostRASchedStrategy>(C) :
275*0b57cec5SDimitry Andric                       llvm::make_unique<PostGenericScheduler>(C), true);
276*0b57cec5SDimitry Andric   // add DAG Mutations here.
277*0b57cec5SDimitry Andric   return DAG;
278*0b57cec5SDimitry Andric }
279*0b57cec5SDimitry Andric 
280*0b57cec5SDimitry Andric // The FeatureString here is a little subtle. We are modifying the feature
281*0b57cec5SDimitry Andric // string with what are (currently) non-function specific overrides as it goes
282*0b57cec5SDimitry Andric // into the LLVMTargetMachine constructor and then using the stored value in the
283*0b57cec5SDimitry Andric // Subtarget constructor below it.
284*0b57cec5SDimitry Andric PPCTargetMachine::PPCTargetMachine(const Target &T, const Triple &TT,
285*0b57cec5SDimitry Andric                                    StringRef CPU, StringRef FS,
286*0b57cec5SDimitry Andric                                    const TargetOptions &Options,
287*0b57cec5SDimitry Andric                                    Optional<Reloc::Model> RM,
288*0b57cec5SDimitry Andric                                    Optional<CodeModel::Model> CM,
289*0b57cec5SDimitry Andric                                    CodeGenOpt::Level OL, bool JIT)
290*0b57cec5SDimitry Andric     : LLVMTargetMachine(T, getDataLayoutString(TT), TT, CPU,
291*0b57cec5SDimitry Andric                         computeFSAdditions(FS, OL, TT), Options,
292*0b57cec5SDimitry Andric                         getEffectiveRelocModel(TT, RM),
293*0b57cec5SDimitry Andric                         getEffectivePPCCodeModel(TT, CM, JIT), OL),
294*0b57cec5SDimitry Andric       TLOF(createTLOF(getTargetTriple())),
295*0b57cec5SDimitry Andric       TargetABI(computeTargetABI(TT, Options)) {
296*0b57cec5SDimitry Andric   initAsmInfo();
297*0b57cec5SDimitry Andric }
298*0b57cec5SDimitry Andric 
299*0b57cec5SDimitry Andric PPCTargetMachine::~PPCTargetMachine() = default;
300*0b57cec5SDimitry Andric 
301*0b57cec5SDimitry Andric const PPCSubtarget *
302*0b57cec5SDimitry Andric PPCTargetMachine::getSubtargetImpl(const Function &F) const {
303*0b57cec5SDimitry Andric   Attribute CPUAttr = F.getFnAttribute("target-cpu");
304*0b57cec5SDimitry Andric   Attribute FSAttr = F.getFnAttribute("target-features");
305*0b57cec5SDimitry Andric 
306*0b57cec5SDimitry Andric   std::string CPU = !CPUAttr.hasAttribute(Attribute::None)
307*0b57cec5SDimitry Andric                         ? CPUAttr.getValueAsString().str()
308*0b57cec5SDimitry Andric                         : TargetCPU;
309*0b57cec5SDimitry Andric   std::string FS = !FSAttr.hasAttribute(Attribute::None)
310*0b57cec5SDimitry Andric                        ? FSAttr.getValueAsString().str()
311*0b57cec5SDimitry Andric                        : TargetFS;
312*0b57cec5SDimitry Andric 
313*0b57cec5SDimitry Andric   // FIXME: This is related to the code below to reset the target options,
314*0b57cec5SDimitry Andric   // we need to know whether or not the soft float flag is set on the
315*0b57cec5SDimitry Andric   // function before we can generate a subtarget. We also need to use
316*0b57cec5SDimitry Andric   // it as a key for the subtarget since that can be the only difference
317*0b57cec5SDimitry Andric   // between two functions.
318*0b57cec5SDimitry Andric   bool SoftFloat =
319*0b57cec5SDimitry Andric       F.getFnAttribute("use-soft-float").getValueAsString() == "true";
320*0b57cec5SDimitry Andric   // If the soft float attribute is set on the function turn on the soft float
321*0b57cec5SDimitry Andric   // subtarget feature.
322*0b57cec5SDimitry Andric   if (SoftFloat)
323*0b57cec5SDimitry Andric     FS += FS.empty() ? "-hard-float" : ",-hard-float";
324*0b57cec5SDimitry Andric 
325*0b57cec5SDimitry Andric   auto &I = SubtargetMap[CPU + FS];
326*0b57cec5SDimitry Andric   if (!I) {
327*0b57cec5SDimitry Andric     // This needs to be done before we create a new subtarget since any
328*0b57cec5SDimitry Andric     // creation will depend on the TM and the code generation flags on the
329*0b57cec5SDimitry Andric     // function that reside in TargetOptions.
330*0b57cec5SDimitry Andric     resetTargetOptions(F);
331*0b57cec5SDimitry Andric     I = llvm::make_unique<PPCSubtarget>(
332*0b57cec5SDimitry Andric         TargetTriple, CPU,
333*0b57cec5SDimitry Andric         // FIXME: It would be good to have the subtarget additions here
334*0b57cec5SDimitry Andric         // not necessary. Anything that turns them on/off (overrides) ends
335*0b57cec5SDimitry Andric         // up being put at the end of the feature string, but the defaults
336*0b57cec5SDimitry Andric         // shouldn't require adding them. Fixing this means pulling Feature64Bit
337*0b57cec5SDimitry Andric         // out of most of the target cpus in the .td file and making it set only
338*0b57cec5SDimitry Andric         // as part of initialization via the TargetTriple.
339*0b57cec5SDimitry Andric         computeFSAdditions(FS, getOptLevel(), getTargetTriple()), *this);
340*0b57cec5SDimitry Andric   }
341*0b57cec5SDimitry Andric   return I.get();
342*0b57cec5SDimitry Andric }
343*0b57cec5SDimitry Andric 
344*0b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
345*0b57cec5SDimitry Andric // Pass Pipeline Configuration
346*0b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
347*0b57cec5SDimitry Andric 
348*0b57cec5SDimitry Andric namespace {
349*0b57cec5SDimitry Andric 
350*0b57cec5SDimitry Andric /// PPC Code Generator Pass Configuration Options.
351*0b57cec5SDimitry Andric class PPCPassConfig : public TargetPassConfig {
352*0b57cec5SDimitry Andric public:
353*0b57cec5SDimitry Andric   PPCPassConfig(PPCTargetMachine &TM, PassManagerBase &PM)
354*0b57cec5SDimitry Andric     : TargetPassConfig(TM, PM) {
355*0b57cec5SDimitry Andric     // At any optimization level above -O0 we use the Machine Scheduler and not
356*0b57cec5SDimitry Andric     // the default Post RA List Scheduler.
357*0b57cec5SDimitry Andric     if (TM.getOptLevel() != CodeGenOpt::None)
358*0b57cec5SDimitry Andric       substitutePass(&PostRASchedulerID, &PostMachineSchedulerID);
359*0b57cec5SDimitry Andric   }
360*0b57cec5SDimitry Andric 
361*0b57cec5SDimitry Andric   PPCTargetMachine &getPPCTargetMachine() const {
362*0b57cec5SDimitry Andric     return getTM<PPCTargetMachine>();
363*0b57cec5SDimitry Andric   }
364*0b57cec5SDimitry Andric 
365*0b57cec5SDimitry Andric   void addIRPasses() override;
366*0b57cec5SDimitry Andric   bool addPreISel() override;
367*0b57cec5SDimitry Andric   bool addILPOpts() override;
368*0b57cec5SDimitry Andric   bool addInstSelector() override;
369*0b57cec5SDimitry Andric   void addMachineSSAOptimization() override;
370*0b57cec5SDimitry Andric   void addPreRegAlloc() override;
371*0b57cec5SDimitry Andric   void addPreSched2() override;
372*0b57cec5SDimitry Andric   void addPreEmitPass() override;
373*0b57cec5SDimitry Andric   ScheduleDAGInstrs *
374*0b57cec5SDimitry Andric   createMachineScheduler(MachineSchedContext *C) const override {
375*0b57cec5SDimitry Andric     return createPPCMachineScheduler(C);
376*0b57cec5SDimitry Andric   }
377*0b57cec5SDimitry Andric   ScheduleDAGInstrs *
378*0b57cec5SDimitry Andric   createPostMachineScheduler(MachineSchedContext *C) const override {
379*0b57cec5SDimitry Andric     return createPPCPostMachineScheduler(C);
380*0b57cec5SDimitry Andric   }
381*0b57cec5SDimitry Andric };
382*0b57cec5SDimitry Andric 
383*0b57cec5SDimitry Andric } // end anonymous namespace
384*0b57cec5SDimitry Andric 
385*0b57cec5SDimitry Andric TargetPassConfig *PPCTargetMachine::createPassConfig(PassManagerBase &PM) {
386*0b57cec5SDimitry Andric   return new PPCPassConfig(*this, PM);
387*0b57cec5SDimitry Andric }
388*0b57cec5SDimitry Andric 
389*0b57cec5SDimitry Andric void PPCPassConfig::addIRPasses() {
390*0b57cec5SDimitry Andric   if (TM->getOptLevel() != CodeGenOpt::None)
391*0b57cec5SDimitry Andric     addPass(createPPCBoolRetToIntPass());
392*0b57cec5SDimitry Andric   addPass(createAtomicExpandPass());
393*0b57cec5SDimitry Andric 
394*0b57cec5SDimitry Andric   // For the BG/Q (or if explicitly requested), add explicit data prefetch
395*0b57cec5SDimitry Andric   // intrinsics.
396*0b57cec5SDimitry Andric   bool UsePrefetching = TM->getTargetTriple().getVendor() == Triple::BGQ &&
397*0b57cec5SDimitry Andric                         getOptLevel() != CodeGenOpt::None;
398*0b57cec5SDimitry Andric   if (EnablePrefetch.getNumOccurrences() > 0)
399*0b57cec5SDimitry Andric     UsePrefetching = EnablePrefetch;
400*0b57cec5SDimitry Andric   if (UsePrefetching)
401*0b57cec5SDimitry Andric     addPass(createLoopDataPrefetchPass());
402*0b57cec5SDimitry Andric 
403*0b57cec5SDimitry Andric   if (TM->getOptLevel() >= CodeGenOpt::Default && EnableGEPOpt) {
404*0b57cec5SDimitry Andric     // Call SeparateConstOffsetFromGEP pass to extract constants within indices
405*0b57cec5SDimitry Andric     // and lower a GEP with multiple indices to either arithmetic operations or
406*0b57cec5SDimitry Andric     // multiple GEPs with single index.
407*0b57cec5SDimitry Andric     addPass(createSeparateConstOffsetFromGEPPass(true));
408*0b57cec5SDimitry Andric     // Call EarlyCSE pass to find and remove subexpressions in the lowered
409*0b57cec5SDimitry Andric     // result.
410*0b57cec5SDimitry Andric     addPass(createEarlyCSEPass());
411*0b57cec5SDimitry Andric     // Do loop invariant code motion in case part of the lowered result is
412*0b57cec5SDimitry Andric     // invariant.
413*0b57cec5SDimitry Andric     addPass(createLICMPass());
414*0b57cec5SDimitry Andric   }
415*0b57cec5SDimitry Andric 
416*0b57cec5SDimitry Andric   TargetPassConfig::addIRPasses();
417*0b57cec5SDimitry Andric }
418*0b57cec5SDimitry Andric 
419*0b57cec5SDimitry Andric bool PPCPassConfig::addPreISel() {
420*0b57cec5SDimitry Andric   if (!DisablePreIncPrep && getOptLevel() != CodeGenOpt::None)
421*0b57cec5SDimitry Andric     addPass(createPPCLoopPreIncPrepPass(getPPCTargetMachine()));
422*0b57cec5SDimitry Andric 
423*0b57cec5SDimitry Andric   if (!DisableCTRLoops && getOptLevel() != CodeGenOpt::None)
424*0b57cec5SDimitry Andric     addPass(createHardwareLoopsPass());
425*0b57cec5SDimitry Andric 
426*0b57cec5SDimitry Andric   return false;
427*0b57cec5SDimitry Andric }
428*0b57cec5SDimitry Andric 
429*0b57cec5SDimitry Andric bool PPCPassConfig::addILPOpts() {
430*0b57cec5SDimitry Andric   addPass(&EarlyIfConverterID);
431*0b57cec5SDimitry Andric 
432*0b57cec5SDimitry Andric   if (EnableMachineCombinerPass)
433*0b57cec5SDimitry Andric     addPass(&MachineCombinerID);
434*0b57cec5SDimitry Andric 
435*0b57cec5SDimitry Andric   return true;
436*0b57cec5SDimitry Andric }
437*0b57cec5SDimitry Andric 
438*0b57cec5SDimitry Andric bool PPCPassConfig::addInstSelector() {
439*0b57cec5SDimitry Andric   // Install an instruction selector.
440*0b57cec5SDimitry Andric   addPass(createPPCISelDag(getPPCTargetMachine(), getOptLevel()));
441*0b57cec5SDimitry Andric 
442*0b57cec5SDimitry Andric #ifndef NDEBUG
443*0b57cec5SDimitry Andric   if (!DisableCTRLoops && getOptLevel() != CodeGenOpt::None)
444*0b57cec5SDimitry Andric     addPass(createPPCCTRLoopsVerify());
445*0b57cec5SDimitry Andric #endif
446*0b57cec5SDimitry Andric 
447*0b57cec5SDimitry Andric   addPass(createPPCVSXCopyPass());
448*0b57cec5SDimitry Andric   return false;
449*0b57cec5SDimitry Andric }
450*0b57cec5SDimitry Andric 
451*0b57cec5SDimitry Andric void PPCPassConfig::addMachineSSAOptimization() {
452*0b57cec5SDimitry Andric   // PPCBranchCoalescingPass need to be done before machine sinking
453*0b57cec5SDimitry Andric   // since it merges empty blocks.
454*0b57cec5SDimitry Andric   if (EnableBranchCoalescing && getOptLevel() != CodeGenOpt::None)
455*0b57cec5SDimitry Andric     addPass(createPPCBranchCoalescingPass());
456*0b57cec5SDimitry Andric   TargetPassConfig::addMachineSSAOptimization();
457*0b57cec5SDimitry Andric   // For little endian, remove where possible the vector swap instructions
458*0b57cec5SDimitry Andric   // introduced at code generation to normalize vector element order.
459*0b57cec5SDimitry Andric   if (TM->getTargetTriple().getArch() == Triple::ppc64le &&
460*0b57cec5SDimitry Andric       !DisableVSXSwapRemoval)
461*0b57cec5SDimitry Andric     addPass(createPPCVSXSwapRemovalPass());
462*0b57cec5SDimitry Andric   // Reduce the number of cr-logical ops.
463*0b57cec5SDimitry Andric   if (ReduceCRLogical && getOptLevel() != CodeGenOpt::None)
464*0b57cec5SDimitry Andric     addPass(createPPCReduceCRLogicalsPass());
465*0b57cec5SDimitry Andric   // Target-specific peephole cleanups performed after instruction
466*0b57cec5SDimitry Andric   // selection.
467*0b57cec5SDimitry Andric   if (!DisableMIPeephole) {
468*0b57cec5SDimitry Andric     addPass(createPPCMIPeepholePass());
469*0b57cec5SDimitry Andric     addPass(&DeadMachineInstructionElimID);
470*0b57cec5SDimitry Andric   }
471*0b57cec5SDimitry Andric }
472*0b57cec5SDimitry Andric 
473*0b57cec5SDimitry Andric void PPCPassConfig::addPreRegAlloc() {
474*0b57cec5SDimitry Andric   if (getOptLevel() != CodeGenOpt::None) {
475*0b57cec5SDimitry Andric     initializePPCVSXFMAMutatePass(*PassRegistry::getPassRegistry());
476*0b57cec5SDimitry Andric     insertPass(VSXFMAMutateEarly ? &RegisterCoalescerID : &MachineSchedulerID,
477*0b57cec5SDimitry Andric                &PPCVSXFMAMutateID);
478*0b57cec5SDimitry Andric   }
479*0b57cec5SDimitry Andric 
480*0b57cec5SDimitry Andric   // FIXME: We probably don't need to run these for -fPIE.
481*0b57cec5SDimitry Andric   if (getPPCTargetMachine().isPositionIndependent()) {
482*0b57cec5SDimitry Andric     // FIXME: LiveVariables should not be necessary here!
483*0b57cec5SDimitry Andric     // PPCTLSDynamicCallPass uses LiveIntervals which previously dependent on
484*0b57cec5SDimitry Andric     // LiveVariables. This (unnecessary) dependency has been removed now,
485*0b57cec5SDimitry Andric     // however a stage-2 clang build fails without LiveVariables computed here.
486*0b57cec5SDimitry Andric     addPass(&LiveVariablesID, false);
487*0b57cec5SDimitry Andric     addPass(createPPCTLSDynamicCallPass());
488*0b57cec5SDimitry Andric   }
489*0b57cec5SDimitry Andric   if (EnableExtraTOCRegDeps)
490*0b57cec5SDimitry Andric     addPass(createPPCTOCRegDepsPass());
491*0b57cec5SDimitry Andric 
492*0b57cec5SDimitry Andric   if (getOptLevel() != CodeGenOpt::None)
493*0b57cec5SDimitry Andric     addPass(&MachinePipelinerID);
494*0b57cec5SDimitry Andric }
495*0b57cec5SDimitry Andric 
496*0b57cec5SDimitry Andric void PPCPassConfig::addPreSched2() {
497*0b57cec5SDimitry Andric   if (getOptLevel() != CodeGenOpt::None) {
498*0b57cec5SDimitry Andric     addPass(&IfConverterID);
499*0b57cec5SDimitry Andric 
500*0b57cec5SDimitry Andric     // This optimization must happen after anything that might do store-to-load
501*0b57cec5SDimitry Andric     // forwarding. Here we're after RA (and, thus, when spills are inserted)
502*0b57cec5SDimitry Andric     // but before post-RA scheduling.
503*0b57cec5SDimitry Andric     if (!DisableQPXLoadSplat)
504*0b57cec5SDimitry Andric       addPass(createPPCQPXLoadSplatPass());
505*0b57cec5SDimitry Andric   }
506*0b57cec5SDimitry Andric }
507*0b57cec5SDimitry Andric 
508*0b57cec5SDimitry Andric void PPCPassConfig::addPreEmitPass() {
509*0b57cec5SDimitry Andric   addPass(createPPCPreEmitPeepholePass());
510*0b57cec5SDimitry Andric   addPass(createPPCExpandISELPass());
511*0b57cec5SDimitry Andric 
512*0b57cec5SDimitry Andric   if (getOptLevel() != CodeGenOpt::None)
513*0b57cec5SDimitry Andric     addPass(createPPCEarlyReturnPass(), false);
514*0b57cec5SDimitry Andric   // Must run branch selection immediately preceding the asm printer.
515*0b57cec5SDimitry Andric   addPass(createPPCBranchSelectionPass(), false);
516*0b57cec5SDimitry Andric }
517*0b57cec5SDimitry Andric 
518*0b57cec5SDimitry Andric TargetTransformInfo
519*0b57cec5SDimitry Andric PPCTargetMachine::getTargetTransformInfo(const Function &F) {
520*0b57cec5SDimitry Andric   return TargetTransformInfo(PPCTTIImpl(this, F));
521*0b57cec5SDimitry Andric }
522*0b57cec5SDimitry Andric 
523*0b57cec5SDimitry Andric static MachineSchedRegistry
524*0b57cec5SDimitry Andric PPCPreRASchedRegistry("ppc-prera",
525*0b57cec5SDimitry Andric                       "Run PowerPC PreRA specific scheduler",
526*0b57cec5SDimitry Andric                       createPPCMachineScheduler);
527*0b57cec5SDimitry Andric 
528*0b57cec5SDimitry Andric static MachineSchedRegistry
529*0b57cec5SDimitry Andric PPCPostRASchedRegistry("ppc-postra",
530*0b57cec5SDimitry Andric                        "Run PowerPC PostRA specific scheduler",
531*0b57cec5SDimitry Andric                        createPPCPostMachineScheduler);
532