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