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