LCOV - code coverage report
Current view: top level - lib/Target/AArch64 - AArch64TargetMachine.cpp (source / functions) Hit Total Coverage
Test: llvm-toolchain.info Lines: 191 197 97.0 %
Date: 2018-09-23 13:06:45 Functions: 26 28 92.9 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : //===-- AArch64TargetMachine.cpp - Define TargetMachine for AArch64 -------===//
       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             : //
      11             : //===----------------------------------------------------------------------===//
      12             : 
      13             : #include "AArch64TargetMachine.h"
      14             : #include "AArch64.h"
      15             : #include "AArch64MacroFusion.h"
      16             : #include "AArch64Subtarget.h"
      17             : #include "AArch64TargetObjectFile.h"
      18             : #include "AArch64TargetTransformInfo.h"
      19             : #include "MCTargetDesc/AArch64MCTargetDesc.h"
      20             : #include "llvm/ADT/STLExtras.h"
      21             : #include "llvm/ADT/Triple.h"
      22             : #include "llvm/Analysis/TargetTransformInfo.h"
      23             : #include "llvm/CodeGen/GlobalISel/IRTranslator.h"
      24             : #include "llvm/CodeGen/GlobalISel/InstructionSelect.h"
      25             : #include "llvm/CodeGen/GlobalISel/Legalizer.h"
      26             : #include "llvm/CodeGen/GlobalISel/Localizer.h"
      27             : #include "llvm/CodeGen/GlobalISel/RegBankSelect.h"
      28             : #include "llvm/CodeGen/MachineScheduler.h"
      29             : #include "llvm/CodeGen/Passes.h"
      30             : #include "llvm/CodeGen/TargetPassConfig.h"
      31             : #include "llvm/IR/Attributes.h"
      32             : #include "llvm/IR/Function.h"
      33             : #include "llvm/MC/MCTargetOptions.h"
      34             : #include "llvm/Pass.h"
      35             : #include "llvm/Support/CodeGen.h"
      36             : #include "llvm/Support/CommandLine.h"
      37             : #include "llvm/Support/TargetRegistry.h"
      38             : #include "llvm/Target/TargetLoweringObjectFile.h"
      39             : #include "llvm/Target/TargetOptions.h"
      40             : #include "llvm/Transforms/Scalar.h"
      41             : #include <memory>
      42             : #include <string>
      43             : 
      44             : using namespace llvm;
      45             : 
      46             : static cl::opt<bool> EnableCCMP("aarch64-enable-ccmp",
      47             :                                 cl::desc("Enable the CCMP formation pass"),
      48             :                                 cl::init(true), cl::Hidden);
      49             : 
      50             : static cl::opt<bool>
      51             :     EnableCondBrTuning("aarch64-enable-cond-br-tune",
      52             :                        cl::desc("Enable the conditional branch tuning pass"),
      53             :                        cl::init(true), cl::Hidden);
      54             : 
      55             : static cl::opt<bool> EnableMCR("aarch64-enable-mcr",
      56             :                                cl::desc("Enable the machine combiner pass"),
      57             :                                cl::init(true), cl::Hidden);
      58             : 
      59             : static cl::opt<bool> EnableStPairSuppress("aarch64-enable-stp-suppress",
      60             :                                           cl::desc("Suppress STP for AArch64"),
      61             :                                           cl::init(true), cl::Hidden);
      62             : 
      63             : static cl::opt<bool> EnableAdvSIMDScalar(
      64             :     "aarch64-enable-simd-scalar",
      65             :     cl::desc("Enable use of AdvSIMD scalar integer instructions"),
      66             :     cl::init(false), cl::Hidden);
      67             : 
      68             : static cl::opt<bool>
      69             :     EnablePromoteConstant("aarch64-enable-promote-const",
      70             :                           cl::desc("Enable the promote constant pass"),
      71             :                           cl::init(true), cl::Hidden);
      72             : 
      73             : static cl::opt<bool> EnableCollectLOH(
      74             :     "aarch64-enable-collect-loh",
      75             :     cl::desc("Enable the pass that emits the linker optimization hints (LOH)"),
      76             :     cl::init(true), cl::Hidden);
      77             : 
      78             : static cl::opt<bool>
      79             :     EnableDeadRegisterElimination("aarch64-enable-dead-defs", cl::Hidden,
      80             :                                   cl::desc("Enable the pass that removes dead"
      81             :                                            " definitons and replaces stores to"
      82             :                                            " them with stores to the zero"
      83             :                                            " register"),
      84             :                                   cl::init(true));
      85             : 
      86             : static cl::opt<bool> EnableRedundantCopyElimination(
      87             :     "aarch64-enable-copyelim",
      88             :     cl::desc("Enable the redundant copy elimination pass"), cl::init(true),
      89             :     cl::Hidden);
      90             : 
      91             : static cl::opt<bool> EnableLoadStoreOpt("aarch64-enable-ldst-opt",
      92             :                                         cl::desc("Enable the load/store pair"
      93             :                                                  " optimization pass"),
      94             :                                         cl::init(true), cl::Hidden);
      95             : 
      96             : static cl::opt<bool> EnableAtomicTidy(
      97             :     "aarch64-enable-atomic-cfg-tidy", cl::Hidden,
      98             :     cl::desc("Run SimplifyCFG after expanding atomic operations"
      99             :              " to make use of cmpxchg flow-based information"),
     100             :     cl::init(true));
     101             : 
     102             : static cl::opt<bool>
     103             : EnableEarlyIfConversion("aarch64-enable-early-ifcvt", cl::Hidden,
     104             :                         cl::desc("Run early if-conversion"),
     105             :                         cl::init(true));
     106             : 
     107             : static cl::opt<bool>
     108             :     EnableCondOpt("aarch64-enable-condopt",
     109             :                   cl::desc("Enable the condition optimizer pass"),
     110             :                   cl::init(true), cl::Hidden);
     111             : 
     112             : static cl::opt<bool>
     113             : EnableA53Fix835769("aarch64-fix-cortex-a53-835769", cl::Hidden,
     114             :                 cl::desc("Work around Cortex-A53 erratum 835769"),
     115             :                 cl::init(false));
     116             : 
     117             : static cl::opt<bool>
     118             :     EnableGEPOpt("aarch64-enable-gep-opt", cl::Hidden,
     119             :                  cl::desc("Enable optimizations on complex GEPs"),
     120             :                  cl::init(false));
     121             : 
     122             : static cl::opt<bool>
     123             :     BranchRelaxation("aarch64-enable-branch-relax", cl::Hidden, cl::init(true),
     124             :                      cl::desc("Relax out of range conditional branches"));
     125             : 
     126             : // FIXME: Unify control over GlobalMerge.
     127             : static cl::opt<cl::boolOrDefault>
     128             :     EnableGlobalMerge("aarch64-enable-global-merge", cl::Hidden,
     129             :                       cl::desc("Enable the global merge pass"));
     130             : 
     131             : static cl::opt<bool>
     132             :     EnableLoopDataPrefetch("aarch64-enable-loop-data-prefetch", cl::Hidden,
     133             :                            cl::desc("Enable the loop data prefetch pass"),
     134             :                            cl::init(true));
     135             : 
     136             : static cl::opt<int> EnableGlobalISelAtO(
     137             :     "aarch64-enable-global-isel-at-O", cl::Hidden,
     138             :     cl::desc("Enable GlobalISel at or below an opt level (-1 to disable)"),
     139             :     cl::init(0));
     140             : 
     141             : static cl::opt<bool> EnableFalkorHWPFFix("aarch64-enable-falkor-hwpf-fix",
     142             :                                          cl::init(true), cl::Hidden);
     143             : 
     144      124282 : extern "C" void LLVMInitializeAArch64Target() {
     145             :   // Register the target.
     146      124282 :   RegisterTargetMachine<AArch64leTargetMachine> X(getTheAArch64leTarget());
     147      124282 :   RegisterTargetMachine<AArch64beTargetMachine> Y(getTheAArch64beTarget());
     148      124282 :   RegisterTargetMachine<AArch64leTargetMachine> Z(getTheARM64Target());
     149      124282 :   auto PR = PassRegistry::getPassRegistry();
     150      124282 :   initializeGlobalISel(*PR);
     151      124282 :   initializeAArch64A53Fix835769Pass(*PR);
     152      124282 :   initializeAArch64A57FPLoadBalancingPass(*PR);
     153      124282 :   initializeAArch64AdvSIMDScalarPass(*PR);
     154      124282 :   initializeAArch64CollectLOHPass(*PR);
     155      124282 :   initializeAArch64ConditionalComparesPass(*PR);
     156      124282 :   initializeAArch64ConditionOptimizerPass(*PR);
     157      124282 :   initializeAArch64DeadRegisterDefinitionsPass(*PR);
     158      124282 :   initializeAArch64ExpandPseudoPass(*PR);
     159      124282 :   initializeAArch64LoadStoreOptPass(*PR);
     160      124282 :   initializeAArch64SIMDInstrOptPass(*PR);
     161      124282 :   initializeAArch64PromoteConstantPass(*PR);
     162      124282 :   initializeAArch64RedundantCopyEliminationPass(*PR);
     163      124282 :   initializeAArch64StorePairSuppressPass(*PR);
     164      124282 :   initializeFalkorHWPFFixPass(*PR);
     165      124282 :   initializeFalkorMarkStridedAccessesLegacyPass(*PR);
     166      124282 :   initializeLDTLSCleanupPass(*PR);
     167      124282 : }
     168             : 
     169             : //===----------------------------------------------------------------------===//
     170             : // AArch64 Lowering public interface.
     171             : //===----------------------------------------------------------------------===//
     172        1807 : static std::unique_ptr<TargetLoweringObjectFile> createTLOF(const Triple &TT) {
     173        1807 :   if (TT.isOSBinFormatMachO())
     174             :     return llvm::make_unique<AArch64_MachoTargetObjectFile>();
     175        1378 :   if (TT.isOSBinFormatCOFF())
     176          37 :     return llvm::make_unique<AArch64_COFFTargetObjectFile>();
     177             : 
     178        1341 :   return llvm::make_unique<AArch64_ELFTargetObjectFile>();
     179             : }
     180             : 
     181             : // Helper function to build a DataLayout string
     182        1807 : static std::string computeDataLayout(const Triple &TT,
     183             :                                      const MCTargetOptions &Options,
     184             :                                      bool LittleEndian) {
     185        1807 :   if (Options.getABIName() == "ilp32")
     186           0 :     return "e-m:e-p:32:32-i8:8-i16:16-i64:64-S128";
     187        1807 :   if (TT.isOSBinFormatMachO())
     188         429 :     return "e-m:o-i64:64-i128:128-n32:64-S128";
     189        1378 :   if (TT.isOSBinFormatCOFF())
     190          37 :     return "e-m:w-p:64:64-i32:32-i64:64-i128:128-n32:64-S128";
     191        1341 :   if (LittleEndian)
     192        1307 :     return "e-m:e-i8:8:32-i16:16:32-i64:64-i128:128-n32:64-S128";
     193          34 :   return "E-m:e-i8:8:32-i16:16:32-i64:64-i128:128-n32:64-S128";
     194             : }
     195             : 
     196             : static Reloc::Model getEffectiveRelocModel(const Triple &TT,
     197             :                                            Optional<Reloc::Model> RM) {
     198             :   // AArch64 Darwin is always PIC.
     199             :   if (TT.isOSDarwin())
     200             :     return Reloc::PIC_;
     201             :   // On ELF platforms the default static relocation model has a smart enough
     202             :   // linker to cope with referencing external symbols defined in a shared
     203             :   // library. Hence DynamicNoPIC doesn't need to be promoted to PIC.
     204        1380 :   if (!RM.hasValue() || *RM == Reloc::DynamicNoPIC)
     205             :     return Reloc::Static;
     206             :   return *RM;
     207             : }
     208             : 
     209        1810 : static CodeModel::Model getEffectiveCodeModel(const Triple &TT,
     210             :                                               Optional<CodeModel::Model> CM,
     211             :                                               bool JIT) {
     212        1810 :   if (CM) {
     213          54 :     if (*CM != CodeModel::Small && *CM != CodeModel::Tiny &&
     214             :         *CM != CodeModel::Large) {
     215           6 :       if (!TT.isOSFuchsia())
     216           0 :         report_fatal_error(
     217             :             "Only small, tiny and large code models are allowed on AArch64");
     218           6 :       else if (*CM != CodeModel::Kernel)
     219           0 :         report_fatal_error("Only small, tiny, kernel, and large code models "
     220             :                            "are allowed on AArch64");
     221          48 :     } else if (*CM == CodeModel::Tiny && !TT.isOSBinFormatELF())
     222           3 :       report_fatal_error("tiny code model is only supported on ELF");
     223             :     return *CM;
     224             :   }
     225             :   // The default MCJIT memory managers make no guarantees about where they can
     226             :   // find an executable page; JITed code needs to be able to refer to globals
     227             :   // no matter how far away they are.
     228        1756 :   if (JIT)
     229           0 :     return CodeModel::Large;
     230             :   return CodeModel::Small;
     231             : }
     232             : 
     233             : /// Create an AArch64 architecture model.
     234             : ///
     235        1810 : AArch64TargetMachine::AArch64TargetMachine(const Target &T, const Triple &TT,
     236             :                                            StringRef CPU, StringRef FS,
     237             :                                            const TargetOptions &Options,
     238             :                                            Optional<Reloc::Model> RM,
     239             :                                            Optional<CodeModel::Model> CM,
     240             :                                            CodeGenOpt::Level OL, bool JIT,
     241        1810 :                                            bool LittleEndian)
     242             :     : LLVMTargetMachine(T,
     243        1807 :                         computeDataLayout(TT, Options.MCOptions, LittleEndian),
     244             :                         TT, CPU, FS, Options, getEffectiveRelocModel(TT, RM),
     245             :                         getEffectiveCodeModel(TT, CM, JIT), OL),
     246        7285 :       TLOF(createTLOF(getTargetTriple())), isLittle(LittleEndian) {
     247        1807 :   initAsmInfo();
     248             : 
     249        1807 :   if (TT.isOSBinFormatMachO()) {
     250         429 :     this->Options.TrapUnreachable = true;
     251         429 :     this->Options.NoTrapAfterNoreturn = true;
     252             :   }
     253             : 
     254             :   // Enable GlobalISel at or below EnableGlobalISelAt0.
     255        1807 :   if (getOptLevel() <= EnableGlobalISelAtO)
     256             :     setGlobalISel(true);
     257             : 
     258             :   // AArch64 supports the MachineOutliner.
     259             :   setMachineOutliner(true);
     260             : 
     261             :   // AArch64 supports default outlining behaviour.
     262             :   setSupportsDefaultOutlining(true);
     263        1807 : }
     264             : 
     265             : AArch64TargetMachine::~AArch64TargetMachine() = default;
     266             : 
     267             : const AArch64Subtarget *
     268      276386 : AArch64TargetMachine::getSubtargetImpl(const Function &F) const {
     269      276386 :   Attribute CPUAttr = F.getFnAttribute("target-cpu");
     270      276386 :   Attribute FSAttr = F.getFnAttribute("target-features");
     271             : 
     272      276386 :   std::string CPU = !CPUAttr.hasAttribute(Attribute::None)
     273       39272 :                         ? CPUAttr.getValueAsString().str()
     274      315658 :                         : TargetCPU;
     275      276386 :   std::string FS = !FSAttr.hasAttribute(Attribute::None)
     276       95215 :                        ? FSAttr.getValueAsString().str()
     277      371601 :                        : TargetFS;
     278             : 
     279      280902 :   auto &I = SubtargetMap[CPU + FS];
     280      276386 :   if (!I) {
     281             :     // This needs to be done before we create a new subtarget since any
     282             :     // creation will depend on the TM and the code generation flags on the
     283             :     // function that reside in TargetOptions.
     284        1533 :     resetTargetOptions(F);
     285        3066 :     I = llvm::make_unique<AArch64Subtarget>(TargetTriple, CPU, FS, *this,
     286        1533 :                                             isLittle);
     287             :   }
     288      276386 :   return I.get();
     289             : }
     290             : 
     291           0 : void AArch64leTargetMachine::anchor() { }
     292             : 
     293        1776 : AArch64leTargetMachine::AArch64leTargetMachine(
     294             :     const Target &T, const Triple &TT, StringRef CPU, StringRef FS,
     295             :     const TargetOptions &Options, Optional<Reloc::Model> RM,
     296        1776 :     Optional<CodeModel::Model> CM, CodeGenOpt::Level OL, bool JIT)
     297        3552 :     : AArch64TargetMachine(T, TT, CPU, FS, Options, RM, CM, OL, JIT, true) {}
     298             : 
     299           0 : void AArch64beTargetMachine::anchor() { }
     300             : 
     301          34 : AArch64beTargetMachine::AArch64beTargetMachine(
     302             :     const Target &T, const Triple &TT, StringRef CPU, StringRef FS,
     303             :     const TargetOptions &Options, Optional<Reloc::Model> RM,
     304          34 :     Optional<CodeModel::Model> CM, CodeGenOpt::Level OL, bool JIT)
     305          68 :     : AArch64TargetMachine(T, TT, CPU, FS, Options, RM, CM, OL, JIT, false) {}
     306             : 
     307             : namespace {
     308             : 
     309             : /// AArch64 Code Generator Pass Configuration Options.
     310             : class AArch64PassConfig : public TargetPassConfig {
     311             : public:
     312        1583 :   AArch64PassConfig(AArch64TargetMachine &TM, PassManagerBase &PM)
     313        1583 :       : TargetPassConfig(TM, PM) {
     314        1583 :     if (TM.getOptLevel() != CodeGenOpt::None)
     315        2416 :       substitutePass(&PostRASchedulerID, &PostMachineSchedulerID);
     316        1583 :   }
     317             : 
     318             :   AArch64TargetMachine &getAArch64TargetMachine() const {
     319        1180 :     return getTM<AArch64TargetMachine>();
     320             :   }
     321             : 
     322             :   ScheduleDAGInstrs *
     323       13413 :   createMachineScheduler(MachineSchedContext *C) const override {
     324       13413 :     const AArch64Subtarget &ST = C->MF->getSubtarget<AArch64Subtarget>();
     325       13413 :     ScheduleDAGMILive *DAG = createGenericSchedLive(C);
     326       13413 :     DAG->addMutation(createLoadClusterDAGMutation(DAG->TII, DAG->TRI));
     327       26826 :     DAG->addMutation(createStoreClusterDAGMutation(DAG->TII, DAG->TRI));
     328             :     if (ST.hasFusion())
     329       25810 :       DAG->addMutation(createAArch64MacroFusionDAGMutation());
     330       13413 :     return DAG;
     331             :   }
     332             : 
     333             :   ScheduleDAGInstrs *
     334       10367 :   createPostMachineScheduler(MachineSchedContext *C) const override {
     335       10367 :     const AArch64Subtarget &ST = C->MF->getSubtarget<AArch64Subtarget>();
     336             :     if (ST.hasFusion()) {
     337             :       // Run the Macro Fusion after RA again since literals are expanded from
     338             :       // pseudos then (v. addPreSched2()).
     339       10264 :       ScheduleDAGMI *DAG = createGenericSchedPostRA(C);
     340       10264 :       DAG->addMutation(createAArch64MacroFusionDAGMutation());
     341       10264 :       return DAG;
     342             :     }
     343             : 
     344             :     return nullptr;
     345             :   }
     346             : 
     347             :   void addIRPasses()  override;
     348             :   bool addPreISel() override;
     349             :   bool addInstSelector() override;
     350             :   bool addIRTranslator() override;
     351             :   bool addLegalizeMachineIR() override;
     352             :   bool addRegBankSelect() override;
     353             :   void addPreGlobalInstructionSelect() override;
     354             :   bool addGlobalInstructionSelect() override;
     355             :   bool addILPOpts() override;
     356             :   void addPreRegAlloc() override;
     357             :   void addPostRegAlloc() override;
     358             :   void addPreSched2() override;
     359             :   void addPreEmitPass() override;
     360             : };
     361             : 
     362             : } // end anonymous namespace
     363             : 
     364             : TargetTransformInfo
     365      146026 : AArch64TargetMachine::getTargetTransformInfo(const Function &F) {
     366      146026 :   return TargetTransformInfo(AArch64TTIImpl(this, F));
     367             : }
     368             : 
     369        1583 : TargetPassConfig *AArch64TargetMachine::createPassConfig(PassManagerBase &PM) {
     370        1583 :   return new AArch64PassConfig(*this, PM);
     371             : }
     372             : 
     373        1195 : void AArch64PassConfig::addIRPasses() {
     374             :   // Always expand atomic operations, we don't deal with atomicrmw or cmpxchg
     375             :   // ourselves.
     376        1195 :   addPass(createAtomicExpandPass());
     377             : 
     378             :   // Cmpxchg instructions are often used with a subsequent comparison to
     379             :   // determine whether it succeeded. We can exploit existing control-flow in
     380             :   // ldrex/strex loops to simplify this, but it needs tidying up.
     381        1195 :   if (TM->getOptLevel() != CodeGenOpt::None && EnableAtomicTidy)
     382        2122 :     addPass(createCFGSimplificationPass(1, true, true, false, true));
     383             : 
     384             :   // Run LoopDataPrefetch
     385             :   //
     386             :   // Run this before LSR to remove the multiplies involved in computing the
     387             :   // pointer values N iterations ahead.
     388        1195 :   if (TM->getOptLevel() != CodeGenOpt::None) {
     389        1094 :     if (EnableLoopDataPrefetch)
     390        1094 :       addPass(createLoopDataPrefetchPass());
     391        1094 :     if (EnableFalkorHWPFFix)
     392        1094 :       addPass(createFalkorMarkStridedAccessesPass());
     393             :   }
     394             : 
     395        1195 :   TargetPassConfig::addIRPasses();
     396             : 
     397             :   // Match interleaved memory accesses to ldN/stN intrinsics.
     398        1195 :   if (TM->getOptLevel() != CodeGenOpt::None)
     399        1094 :     addPass(createInterleavedAccessPass());
     400             : 
     401        1195 :   if (TM->getOptLevel() == CodeGenOpt::Aggressive && EnableGEPOpt) {
     402             :     // Call SeparateConstOffsetFromGEP pass to extract constants within indices
     403             :     // and lower a GEP with multiple indices to either arithmetic operations or
     404             :     // multiple GEPs with single index.
     405           6 :     addPass(createSeparateConstOffsetFromGEPPass(true));
     406             :     // Call EarlyCSE pass to find and remove subexpressions in the lowered
     407             :     // result.
     408           6 :     addPass(createEarlyCSEPass());
     409             :     // Do loop invariant code motion in case part of the lowered result is
     410             :     // invariant.
     411           6 :     addPass(createLICMPass());
     412             :   }
     413        1195 : }
     414             : 
     415             : // Pass Pipeline Configuration
     416        1195 : bool AArch64PassConfig::addPreISel() {
     417             :   // Run promote constant before global merge, so that the promoted constants
     418             :   // get a chance to be merged
     419        1195 :   if (TM->getOptLevel() != CodeGenOpt::None && EnablePromoteConstant)
     420        1093 :     addPass(createAArch64PromoteConstantPass());
     421             :   // FIXME: On AArch64, this depends on the type.
     422             :   // Basically, the addressable offsets are up to 4095 * Ty.getSizeInBytes().
     423             :   // and the offset has to be a multiple of the related size in bytes.
     424        2289 :   if ((TM->getOptLevel() != CodeGenOpt::None &&
     425        1210 :        EnableGlobalMerge == cl::BOU_UNSET) ||
     426             :       EnableGlobalMerge == cl::BOU_TRUE) {
     427        1094 :     bool OnlyOptimizeForSize = (TM->getOptLevel() < CodeGenOpt::Aggressive) &&
     428             :                                (EnableGlobalMerge == cl::BOU_UNSET);
     429        1094 :     addPass(createGlobalMergePass(TM, 4095, OnlyOptimizeForSize));
     430             :   }
     431             : 
     432        1195 :   return false;
     433             : }
     434             : 
     435        1180 : bool AArch64PassConfig::addInstSelector() {
     436        1180 :   addPass(createAArch64ISelDag(getAArch64TargetMachine(), getOptLevel()));
     437             : 
     438             :   // For ELF, cleanup any local-dynamic TLS accesses (i.e. combine as many
     439             :   // references to _TLS_MODULE_BASE_ as possible.
     440        3205 :   if (TM->getTargetTriple().isOSBinFormatELF() &&
     441         845 :       getOptLevel() != CodeGenOpt::None)
     442         800 :     addPass(createAArch64CleanupLocalDynamicTLSPass());
     443             : 
     444        1180 :   return false;
     445             : }
     446             : 
     447          68 : bool AArch64PassConfig::addIRTranslator() {
     448          68 :   addPass(new IRTranslator());
     449          68 :   return false;
     450             : }
     451             : 
     452          68 : bool AArch64PassConfig::addLegalizeMachineIR() {
     453          68 :   addPass(new Legalizer());
     454          68 :   return false;
     455             : }
     456             : 
     457          68 : bool AArch64PassConfig::addRegBankSelect() {
     458          68 :   addPass(new RegBankSelect());
     459          68 :   return false;
     460             : }
     461             : 
     462          68 : void AArch64PassConfig::addPreGlobalInstructionSelect() {
     463             :   // Workaround the deficiency of the fast register allocator.
     464          68 :   if (TM->getOptLevel() == CodeGenOpt::None)
     465          47 :     addPass(new Localizer());
     466          68 : }
     467             : 
     468          68 : bool AArch64PassConfig::addGlobalInstructionSelect() {
     469          68 :   addPass(new InstructionSelect());
     470          68 :   return false;
     471             : }
     472             : 
     473        1094 : bool AArch64PassConfig::addILPOpts() {
     474        1094 :   if (EnableCondOpt)
     475        1094 :     addPass(createAArch64ConditionOptimizerPass());
     476        1094 :   if (EnableCCMP)
     477        1094 :     addPass(createAArch64ConditionalCompares());
     478        1094 :   if (EnableMCR)
     479        1094 :     addPass(&MachineCombinerID);
     480        1094 :   if (EnableCondBrTuning)
     481        1090 :     addPass(createAArch64CondBrTuning());
     482        1094 :   if (EnableEarlyIfConversion)
     483        1093 :     addPass(&EarlyIfConverterID);
     484        1094 :   if (EnableStPairSuppress)
     485        1091 :     addPass(createAArch64StorePairSuppressPass());
     486        1094 :   addPass(createAArch64SIMDInstrOptPass());
     487        1094 :   return true;
     488             : }
     489             : 
     490        1195 : void AArch64PassConfig::addPreRegAlloc() {
     491             :   // Change dead register definitions to refer to the zero register.
     492        1195 :   if (TM->getOptLevel() != CodeGenOpt::None && EnableDeadRegisterElimination)
     493        1093 :     addPass(createAArch64DeadRegisterDefinitions());
     494             : 
     495             :   // Use AdvSIMD scalar instructions whenever profitable.
     496        1195 :   if (TM->getOptLevel() != CodeGenOpt::None && EnableAdvSIMDScalar) {
     497           5 :     addPass(createAArch64AdvSIMDScalar());
     498             :     // The AdvSIMD pass may produce copies that can be rewritten to
     499             :     // be register coaleascer friendly.
     500           5 :     addPass(&PeepholeOptimizerID);
     501             :   }
     502        1195 : }
     503             : 
     504        1195 : void AArch64PassConfig::addPostRegAlloc() {
     505             :   // Remove redundant copy instructions.
     506        1195 :   if (TM->getOptLevel() != CodeGenOpt::None && EnableRedundantCopyElimination)
     507        1094 :     addPass(createAArch64RedundantCopyEliminationPass());
     508             : 
     509        1195 :   if (TM->getOptLevel() != CodeGenOpt::None && usingDefaultRegAlloc())
     510             :     // Improve performance for some FP/SIMD code for A57.
     511        1088 :     addPass(createAArch64A57FPLoadBalancing());
     512        1195 : }
     513             : 
     514        1195 : void AArch64PassConfig::addPreSched2() {
     515             :   // Expand some pseudo instructions to allow proper scheduling.
     516        1195 :   addPass(createAArch64ExpandPseudoPass());
     517             :   // Use load/store pair instructions when possible.
     518        1195 :   if (TM->getOptLevel() != CodeGenOpt::None) {
     519        1094 :     if (EnableLoadStoreOpt)
     520        1087 :       addPass(createAArch64LoadStoreOptimizationPass());
     521        1094 :     if (EnableFalkorHWPFFix)
     522        1094 :       addPass(createFalkorHWPFFixPass());
     523             :   }
     524        1195 : }
     525             : 
     526        1195 : void AArch64PassConfig::addPreEmitPass() {
     527        1195 :   if (EnableA53Fix835769)
     528           3 :     addPass(createAArch64A53Fix835769());
     529             :   // Relax conditional branch instructions if they're otherwise out of
     530             :   // range of their destination.
     531        1195 :   if (BranchRelaxation)
     532        1195 :     addPass(&BranchRelaxationPassID);
     533             : 
     534        1195 :   if (TM->getOptLevel() != CodeGenOpt::None && EnableCollectLOH &&
     535        1090 :       TM->getTargetTriple().isOSBinFormatMachO())
     536         260 :     addPass(createAArch64CollectLOHPass());
     537        1195 : }

Generated by: LCOV version 1.13