1 //=== lib/CodeGen/GlobalISel/AMDGPUPreLegalizerCombiner.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 // before the legalizer. 11 // 12 //===----------------------------------------------------------------------===// 13 14 #include "AMDGPU.h" 15 #include "llvm/CodeGen/GlobalISel/Combiner.h" 16 #include "llvm/CodeGen/GlobalISel/CombinerHelper.h" 17 #include "llvm/CodeGen/GlobalISel/CombinerInfo.h" 18 #include "llvm/CodeGen/GlobalISel/GISelKnownBits.h" 19 #include "llvm/CodeGen/GlobalISel/MIPatternMatch.h" 20 #include "llvm/CodeGen/MachineDominators.h" 21 #include "llvm/CodeGen/TargetPassConfig.h" 22 #include "llvm/Target/TargetMachine.h" 23 24 #define DEBUG_TYPE "amdgpu-prelegalizer-combiner" 25 26 using namespace llvm; 27 using namespace MIPatternMatch; 28 29 #define AMDGPUPRELEGALIZERCOMBINERHELPER_GENCOMBINERHELPER_DEPS 30 #include "AMDGPUGenPreLegalizeGICombiner.inc" 31 #undef AMDGPUPRELEGALIZERCOMBINERHELPER_GENCOMBINERHELPER_DEPS 32 33 namespace { 34 #define AMDGPUPRELEGALIZERCOMBINERHELPER_GENCOMBINERHELPER_H 35 #include "AMDGPUGenPreLegalizeGICombiner.inc" 36 #undef AMDGPUPRELEGALIZERCOMBINERHELPER_GENCOMBINERHELPER_H 37 38 class AMDGPUPreLegalizerCombinerInfo final : public CombinerInfo { 39 GISelKnownBits *KB; 40 MachineDominatorTree *MDT; 41 42 public: 43 AMDGPUGenPreLegalizerCombinerHelperRuleConfig GeneratedRuleCfg; 44 45 AMDGPUPreLegalizerCombinerInfo(bool EnableOpt, bool OptSize, bool MinSize, 46 GISelKnownBits *KB, MachineDominatorTree *MDT) 47 : CombinerInfo(/*AllowIllegalOps*/ true, /*ShouldLegalizeIllegal*/ false, 48 /*LegalizerInfo*/ nullptr, EnableOpt, OptSize, MinSize), 49 KB(KB), MDT(MDT) { 50 if (!GeneratedRuleCfg.parseCommandLineOption()) 51 report_fatal_error("Invalid rule identifier"); 52 } 53 54 virtual bool combine(GISelChangeObserver &Observer, MachineInstr &MI, 55 MachineIRBuilder &B) const override; 56 }; 57 58 bool AMDGPUPreLegalizerCombinerInfo::combine(GISelChangeObserver &Observer, 59 MachineInstr &MI, 60 MachineIRBuilder &B) const { 61 CombinerHelper Helper(Observer, B, KB, MDT); 62 AMDGPUGenPreLegalizerCombinerHelper Generated(GeneratedRuleCfg); 63 64 if (Generated.tryCombineAll(Observer, MI, B, Helper)) 65 return true; 66 67 switch (MI.getOpcode()) { 68 case TargetOpcode::G_CONCAT_VECTORS: 69 return Helper.tryCombineConcatVectors(MI); 70 case TargetOpcode::G_SHUFFLE_VECTOR: 71 return Helper.tryCombineShuffleVector(MI); 72 } 73 74 return false; 75 } 76 77 #define AMDGPUPRELEGALIZERCOMBINERHELPER_GENCOMBINERHELPER_CPP 78 #include "AMDGPUGenPreLegalizeGICombiner.inc" 79 #undef AMDGPUPRELEGALIZERCOMBINERHELPER_GENCOMBINERHELPER_CPP 80 81 // Pass boilerplate 82 // ================ 83 84 class AMDGPUPreLegalizerCombiner : public MachineFunctionPass { 85 public: 86 static char ID; 87 88 AMDGPUPreLegalizerCombiner(bool IsOptNone = false); 89 90 StringRef getPassName() const override { 91 return "AMDGPUPreLegalizerCombiner"; 92 } 93 94 bool runOnMachineFunction(MachineFunction &MF) override; 95 96 void getAnalysisUsage(AnalysisUsage &AU) const override; 97 private: 98 bool IsOptNone; 99 }; 100 } // end anonymous namespace 101 102 void AMDGPUPreLegalizerCombiner::getAnalysisUsage(AnalysisUsage &AU) const { 103 AU.addRequired<TargetPassConfig>(); 104 AU.setPreservesCFG(); 105 getSelectionDAGFallbackAnalysisUsage(AU); 106 AU.addRequired<GISelKnownBitsAnalysis>(); 107 AU.addPreserved<GISelKnownBitsAnalysis>(); 108 if (!IsOptNone) { 109 AU.addRequired<MachineDominatorTree>(); 110 AU.addPreserved<MachineDominatorTree>(); 111 } 112 MachineFunctionPass::getAnalysisUsage(AU); 113 } 114 115 AMDGPUPreLegalizerCombiner::AMDGPUPreLegalizerCombiner(bool IsOptNone) 116 : MachineFunctionPass(ID), IsOptNone(IsOptNone) { 117 initializeAMDGPUPreLegalizerCombinerPass(*PassRegistry::getPassRegistry()); 118 } 119 120 bool AMDGPUPreLegalizerCombiner::runOnMachineFunction(MachineFunction &MF) { 121 if (MF.getProperties().hasProperty( 122 MachineFunctionProperties::Property::FailedISel)) 123 return false; 124 auto *TPC = &getAnalysis<TargetPassConfig>(); 125 const Function &F = MF.getFunction(); 126 bool EnableOpt = 127 MF.getTarget().getOptLevel() != CodeGenOpt::None && !skipFunction(F); 128 GISelKnownBits *KB = &getAnalysis<GISelKnownBitsAnalysis>().get(MF); 129 MachineDominatorTree *MDT = 130 IsOptNone ? nullptr : &getAnalysis<MachineDominatorTree>(); 131 AMDGPUPreLegalizerCombinerInfo PCInfo(EnableOpt, F.hasOptSize(), 132 F.hasMinSize(), KB, MDT); 133 Combiner C(PCInfo, TPC); 134 return C.combineMachineInstrs(MF, /*CSEInfo*/ nullptr); 135 } 136 137 char AMDGPUPreLegalizerCombiner::ID = 0; 138 INITIALIZE_PASS_BEGIN(AMDGPUPreLegalizerCombiner, DEBUG_TYPE, 139 "Combine AMDGPU machine instrs before legalization", 140 false, false) 141 INITIALIZE_PASS_DEPENDENCY(TargetPassConfig) 142 INITIALIZE_PASS_DEPENDENCY(GISelKnownBitsAnalysis) 143 INITIALIZE_PASS_END(AMDGPUPreLegalizerCombiner, DEBUG_TYPE, 144 "Combine AMDGPU machine instrs before legalization", false, 145 false) 146 147 namespace llvm { 148 FunctionPass *createAMDGPUPreLegalizeCombiner(bool IsOptNone) { 149 return new AMDGPUPreLegalizerCombiner(IsOptNone); 150 } 151 } // end namespace llvm 152