xref: /aosp_15_r20/external/llvm/lib/Target/AArch64/AArch64Subtarget.cpp (revision 9880d6810fe72a1726cb53787c6711e909410d58)
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