1 //=== lib/CodeGen/GlobalISel/AMDGPURegBankCombiner.cpp ---------------===// 2 // 3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4 // See https://llvm.org/LICENSE.txt for license information. 5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6 // 7 //===----------------------------------------------------------------------===// 8 // 9 // This pass does combining of machine instructions at the generic MI level, 10 // after register banks are known. 11 // 12 //===----------------------------------------------------------------------===// 13 14 #include "AMDGPU.h" 15 #include "AMDGPULegalizerInfo.h" 16 #include "GCNSubtarget.h" 17 #include "llvm/CodeGen/GlobalISel/Combiner.h" 18 #include "llvm/CodeGen/GlobalISel/CombinerHelper.h" 19 #include "llvm/CodeGen/GlobalISel/CombinerInfo.h" 20 #include "llvm/CodeGen/GlobalISel/GISelKnownBits.h" 21 #include "llvm/CodeGen/GlobalISel/MIPatternMatch.h" 22 #include "llvm/CodeGen/MachineDominators.h" 23 #include "llvm/CodeGen/TargetPassConfig.h" 24 #include "llvm/Target/TargetMachine.h" 25 #define DEBUG_TYPE "amdgpu-regbank-combiner" 26 27 using namespace llvm; 28 using namespace MIPatternMatch; 29 30 31 #define AMDGPUREGBANKCOMBINERHELPER_GENCOMBINERHELPER_DEPS 32 #include "AMDGPUGenRegBankGICombiner.inc" 33 #undef AMDGPUREGBANKCOMBINERHELPER_GENCOMBINERHELPER_DEPS 34 35 namespace { 36 #define AMDGPUREGBANKCOMBINERHELPER_GENCOMBINERHELPER_H 37 #include "AMDGPUGenRegBankGICombiner.inc" 38 #undef AMDGPUREGBANKCOMBINERHELPER_GENCOMBINERHELPER_H 39 40 class AMDGPURegBankCombinerInfo final : public CombinerInfo { 41 GISelKnownBits *KB; 42 MachineDominatorTree *MDT; 43 44 public: 45 AMDGPUGenRegBankCombinerHelperRuleConfig GeneratedRuleCfg; 46 47 AMDGPURegBankCombinerInfo(bool EnableOpt, bool OptSize, bool MinSize, 48 const AMDGPULegalizerInfo *LI, 49 GISelKnownBits *KB, MachineDominatorTree *MDT) 50 : CombinerInfo(/*AllowIllegalOps*/ false, /*ShouldLegalizeIllegal*/ true, 51 /*LegalizerInfo*/ LI, EnableOpt, OptSize, MinSize), 52 KB(KB), MDT(MDT) { 53 if (!GeneratedRuleCfg.parseCommandLineOption()) 54 report_fatal_error("Invalid rule identifier"); 55 } 56 57 bool combine(GISelChangeObserver &Observer, MachineInstr &MI, 58 MachineIRBuilder &B) const override; 59 }; 60 61 bool AMDGPURegBankCombinerInfo::combine(GISelChangeObserver &Observer, 62 MachineInstr &MI, 63 MachineIRBuilder &B) const { 64 CombinerHelper Helper(Observer, B, KB, MDT); 65 AMDGPUGenRegBankCombinerHelper Generated(GeneratedRuleCfg); 66 67 if (Generated.tryCombineAll(Observer, MI, B, Helper)) 68 return true; 69 70 return false; 71 } 72 73 #define AMDGPUREGBANKCOMBINERHELPER_GENCOMBINERHELPER_CPP 74 #include "AMDGPUGenRegBankGICombiner.inc" 75 #undef AMDGPUREGBANKCOMBINERHELPER_GENCOMBINERHELPER_CPP 76 77 // Pass boilerplate 78 // ================ 79 80 class AMDGPURegBankCombiner : public MachineFunctionPass { 81 public: 82 static char ID; 83 84 AMDGPURegBankCombiner(bool IsOptNone = false); 85 86 StringRef getPassName() const override { 87 return "AMDGPURegBankCombiner"; 88 } 89 90 bool runOnMachineFunction(MachineFunction &MF) override; 91 92 void getAnalysisUsage(AnalysisUsage &AU) const override; 93 private: 94 bool IsOptNone; 95 }; 96 } // end anonymous namespace 97 98 void AMDGPURegBankCombiner::getAnalysisUsage(AnalysisUsage &AU) const { 99 AU.addRequired<TargetPassConfig>(); 100 AU.setPreservesCFG(); 101 getSelectionDAGFallbackAnalysisUsage(AU); 102 AU.addRequired<GISelKnownBitsAnalysis>(); 103 AU.addPreserved<GISelKnownBitsAnalysis>(); 104 if (!IsOptNone) { 105 AU.addRequired<MachineDominatorTree>(); 106 AU.addPreserved<MachineDominatorTree>(); 107 } 108 MachineFunctionPass::getAnalysisUsage(AU); 109 } 110 111 AMDGPURegBankCombiner::AMDGPURegBankCombiner(bool IsOptNone) 112 : MachineFunctionPass(ID), IsOptNone(IsOptNone) { 113 initializeAMDGPURegBankCombinerPass(*PassRegistry::getPassRegistry()); 114 } 115 116 bool AMDGPURegBankCombiner::runOnMachineFunction(MachineFunction &MF) { 117 if (MF.getProperties().hasProperty( 118 MachineFunctionProperties::Property::FailedISel)) 119 return false; 120 auto *TPC = &getAnalysis<TargetPassConfig>(); 121 const Function &F = MF.getFunction(); 122 bool EnableOpt = 123 MF.getTarget().getOptLevel() != CodeGenOpt::None && !skipFunction(F); 124 125 const GCNSubtarget &ST = MF.getSubtarget<GCNSubtarget>(); 126 const AMDGPULegalizerInfo *LI 127 = static_cast<const AMDGPULegalizerInfo *>(ST.getLegalizerInfo()); 128 129 GISelKnownBits *KB = &getAnalysis<GISelKnownBitsAnalysis>().get(MF); 130 MachineDominatorTree *MDT = 131 IsOptNone ? nullptr : &getAnalysis<MachineDominatorTree>(); 132 AMDGPURegBankCombinerInfo PCInfo(EnableOpt, F.hasOptSize(), 133 F.hasMinSize(), LI, KB, MDT); 134 Combiner C(PCInfo, TPC); 135 return C.combineMachineInstrs(MF, /*CSEInfo*/ nullptr); 136 } 137 138 char AMDGPURegBankCombiner::ID = 0; 139 INITIALIZE_PASS_BEGIN(AMDGPURegBankCombiner, DEBUG_TYPE, 140 "Combine AMDGPU machine instrs after regbankselect", 141 false, false) 142 INITIALIZE_PASS_DEPENDENCY(TargetPassConfig) 143 INITIALIZE_PASS_DEPENDENCY(GISelKnownBitsAnalysis) 144 INITIALIZE_PASS_END(AMDGPURegBankCombiner, DEBUG_TYPE, 145 "Combine AMDGPU machine instrs after regbankselect", false, 146 false) 147 148 namespace llvm { 149 FunctionPass *createAMDGPURegBankCombiner(bool IsOptNone) { 150 return new AMDGPURegBankCombiner(IsOptNone); 151 } 152 } // end namespace llvm 153