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

Generated by: LCOV version 1.13