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