LLVM  6.0.0svn
AArch64Subtarget.cpp
Go to the documentation of this file.
1 //===-- AArch64Subtarget.cpp - AArch64 Subtarget Information ----*- C++ -*-===//
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 AArch64 specific subclass of TargetSubtarget.
11 //
12 //===----------------------------------------------------------------------===//
13 
14 #include "AArch64Subtarget.h"
15 
16 #include "AArch64.h"
17 #include "AArch64InstrInfo.h"
18 #include "AArch64PBQPRegAlloc.h"
19 #include "AArch64TargetMachine.h"
20 
21 #include "AArch64CallLowering.h"
22 #include "AArch64LegalizerInfo.h"
29 #include "llvm/IR/GlobalValue.h"
31 
32 using namespace llvm;
33 
34 #define DEBUG_TYPE "aarch64-subtarget"
35 
36 #define GET_SUBTARGETINFO_CTOR
37 #define GET_SUBTARGETINFO_TARGET_DESC
38 #include "AArch64GenSubtargetInfo.inc"
39 
40 static cl::opt<bool>
41 EnableEarlyIfConvert("aarch64-early-ifcvt", cl::desc("Enable the early if "
42  "converter pass"), cl::init(true), cl::Hidden);
43 
44 // If OS supports TBI, use this flag to enable it.
45 static cl::opt<bool>
46 UseAddressTopByteIgnored("aarch64-use-tbi", cl::desc("Assume that top byte of "
47  "an address is ignored"), cl::init(false), cl::Hidden);
48 
49 static cl::opt<bool>
50  UseNonLazyBind("aarch64-enable-nonlazybind",
51  cl::desc("Call nonlazybind functions via direct GOT load"),
52  cl::init(false), cl::Hidden);
53 
55 AArch64Subtarget::initializeSubtargetDependencies(StringRef FS,
56  StringRef CPUString) {
57  // Determine default and user-specified characteristics
58 
59  if (CPUString.empty())
60  CPUString = "generic";
61 
62  ParseSubtargetFeatures(CPUString, FS);
63  initializeProperties();
64 
65  return *this;
66 }
67 
68 void AArch64Subtarget::initializeProperties() {
69  // Initialize CPU specific properties. We should add a tablegen feature for
70  // this in the future so we can specify it together with the subtarget
71  // features.
72  switch (ARMProcFamily) {
73  case Cyclone:
74  CacheLineSize = 64;
75  PrefetchDistance = 280;
76  MinPrefetchStride = 2048;
78  break;
79  case CortexA57:
82  break;
83  case ExynosM1:
85  MaxJumpTableSize = 8;
88  break;
89  case Falkor:
91  // FIXME: remove this to enable 64-bit SLP if performance looks good.
93  CacheLineSize = 128;
94  PrefetchDistance = 820;
95  MinPrefetchStride = 2048;
97  break;
98  case Saphira:
100  // FIXME: remove this to enable 64-bit SLP if performance looks good.
102  break;
103  case Kryo:
106  CacheLineSize = 128;
107  PrefetchDistance = 740;
108  MinPrefetchStride = 1024;
110  // FIXME: remove this to enable 64-bit SLP if performance looks good.
112  break;
113  case ThunderX2T99:
114  CacheLineSize = 64;
116  PrefLoopAlignment = 2;
118  PrefetchDistance = 128;
119  MinPrefetchStride = 1024;
121  // FIXME: remove this to enable 64-bit SLP if performance looks good.
123  break;
124  case ThunderX:
125  case ThunderXT88:
126  case ThunderXT81:
127  case ThunderXT83:
128  CacheLineSize = 128;
130  PrefLoopAlignment = 2;
131  // FIXME: remove this to enable 64-bit SLP if performance looks good.
133  break;
134  case CortexA35: break;
135  case CortexA53:
137  break;
138  case CortexA55: break;
139  case CortexA72:
140  case CortexA73:
141  case CortexA75:
143  break;
144  case Others: break;
145  }
146 }
147 
148 AArch64Subtarget::AArch64Subtarget(const Triple &TT, const std::string &CPU,
149  const std::string &FS,
150  const TargetMachine &TM, bool LittleEndian)
151  : AArch64GenSubtargetInfo(TT, CPU, FS),
152  ReserveX18(TT.isOSDarwin() || TT.isOSWindows()), IsLittle(LittleEndian),
154  InstrInfo(initializeSubtargetDependencies(FS, CPU)), TSInfo(),
155  TLInfo(TM, *this) {
157  Legalizer.reset(new AArch64LegalizerInfo());
158 
159  auto *RBI = new AArch64RegisterBankInfo(*getRegisterInfo());
160 
161  // FIXME: At this point, we can't rely on Subtarget having RBI.
162  // It's awkward to mix passing RBI and the Subtarget; should we pass
163  // TII/TRI as well?
165  *static_cast<const AArch64TargetMachine *>(&TM), *this, *RBI));
166 
167  RegBankInfo.reset(RBI);
168 }
169 
171  return CallLoweringInfo.get();
172 }
173 
175  return InstSelector.get();
176 }
177 
179  return Legalizer.get();
180 }
181 
183  return RegBankInfo.get();
184 }
185 
186 /// Find the target operand flags that describe how a global value should be
187 /// referenced for the current subtarget.
188 unsigned char
190  const TargetMachine &TM) const {
191  // MachO large model always goes via a GOT, simply to get a single 8-byte
192  // absolute relocation on all global addresses.
194  return AArch64II::MO_GOT;
195 
196  if (!TM.shouldAssumeDSOLocal(*GV->getParent(), GV))
197  return AArch64II::MO_GOT;
198 
199  // The small code model's direct accesses use ADRP, which cannot
200  // necessarily produce the value 0 (if the code is above 4GB).
202  return AArch64II::MO_GOT;
203 
204  return AArch64II::MO_NO_FLAG;
205 }
206 
208  const GlobalValue *GV, const TargetMachine &TM) const {
209  // MachO large model always goes via a GOT, because we don't have the
210  // relocations available to do anything else..
211  if (TM.getCodeModel() == CodeModel::Large && isTargetMachO() &&
212  !GV->hasInternalLinkage())
213  return AArch64II::MO_GOT;
214 
215  // NonLazyBind goes via GOT unless we know it's available locally.
216  auto *F = dyn_cast<Function>(GV);
217  if (UseNonLazyBind && F && F->hasFnAttribute(Attribute::NonLazyBind) &&
218  !TM.shouldAssumeDSOLocal(*GV->getParent(), GV))
219  return AArch64II::MO_GOT;
220 
221  return AArch64II::MO_NO_FLAG;
222 }
223 
224 /// This function returns the name of a function which has an interface
225 /// like the non-standard bzero function, if such a function exists on
226 /// the current subtarget and it is considered prefereable over
227 /// memset with zero passed as the second argument. Otherwise it
228 /// returns null.
229 const char *AArch64Subtarget::getBZeroEntry() const {
230  // Prefer bzero on Darwin only.
231  if(isTargetDarwin())
232  return "bzero";
233 
234  return nullptr;
235 }
236 
238  unsigned NumRegionInstrs) const {
239  // LNT run (at least on Cyclone) showed reasonably significant gains for
240  // bi-directional scheduling. 253.perlbmk.
241  Policy.OnlyTopDown = false;
242  Policy.OnlyBottomUp = false;
243  // Enabling or Disabling the latency heuristic is a close call: It seems to
244  // help nearly no benchmark on out-of-order architectures, on the other hand
245  // it regresses register pressure on a few benchmarking.
247 }
248 
250  return EnableEarlyIfConvert;
251 }
252 
255  return false;
256 
257  if (TargetTriple.isiOS()) {
258  unsigned Major, Minor, Micro;
259  TargetTriple.getiOSVersion(Major, Minor, Micro);
260  return Major >= 8;
261  }
262 
263  return false;
264 }
265 
266 std::unique_ptr<PBQPRAConstraint>
268  return balanceFPOps() ? llvm::make_unique<A57ChainingConstraint>() : nullptr;
269 }
void getiOSVersion(unsigned &Major, unsigned &Minor, unsigned &Micro) const
getiOSVersion - Parse the version number as with getOSVersion.
Definition: Triple.cpp:1065
Compute iterated dominance frontiers using a linear time algorithm.
Definition: AllocatorList.h:24
unsigned char ClassifyGlobalReference(const GlobalValue *GV, const TargetMachine &TM) const
ClassifyGlobalReference - Find the target operand flags that describe how a global value should be re...
const InstructionSelector * getInstructionSelector() const override
This class provides the information for the target register banks.
AArch64SelectionDAGInfo TSInfo
F(f)
bool hasExternalWeakLinkage() const
Definition: GlobalValue.h:428
const CallLowering * getCallLowering() const override
void overrideSchedPolicy(MachineSchedPolicy &Policy, unsigned NumRegionInstrs) const override
This file declares the targeting of the RegisterBankInfo class for AArch64.
Holds all the information related to register banks.
static cl::opt< bool > EnableEarlyIfConvert("aarch64-early-ifcvt", cl::desc("Enable the early if " "converter pass"), cl::init(true), cl::Hidden)
std::unique_ptr< InstructionSelector > InstSelector
MO_GOT - This flag indicates that a symbol operand represents the address of the GOT entry for the sy...
const AArch64RegisterInfo * getRegisterInfo() const override
This file declares the targeting of the Machinelegalizer class for AArch64.
LLVM_NODISCARD LLVM_ATTRIBUTE_ALWAYS_INLINE bool empty() const
empty - Check if the string is empty.
Definition: StringRef.h:133
bool isiOS() const
Is this an iOS triple.
Definition: Triple.h:451
bool supportsAddressTopByteIgnored() const
CPU has TBI (top byte of addresses is ignored during HW address translation) and OS enables it...
bool enableEarlyIfConversion() const override
const AArch64TargetLowering * getTargetLowering() const override
initializer< Ty > init(const Ty &Val)
Definition: CommandLine.h:406
bool shouldAssumeDSOLocal(const Module &M, const GlobalValue *GV) const
bool useSmallAddressing() const
bool hasInternalLinkage() const
Definition: GlobalValue.h:425
std::unique_ptr< CallLowering > CallLoweringInfo
GlobalISel related APIs.
Triple - Helper class for working with autoconf configuration names.
Definition: Triple.h:44
AArch64InstrInfo InstrInfo
void ParseSubtargetFeatures(StringRef CPU, StringRef FS)
ParseSubtargetFeatures - Parses features string setting specified subtarget options.
CodeModel::Model getCodeModel() const
Returns the code model.
std::unique_ptr< RegisterBankInfo > RegBankInfo
const char * getBZeroEntry() const
This function returns the name of a function which has an interface like the non-standard bzero funct...
Provides the logic to select generic machine instructions.
Define a generic scheduling policy for targets that don&#39;t provide their own MachineSchedStrategy.
This class provides the information for the target register banks.
std::unique_ptr< PBQPRAConstraint > getCustomPBQPConstraints() const override
AArch64Subtarget(const Triple &TT, const std::string &CPU, const std::string &FS, const TargetMachine &TM, bool LittleEndian)
This constructor initializes the data members to match that of the specified triple.
const LegalizerInfo * getLegalizerInfo() const override
static cl::opt< bool > UseNonLazyBind("aarch64-enable-nonlazybind", cl::desc("Call nonlazybind functions via direct GOT load"), cl::init(false), cl::Hidden)
AArch64FrameLowering FrameLowering
InstructionSelector * createAArch64InstructionSelector(const AArch64TargetMachine &, AArch64Subtarget &, AArch64RegisterBankInfo &)
LLVM_NODISCARD std::enable_if<!is_simple_type< Y >::value, typename cast_retty< X, const Y >::ret_type >::type dyn_cast(const Y &Val)
Definition: Casting.h:323
This file describes how to lower LLVM calls to machine code calls.
Triple TargetTriple
TargetTriple - What processor and OS we&#39;re targeting.
ARMProcFamilyEnum ARMProcFamily
ARMProcFamily - ARM processor family: Cortex-A53, Cortex-A57, and others.
This file declares the IRTranslator pass.
Module * getParent()
Get the module that this global value is contained inside of...
Definition: GlobalValue.h:556
const RegisterBankInfo * getRegBankInfo() const override
Primary interface to the complete machine description for the target machine.
Definition: TargetMachine.h:57
StringRef - Represent a constant reference to a string, i.e.
Definition: StringRef.h:49
AArch64TargetLowering TLInfo
unsigned char classifyGlobalFunctionReference(const GlobalValue *GV, const TargetMachine &TM) const
static cl::opt< bool > UseAddressTopByteIgnored("aarch64-use-tbi", cl::desc("Assume that top byte of " "an address is ignored"), cl::init(false), cl::Hidden)