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

Generated by: LCOV version 1.13