LLVM  7.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"
26 #include "llvm/IR/GlobalValue.h"
27 
28 using namespace llvm;
29 
30 #define DEBUG_TYPE "aarch64-subtarget"
31 
32 #define GET_SUBTARGETINFO_CTOR
33 #define GET_SUBTARGETINFO_TARGET_DESC
34 #include "AArch64GenSubtargetInfo.inc"
35 
36 static cl::opt<bool>
37 EnableEarlyIfConvert("aarch64-early-ifcvt", cl::desc("Enable the early if "
38  "converter pass"), cl::init(true), cl::Hidden);
39 
40 // If OS supports TBI, use this flag to enable it.
41 static cl::opt<bool>
42 UseAddressTopByteIgnored("aarch64-use-tbi", cl::desc("Assume that top byte of "
43  "an address is ignored"), cl::init(false), cl::Hidden);
44 
45 static cl::opt<bool>
46  UseNonLazyBind("aarch64-enable-nonlazybind",
47  cl::desc("Call nonlazybind functions via direct GOT load"),
48  cl::init(false), cl::Hidden);
49 
51 AArch64Subtarget::initializeSubtargetDependencies(StringRef FS,
52  StringRef CPUString) {
53  // Determine default and user-specified characteristics
54 
55  if (CPUString.empty())
56  CPUString = "generic";
57 
58  ParseSubtargetFeatures(CPUString, FS);
59  initializeProperties();
60 
61  return *this;
62 }
63 
64 void AArch64Subtarget::initializeProperties() {
65  // Initialize CPU specific properties. We should add a tablegen feature for
66  // this in the future so we can specify it together with the subtarget
67  // features.
68  switch (ARMProcFamily) {
69  case Cyclone:
70  CacheLineSize = 64;
71  PrefetchDistance = 280;
72  MinPrefetchStride = 2048;
74  break;
75  case CortexA57:
78  break;
79  case ExynosM1:
81  MaxJumpTableSize = 8;
84  break;
85  case ExynosM3:
87  MaxJumpTableSize = 20;
90  break;
91  case Falkor:
93  // FIXME: remove this to enable 64-bit SLP if performance looks good.
95  CacheLineSize = 128;
96  PrefetchDistance = 820;
97  MinPrefetchStride = 2048;
99  break;
100  case Saphira:
102  // FIXME: remove this to enable 64-bit SLP if performance looks good.
104  break;
105  case Kryo:
108  CacheLineSize = 128;
109  PrefetchDistance = 740;
110  MinPrefetchStride = 1024;
112  // FIXME: remove this to enable 64-bit SLP if performance looks good.
114  break;
115  case ThunderX2T99:
116  CacheLineSize = 64;
118  PrefLoopAlignment = 2;
120  PrefetchDistance = 128;
121  MinPrefetchStride = 1024;
123  // FIXME: remove this to enable 64-bit SLP if performance looks good.
125  break;
126  case ThunderX:
127  case ThunderXT88:
128  case ThunderXT81:
129  case ThunderXT83:
130  CacheLineSize = 128;
132  PrefLoopAlignment = 2;
133  // FIXME: remove this to enable 64-bit SLP if performance looks good.
135  break;
136  case CortexA35: break;
137  case CortexA53:
139  break;
140  case CortexA55: break;
141  case CortexA72:
142  case CortexA73:
143  case CortexA75:
145  break;
146  case Others: break;
147  }
148 }
149 
150 AArch64Subtarget::AArch64Subtarget(const Triple &TT, const std::string &CPU,
151  const std::string &FS,
152  const TargetMachine &TM, bool LittleEndian)
153  : AArch64GenSubtargetInfo(TT, CPU, FS),
154  ReserveX18(TT.isOSDarwin() || TT.isOSWindows()), IsLittle(LittleEndian),
156  InstrInfo(initializeSubtargetDependencies(FS, CPU)), TSInfo(),
157  TLInfo(TM, *this) {
159  Legalizer.reset(new AArch64LegalizerInfo(*this));
160 
161  auto *RBI = new AArch64RegisterBankInfo(*getRegisterInfo());
162 
163  // FIXME: At this point, we can't rely on Subtarget having RBI.
164  // It's awkward to mix passing RBI and the Subtarget; should we pass
165  // TII/TRI as well?
167  *static_cast<const AArch64TargetMachine *>(&TM), *this, *RBI));
168 
169  RegBankInfo.reset(RBI);
170 }
171 
173  return CallLoweringInfo.get();
174 }
175 
177  return InstSelector.get();
178 }
179 
181  return Legalizer.get();
182 }
183 
185  return RegBankInfo.get();
186 }
187 
188 /// Find the target operand flags that describe how a global value should be
189 /// referenced for the current subtarget.
190 unsigned char
192  const TargetMachine &TM) const {
193  // MachO large model always goes via a GOT, simply to get a single 8-byte
194  // absolute relocation on all global addresses.
196  return AArch64II::MO_GOT;
197 
198  unsigned Flags = GV->hasDLLImportStorageClass() ? AArch64II::MO_DLLIMPORT
200 
201  if (!TM.shouldAssumeDSOLocal(*GV->getParent(), GV))
202  return AArch64II::MO_GOT | Flags;
203 
204  // The small code model's direct accesses use ADRP, which cannot
205  // necessarily produce the value 0 (if the code is above 4GB).
207  return AArch64II::MO_GOT | Flags;
208 
209  return Flags;
210 }
211 
213  const GlobalValue *GV, const TargetMachine &TM) const {
214  // MachO large model always goes via a GOT, because we don't have the
215  // relocations available to do anything else..
216  if (TM.getCodeModel() == CodeModel::Large && isTargetMachO() &&
217  !GV->hasInternalLinkage())
218  return AArch64II::MO_GOT;
219 
220  // NonLazyBind goes via GOT unless we know it's available locally.
221  auto *F = dyn_cast<Function>(GV);
222  if (UseNonLazyBind && F && F->hasFnAttribute(Attribute::NonLazyBind) &&
223  !TM.shouldAssumeDSOLocal(*GV->getParent(), GV))
224  return AArch64II::MO_GOT;
225 
226  return AArch64II::MO_NO_FLAG;
227 }
228 
230  unsigned NumRegionInstrs) const {
231  // LNT run (at least on Cyclone) showed reasonably significant gains for
232  // bi-directional scheduling. 253.perlbmk.
233  Policy.OnlyTopDown = false;
234  Policy.OnlyBottomUp = false;
235  // Enabling or Disabling the latency heuristic is a close call: It seems to
236  // help nearly no benchmark on out-of-order architectures, on the other hand
237  // it regresses register pressure on a few benchmarking.
239 }
240 
242  return EnableEarlyIfConvert;
243 }
244 
247  return false;
248 
249  if (TargetTriple.isiOS()) {
250  unsigned Major, Minor, Micro;
251  TargetTriple.getiOSVersion(Major, Minor, Micro);
252  return Major >= 8;
253  }
254 
255  return false;
256 }
257 
258 std::unique_ptr<PBQPRAConstraint>
260  return balanceFPOps() ? llvm::make_unique<A57ChainingConstraint>() : nullptr;
261 }
262 
264  // We usually compute max call frame size after ISel. Do the computation now
265  // if the .mir file didn't specify it. Note that this will probably give you
266  // bogus values after PEI has eliminated the callframe setup/destroy pseudo
267  // instructions, specify explicitely if you need it to be correct.
268  MachineFrameInfo &MFI = MF.getFrameInfo();
269  if (!MFI.isMaxCallFrameSizeComputed())
270  MFI.computeMaxCallFrameSize(MF);
271 }
void getiOSVersion(unsigned &Major, unsigned &Minor, unsigned &Micro) const
getiOSVersion - Parse the version number as with getOSVersion.
Definition: Triple.cpp:1067
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
bool hasDLLImportStorageClass() const
Definition: GlobalValue.h:261
F(f)
bool hasExternalWeakLinkage() const
Definition: GlobalValue.h:436
const CallLowering * getCallLowering() const override
void mirFileLoaded(MachineFunction &MF) 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.
The MachineFrameInfo class represents an abstract stack frame until prolog/epilog code is inserted...
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
MachineFrameInfo & getFrameInfo()
getFrameInfo - Return the frame info object for the current function.
bool useSmallAddressing() const
bool hasInternalLinkage() const
Definition: GlobalValue.h:433
void computeMaxCallFrameSize(const MachineFunction &MF)
Computes the maximum size of a callframe and the AdjustsStack property.
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
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)
MO_DLLIMPORT - On a symbol operand, this represents that the reference to the symbol is for an import...
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.
Module * getParent()
Get the module that this global value is contained inside of...
Definition: GlobalValue.h:565
const RegisterBankInfo * getRegBankInfo() const override
bool isMaxCallFrameSizeComputed() const
Primary interface to the complete machine description for the target machine.
Definition: TargetMachine.h:59
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)