18677aaa1SCraig Topper //=== RISCVPreLegalizerCombiner.cpp ---------------------------------------===// 28677aaa1SCraig Topper // 38677aaa1SCraig Topper // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 48677aaa1SCraig Topper // See https://llvm.org/LICENSE.txt for license information. 58677aaa1SCraig Topper // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 68677aaa1SCraig Topper // 78677aaa1SCraig Topper //===----------------------------------------------------------------------===// 88677aaa1SCraig Topper // 98677aaa1SCraig Topper // This pass does combining of machine instructions at the generic MI level, 108677aaa1SCraig Topper // before the legalizer. 118677aaa1SCraig Topper // 128677aaa1SCraig Topper //===----------------------------------------------------------------------===// 138677aaa1SCraig Topper 148677aaa1SCraig Topper #include "RISCVSubtarget.h" 158677aaa1SCraig Topper #include "llvm/CodeGen/GlobalISel/CSEInfo.h" 168677aaa1SCraig Topper #include "llvm/CodeGen/GlobalISel/Combiner.h" 178677aaa1SCraig Topper #include "llvm/CodeGen/GlobalISel/CombinerHelper.h" 188677aaa1SCraig Topper #include "llvm/CodeGen/GlobalISel/CombinerInfo.h" 198677aaa1SCraig Topper #include "llvm/CodeGen/GlobalISel/GIMatchTableExecutorImpl.h" 208677aaa1SCraig Topper #include "llvm/CodeGen/GlobalISel/GISelKnownBits.h" 218677aaa1SCraig Topper #include "llvm/CodeGen/GlobalISel/MachineIRBuilder.h" 228677aaa1SCraig Topper #include "llvm/CodeGen/MachineDominators.h" 238677aaa1SCraig Topper #include "llvm/CodeGen/MachineFunction.h" 248677aaa1SCraig Topper #include "llvm/CodeGen/MachineFunctionPass.h" 258677aaa1SCraig Topper #include "llvm/CodeGen/TargetPassConfig.h" 268677aaa1SCraig Topper 278677aaa1SCraig Topper #define GET_GICOMBINER_DEPS 288677aaa1SCraig Topper #include "RISCVGenPreLegalizeGICombiner.inc" 298677aaa1SCraig Topper #undef GET_GICOMBINER_DEPS 308677aaa1SCraig Topper 318677aaa1SCraig Topper #define DEBUG_TYPE "riscv-prelegalizer-combiner" 328677aaa1SCraig Topper 338677aaa1SCraig Topper using namespace llvm; 348677aaa1SCraig Topper 358677aaa1SCraig Topper namespace { 368677aaa1SCraig Topper 378677aaa1SCraig Topper #define GET_GICOMBINER_TYPES 388677aaa1SCraig Topper #include "RISCVGenPreLegalizeGICombiner.inc" 398677aaa1SCraig Topper #undef GET_GICOMBINER_TYPES 408677aaa1SCraig Topper 418677aaa1SCraig Topper class RISCVPreLegalizerCombinerImpl : public Combiner { 428677aaa1SCraig Topper protected: 43*ee7ca0ddSPaul Bowen-Huggett const CombinerHelper Helper; 448677aaa1SCraig Topper const RISCVPreLegalizerCombinerImplRuleConfig &RuleConfig; 458677aaa1SCraig Topper const RISCVSubtarget &STI; 468677aaa1SCraig Topper 478677aaa1SCraig Topper public: 488677aaa1SCraig Topper RISCVPreLegalizerCombinerImpl( 498677aaa1SCraig Topper MachineFunction &MF, CombinerInfo &CInfo, const TargetPassConfig *TPC, 508677aaa1SCraig Topper GISelKnownBits &KB, GISelCSEInfo *CSEInfo, 518677aaa1SCraig Topper const RISCVPreLegalizerCombinerImplRuleConfig &RuleConfig, 528677aaa1SCraig Topper const RISCVSubtarget &STI, MachineDominatorTree *MDT, 538677aaa1SCraig Topper const LegalizerInfo *LI); 548677aaa1SCraig Topper 558677aaa1SCraig Topper static const char *getName() { return "RISCV00PreLegalizerCombiner"; } 568677aaa1SCraig Topper 578677aaa1SCraig Topper bool tryCombineAll(MachineInstr &I) const override; 588677aaa1SCraig Topper 598677aaa1SCraig Topper private: 608677aaa1SCraig Topper #define GET_GICOMBINER_CLASS_MEMBERS 618677aaa1SCraig Topper #include "RISCVGenPreLegalizeGICombiner.inc" 628677aaa1SCraig Topper #undef GET_GICOMBINER_CLASS_MEMBERS 638677aaa1SCraig Topper }; 648677aaa1SCraig Topper 658677aaa1SCraig Topper #define GET_GICOMBINER_IMPL 668677aaa1SCraig Topper #include "RISCVGenPreLegalizeGICombiner.inc" 678677aaa1SCraig Topper #undef GET_GICOMBINER_IMPL 688677aaa1SCraig Topper 698677aaa1SCraig Topper RISCVPreLegalizerCombinerImpl::RISCVPreLegalizerCombinerImpl( 708677aaa1SCraig Topper MachineFunction &MF, CombinerInfo &CInfo, const TargetPassConfig *TPC, 718677aaa1SCraig Topper GISelKnownBits &KB, GISelCSEInfo *CSEInfo, 728677aaa1SCraig Topper const RISCVPreLegalizerCombinerImplRuleConfig &RuleConfig, 738677aaa1SCraig Topper const RISCVSubtarget &STI, MachineDominatorTree *MDT, 748677aaa1SCraig Topper const LegalizerInfo *LI) 758677aaa1SCraig Topper : Combiner(MF, CInfo, TPC, &KB, CSEInfo), 768677aaa1SCraig Topper Helper(Observer, B, /*IsPreLegalize*/ true, &KB, MDT, LI), 778677aaa1SCraig Topper RuleConfig(RuleConfig), STI(STI), 788677aaa1SCraig Topper #define GET_GICOMBINER_CONSTRUCTOR_INITS 798677aaa1SCraig Topper #include "RISCVGenPreLegalizeGICombiner.inc" 808677aaa1SCraig Topper #undef GET_GICOMBINER_CONSTRUCTOR_INITS 818677aaa1SCraig Topper { 828677aaa1SCraig Topper } 838677aaa1SCraig Topper 848677aaa1SCraig Topper // Pass boilerplate 858677aaa1SCraig Topper // ================ 868677aaa1SCraig Topper 878677aaa1SCraig Topper class RISCVPreLegalizerCombiner : public MachineFunctionPass { 888677aaa1SCraig Topper public: 898677aaa1SCraig Topper static char ID; 908677aaa1SCraig Topper 918677aaa1SCraig Topper RISCVPreLegalizerCombiner(); 928677aaa1SCraig Topper 938677aaa1SCraig Topper StringRef getPassName() const override { return "RISCVPreLegalizerCombiner"; } 948677aaa1SCraig Topper 958677aaa1SCraig Topper bool runOnMachineFunction(MachineFunction &MF) override; 968677aaa1SCraig Topper 978677aaa1SCraig Topper void getAnalysisUsage(AnalysisUsage &AU) const override; 988677aaa1SCraig Topper 998677aaa1SCraig Topper private: 1008677aaa1SCraig Topper RISCVPreLegalizerCombinerImplRuleConfig RuleConfig; 1018677aaa1SCraig Topper }; 1028677aaa1SCraig Topper } // end anonymous namespace 1038677aaa1SCraig Topper 1048677aaa1SCraig Topper void RISCVPreLegalizerCombiner::getAnalysisUsage(AnalysisUsage &AU) const { 1058677aaa1SCraig Topper AU.addRequired<TargetPassConfig>(); 1068677aaa1SCraig Topper AU.setPreservesCFG(); 1078677aaa1SCraig Topper getSelectionDAGFallbackAnalysisUsage(AU); 1088677aaa1SCraig Topper AU.addRequired<GISelKnownBitsAnalysis>(); 1098677aaa1SCraig Topper AU.addPreserved<GISelKnownBitsAnalysis>(); 110837dc542Spaperchalice AU.addRequired<MachineDominatorTreeWrapperPass>(); 111837dc542Spaperchalice AU.addPreserved<MachineDominatorTreeWrapperPass>(); 1128677aaa1SCraig Topper AU.addRequired<GISelCSEAnalysisWrapperPass>(); 1138677aaa1SCraig Topper AU.addPreserved<GISelCSEAnalysisWrapperPass>(); 1148677aaa1SCraig Topper MachineFunctionPass::getAnalysisUsage(AU); 1158677aaa1SCraig Topper } 1168677aaa1SCraig Topper 1178677aaa1SCraig Topper RISCVPreLegalizerCombiner::RISCVPreLegalizerCombiner() 1188677aaa1SCraig Topper : MachineFunctionPass(ID) { 1198677aaa1SCraig Topper initializeRISCVPreLegalizerCombinerPass(*PassRegistry::getPassRegistry()); 1208677aaa1SCraig Topper 1218677aaa1SCraig Topper if (!RuleConfig.parseCommandLineOption()) 1228677aaa1SCraig Topper report_fatal_error("Invalid rule identifier"); 1238677aaa1SCraig Topper } 1248677aaa1SCraig Topper 1258677aaa1SCraig Topper bool RISCVPreLegalizerCombiner::runOnMachineFunction(MachineFunction &MF) { 1268677aaa1SCraig Topper if (MF.getProperties().hasProperty( 1278677aaa1SCraig Topper MachineFunctionProperties::Property::FailedISel)) 1288677aaa1SCraig Topper return false; 1298677aaa1SCraig Topper auto &TPC = getAnalysis<TargetPassConfig>(); 1308677aaa1SCraig Topper 1318677aaa1SCraig Topper // Enable CSE. 1328677aaa1SCraig Topper GISelCSEAnalysisWrapper &Wrapper = 1338677aaa1SCraig Topper getAnalysis<GISelCSEAnalysisWrapperPass>().getCSEWrapper(); 1348677aaa1SCraig Topper auto *CSEInfo = &Wrapper.get(TPC.getCSEConfig()); 1358677aaa1SCraig Topper 1368677aaa1SCraig Topper const RISCVSubtarget &ST = MF.getSubtarget<RISCVSubtarget>(); 1378677aaa1SCraig Topper const auto *LI = ST.getLegalizerInfo(); 1388677aaa1SCraig Topper 1398677aaa1SCraig Topper const Function &F = MF.getFunction(); 1408677aaa1SCraig Topper bool EnableOpt = 1418677aaa1SCraig Topper MF.getTarget().getOptLevel() != CodeGenOptLevel::None && !skipFunction(F); 1428677aaa1SCraig Topper GISelKnownBits *KB = &getAnalysis<GISelKnownBitsAnalysis>().get(MF); 143837dc542Spaperchalice MachineDominatorTree *MDT = 144837dc542Spaperchalice &getAnalysis<MachineDominatorTreeWrapperPass>().getDomTree(); 1458677aaa1SCraig Topper CombinerInfo CInfo(/*AllowIllegalOps*/ true, /*ShouldLegalizeIllegal*/ false, 1468677aaa1SCraig Topper /*LegalizerInfo*/ nullptr, EnableOpt, F.hasOptSize(), 1478677aaa1SCraig Topper F.hasMinSize()); 1484bd6e15aSCraig Topper // Disable fixed-point iteration to reduce compile-time 1494bd6e15aSCraig Topper CInfo.MaxIterations = 1; 1504bd6e15aSCraig Topper CInfo.ObserverLvl = CombinerInfo::ObserverLevel::SinglePass; 1514bd6e15aSCraig Topper // This is the first Combiner, so the input IR might contain dead 1524bd6e15aSCraig Topper // instructions. 1534bd6e15aSCraig Topper CInfo.EnableFullDCE = true; 1548677aaa1SCraig Topper RISCVPreLegalizerCombinerImpl Impl(MF, CInfo, &TPC, *KB, CSEInfo, RuleConfig, 1558677aaa1SCraig Topper ST, MDT, LI); 1568677aaa1SCraig Topper return Impl.combineMachineInstrs(); 1578677aaa1SCraig Topper } 1588677aaa1SCraig Topper 1598677aaa1SCraig Topper char RISCVPreLegalizerCombiner::ID = 0; 1608677aaa1SCraig Topper INITIALIZE_PASS_BEGIN(RISCVPreLegalizerCombiner, DEBUG_TYPE, 1618e87dc10SCraig Topper "Combine RISC-V machine instrs before legalization", false, 1628677aaa1SCraig Topper false) 1638677aaa1SCraig Topper INITIALIZE_PASS_DEPENDENCY(TargetPassConfig) 1648677aaa1SCraig Topper INITIALIZE_PASS_DEPENDENCY(GISelKnownBitsAnalysis) 1658677aaa1SCraig Topper INITIALIZE_PASS_DEPENDENCY(GISelCSEAnalysisWrapperPass) 1668677aaa1SCraig Topper INITIALIZE_PASS_END(RISCVPreLegalizerCombiner, DEBUG_TYPE, 1678e87dc10SCraig Topper "Combine RISC-V machine instrs before legalization", false, 1688677aaa1SCraig Topper false) 1698677aaa1SCraig Topper 1708677aaa1SCraig Topper namespace llvm { 1718677aaa1SCraig Topper FunctionPass *createRISCVPreLegalizerCombiner() { 1728677aaa1SCraig Topper return new RISCVPreLegalizerCombiner(); 1738677aaa1SCraig Topper } 1748677aaa1SCraig Topper } // end namespace llvm 175