1234353Sdim//===-- PowerPCSubtarget.cpp - PPC Subtarget Information ------------------===// 2193323Sed// 3193323Sed// The LLVM Compiler Infrastructure 4193323Sed// 5193323Sed// This file is distributed under the University of Illinois Open Source 6193323Sed// License. See LICENSE.TXT for details. 7193323Sed// 8193323Sed//===----------------------------------------------------------------------===// 9193323Sed// 10224145Sdim// This file implements the PPC specific subclass of TargetSubtargetInfo. 11193323Sed// 12193323Sed//===----------------------------------------------------------------------===// 13193323Sed 14193323Sed#include "PPCSubtarget.h" 15249423Sdim#include "PPC.h" 16234353Sdim#include "PPCRegisterInfo.h" 17263508Sdim#include "llvm/CodeGen/MachineFunction.h" 18263508Sdim#include "llvm/CodeGen/MachineScheduler.h" 19263508Sdim#include "llvm/IR/Attributes.h" 20249423Sdim#include "llvm/IR/GlobalValue.h" 21263508Sdim#include "llvm/IR/Function.h" 22239462Sdim#include "llvm/Support/Host.h" 23226633Sdim#include "llvm/Support/TargetRegistry.h" 24249423Sdim#include "llvm/Target/TargetMachine.h" 25193323Sed#include <cstdlib> 26224145Sdim 27224145Sdim#define GET_SUBTARGETINFO_TARGET_DESC 28224145Sdim#define GET_SUBTARGETINFO_CTOR 29224145Sdim#include "PPCGenSubtargetInfo.inc" 30224145Sdim 31193323Sedusing namespace llvm; 32193323Sed 33224145SdimPPCSubtarget::PPCSubtarget(const std::string &TT, const std::string &CPU, 34224145Sdim const std::string &FS, bool is64Bit) 35224145Sdim : PPCGenSubtargetInfo(TT, CPU, FS) 36193323Sed , IsPPC64(is64Bit) 37221345Sdim , TargetTriple(TT) { 38263508Sdim initializeEnvironment(); 39263508Sdim resetSubtargetFeatures(CPU, FS); 40263508Sdim} 41193323Sed 42263508Sdim/// SetJITMode - This is called to inform the subtarget info that we are 43263508Sdim/// producing code for the JIT. 44263508Sdimvoid PPCSubtarget::SetJITMode() { 45263508Sdim // JIT mode doesn't want lazy resolver stubs, it knows exactly where 46263508Sdim // everything is. This matters for PPC64, which codegens in PIC mode without 47263508Sdim // stubs. 48263508Sdim HasLazyResolverStubs = false; 49263508Sdim 50263508Sdim // Calls to external functions need to use indirect calls 51263508Sdim IsJITCodeModel = true; 52263508Sdim} 53263508Sdim 54263508Sdimvoid PPCSubtarget::resetSubtargetFeatures(const MachineFunction *MF) { 55263508Sdim AttributeSet FnAttrs = MF->getFunction()->getAttributes(); 56263508Sdim Attribute CPUAttr = FnAttrs.getAttribute(AttributeSet::FunctionIndex, 57263508Sdim "target-cpu"); 58263508Sdim Attribute FSAttr = FnAttrs.getAttribute(AttributeSet::FunctionIndex, 59263508Sdim "target-features"); 60263508Sdim std::string CPU = 61263508Sdim !CPUAttr.hasAttribute(Attribute::None) ? CPUAttr.getValueAsString() : ""; 62263508Sdim std::string FS = 63263508Sdim !FSAttr.hasAttribute(Attribute::None) ? FSAttr.getValueAsString() : ""; 64263508Sdim if (!FS.empty()) { 65263508Sdim initializeEnvironment(); 66263508Sdim resetSubtargetFeatures(CPU, FS); 67263508Sdim } 68263508Sdim} 69263508Sdim 70263508Sdimvoid PPCSubtarget::initializeEnvironment() { 71263508Sdim StackAlignment = 16; 72263508Sdim DarwinDirective = PPC::DIR_NONE; 73263508Sdim HasMFOCRF = false; 74263508Sdim Has64BitSupport = false; 75263508Sdim Use64BitRegs = false; 76263508Sdim HasAltivec = false; 77263508Sdim HasQPX = false; 78263508Sdim HasFCPSGN = false; 79263508Sdim HasFSQRT = false; 80263508Sdim HasFRE = false; 81263508Sdim HasFRES = false; 82263508Sdim HasFRSQRTE = false; 83263508Sdim HasFRSQRTES = false; 84263508Sdim HasRecipPrec = false; 85263508Sdim HasSTFIWX = false; 86263508Sdim HasLFIWAX = false; 87263508Sdim HasFPRND = false; 88263508Sdim HasFPCVT = false; 89263508Sdim HasISEL = false; 90263508Sdim HasPOPCNTD = false; 91263508Sdim HasLDBRX = false; 92263508Sdim IsBookE = false; 93263508Sdim DeprecatedMFTB = false; 94263508Sdim DeprecatedDST = false; 95263508Sdim HasLazyResolverStubs = false; 96263508Sdim IsJITCodeModel = false; 97263508Sdim} 98263508Sdim 99263508Sdimvoid PPCSubtarget::resetSubtargetFeatures(StringRef CPU, StringRef FS) { 100193323Sed // Determine default and user specified characteristics 101224145Sdim std::string CPUName = CPU; 102224145Sdim if (CPUName.empty()) 103224145Sdim CPUName = "generic"; 104239462Sdim#if (defined(__APPLE__) || defined(__linux__)) && \ 105239462Sdim (defined(__ppc__) || defined(__powerpc__)) 106224145Sdim if (CPUName == "generic") 107239462Sdim CPUName = sys::getHostCPUName(); 108193323Sed#endif 109193323Sed 110224145Sdim // Initialize scheduling itinerary for the specified CPU. 111224145Sdim InstrItins = getInstrItineraryForCPU(CPUName); 112224145Sdim 113243830Sdim // Make sure 64-bit features are available when CPUname is generic 114243830Sdim std::string FullFS = FS; 115243830Sdim 116193323Sed // If we are generating code for ppc64, verify that options make sense. 117263508Sdim if (IsPPC64) { 118193323Sed Has64BitSupport = true; 119193323Sed // Silently force 64-bit register use on ppc64. 120193323Sed Use64BitRegs = true; 121243830Sdim if (!FullFS.empty()) 122243830Sdim FullFS = "+64bit," + FullFS; 123243830Sdim else 124243830Sdim FullFS = "+64bit"; 125193323Sed } 126243830Sdim 127243830Sdim // Parse features string. 128243830Sdim ParseSubtargetFeatures(CPUName, FullFS); 129243830Sdim 130193323Sed // If the user requested use of 64-bit regs, but the cpu selected doesn't 131193323Sed // support it, ignore. 132193323Sed if (use64BitRegs() && !has64BitSupport()) 133193323Sed Use64BitRegs = false; 134193323Sed 135193323Sed // Set up darwin-specific properties. 136198090Srdivacky if (isDarwin()) 137193323Sed HasLazyResolverStubs = true; 138249423Sdim 139249423Sdim // QPX requires a 32-byte aligned stack. Note that we need to do this if 140249423Sdim // we're compiling for a BG/Q system regardless of whether or not QPX 141249423Sdim // is enabled because external functions will assume this alignment. 142249423Sdim if (hasQPX() || isBGQ()) 143249423Sdim StackAlignment = 32; 144193323Sed 145263508Sdim // Determine endianness. 146263508Sdim IsLittleEndian = (TargetTriple.getArch() == Triple::ppc64le); 147193323Sed} 148193323Sed 149193323Sed/// hasLazyResolverStub - Return true if accesses to the specified global have 150193323Sed/// to go through a dyld lazy resolution stub. This means that an extra load 151193323Sed/// is required to get the address of the global. 152198090Srdivackybool PPCSubtarget::hasLazyResolverStub(const GlobalValue *GV, 153198090Srdivacky const TargetMachine &TM) const { 154218893Sdim // We never have stubs if HasLazyResolverStubs=false or if in static mode. 155193323Sed if (!HasLazyResolverStubs || TM.getRelocationModel() == Reloc::Static) 156193323Sed return false; 157193323Sed // If symbol visibility is hidden, the extra load is not needed if 158193323Sed // the symbol is definitely defined in the current translation unit. 159203954Srdivacky bool isDecl = GV->isDeclaration() && !GV->isMaterializable(); 160193323Sed if (GV->hasHiddenVisibility() && !isDecl && !GV->hasCommonLinkage()) 161193323Sed return false; 162193323Sed return GV->hasWeakLinkage() || GV->hasLinkOnceLinkage() || 163193323Sed GV->hasCommonLinkage() || isDecl; 164193323Sed} 165234353Sdim 166234353Sdimbool PPCSubtarget::enablePostRAScheduler( 167234353Sdim CodeGenOpt::Level OptLevel, 168234353Sdim TargetSubtargetInfo::AntiDepBreakMode& Mode, 169234353Sdim RegClassVector& CriticalPathRCs) const { 170263508Sdim Mode = TargetSubtargetInfo::ANTIDEP_ALL; 171234353Sdim 172234353Sdim CriticalPathRCs.clear(); 173234353Sdim 174234353Sdim if (isPPC64()) 175234353Sdim CriticalPathRCs.push_back(&PPC::G8RCRegClass); 176234353Sdim else 177234353Sdim CriticalPathRCs.push_back(&PPC::GPRCRegClass); 178239462Sdim 179234353Sdim return OptLevel >= CodeGenOpt::Default; 180234353Sdim} 181234353Sdim 182263508Sdim// Embedded cores need aggressive scheduling. 183263508Sdimstatic bool needsAggressiveScheduling(unsigned Directive) { 184263508Sdim switch (Directive) { 185263508Sdim default: return false; 186263508Sdim case PPC::DIR_440: 187263508Sdim case PPC::DIR_A2: 188263508Sdim case PPC::DIR_E500mc: 189263508Sdim case PPC::DIR_E5500: 190263508Sdim return true; 191263508Sdim } 192263508Sdim} 193263508Sdim 194263508Sdimbool PPCSubtarget::enableMachineScheduler() const { 195263508Sdim // Enable MI scheduling for the embedded cores. 196263508Sdim // FIXME: Enable this for all cores (some additional modeling 197263508Sdim // may be necessary). 198263508Sdim return needsAggressiveScheduling(DarwinDirective); 199263508Sdim} 200263508Sdim 201263508Sdimvoid PPCSubtarget::overrideSchedPolicy(MachineSchedPolicy &Policy, 202263508Sdim MachineInstr *begin, 203263508Sdim MachineInstr *end, 204263508Sdim unsigned NumRegionInstrs) const { 205263508Sdim if (needsAggressiveScheduling(DarwinDirective)) { 206263508Sdim Policy.OnlyTopDown = false; 207263508Sdim Policy.OnlyBottomUp = false; 208263508Sdim } 209263508Sdim 210263508Sdim // Spilling is generally expensive on all PPC cores, so always enable 211263508Sdim // register-pressure tracking. 212263508Sdim Policy.ShouldTrackPressure = true; 213263508Sdim} 214263508Sdim 215263508Sdimbool PPCSubtarget::useAA() const { 216263508Sdim // Use AA during code generation for the embedded cores. 217263508Sdim return needsAggressiveScheduling(DarwinDirective); 218263508Sdim} 219263508Sdim 220