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

Generated by: LCOV version 1.13