LLVM API Documentation
00001 //===-- AArch64Subtarget.cpp - AArch64 Subtarget Information ----*- C++ -*-===// 00002 // 00003 // The LLVM Compiler Infrastructure 00004 // 00005 // This file is distributed under the University of Illinois Open Source 00006 // License. See LICENSE.TXT for details. 00007 // 00008 //===----------------------------------------------------------------------===// 00009 // 00010 // This file implements the AArch64 specific subclass of TargetSubtarget. 00011 // 00012 //===----------------------------------------------------------------------===// 00013 00014 #include "AArch64InstrInfo.h" 00015 #include "AArch64Subtarget.h" 00016 #include "llvm/ADT/SmallVector.h" 00017 #include "llvm/CodeGen/MachineScheduler.h" 00018 #include "llvm/IR/GlobalValue.h" 00019 #include "llvm/Support/TargetRegistry.h" 00020 00021 using namespace llvm; 00022 00023 #define DEBUG_TYPE "aarch64-subtarget" 00024 00025 #define GET_SUBTARGETINFO_CTOR 00026 #define GET_SUBTARGETINFO_TARGET_DESC 00027 #include "AArch64GenSubtargetInfo.inc" 00028 00029 static cl::opt<bool> 00030 EnableEarlyIfConvert("aarch64-early-ifcvt", cl::desc("Enable the early if " 00031 "converter pass"), cl::init(true), cl::Hidden); 00032 00033 AArch64Subtarget & 00034 AArch64Subtarget::initializeSubtargetDependencies(StringRef FS) { 00035 // Determine default and user-specified characteristics 00036 00037 if (CPUString.empty()) 00038 CPUString = "generic"; 00039 00040 ParseSubtargetFeatures(CPUString, FS); 00041 return *this; 00042 } 00043 00044 AArch64Subtarget::AArch64Subtarget(const std::string &TT, 00045 const std::string &CPU, 00046 const std::string &FS, TargetMachine &TM, 00047 bool LittleEndian) 00048 : AArch64GenSubtargetInfo(TT, CPU, FS), ARMProcFamily(Others), 00049 HasFPARMv8(false), HasNEON(false), HasCrypto(false), HasCRC(false), 00050 HasZeroCycleRegMove(false), HasZeroCycleZeroing(false), CPUString(CPU), 00051 TargetTriple(TT), 00052 // This nested ternary is horrible, but DL needs to be properly 00053 // initialized 00054 // before TLInfo is constructed. 00055 DL(isTargetMachO() 00056 ? "e-m:o-i64:64-i128:128-n32:64-S128" 00057 : (LittleEndian ? "e-m:e-i64:64-i128:128-n32:64-S128" 00058 : "E-m:e-i64:64-i128:128-n32:64-S128")), 00059 FrameLowering(), InstrInfo(initializeSubtargetDependencies(FS)), 00060 TSInfo(&DL), TLInfo(TM) {} 00061 00062 /// ClassifyGlobalReference - Find the target operand flags that describe 00063 /// how a global value should be referenced for the current subtarget. 00064 unsigned char 00065 AArch64Subtarget::ClassifyGlobalReference(const GlobalValue *GV, 00066 const TargetMachine &TM) const { 00067 00068 // Determine whether this is a reference to a definition or a declaration. 00069 // Materializable GVs (in JIT lazy compilation mode) do not require an extra 00070 // load from stub. 00071 bool isDecl = GV->hasAvailableExternallyLinkage(); 00072 if (GV->isDeclaration() && !GV->isMaterializable()) 00073 isDecl = true; 00074 00075 // MachO large model always goes via a GOT, simply to get a single 8-byte 00076 // absolute relocation on all global addresses. 00077 if (TM.getCodeModel() == CodeModel::Large && isTargetMachO()) 00078 return AArch64II::MO_GOT; 00079 00080 // The small code mode's direct accesses use ADRP, which cannot necessarily 00081 // produce the value 0 (if the code is above 4GB). 00082 if (TM.getCodeModel() == CodeModel::Small && 00083 GV->isWeakForLinker() && isDecl) { 00084 // In PIC mode use the GOT, but in absolute mode use a constant pool load. 00085 if (TM.getRelocationModel() == Reloc::Static) 00086 return AArch64II::MO_CONSTPOOL; 00087 else 00088 return AArch64II::MO_GOT; 00089 } 00090 00091 // If symbol visibility is hidden, the extra load is not needed if 00092 // the symbol is definitely defined in the current translation unit. 00093 00094 // The handling of non-hidden symbols in PIC mode is rather target-dependent: 00095 // + On MachO, if the symbol is defined in this module the GOT can be 00096 // skipped. 00097 // + On ELF, the R_AARCH64_COPY relocation means that even symbols actually 00098 // defined could end up in unexpected places. Use a GOT. 00099 if (TM.getRelocationModel() != Reloc::Static && GV->hasDefaultVisibility()) { 00100 if (isTargetMachO()) 00101 return (isDecl || GV->isWeakForLinker()) ? AArch64II::MO_GOT 00102 : AArch64II::MO_NO_FLAG; 00103 else 00104 // No need to go through the GOT for local symbols on ELF. 00105 return GV->hasLocalLinkage() ? AArch64II::MO_NO_FLAG : AArch64II::MO_GOT; 00106 } 00107 00108 return AArch64II::MO_NO_FLAG; 00109 } 00110 00111 /// This function returns the name of a function which has an interface 00112 /// like the non-standard bzero function, if such a function exists on 00113 /// the current subtarget and it is considered prefereable over 00114 /// memset with zero passed as the second argument. Otherwise it 00115 /// returns null. 00116 const char *AArch64Subtarget::getBZeroEntry() const { 00117 // Prefer bzero on Darwin only. 00118 if(isTargetDarwin()) 00119 return "bzero"; 00120 00121 return nullptr; 00122 } 00123 00124 void AArch64Subtarget::overrideSchedPolicy(MachineSchedPolicy &Policy, 00125 MachineInstr *begin, MachineInstr *end, 00126 unsigned NumRegionInstrs) const { 00127 // LNT run (at least on Cyclone) showed reasonably significant gains for 00128 // bi-directional scheduling. 253.perlbmk. 00129 Policy.OnlyTopDown = false; 00130 Policy.OnlyBottomUp = false; 00131 } 00132 00133 bool AArch64Subtarget::enableEarlyIfConversion() const { 00134 return EnableEarlyIfConvert; 00135 }