1 //=== lib/CodeGen/GlobalISel/MipsPreLegalizerCombiner.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 "MipsTargetMachine.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/MIPatternMatch.h" 19 #include "llvm/CodeGen/TargetPassConfig.h" 20 #include "llvm/InitializePasses.h" 21 22 #define DEBUG_TYPE "mips-prelegalizer-combiner" 23 24 using namespace llvm; 25 26 namespace { 27 class MipsPreLegalizerCombinerInfo : public CombinerInfo { 28 public: 29 MipsPreLegalizerCombinerInfo() 30 : CombinerInfo(/*AllowIllegalOps*/ true, /*ShouldLegalizeIllegal*/ false, 31 /*LegalizerInfo*/ nullptr, /*EnableOpt*/ false, 32 /*EnableOptSize*/ false, /*EnableMinSize*/ false) {} 33 virtual bool combine(GISelChangeObserver &Observer, MachineInstr &MI, 34 MachineIRBuilder &B) const override; 35 }; 36 37 bool MipsPreLegalizerCombinerInfo::combine(GISelChangeObserver &Observer, 38 MachineInstr &MI, 39 MachineIRBuilder &B) const { 40 CombinerHelper Helper(Observer, B); 41 42 switch (MI.getOpcode()) { 43 default: 44 return false; 45 case TargetOpcode::G_LOAD: 46 case TargetOpcode::G_SEXTLOAD: 47 case TargetOpcode::G_ZEXTLOAD: { 48 // Don't attempt to combine non power of 2 loads or unaligned loads when 49 // subtarget doesn't support them. 50 auto MMO = *MI.memoperands_begin(); 51 const MipsSubtarget &STI = 52 static_cast<const MipsSubtarget &>(MI.getMF()->getSubtarget()); 53 if (!isPowerOf2_64(MMO->getSize())) 54 return false; 55 bool isUnaligned = MMO->getAlign() < MMO->getSize(); 56 if (!STI.systemSupportsUnalignedAccess() && isUnaligned) 57 return false; 58 59 return Helper.tryCombineExtendingLoads(MI); 60 } 61 } 62 63 return false; 64 } 65 66 // Pass boilerplate 67 // ================ 68 69 class MipsPreLegalizerCombiner : public MachineFunctionPass { 70 public: 71 static char ID; 72 73 MipsPreLegalizerCombiner(); 74 75 StringRef getPassName() const override { return "MipsPreLegalizerCombiner"; } 76 77 bool runOnMachineFunction(MachineFunction &MF) override; 78 79 void getAnalysisUsage(AnalysisUsage &AU) const override; 80 }; 81 } // end anonymous namespace 82 83 void MipsPreLegalizerCombiner::getAnalysisUsage(AnalysisUsage &AU) const { 84 AU.addRequired<TargetPassConfig>(); 85 AU.setPreservesCFG(); 86 getSelectionDAGFallbackAnalysisUsage(AU); 87 MachineFunctionPass::getAnalysisUsage(AU); 88 } 89 90 MipsPreLegalizerCombiner::MipsPreLegalizerCombiner() : MachineFunctionPass(ID) { 91 initializeMipsPreLegalizerCombinerPass(*PassRegistry::getPassRegistry()); 92 } 93 94 bool MipsPreLegalizerCombiner::runOnMachineFunction(MachineFunction &MF) { 95 if (MF.getProperties().hasProperty( 96 MachineFunctionProperties::Property::FailedISel)) 97 return false; 98 auto *TPC = &getAnalysis<TargetPassConfig>(); 99 MipsPreLegalizerCombinerInfo PCInfo; 100 Combiner C(PCInfo, TPC); 101 return C.combineMachineInstrs(MF, nullptr); 102 } 103 104 char MipsPreLegalizerCombiner::ID = 0; 105 INITIALIZE_PASS_BEGIN(MipsPreLegalizerCombiner, DEBUG_TYPE, 106 "Combine Mips machine instrs before legalization", false, 107 false) 108 INITIALIZE_PASS_DEPENDENCY(TargetPassConfig) 109 INITIALIZE_PASS_END(MipsPreLegalizerCombiner, DEBUG_TYPE, 110 "Combine Mips machine instrs before legalization", false, 111 false) 112 113 namespace llvm { 114 FunctionPass *createMipsPreLegalizeCombiner() { 115 return new MipsPreLegalizerCombiner(); 116 } 117 } // end namespace llvm 118