LCOV - code coverage report
Current view: top level - lib/Target/AArch64 - AArch64Subtarget.cpp (source / functions) Hit Total Coverage
Test: llvm-toolchain.info Lines: 116 117 99.1 %
Date: 2017-09-14 15:23:50 Functions: 16 16 100.0 %
Legend: Lines: hit not hit

          Line data    Source code
       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 "AArch64Subtarget.h"
      15             : 
      16             : #include "AArch64.h"
      17             : #include "AArch64InstrInfo.h"
      18             : #include "AArch64PBQPRegAlloc.h"
      19             : #include "AArch64TargetMachine.h"
      20             : 
      21             : #include "AArch64CallLowering.h"
      22             : #include "AArch64LegalizerInfo.h"
      23             : #include "AArch64RegisterBankInfo.h"
      24             : #include "llvm/CodeGen/GlobalISel/IRTranslator.h"
      25             : #include "llvm/CodeGen/GlobalISel/InstructionSelect.h"
      26             : #include "llvm/CodeGen/GlobalISel/Legalizer.h"
      27             : #include "llvm/CodeGen/GlobalISel/RegBankSelect.h"
      28             : #include "llvm/CodeGen/MachineScheduler.h"
      29             : #include "llvm/IR/GlobalValue.h"
      30             : #include "llvm/Support/TargetRegistry.h"
      31             : 
      32             : using namespace llvm;
      33             : 
      34             : #define DEBUG_TYPE "aarch64-subtarget"
      35             : 
      36             : #define GET_SUBTARGETINFO_CTOR
      37             : #define GET_SUBTARGETINFO_TARGET_DESC
      38             : #include "AArch64GenSubtargetInfo.inc"
      39             : 
      40             : static cl::opt<bool>
      41      289224 : EnableEarlyIfConvert("aarch64-early-ifcvt", cl::desc("Enable the early if "
      42      289224 :                      "converter pass"), cl::init(true), cl::Hidden);
      43             : 
      44             : // If OS supports TBI, use this flag to enable it.
      45             : static cl::opt<bool>
      46      289224 : UseAddressTopByteIgnored("aarch64-use-tbi", cl::desc("Assume that top byte of "
      47      289224 :                          "an address is ignored"), cl::init(false), cl::Hidden);
      48             : 
      49             : static cl::opt<bool>
      50       72306 :     UseNonLazyBind("aarch64-enable-nonlazybind",
      51      216918 :                    cl::desc("Call nonlazybind functions via direct GOT load"),
      52      289224 :                    cl::init(false), cl::Hidden);
      53             : 
      54             : AArch64Subtarget &
      55        1214 : AArch64Subtarget::initializeSubtargetDependencies(StringRef FS,
      56             :                                                   StringRef CPUString) {
      57             :   // Determine default and user-specified characteristics
      58             : 
      59        1214 :   if (CPUString.empty())
      60         985 :     CPUString = "generic";
      61             : 
      62        1214 :   ParseSubtargetFeatures(CPUString, FS);
      63        1214 :   initializeProperties();
      64             : 
      65        1214 :   return *this;
      66             : }
      67             : 
      68        1214 : void AArch64Subtarget::initializeProperties() {
      69             :   // Initialize CPU specific properties. We should add a tablegen feature for
      70             :   // this in the future so we can specify it together with the subtarget
      71             :   // features.
      72        1214 :   switch (ARMProcFamily) {
      73          81 :   case Cyclone:
      74          81 :     CacheLineSize = 64;
      75          81 :     PrefetchDistance = 280;
      76          81 :     MinPrefetchStride = 2048;
      77          81 :     MaxPrefetchIterationsAhead = 3;
      78          81 :     break;
      79          30 :   case CortexA57:
      80          30 :     MaxInterleaveFactor = 4;
      81          30 :     PrefFunctionAlignment = 4;
      82          30 :     break;
      83          16 :   case ExynosM1:
      84          16 :     MaxInterleaveFactor = 4;
      85          16 :     MaxJumpTableSize = 8;
      86          16 :     PrefFunctionAlignment = 4;
      87          16 :     PrefLoopAlignment = 3;
      88          16 :     break;
      89          12 :   case Falkor:
      90          12 :     MaxInterleaveFactor = 4;
      91             :     // FIXME: remove this to enable 64-bit SLP if performance looks good.
      92          12 :     MinVectorRegisterBitWidth = 128;
      93          12 :     CacheLineSize = 128;
      94          12 :     PrefetchDistance = 820;
      95          12 :     MinPrefetchStride = 2048;
      96          12 :     MaxPrefetchIterationsAhead = 8;
      97          12 :     break;
      98          12 :   case Kryo:
      99          12 :     MaxInterleaveFactor = 4;
     100          12 :     VectorInsertExtractBaseCost = 2;
     101          12 :     CacheLineSize = 128;
     102          12 :     PrefetchDistance = 740;
     103          12 :     MinPrefetchStride = 1024;
     104          12 :     MaxPrefetchIterationsAhead = 11;
     105             :     // FIXME: remove this to enable 64-bit SLP if performance looks good.
     106          12 :     MinVectorRegisterBitWidth = 128;
     107          12 :     break;
     108           4 :   case ThunderX2T99:
     109           4 :     CacheLineSize = 64;
     110           4 :     PrefFunctionAlignment = 3;
     111           4 :     PrefLoopAlignment = 2;
     112           4 :     MaxInterleaveFactor = 4;
     113           4 :     PrefetchDistance = 128;
     114           4 :     MinPrefetchStride = 1024;
     115           4 :     MaxPrefetchIterationsAhead = 4;
     116             :     // FIXME: remove this to enable 64-bit SLP if performance looks good.
     117           4 :     MinVectorRegisterBitWidth = 128;
     118           4 :     break;
     119           4 :   case ThunderX:
     120             :   case ThunderXT88:
     121             :   case ThunderXT81:
     122             :   case ThunderXT83:
     123           4 :     CacheLineSize = 128;
     124           4 :     PrefFunctionAlignment = 3;
     125           4 :     PrefLoopAlignment = 2;
     126             :     // FIXME: remove this to enable 64-bit SLP if performance looks good.
     127           4 :     MinVectorRegisterBitWidth = 128;
     128           4 :     break;
     129             :   case CortexA35: break;
     130          16 :   case CortexA53:
     131          16 :     PrefFunctionAlignment = 3;
     132          16 :     break;
     133             :   case CortexA55: break;
     134          12 :   case CortexA72:
     135             :   case CortexA73:
     136             :   case CortexA75:
     137          12 :     PrefFunctionAlignment = 4;
     138          12 :     break;
     139             :   case Others: break;
     140             :   }
     141        1214 : }
     142             : 
     143        1214 : AArch64Subtarget::AArch64Subtarget(const Triple &TT, const std::string &CPU,
     144             :                                    const std::string &FS,
     145        1214 :                                    const TargetMachine &TM, bool LittleEndian)
     146             :     : AArch64GenSubtargetInfo(TT, CPU, FS),
     147        1752 :       ReserveX18(TT.isOSDarwin() || TT.isOSWindows()), IsLittle(LittleEndian),
     148             :       TargetTriple(TT), FrameLowering(),
     149        3642 :       InstrInfo(initializeSubtargetDependencies(FS, CPU)), TSInfo(),
     150       14568 :       TLInfo(TM, *this) {
     151        2428 :   CallLoweringInfo.reset(new AArch64CallLowering(*getTargetLowering()));
     152        2428 :   Legalizer.reset(new AArch64LegalizerInfo());
     153             : 
     154        1214 :   auto *RBI = new AArch64RegisterBankInfo(*getRegisterInfo());
     155             : 
     156             :   // FIXME: At this point, we can't rely on Subtarget having RBI.
     157             :   // It's awkward to mix passing RBI and the Subtarget; should we pass
     158             :   // TII/TRI as well?
     159        2428 :   InstSelector.reset(createAArch64InstructionSelector(
     160             :       *static_cast<const AArch64TargetMachine *>(&TM), *this, *RBI));
     161             : 
     162        2428 :   RegBankInfo.reset(RBI);
     163        1214 : }
     164             : 
     165         211 : const CallLowering *AArch64Subtarget::getCallLowering() const {
     166         422 :   return CallLoweringInfo.get();
     167             : }
     168             : 
     169         185 : const InstructionSelector *AArch64Subtarget::getInstructionSelector() const {
     170         370 :   return InstSelector.get();
     171             : }
     172             : 
     173         107 : const LegalizerInfo *AArch64Subtarget::getLegalizerInfo() const {
     174         214 :   return Legalizer.get();
     175             : }
     176             : 
     177         211 : const RegisterBankInfo *AArch64Subtarget::getRegBankInfo() const {
     178         422 :   return RegBankInfo.get();
     179             : }
     180             : 
     181             : /// Find the target operand flags that describe how a global value should be
     182             : /// referenced for the current subtarget.
     183             : unsigned char
     184        2151 : AArch64Subtarget::ClassifyGlobalReference(const GlobalValue *GV,
     185             :                                           const TargetMachine &TM) const {
     186             :   // MachO large model always goes via a GOT, simply to get a single 8-byte
     187             :   // absolute relocation on all global addresses.
     188        2186 :   if (TM.getCodeModel() == CodeModel::Large && isTargetMachO())
     189             :     return AArch64II::MO_GOT;
     190             : 
     191        2140 :   if (!TM.shouldAssumeDSOLocal(*GV->getParent(), GV))
     192             :     return AArch64II::MO_GOT;
     193             : 
     194             :   // The small code model's direct accesses use ADRP, which cannot
     195             :   // necessarily produce the value 0 (if the code is above 4GB).
     196        3772 :   if (useSmallAddressing() && GV->hasExternalWeakLinkage())
     197             :     return AArch64II::MO_GOT;
     198             : 
     199             :   return AArch64II::MO_NO_FLAG;
     200             : }
     201             : 
     202        1194 : unsigned char AArch64Subtarget::classifyGlobalFunctionReference(
     203             :     const GlobalValue *GV, const TargetMachine &TM) const {
     204             :   // MachO large model always goes via a GOT, because we don't have the
     205             :   // relocations available to do anything else..
     206        1195 :   if (TM.getCodeModel() == CodeModel::Large && isTargetMachO() &&
     207           0 :       !GV->hasInternalLinkage())
     208             :     return AArch64II::MO_GOT;
     209             : 
     210             :   // NonLazyBind goes via GOT unless we know it's available locally.
     211        1194 :   auto *F = dyn_cast<Function>(GV);
     212        1200 :   if (UseNonLazyBind && F && F->hasFnAttribute(Attribute::NonLazyBind) &&
     213           3 :       !TM.shouldAssumeDSOLocal(*GV->getParent(), GV))
     214             :     return AArch64II::MO_GOT;
     215             : 
     216             :   return AArch64II::MO_NO_FLAG;
     217             : }
     218             : 
     219             : /// This function returns the name of a function which has an interface
     220             : /// like the non-standard bzero function, if such a function exists on
     221             : /// the current subtarget and it is considered prefereable over
     222             : /// memset with zero passed as the second argument. Otherwise it
     223             : /// returns null.
     224          14 : const char *AArch64Subtarget::getBZeroEntry() const {
     225             :   // Prefer bzero on Darwin only.
     226           7 :   if(isTargetDarwin())
     227             :     return "bzero";
     228             : 
     229             :   return nullptr;
     230             : }
     231             : 
     232       17673 : void AArch64Subtarget::overrideSchedPolicy(MachineSchedPolicy &Policy,
     233             :                                            unsigned NumRegionInstrs) const {
     234             :   // LNT run (at least on Cyclone) showed reasonably significant gains for
     235             :   // bi-directional scheduling. 253.perlbmk.
     236       17673 :   Policy.OnlyTopDown = false;
     237       17673 :   Policy.OnlyBottomUp = false;
     238             :   // Enabling or Disabling the latency heuristic is a close call: It seems to
     239             :   // help nearly no benchmark on out-of-order architectures, on the other hand
     240             :   // it regresses register pressure on a few benchmarking.
     241       17673 :   Policy.DisableLatencyHeuristic = DisableLatencySchedHeuristic;
     242       17673 : }
     243             : 
     244       11001 : bool AArch64Subtarget::enableEarlyIfConversion() const {
     245       11001 :   return EnableEarlyIfConvert;
     246             : }
     247             : 
     248       13367 : bool AArch64Subtarget::supportsAddressTopByteIgnored() const {
     249       13367 :   if (!UseAddressTopByteIgnored)
     250             :     return false;
     251             : 
     252           7 :   if (TargetTriple.isiOS()) {
     253             :     unsigned Major, Minor, Micro;
     254           7 :     TargetTriple.getiOSVersion(Major, Minor, Micro);
     255           7 :     return Major >= 8;
     256             :   }
     257             : 
     258             :   return false;
     259             : }
     260             : 
     261             : std::unique_ptr<PBQPRAConstraint>
     262           5 : AArch64Subtarget::getCustomPBQPConstraints() const {
     263          15 :   return balanceFPOps() ? llvm::make_unique<A57ChainingConstraint>() : nullptr;
     264      216918 : }

Generated by: LCOV version 1.13