AArch64/ARM64: remove AArch64 from tree prior to renaming ARM64.
[oota-llvm.git] / lib / Target / ARM64 / ARM64Subtarget.cpp
1 //===-- ARM64Subtarget.cpp - ARM64 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 ARM64 specific subclass of TargetSubtarget.
11 //
12 //===----------------------------------------------------------------------===//
13
14 #include "ARM64InstrInfo.h"
15 #include "ARM64Subtarget.h"
16 #include "llvm/ADT/SmallVector.h"
17 #include "llvm/CodeGen/MachineScheduler.h"
18 #include "llvm/IR/GlobalValue.h"
19 #include "llvm/Support/TargetRegistry.h"
20
21 using namespace llvm;
22
23 #define DEBUG_TYPE "arm64-subtarget"
24
25 #define GET_SUBTARGETINFO_CTOR
26 #define GET_SUBTARGETINFO_TARGET_DESC
27 #include "ARM64GenSubtargetInfo.inc"
28
29 static cl::opt<bool>
30 EnableEarlyIfConvert("arm64-early-ifcvt", cl::desc("Enable the early if "
31                      "converter pass"), cl::init(true), cl::Hidden);
32
33 ARM64Subtarget::ARM64Subtarget(const std::string &TT, const std::string &CPU,
34                                const std::string &FS, bool LittleEndian)
35     : ARM64GenSubtargetInfo(TT, CPU, FS), ARMProcFamily(Others),
36       HasFPARMv8(false), HasNEON(false), HasCrypto(false), HasCRC(false),
37       HasZeroCycleRegMove(false), HasZeroCycleZeroing(false),
38       CPUString(CPU), TargetTriple(TT), IsLittleEndian(LittleEndian) {
39   // Determine default and user-specified characteristics
40
41   if (CPUString.empty())
42     CPUString = "generic";
43
44   ParseSubtargetFeatures(CPUString, FS);
45 }
46
47 /// ClassifyGlobalReference - Find the target operand flags that describe
48 /// how a global value should be referenced for the current subtarget.
49 unsigned char
50 ARM64Subtarget::ClassifyGlobalReference(const GlobalValue *GV,
51                                         const TargetMachine &TM) const {
52
53   // Determine whether this is a reference to a definition or a declaration.
54   // Materializable GVs (in JIT lazy compilation mode) do not require an extra
55   // load from stub.
56   bool isDecl = GV->hasAvailableExternallyLinkage();
57   if (GV->isDeclaration() && !GV->isMaterializable())
58     isDecl = true;
59
60   // MachO large model always goes via a GOT, simply to get a single 8-byte
61   // absolute relocation on all global addresses.
62   if (TM.getCodeModel() == CodeModel::Large && isTargetMachO())
63     return ARM64II::MO_GOT;
64
65   // The small code mode's direct accesses use ADRP, which cannot necessarily
66   // produce the value 0 (if the code is above 4GB). Therefore they must use the
67   // GOT.
68   if (TM.getCodeModel() == CodeModel::Small && GV->isWeakForLinker() && isDecl)
69     return ARM64II::MO_GOT;
70
71   // If symbol visibility is hidden, the extra load is not needed if
72   // the symbol is definitely defined in the current translation unit.
73
74   // The handling of non-hidden symbols in PIC mode is rather target-dependent:
75   //   + On MachO, if the symbol is defined in this module the GOT can be
76   //     skipped.
77   //   + On ELF, the R_AARCH64_COPY relocation means that even symbols actually
78   //     defined could end up in unexpected places. Use a GOT.
79   if (TM.getRelocationModel() != Reloc::Static && GV->hasDefaultVisibility()) {
80     if (isTargetMachO())
81       return (isDecl || GV->isWeakForLinker()) ? ARM64II::MO_GOT
82                                                : ARM64II::MO_NO_FLAG;
83     else
84       // No need to go through the GOT for local symbols on ELF.
85       return GV->hasLocalLinkage() ? ARM64II::MO_NO_FLAG : ARM64II::MO_GOT;
86   }
87
88   return ARM64II::MO_NO_FLAG;
89 }
90
91 /// This function returns the name of a function which has an interface
92 /// like the non-standard bzero function, if such a function exists on
93 /// the current subtarget and it is considered prefereable over
94 /// memset with zero passed as the second argument. Otherwise it
95 /// returns null.
96 const char *ARM64Subtarget::getBZeroEntry() const {
97   // Prefer bzero on Darwin only.
98   if(isTargetDarwin())
99     return "bzero";
100
101   return nullptr;
102 }
103
104 void ARM64Subtarget::overrideSchedPolicy(MachineSchedPolicy &Policy,
105                                          MachineInstr *begin, MachineInstr *end,
106                                          unsigned NumRegionInstrs) const {
107   // LNT run (at least on Cyclone) showed reasonably significant gains for
108   // bi-directional scheduling. 253.perlbmk.
109   Policy.OnlyTopDown = false;
110   Policy.OnlyBottomUp = false;
111 }
112
113 bool ARM64Subtarget::enableEarlyIfConversion() const {
114   return EnableEarlyIfConvert;
115 }