1*9880d681SAndroid Build Coastguard Worker //===-- AArch64Subtarget.cpp - AArch64 Subtarget Information ----*- C++ -*-===//
2*9880d681SAndroid Build Coastguard Worker //
3*9880d681SAndroid Build Coastguard Worker // The LLVM Compiler Infrastructure
4*9880d681SAndroid Build Coastguard Worker //
5*9880d681SAndroid Build Coastguard Worker // This file is distributed under the University of Illinois Open Source
6*9880d681SAndroid Build Coastguard Worker // License. See LICENSE.TXT for details.
7*9880d681SAndroid Build Coastguard Worker //
8*9880d681SAndroid Build Coastguard Worker //===----------------------------------------------------------------------===//
9*9880d681SAndroid Build Coastguard Worker //
10*9880d681SAndroid Build Coastguard Worker // This file implements the AArch64 specific subclass of TargetSubtarget.
11*9880d681SAndroid Build Coastguard Worker //
12*9880d681SAndroid Build Coastguard Worker //===----------------------------------------------------------------------===//
13*9880d681SAndroid Build Coastguard Worker
14*9880d681SAndroid Build Coastguard Worker #include "AArch64Subtarget.h"
15*9880d681SAndroid Build Coastguard Worker #include "AArch64InstrInfo.h"
16*9880d681SAndroid Build Coastguard Worker #include "AArch64PBQPRegAlloc.h"
17*9880d681SAndroid Build Coastguard Worker #include "llvm/CodeGen/MachineScheduler.h"
18*9880d681SAndroid Build Coastguard Worker #include "llvm/IR/GlobalValue.h"
19*9880d681SAndroid Build Coastguard Worker #include "llvm/Support/TargetRegistry.h"
20*9880d681SAndroid Build Coastguard Worker
21*9880d681SAndroid Build Coastguard Worker using namespace llvm;
22*9880d681SAndroid Build Coastguard Worker
23*9880d681SAndroid Build Coastguard Worker #define DEBUG_TYPE "aarch64-subtarget"
24*9880d681SAndroid Build Coastguard Worker
25*9880d681SAndroid Build Coastguard Worker #define GET_SUBTARGETINFO_CTOR
26*9880d681SAndroid Build Coastguard Worker #define GET_SUBTARGETINFO_TARGET_DESC
27*9880d681SAndroid Build Coastguard Worker #include "AArch64GenSubtargetInfo.inc"
28*9880d681SAndroid Build Coastguard Worker
29*9880d681SAndroid Build Coastguard Worker static cl::opt<bool>
30*9880d681SAndroid Build Coastguard Worker EnableEarlyIfConvert("aarch64-early-ifcvt", cl::desc("Enable the early if "
31*9880d681SAndroid Build Coastguard Worker "converter pass"), cl::init(true), cl::Hidden);
32*9880d681SAndroid Build Coastguard Worker
33*9880d681SAndroid Build Coastguard Worker // If OS supports TBI, use this flag to enable it.
34*9880d681SAndroid Build Coastguard Worker static cl::opt<bool>
35*9880d681SAndroid Build Coastguard Worker UseAddressTopByteIgnored("aarch64-use-tbi", cl::desc("Assume that top byte of "
36*9880d681SAndroid Build Coastguard Worker "an address is ignored"), cl::init(false), cl::Hidden);
37*9880d681SAndroid Build Coastguard Worker
38*9880d681SAndroid Build Coastguard Worker AArch64Subtarget &
initializeSubtargetDependencies(StringRef FS)39*9880d681SAndroid Build Coastguard Worker AArch64Subtarget::initializeSubtargetDependencies(StringRef FS) {
40*9880d681SAndroid Build Coastguard Worker // Determine default and user-specified characteristics
41*9880d681SAndroid Build Coastguard Worker
42*9880d681SAndroid Build Coastguard Worker if (CPUString.empty())
43*9880d681SAndroid Build Coastguard Worker CPUString = "generic";
44*9880d681SAndroid Build Coastguard Worker
45*9880d681SAndroid Build Coastguard Worker ParseSubtargetFeatures(CPUString, FS);
46*9880d681SAndroid Build Coastguard Worker initializeProperties();
47*9880d681SAndroid Build Coastguard Worker
48*9880d681SAndroid Build Coastguard Worker return *this;
49*9880d681SAndroid Build Coastguard Worker }
50*9880d681SAndroid Build Coastguard Worker
initializeProperties()51*9880d681SAndroid Build Coastguard Worker void AArch64Subtarget::initializeProperties() {
52*9880d681SAndroid Build Coastguard Worker // Initialize CPU specific properties. We should add a tablegen feature for
53*9880d681SAndroid Build Coastguard Worker // this in the future so we can specify it together with the subtarget
54*9880d681SAndroid Build Coastguard Worker // features.
55*9880d681SAndroid Build Coastguard Worker switch (ARMProcFamily) {
56*9880d681SAndroid Build Coastguard Worker case Cyclone:
57*9880d681SAndroid Build Coastguard Worker CacheLineSize = 64;
58*9880d681SAndroid Build Coastguard Worker PrefetchDistance = 280;
59*9880d681SAndroid Build Coastguard Worker MinPrefetchStride = 2048;
60*9880d681SAndroid Build Coastguard Worker MaxPrefetchIterationsAhead = 3;
61*9880d681SAndroid Build Coastguard Worker break;
62*9880d681SAndroid Build Coastguard Worker case CortexA57:
63*9880d681SAndroid Build Coastguard Worker MaxInterleaveFactor = 4;
64*9880d681SAndroid Build Coastguard Worker break;
65*9880d681SAndroid Build Coastguard Worker case ExynosM1:
66*9880d681SAndroid Build Coastguard Worker PrefFunctionAlignment = 4;
67*9880d681SAndroid Build Coastguard Worker PrefLoopAlignment = 3;
68*9880d681SAndroid Build Coastguard Worker break;
69*9880d681SAndroid Build Coastguard Worker case Kryo:
70*9880d681SAndroid Build Coastguard Worker MaxInterleaveFactor = 4;
71*9880d681SAndroid Build Coastguard Worker VectorInsertExtractBaseCost = 2;
72*9880d681SAndroid Build Coastguard Worker CacheLineSize = 128;
73*9880d681SAndroid Build Coastguard Worker PrefetchDistance = 740;
74*9880d681SAndroid Build Coastguard Worker MinPrefetchStride = 1024;
75*9880d681SAndroid Build Coastguard Worker MaxPrefetchIterationsAhead = 11;
76*9880d681SAndroid Build Coastguard Worker break;
77*9880d681SAndroid Build Coastguard Worker case Vulcan:
78*9880d681SAndroid Build Coastguard Worker MaxInterleaveFactor = 4;
79*9880d681SAndroid Build Coastguard Worker break;
80*9880d681SAndroid Build Coastguard Worker case CortexA35: break;
81*9880d681SAndroid Build Coastguard Worker case CortexA53: break;
82*9880d681SAndroid Build Coastguard Worker case CortexA72: break;
83*9880d681SAndroid Build Coastguard Worker case CortexA73: break;
84*9880d681SAndroid Build Coastguard Worker case Others: break;
85*9880d681SAndroid Build Coastguard Worker }
86*9880d681SAndroid Build Coastguard Worker }
87*9880d681SAndroid Build Coastguard Worker
AArch64Subtarget(const Triple & TT,const std::string & CPU,const std::string & FS,const TargetMachine & TM,bool LittleEndian)88*9880d681SAndroid Build Coastguard Worker AArch64Subtarget::AArch64Subtarget(const Triple &TT, const std::string &CPU,
89*9880d681SAndroid Build Coastguard Worker const std::string &FS,
90*9880d681SAndroid Build Coastguard Worker const TargetMachine &TM, bool LittleEndian)
91*9880d681SAndroid Build Coastguard Worker : AArch64GenSubtargetInfo(TT, CPU, FS),
92*9880d681SAndroid Build Coastguard Worker ReserveX18(TT.isOSDarwin() || TT.isAndroid()), IsLittle(LittleEndian),
93*9880d681SAndroid Build Coastguard Worker CPUString(CPU), TargetTriple(TT), FrameLowering(),
94*9880d681SAndroid Build Coastguard Worker InstrInfo(initializeSubtargetDependencies(FS)), TSInfo(),
95*9880d681SAndroid Build Coastguard Worker TLInfo(TM, *this), GISel() {}
96*9880d681SAndroid Build Coastguard Worker
getCallLowering() const97*9880d681SAndroid Build Coastguard Worker const CallLowering *AArch64Subtarget::getCallLowering() const {
98*9880d681SAndroid Build Coastguard Worker assert(GISel && "Access to GlobalISel APIs not set");
99*9880d681SAndroid Build Coastguard Worker return GISel->getCallLowering();
100*9880d681SAndroid Build Coastguard Worker }
101*9880d681SAndroid Build Coastguard Worker
getRegBankInfo() const102*9880d681SAndroid Build Coastguard Worker const RegisterBankInfo *AArch64Subtarget::getRegBankInfo() const {
103*9880d681SAndroid Build Coastguard Worker assert(GISel && "Access to GlobalISel APIs not set");
104*9880d681SAndroid Build Coastguard Worker return GISel->getRegBankInfo();
105*9880d681SAndroid Build Coastguard Worker }
106*9880d681SAndroid Build Coastguard Worker
107*9880d681SAndroid Build Coastguard Worker /// Find the target operand flags that describe how a global value should be
108*9880d681SAndroid Build Coastguard Worker /// referenced for the current subtarget.
109*9880d681SAndroid Build Coastguard Worker unsigned char
ClassifyGlobalReference(const GlobalValue * GV,const TargetMachine & TM) const110*9880d681SAndroid Build Coastguard Worker AArch64Subtarget::ClassifyGlobalReference(const GlobalValue *GV,
111*9880d681SAndroid Build Coastguard Worker const TargetMachine &TM) const {
112*9880d681SAndroid Build Coastguard Worker // MachO large model always goes via a GOT, simply to get a single 8-byte
113*9880d681SAndroid Build Coastguard Worker // absolute relocation on all global addresses.
114*9880d681SAndroid Build Coastguard Worker if (TM.getCodeModel() == CodeModel::Large && isTargetMachO())
115*9880d681SAndroid Build Coastguard Worker return AArch64II::MO_GOT;
116*9880d681SAndroid Build Coastguard Worker
117*9880d681SAndroid Build Coastguard Worker if (!TM.shouldAssumeDSOLocal(*GV->getParent(), GV))
118*9880d681SAndroid Build Coastguard Worker return AArch64II::MO_GOT;
119*9880d681SAndroid Build Coastguard Worker
120*9880d681SAndroid Build Coastguard Worker // The small code mode's direct accesses use ADRP, which cannot necessarily
121*9880d681SAndroid Build Coastguard Worker // produce the value 0 (if the code is above 4GB).
122*9880d681SAndroid Build Coastguard Worker if (TM.getCodeModel() == CodeModel::Small && GV->hasExternalWeakLinkage())
123*9880d681SAndroid Build Coastguard Worker return AArch64II::MO_GOT;
124*9880d681SAndroid Build Coastguard Worker
125*9880d681SAndroid Build Coastguard Worker return AArch64II::MO_NO_FLAG;
126*9880d681SAndroid Build Coastguard Worker }
127*9880d681SAndroid Build Coastguard Worker
128*9880d681SAndroid Build Coastguard Worker /// This function returns the name of a function which has an interface
129*9880d681SAndroid Build Coastguard Worker /// like the non-standard bzero function, if such a function exists on
130*9880d681SAndroid Build Coastguard Worker /// the current subtarget and it is considered prefereable over
131*9880d681SAndroid Build Coastguard Worker /// memset with zero passed as the second argument. Otherwise it
132*9880d681SAndroid Build Coastguard Worker /// returns null.
getBZeroEntry() const133*9880d681SAndroid Build Coastguard Worker const char *AArch64Subtarget::getBZeroEntry() const {
134*9880d681SAndroid Build Coastguard Worker // Prefer bzero on Darwin only.
135*9880d681SAndroid Build Coastguard Worker if(isTargetDarwin())
136*9880d681SAndroid Build Coastguard Worker return "bzero";
137*9880d681SAndroid Build Coastguard Worker
138*9880d681SAndroid Build Coastguard Worker return nullptr;
139*9880d681SAndroid Build Coastguard Worker }
140*9880d681SAndroid Build Coastguard Worker
overrideSchedPolicy(MachineSchedPolicy & Policy,unsigned NumRegionInstrs) const141*9880d681SAndroid Build Coastguard Worker void AArch64Subtarget::overrideSchedPolicy(MachineSchedPolicy &Policy,
142*9880d681SAndroid Build Coastguard Worker unsigned NumRegionInstrs) const {
143*9880d681SAndroid Build Coastguard Worker // LNT run (at least on Cyclone) showed reasonably significant gains for
144*9880d681SAndroid Build Coastguard Worker // bi-directional scheduling. 253.perlbmk.
145*9880d681SAndroid Build Coastguard Worker Policy.OnlyTopDown = false;
146*9880d681SAndroid Build Coastguard Worker Policy.OnlyBottomUp = false;
147*9880d681SAndroid Build Coastguard Worker // Enabling or Disabling the latency heuristic is a close call: It seems to
148*9880d681SAndroid Build Coastguard Worker // help nearly no benchmark on out-of-order architectures, on the other hand
149*9880d681SAndroid Build Coastguard Worker // it regresses register pressure on a few benchmarking.
150*9880d681SAndroid Build Coastguard Worker Policy.DisableLatencyHeuristic = DisableLatencySchedHeuristic;
151*9880d681SAndroid Build Coastguard Worker }
152*9880d681SAndroid Build Coastguard Worker
enableEarlyIfConversion() const153*9880d681SAndroid Build Coastguard Worker bool AArch64Subtarget::enableEarlyIfConversion() const {
154*9880d681SAndroid Build Coastguard Worker return EnableEarlyIfConvert;
155*9880d681SAndroid Build Coastguard Worker }
156*9880d681SAndroid Build Coastguard Worker
supportsAddressTopByteIgnored() const157*9880d681SAndroid Build Coastguard Worker bool AArch64Subtarget::supportsAddressTopByteIgnored() const {
158*9880d681SAndroid Build Coastguard Worker if (!UseAddressTopByteIgnored)
159*9880d681SAndroid Build Coastguard Worker return false;
160*9880d681SAndroid Build Coastguard Worker
161*9880d681SAndroid Build Coastguard Worker if (TargetTriple.isiOS()) {
162*9880d681SAndroid Build Coastguard Worker unsigned Major, Minor, Micro;
163*9880d681SAndroid Build Coastguard Worker TargetTriple.getiOSVersion(Major, Minor, Micro);
164*9880d681SAndroid Build Coastguard Worker return Major >= 8;
165*9880d681SAndroid Build Coastguard Worker }
166*9880d681SAndroid Build Coastguard Worker
167*9880d681SAndroid Build Coastguard Worker return false;
168*9880d681SAndroid Build Coastguard Worker }
169*9880d681SAndroid Build Coastguard Worker
170*9880d681SAndroid Build Coastguard Worker std::unique_ptr<PBQPRAConstraint>
getCustomPBQPConstraints() const171*9880d681SAndroid Build Coastguard Worker AArch64Subtarget::getCustomPBQPConstraints() const {
172*9880d681SAndroid Build Coastguard Worker return balanceFPOps() ? llvm::make_unique<A57ChainingConstraint>() : nullptr;
173*9880d681SAndroid Build Coastguard Worker }
174