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