1//===-- PowerPCSubtarget.cpp - PPC Subtarget Information ------------------===// 2// 3// The LLVM Compiler Infrastructure 4// 5// This file is distributed under the University of Illinois Open Source 6// License. See LICENSE.TXT for details. 7// 8//===----------------------------------------------------------------------===// 9// 10// This file implements the PPC specific subclass of TargetSubtargetInfo. 11// 12//===----------------------------------------------------------------------===// 13 14#include "PPCSubtarget.h" 15#include "PPC.h" 16#include "PPCRegisterInfo.h" 17#include "llvm/CodeGen/MachineFunction.h" 18#include "llvm/CodeGen/MachineScheduler.h" 19#include "llvm/IR/Attributes.h" 20#include "llvm/IR/GlobalValue.h" 21#include "llvm/IR/Function.h" 22#include "llvm/Support/Host.h" 23#include "llvm/Support/TargetRegistry.h" 24#include "llvm/Target/TargetMachine.h" 25#include <cstdlib> 26 27#define GET_SUBTARGETINFO_TARGET_DESC 28#define GET_SUBTARGETINFO_CTOR 29#include "PPCGenSubtargetInfo.inc" 30 31using namespace llvm; 32 33PPCSubtarget::PPCSubtarget(const std::string &TT, const std::string &CPU, 34 const std::string &FS, bool is64Bit) 35 : PPCGenSubtargetInfo(TT, CPU, FS) 36 , IsPPC64(is64Bit) 37 , TargetTriple(TT) { 38 initializeEnvironment(); 39 resetSubtargetFeatures(CPU, FS); 40} 41 42/// SetJITMode - This is called to inform the subtarget info that we are 43/// producing code for the JIT. 44void PPCSubtarget::SetJITMode() { 45 // JIT mode doesn't want lazy resolver stubs, it knows exactly where 46 // everything is. This matters for PPC64, which codegens in PIC mode without 47 // stubs. 48 HasLazyResolverStubs = false; 49 50 // Calls to external functions need to use indirect calls 51 IsJITCodeModel = true; 52} 53 54void PPCSubtarget::resetSubtargetFeatures(const MachineFunction *MF) { 55 AttributeSet FnAttrs = MF->getFunction()->getAttributes(); 56 Attribute CPUAttr = FnAttrs.getAttribute(AttributeSet::FunctionIndex, 57 "target-cpu"); 58 Attribute FSAttr = FnAttrs.getAttribute(AttributeSet::FunctionIndex, 59 "target-features"); 60 std::string CPU = 61 !CPUAttr.hasAttribute(Attribute::None) ? CPUAttr.getValueAsString() : ""; 62 std::string FS = 63 !FSAttr.hasAttribute(Attribute::None) ? FSAttr.getValueAsString() : ""; 64 if (!FS.empty()) { 65 initializeEnvironment(); 66 resetSubtargetFeatures(CPU, FS); 67 } 68} 69 70void PPCSubtarget::initializeEnvironment() { 71 StackAlignment = 16; 72 DarwinDirective = PPC::DIR_NONE; 73 HasMFOCRF = false; 74 Has64BitSupport = false; 75 Use64BitRegs = false; 76 HasAltivec = false; 77 HasQPX = false; 78 HasFCPSGN = false; 79 HasFSQRT = false; 80 HasFRE = false; 81 HasFRES = false; 82 HasFRSQRTE = false; 83 HasFRSQRTES = false; 84 HasRecipPrec = false; 85 HasSTFIWX = false; 86 HasLFIWAX = false; 87 HasFPRND = false; 88 HasFPCVT = false; 89 HasISEL = false; 90 HasPOPCNTD = false; 91 HasLDBRX = false; 92 IsBookE = false; 93 DeprecatedMFTB = false; 94 DeprecatedDST = false; 95 HasLazyResolverStubs = false; 96 IsJITCodeModel = false; 97} 98 99void PPCSubtarget::resetSubtargetFeatures(StringRef CPU, StringRef FS) { 100 // Determine default and user specified characteristics 101 std::string CPUName = CPU; 102 if (CPUName.empty()) 103 CPUName = "generic"; 104#if (defined(__APPLE__) || defined(__linux__)) && \ 105 (defined(__ppc__) || defined(__powerpc__)) 106 if (CPUName == "generic") 107 CPUName = sys::getHostCPUName(); 108#endif 109 110 // Initialize scheduling itinerary for the specified CPU. 111 InstrItins = getInstrItineraryForCPU(CPUName); 112 113 // Make sure 64-bit features are available when CPUname is generic 114 std::string FullFS = FS; 115 116 // If we are generating code for ppc64, verify that options make sense. 117 if (IsPPC64) { 118 Has64BitSupport = true; 119 // Silently force 64-bit register use on ppc64. 120 Use64BitRegs = true; 121 if (!FullFS.empty()) 122 FullFS = "+64bit," + FullFS; 123 else 124 FullFS = "+64bit"; 125 } 126 127 // Parse features string. 128 ParseSubtargetFeatures(CPUName, FullFS); 129 130 // If the user requested use of 64-bit regs, but the cpu selected doesn't 131 // support it, ignore. 132 if (use64BitRegs() && !has64BitSupport()) 133 Use64BitRegs = false; 134 135 // Set up darwin-specific properties. 136 if (isDarwin()) 137 HasLazyResolverStubs = true; 138 139 // QPX requires a 32-byte aligned stack. Note that we need to do this if 140 // we're compiling for a BG/Q system regardless of whether or not QPX 141 // is enabled because external functions will assume this alignment. 142 if (hasQPX() || isBGQ()) 143 StackAlignment = 32; 144 145 // Determine endianness. 146 IsLittleEndian = (TargetTriple.getArch() == Triple::ppc64le); 147} 148 149/// hasLazyResolverStub - Return true if accesses to the specified global have 150/// to go through a dyld lazy resolution stub. This means that an extra load 151/// is required to get the address of the global. 152bool PPCSubtarget::hasLazyResolverStub(const GlobalValue *GV, 153 const TargetMachine &TM) const { 154 // We never have stubs if HasLazyResolverStubs=false or if in static mode. 155 if (!HasLazyResolverStubs || TM.getRelocationModel() == Reloc::Static) 156 return false; 157 // If symbol visibility is hidden, the extra load is not needed if 158 // the symbol is definitely defined in the current translation unit. 159 bool isDecl = GV->isDeclaration() && !GV->isMaterializable(); 160 if (GV->hasHiddenVisibility() && !isDecl && !GV->hasCommonLinkage()) 161 return false; 162 return GV->hasWeakLinkage() || GV->hasLinkOnceLinkage() || 163 GV->hasCommonLinkage() || isDecl; 164} 165 166bool PPCSubtarget::enablePostRAScheduler( 167 CodeGenOpt::Level OptLevel, 168 TargetSubtargetInfo::AntiDepBreakMode& Mode, 169 RegClassVector& CriticalPathRCs) const { 170 Mode = TargetSubtargetInfo::ANTIDEP_ALL; 171 172 CriticalPathRCs.clear(); 173 174 if (isPPC64()) 175 CriticalPathRCs.push_back(&PPC::G8RCRegClass); 176 else 177 CriticalPathRCs.push_back(&PPC::GPRCRegClass); 178 179 return OptLevel >= CodeGenOpt::Default; 180} 181 182// Embedded cores need aggressive scheduling. 183static bool needsAggressiveScheduling(unsigned Directive) { 184 switch (Directive) { 185 default: return false; 186 case PPC::DIR_440: 187 case PPC::DIR_A2: 188 case PPC::DIR_E500mc: 189 case PPC::DIR_E5500: 190 return true; 191 } 192} 193 194bool PPCSubtarget::enableMachineScheduler() const { 195 // Enable MI scheduling for the embedded cores. 196 // FIXME: Enable this for all cores (some additional modeling 197 // may be necessary). 198 return needsAggressiveScheduling(DarwinDirective); 199} 200 201void PPCSubtarget::overrideSchedPolicy(MachineSchedPolicy &Policy, 202 MachineInstr *begin, 203 MachineInstr *end, 204 unsigned NumRegionInstrs) const { 205 if (needsAggressiveScheduling(DarwinDirective)) { 206 Policy.OnlyTopDown = false; 207 Policy.OnlyBottomUp = false; 208 } 209 210 // Spilling is generally expensive on all PPC cores, so always enable 211 // register-pressure tracking. 212 Policy.ShouldTrackPressure = true; 213} 214 215bool PPCSubtarget::useAA() const { 216 // Use AA during code generation for the embedded cores. 217 return needsAggressiveScheduling(DarwinDirective); 218} 219 220