1dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines//===-- AArch64Subtarget.cpp - AArch64 Subtarget Information ----*- C++ -*-===// 272062f5744557e270a38192554c3126ea5f97434Tim Northover// 372062f5744557e270a38192554c3126ea5f97434Tim Northover// The LLVM Compiler Infrastructure 472062f5744557e270a38192554c3126ea5f97434Tim Northover// 572062f5744557e270a38192554c3126ea5f97434Tim Northover// This file is distributed under the University of Illinois Open Source 672062f5744557e270a38192554c3126ea5f97434Tim Northover// License. See LICENSE.TXT for details. 772062f5744557e270a38192554c3126ea5f97434Tim Northover// 872062f5744557e270a38192554c3126ea5f97434Tim Northover//===----------------------------------------------------------------------===// 972062f5744557e270a38192554c3126ea5f97434Tim Northover// 10dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines// This file implements the AArch64 specific subclass of TargetSubtarget. 1172062f5744557e270a38192554c3126ea5f97434Tim Northover// 1272062f5744557e270a38192554c3126ea5f97434Tim Northover//===----------------------------------------------------------------------===// 1372062f5744557e270a38192554c3126ea5f97434Tim Northover 14dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines#include "AArch64InstrInfo.h" 1537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines#include "AArch64PBQPRegAlloc.h" 1672062f5744557e270a38192554c3126ea5f97434Tim Northover#include "AArch64Subtarget.h" 1736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines#include "llvm/ADT/SmallVector.h" 18dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines#include "llvm/CodeGen/MachineScheduler.h" 1972062f5744557e270a38192554c3126ea5f97434Tim Northover#include "llvm/IR/GlobalValue.h" 20dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines#include "llvm/Support/TargetRegistry.h" 21dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines 22dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hinesusing namespace llvm; 23dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines 24dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines#define DEBUG_TYPE "aarch64-subtarget" 2572062f5744557e270a38192554c3126ea5f97434Tim Northover 2672062f5744557e270a38192554c3126ea5f97434Tim Northover#define GET_SUBTARGETINFO_CTOR 27dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines#define GET_SUBTARGETINFO_TARGET_DESC 2872062f5744557e270a38192554c3126ea5f97434Tim Northover#include "AArch64GenSubtargetInfo.inc" 2972062f5744557e270a38192554c3126ea5f97434Tim Northover 30dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hinesstatic cl::opt<bool> 31dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen HinesEnableEarlyIfConvert("aarch64-early-ifcvt", cl::desc("Enable the early if " 32dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines "converter pass"), cl::init(true), cl::Hidden); 33354362524a72b3fa43a6c09380b7ae3b2380cbbaJuergen Ributzka 34c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen HinesAArch64Subtarget & 35c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen HinesAArch64Subtarget::initializeSubtargetDependencies(StringRef FS) { 36dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines // Determine default and user-specified characteristics 37dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines 38dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines if (CPUString.empty()) 39dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines CPUString = "generic"; 4072062f5744557e270a38192554c3126ea5f97434Tim Northover 41dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines ParseSubtargetFeatures(CPUString, FS); 42c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines return *this; 43c2884320feebc543d2ce51151d5418dfc18da9e4Amara Emerson} 44c2884320feebc543d2ce51151d5418dfc18da9e4Amara Emerson 45c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen HinesAArch64Subtarget::AArch64Subtarget(const std::string &TT, 46c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines const std::string &CPU, 4737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines const std::string &FS, 4837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines const TargetMachine &TM, bool LittleEndian) 49c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines : AArch64GenSubtargetInfo(TT, CPU, FS), ARMProcFamily(Others), 502c3e0051c31c3f5b2328b447eadf1cf9c4427442Pirama Arumuga Nainar HasV8_1aOps(false), 51c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines HasFPARMv8(false), HasNEON(false), HasCrypto(false), HasCRC(false), 522c3e0051c31c3f5b2328b447eadf1cf9c4427442Pirama Arumuga Nainar HasZeroCycleRegMove(false), HasZeroCycleZeroing(false), 53ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines IsLittle(LittleEndian), CPUString(CPU), TargetTriple(TT), FrameLowering(), 54ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines InstrInfo(initializeSubtargetDependencies(FS)), 55ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines TSInfo(TM.getDataLayout()), TLInfo(TM, *this) {} 56c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines 57dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines/// ClassifyGlobalReference - Find the target operand flags that describe 58dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines/// how a global value should be referenced for the current subtarget. 59dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hinesunsigned char 60dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen HinesAArch64Subtarget::ClassifyGlobalReference(const GlobalValue *GV, 61dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines const TargetMachine &TM) const { 6237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines bool isDecl = GV->isDeclarationForLinker(); 63dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines 64dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines // MachO large model always goes via a GOT, simply to get a single 8-byte 65dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines // absolute relocation on all global addresses. 66dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines if (TM.getCodeModel() == CodeModel::Large && isTargetMachO()) 67dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines return AArch64II::MO_GOT; 68dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines 69dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines // The small code mode's direct accesses use ADRP, which cannot necessarily 7037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines // produce the value 0 (if the code is above 4GB). 7137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines if (TM.getCodeModel() == CodeModel::Small && 7237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines GV->isWeakForLinker() && isDecl) { 7337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines // In PIC mode use the GOT, but in absolute mode use a constant pool load. 7437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines if (TM.getRelocationModel() == Reloc::Static) 7537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines return AArch64II::MO_CONSTPOOL; 7637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines else 7737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines return AArch64II::MO_GOT; 7837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines } 79dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines 80dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines // If symbol visibility is hidden, the extra load is not needed if 81dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines // the symbol is definitely defined in the current translation unit. 82c2884320feebc543d2ce51151d5418dfc18da9e4Amara Emerson 83dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines // The handling of non-hidden symbols in PIC mode is rather target-dependent: 84dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines // + On MachO, if the symbol is defined in this module the GOT can be 85dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines // skipped. 86dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines // + On ELF, the R_AARCH64_COPY relocation means that even symbols actually 87dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines // defined could end up in unexpected places. Use a GOT. 88dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines if (TM.getRelocationModel() != Reloc::Static && GV->hasDefaultVisibility()) { 89dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines if (isTargetMachO()) 90dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines return (isDecl || GV->isWeakForLinker()) ? AArch64II::MO_GOT 91dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines : AArch64II::MO_NO_FLAG; 92c2884320feebc543d2ce51151d5418dfc18da9e4Amara Emerson else 93dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines // No need to go through the GOT for local symbols on ELF. 94dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines return GV->hasLocalLinkage() ? AArch64II::MO_NO_FLAG : AArch64II::MO_GOT; 95c2884320feebc543d2ce51151d5418dfc18da9e4Amara Emerson } 96c2884320feebc543d2ce51151d5418dfc18da9e4Amara Emerson 97dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines return AArch64II::MO_NO_FLAG; 9872062f5744557e270a38192554c3126ea5f97434Tim Northover} 9972062f5744557e270a38192554c3126ea5f97434Tim Northover 100dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines/// This function returns the name of a function which has an interface 101dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines/// like the non-standard bzero function, if such a function exists on 102dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines/// the current subtarget and it is considered prefereable over 103dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines/// memset with zero passed as the second argument. Otherwise it 104dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines/// returns null. 105dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hinesconst char *AArch64Subtarget::getBZeroEntry() const { 106dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines // Prefer bzero on Darwin only. 107dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines if(isTargetDarwin()) 108dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines return "bzero"; 109dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines 110dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines return nullptr; 111dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines} 112dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines 113dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hinesvoid AArch64Subtarget::overrideSchedPolicy(MachineSchedPolicy &Policy, 114dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines MachineInstr *begin, MachineInstr *end, 115dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines unsigned NumRegionInstrs) const { 116dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines // LNT run (at least on Cyclone) showed reasonably significant gains for 117dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines // bi-directional scheduling. 253.perlbmk. 118dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines Policy.OnlyTopDown = false; 119dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines Policy.OnlyBottomUp = false; 120dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines} 12172062f5744557e270a38192554c3126ea5f97434Tim Northover 122dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hinesbool AArch64Subtarget::enableEarlyIfConversion() const { 123dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines return EnableEarlyIfConvert; 12472062f5744557e270a38192554c3126ea5f97434Tim Northover} 12537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines 12637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hinesstd::unique_ptr<PBQPRAConstraint> 12737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen HinesAArch64Subtarget::getCustomPBQPConstraints() const { 12837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines if (!isCortexA57()) 12937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines return nullptr; 13037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines 13137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines return llvm::make_unique<A57ChainingConstraint>(); 13237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines} 133