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 "AMDGPUTargetMachine.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/MachineFunctionPass.h" 22 #include "llvm/CodeGen/TargetPassConfig.h" 23 #include "llvm/Support/Debug.h" 24 25 #define DEBUG_TYPE "amdgpu-prelegalizer-combiner" 26 27 using namespace llvm; 28 using namespace MIPatternMatch; 29 30 #define AMDGPUPRELEGALIZERCOMBINERHELPER_GENCOMBINERHELPER_DEPS 31 #include "AMDGPUGenGICombiner.inc" 32 #undef AMDGPUPRELEGALIZERCOMBINERHELPER_GENCOMBINERHELPER_DEPS 33 34 namespace { 35 #define AMDGPUPRELEGALIZERCOMBINERHELPER_GENCOMBINERHELPER_H 36 #include "AMDGPUGenGICombiner.inc" 37 #undef AMDGPUPRELEGALIZERCOMBINERHELPER_GENCOMBINERHELPER_H 38 39 class AMDGPUPreLegalizerCombinerInfo : public CombinerInfo { 40 GISelKnownBits *KB; 41 MachineDominatorTree *MDT; 42 43 public: 44 AMDGPUGenPreLegalizerCombinerHelper Generated; 45 46 AMDGPUPreLegalizerCombinerInfo(bool EnableOpt, bool OptSize, bool MinSize, 47 GISelKnownBits *KB, MachineDominatorTree *MDT) 48 : CombinerInfo(/*AllowIllegalOps*/ true, /*ShouldLegalizeIllegal*/ false, 49 /*LegalizerInfo*/ nullptr, EnableOpt, OptSize, MinSize), 50 KB(KB), MDT(MDT) { 51 if (!Generated.parseCommandLineOption()) 52 report_fatal_error("Invalid rule identifier"); 53 } 54 55 virtual bool combine(GISelChangeObserver &Observer, MachineInstr &MI, 56 MachineIRBuilder &B) const override; 57 }; 58 59 bool AMDGPUPreLegalizerCombinerInfo::combine(GISelChangeObserver &Observer, 60 MachineInstr &MI, 61 MachineIRBuilder &B) const { 62 CombinerHelper Helper(Observer, B, KB, MDT); 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 "AMDGPUGenGICombiner.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 { return "AMDGPUPreLegalizerCombiner"; } 91 92 bool runOnMachineFunction(MachineFunction &MF) override; 93 94 void getAnalysisUsage(AnalysisUsage &AU) const override; 95 private: 96 bool IsOptNone; 97 }; 98 } // end anonymous namespace 99 100 void AMDGPUPreLegalizerCombiner::getAnalysisUsage(AnalysisUsage &AU) const { 101 AU.addRequired<TargetPassConfig>(); 102 AU.setPreservesCFG(); 103 getSelectionDAGFallbackAnalysisUsage(AU); 104 AU.addRequired<GISelKnownBitsAnalysis>(); 105 AU.addPreserved<GISelKnownBitsAnalysis>(); 106 if (!IsOptNone) { 107 AU.addRequired<MachineDominatorTree>(); 108 AU.addPreserved<MachineDominatorTree>(); 109 } 110 MachineFunctionPass::getAnalysisUsage(AU); 111 } 112 113 AMDGPUPreLegalizerCombiner::AMDGPUPreLegalizerCombiner(bool IsOptNone) 114 : MachineFunctionPass(ID), IsOptNone(IsOptNone) { 115 initializeAMDGPUPreLegalizerCombinerPass(*PassRegistry::getPassRegistry()); 116 } 117 118 bool AMDGPUPreLegalizerCombiner::runOnMachineFunction(MachineFunction &MF) { 119 if (MF.getProperties().hasProperty( 120 MachineFunctionProperties::Property::FailedISel)) 121 return false; 122 auto *TPC = &getAnalysis<TargetPassConfig>(); 123 const Function &F = MF.getFunction(); 124 bool EnableOpt = 125 MF.getTarget().getOptLevel() != CodeGenOpt::None && !skipFunction(F); 126 GISelKnownBits *KB = &getAnalysis<GISelKnownBitsAnalysis>().get(MF); 127 MachineDominatorTree *MDT = 128 IsOptNone ? nullptr : &getAnalysis<MachineDominatorTree>(); 129 AMDGPUPreLegalizerCombinerInfo PCInfo(EnableOpt, F.hasOptSize(), 130 F.hasMinSize(), KB, MDT); 131 Combiner C(PCInfo, TPC); 132 return C.combineMachineInstrs(MF, /*CSEInfo*/ nullptr); 133 } 134 135 char AMDGPUPreLegalizerCombiner::ID = 0; 136 INITIALIZE_PASS_BEGIN(AMDGPUPreLegalizerCombiner, DEBUG_TYPE, 137 "Combine AMDGPU machine instrs before legalization", 138 false, false) 139 INITIALIZE_PASS_DEPENDENCY(TargetPassConfig) 140 INITIALIZE_PASS_DEPENDENCY(GISelKnownBitsAnalysis) 141 INITIALIZE_PASS_END(AMDGPUPreLegalizerCombiner, DEBUG_TYPE, 142 "Combine AMDGPU machine instrs before legalization", false, 143 false) 144 145 namespace llvm { 146 FunctionPass *createAMDGPUPreLegalizeCombiner(bool IsOptNone) { 147 return new AMDGPUPreLegalizerCombiner(IsOptNone); 148 } 149 } // end namespace llvm 150