1 //=== lib/CodeGen/GlobalISel/AArch64PreLegalizerCombiner.cpp --------------===// 2 // 3 // The LLVM Compiler Infrastructure 4 // 5 // This file is distributed under the University of Illinois Open Source 6 // License. See LICENSE.TXT for details. 7 // 8 //===----------------------------------------------------------------------===// 9 // 10 // This pass does combining of machine instructions at the generic MI level, 11 // before the legalizer. 12 // 13 //===----------------------------------------------------------------------===// 14 15 #include "AArch64TargetMachine.h" 16 #include "llvm/CodeGen/GlobalISel/Combiner.h" 17 #include "llvm/CodeGen/GlobalISel/CombinerHelper.h" 18 #include "llvm/CodeGen/GlobalISel/CombinerInfo.h" 19 #include "llvm/CodeGen/GlobalISel/MIPatternMatch.h" 20 #include "llvm/CodeGen/MachineFunctionPass.h" 21 #include "llvm/CodeGen/TargetPassConfig.h" 22 #include "llvm/Support/Debug.h" 23 24 #define DEBUG_TYPE "aarch64-prelegalizer-combiner" 25 26 using namespace llvm; 27 using namespace MIPatternMatch; 28 29 namespace { 30 class AArch64PreLegalizerCombinerInfo : public CombinerInfo { 31 public: 32 AArch64PreLegalizerCombinerInfo() 33 : CombinerInfo(/*AllowIllegalOps*/ true, /*ShouldLegalizeIllegal*/ false, 34 /*LegalizerInfo*/ nullptr) {} 35 virtual bool combine(GISelChangeObserver &Observer, MachineInstr &MI, 36 MachineIRBuilder &B) const override; 37 }; 38 39 bool AArch64PreLegalizerCombinerInfo::combine(GISelChangeObserver &Observer, 40 MachineInstr &MI, 41 MachineIRBuilder &B) const { 42 CombinerHelper Helper(Observer, B); 43 44 switch (MI.getOpcode()) { 45 default: 46 return false; 47 case TargetOpcode::G_LOAD: 48 case TargetOpcode::G_SEXTLOAD: 49 case TargetOpcode::G_ZEXTLOAD: 50 return Helper.tryCombineExtendingLoads(MI); 51 } 52 53 return false; 54 } 55 56 // Pass boilerplate 57 // ================ 58 59 class AArch64PreLegalizerCombiner : public MachineFunctionPass { 60 public: 61 static char ID; 62 63 AArch64PreLegalizerCombiner(); 64 65 StringRef getPassName() const override { return "AArch64PreLegalizerCombiner"; } 66 67 bool runOnMachineFunction(MachineFunction &MF) override; 68 69 void getAnalysisUsage(AnalysisUsage &AU) const override; 70 }; 71 } 72 73 void AArch64PreLegalizerCombiner::getAnalysisUsage(AnalysisUsage &AU) const { 74 AU.addRequired<TargetPassConfig>(); 75 AU.setPreservesCFG(); 76 getSelectionDAGFallbackAnalysisUsage(AU); 77 MachineFunctionPass::getAnalysisUsage(AU); 78 } 79 80 AArch64PreLegalizerCombiner::AArch64PreLegalizerCombiner() : MachineFunctionPass(ID) { 81 initializeAArch64PreLegalizerCombinerPass(*PassRegistry::getPassRegistry()); 82 } 83 84 bool AArch64PreLegalizerCombiner::runOnMachineFunction(MachineFunction &MF) { 85 if (MF.getProperties().hasProperty( 86 MachineFunctionProperties::Property::FailedISel)) 87 return false; 88 auto *TPC = &getAnalysis<TargetPassConfig>(); 89 AArch64PreLegalizerCombinerInfo PCInfo; 90 Combiner C(PCInfo, TPC); 91 return C.combineMachineInstrs(MF, /*CSEInfo*/ nullptr); 92 } 93 94 char AArch64PreLegalizerCombiner::ID = 0; 95 INITIALIZE_PASS_BEGIN(AArch64PreLegalizerCombiner, DEBUG_TYPE, 96 "Combine AArch64 machine instrs before legalization", 97 false, false) 98 INITIALIZE_PASS_DEPENDENCY(TargetPassConfig) 99 INITIALIZE_PASS_END(AArch64PreLegalizerCombiner, DEBUG_TYPE, 100 "Combine AArch64 machine instrs before legalization", false, 101 false) 102 103 104 namespace llvm { 105 FunctionPass *createAArch64PreLegalizeCombiner() { 106 return new AArch64PreLegalizerCombiner(); 107 } 108 } // end namespace llvm 109