LLVM  8.0.1
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 "AArch64CallLowering.h"
18 #include "AArch64InstrInfo.h"
19 #include "AArch64LegalizerInfo.h"
20 #include "AArch64PBQPRegAlloc.h"
22 #include "AArch64TargetMachine.h"
26 #include "llvm/IR/GlobalValue.h"
28 
29 using namespace llvm;
30 
31 #define DEBUG_TYPE "aarch64-subtarget"
32 
33 #define GET_SUBTARGETINFO_CTOR
34 #define GET_SUBTARGETINFO_TARGET_DESC
35 #include "AArch64GenSubtargetInfo.inc"
36 
37 static cl::opt<bool>
38 EnableEarlyIfConvert("aarch64-early-ifcvt", cl::desc("Enable the early if "
39  "converter pass"), cl::init(true), cl::Hidden);
40 
41 // If OS supports TBI, use this flag to enable it.
42 static cl::opt<bool>
43 UseAddressTopByteIgnored("aarch64-use-tbi", cl::desc("Assume that top byte of "
44  "an address is ignored"), cl::init(false), cl::Hidden);
45 
46 static cl::opt<bool>
47  UseNonLazyBind("aarch64-enable-nonlazybind",
48  cl::desc("Call nonlazybind functions via direct GOT load"),
49  cl::init(false), cl::Hidden);
50 
52 AArch64Subtarget::initializeSubtargetDependencies(StringRef FS,
53  StringRef CPUString) {
54  // Determine default and user-specified characteristics
55 
56  if (CPUString.empty())
57  CPUString = "generic";
58 
59  ParseSubtargetFeatures(CPUString, FS);
60  initializeProperties();
61 
62  return *this;
63 }
64 
65 void AArch64Subtarget::initializeProperties() {
66  // Initialize CPU specific properties. We should add a tablegen feature for
67  // this in the future so we can specify it together with the subtarget
68  // features.
69  switch (ARMProcFamily) {
70  case Others:
71  break;
72  case CortexA35:
73  break;
74  case CortexA53:
76  break;
77  case CortexA55:
78  break;
79  case CortexA57:
82  break;
83  case CortexA72:
84  case CortexA73:
85  case CortexA75:
87  break;
88  case Cyclone:
89  CacheLineSize = 64;
90  PrefetchDistance = 280;
91  MinPrefetchStride = 2048;
93  break;
94  case ExynosM1:
96  MaxJumpTableSize = 8;
99  break;
100  case ExynosM3:
102  MaxJumpTableSize = 20;
104  PrefLoopAlignment = 4;
105  break;
106  case Falkor:
108  // FIXME: remove this to enable 64-bit SLP if performance looks good.
110  CacheLineSize = 128;
111  PrefetchDistance = 820;
112  MinPrefetchStride = 2048;
114  break;
115  case Kryo:
118  CacheLineSize = 128;
119  PrefetchDistance = 740;
120  MinPrefetchStride = 1024;
122  // FIXME: remove this to enable 64-bit SLP if performance looks good.
124  break;
125  case Saphira:
127  // FIXME: remove this to enable 64-bit SLP if performance looks good.
129  break;
130  case ThunderX2T99:
131  CacheLineSize = 64;
133  PrefLoopAlignment = 2;
135  PrefetchDistance = 128;
136  MinPrefetchStride = 1024;
138  // FIXME: remove this to enable 64-bit SLP if performance looks good.
140  break;
141  case ThunderX:
142  case ThunderXT88:
143  case ThunderXT81:
144  case ThunderXT83:
145  CacheLineSize = 128;
147  PrefLoopAlignment = 2;
148  // FIXME: remove this to enable 64-bit SLP if performance looks good.
150  break;
151  case TSV110:
152  CacheLineSize = 64;
154  PrefLoopAlignment = 2;
155  break;
156  }
157 }
158 
159 AArch64Subtarget::AArch64Subtarget(const Triple &TT, const std::string &CPU,
160  const std::string &FS,
161  const TargetMachine &TM, bool LittleEndian)
162  : AArch64GenSubtargetInfo(TT, CPU, FS),
163  ReserveXRegister(AArch64::GPR64commonRegClass.getNumRegs()),
164  CustomCallSavedXRegs(AArch64::GPR64commonRegClass.getNumRegs()),
165  IsLittle(LittleEndian),
167  InstrInfo(initializeSubtargetDependencies(FS, CPU)), TSInfo(),
168  TLInfo(TM, *this) {
170  ReserveXRegister.set(18);
171 
173  Legalizer.reset(new AArch64LegalizerInfo(*this));
174 
175  auto *RBI = new AArch64RegisterBankInfo(*getRegisterInfo());
176 
177  // FIXME: At this point, we can't rely on Subtarget having RBI.
178  // It's awkward to mix passing RBI and the Subtarget; should we pass
179  // TII/TRI as well?
181  *static_cast<const AArch64TargetMachine *>(&TM), *this, *RBI));
182 
183  RegBankInfo.reset(RBI);
184 }
185 
187  return CallLoweringInfo.get();
188 }
189 
191  return InstSelector.get();
192 }
193 
195  return Legalizer.get();
196 }
197 
199  return RegBankInfo.get();
200 }
201 
202 /// Find the target operand flags that describe how a global value should be
203 /// referenced for the current subtarget.
204 unsigned char
206  const TargetMachine &TM) const {
207  // MachO large model always goes via a GOT, simply to get a single 8-byte
208  // absolute relocation on all global addresses.
210  return AArch64II::MO_GOT;
211 
212  if (!TM.shouldAssumeDSOLocal(*GV->getParent(), GV)) {
213  if (GV->hasDLLImportStorageClass())
217  return AArch64II::MO_GOT;
218  }
219 
220  // The small code model's direct accesses use ADRP, which cannot
221  // necessarily produce the value 0 (if the code is above 4GB).
222  // Same for the tiny code model, where we have a pc relative LDR.
223  if ((useSmallAddressing() || TM.getCodeModel() == CodeModel::Tiny) &&
225  return AArch64II::MO_GOT;
226 
227  return AArch64II::MO_NO_FLAG;
228 }
229 
231  const GlobalValue *GV, const TargetMachine &TM) const {
232  // MachO large model always goes via a GOT, because we don't have the
233  // relocations available to do anything else..
234  if (TM.getCodeModel() == CodeModel::Large && isTargetMachO() &&
235  !GV->hasInternalLinkage())
236  return AArch64II::MO_GOT;
237 
238  // NonLazyBind goes via GOT unless we know it's available locally.
239  auto *F = dyn_cast<Function>(GV);
240  if (UseNonLazyBind && F && F->hasFnAttribute(Attribute::NonLazyBind) &&
241  !TM.shouldAssumeDSOLocal(*GV->getParent(), GV))
242  return AArch64II::MO_GOT;
243 
244  return AArch64II::MO_NO_FLAG;
245 }
246 
248  unsigned NumRegionInstrs) const {
249  // LNT run (at least on Cyclone) showed reasonably significant gains for
250  // bi-directional scheduling. 253.perlbmk.
251  Policy.OnlyTopDown = false;
252  Policy.OnlyBottomUp = false;
253  // Enabling or Disabling the latency heuristic is a close call: It seems to
254  // help nearly no benchmark on out-of-order architectures, on the other hand
255  // it regresses register pressure on a few benchmarking.
257 }
258 
260  return EnableEarlyIfConvert;
261 }
262 
265  return false;
266 
267  if (TargetTriple.isiOS()) {
268  unsigned Major, Minor, Micro;
269  TargetTriple.getiOSVersion(Major, Minor, Micro);
270  return Major >= 8;
271  }
272 
273  return false;
274 }
275 
276 std::unique_ptr<PBQPRAConstraint>
278  return balanceFPOps() ? llvm::make_unique<A57ChainingConstraint>() : nullptr;
279 }
280 
282  // We usually compute max call frame size after ISel. Do the computation now
283  // if the .mir file didn't specify it. Note that this will probably give you
284  // bogus values after PEI has eliminated the callframe setup/destroy pseudo
285  // instructions, specify explicitly if you need it to be correct.
286  MachineFrameInfo &MFI = MF.getFrameInfo();
287  if (!MFI.isMaxCallFrameSizeComputed())
288  MFI.computeMaxCallFrameSize(MF);
289 }
const Triple & getTargetTriple() const
void getiOSVersion(unsigned &Major, unsigned &Minor, unsigned &Micro) const
getiOSVersion - Parse the version number as with getOSVersion.
Definition: Triple.cpp:1092
BitVector & set()
Definition: BitVector.h:398
This class represents lattice values for constants.
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:262
F(f)
bool hasExternalWeakLinkage() const
Definition: GlobalValue.h:437
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:456
bool supportsAddressTopByteIgnored() const
CPU has TBI (top byte of addresses is ignored during HW address translation) and OS enables it...
bool enableEarlyIfConversion() const override
bool isOSWindows() const
Tests whether the OS is Windows.
Definition: Triple.h:567
const AArch64TargetLowering * getTargetLowering() const override
initializer< Ty > init(const Ty &Val)
Definition: CommandLine.h:423
bool shouldAssumeDSOLocal(const Module &M, const GlobalValue *GV) const
MachineFrameInfo & getFrameInfo()
getFrameInfo - Return the frame info object for the current function.
bool isX18ReservedByDefault(const Triple &TT)
bool useSmallAddressing() const
bool hasInternalLinkage() const
Definition: GlobalValue.h:434
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_COFFSTUB - On a symbol operand "FOO", this indicates that the reference is actually to the "...
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:566
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)