xref: /llvm-project/llvm/lib/Target/RISCV/GISel/RISCVPreLegalizerCombiner.cpp (revision ee7ca0dddafb609090ad1789570c099d95c0afb6)
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