xref: /freebsd-src/contrib/llvm-project/llvm/lib/Target/RISCV/GISel/RISCVPostLegalizerCombiner.cpp (revision 0fca6ea1d4eea4c934cfff25ac9ee8ad6fe95583)
15f757f3fSDimitry Andric //=== RISCVPostLegalizerCombiner.cpp --------------------------*- C++ -*-===//
25f757f3fSDimitry Andric //
35f757f3fSDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
45f757f3fSDimitry Andric // See https://llvm.org/LICENSE.txt for license information.
55f757f3fSDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
65f757f3fSDimitry Andric //
75f757f3fSDimitry Andric //===----------------------------------------------------------------------===//
85f757f3fSDimitry Andric ///
95f757f3fSDimitry Andric /// \file
105f757f3fSDimitry Andric /// Post-legalization combines on generic MachineInstrs.
115f757f3fSDimitry Andric ///
125f757f3fSDimitry Andric /// The combines here must preserve instruction legality.
135f757f3fSDimitry Andric ///
145f757f3fSDimitry Andric /// Combines which don't rely on instruction legality should go in the
155f757f3fSDimitry Andric /// RISCVPreLegalizerCombiner.
165f757f3fSDimitry Andric ///
175f757f3fSDimitry Andric //===----------------------------------------------------------------------===//
185f757f3fSDimitry Andric 
195f757f3fSDimitry Andric #include "RISCVTargetMachine.h"
205f757f3fSDimitry Andric #include "llvm/CodeGen/GlobalISel/CSEInfo.h"
215f757f3fSDimitry Andric #include "llvm/CodeGen/GlobalISel/Combiner.h"
225f757f3fSDimitry Andric #include "llvm/CodeGen/GlobalISel/CombinerHelper.h"
235f757f3fSDimitry Andric #include "llvm/CodeGen/GlobalISel/CombinerInfo.h"
245f757f3fSDimitry Andric #include "llvm/CodeGen/GlobalISel/GIMatchTableExecutorImpl.h"
255f757f3fSDimitry Andric #include "llvm/CodeGen/GlobalISel/GISelKnownBits.h"
265f757f3fSDimitry Andric #include "llvm/CodeGen/GlobalISel/GenericMachineInstrs.h"
275f757f3fSDimitry Andric #include "llvm/CodeGen/GlobalISel/MachineIRBuilder.h"
285f757f3fSDimitry Andric #include "llvm/CodeGen/MachineDominators.h"
295f757f3fSDimitry Andric #include "llvm/CodeGen/MachineFunctionPass.h"
305f757f3fSDimitry Andric #include "llvm/CodeGen/MachineRegisterInfo.h"
315f757f3fSDimitry Andric #include "llvm/CodeGen/TargetPassConfig.h"
325f757f3fSDimitry Andric 
335f757f3fSDimitry Andric #define GET_GICOMBINER_DEPS
345f757f3fSDimitry Andric #include "RISCVGenPostLegalizeGICombiner.inc"
355f757f3fSDimitry Andric #undef GET_GICOMBINER_DEPS
365f757f3fSDimitry Andric 
375f757f3fSDimitry Andric #define DEBUG_TYPE "riscv-postlegalizer-combiner"
385f757f3fSDimitry Andric 
395f757f3fSDimitry Andric using namespace llvm;
405f757f3fSDimitry Andric 
415f757f3fSDimitry Andric namespace {
425f757f3fSDimitry Andric 
435f757f3fSDimitry Andric #define GET_GICOMBINER_TYPES
445f757f3fSDimitry Andric #include "RISCVGenPostLegalizeGICombiner.inc"
455f757f3fSDimitry Andric #undef GET_GICOMBINER_TYPES
465f757f3fSDimitry Andric 
475f757f3fSDimitry Andric class RISCVPostLegalizerCombinerImpl : public Combiner {
485f757f3fSDimitry Andric protected:
495f757f3fSDimitry Andric   // TODO: Make CombinerHelper methods const.
505f757f3fSDimitry Andric   mutable CombinerHelper Helper;
515f757f3fSDimitry Andric   const RISCVPostLegalizerCombinerImplRuleConfig &RuleConfig;
525f757f3fSDimitry Andric   const RISCVSubtarget &STI;
535f757f3fSDimitry Andric 
545f757f3fSDimitry Andric public:
555f757f3fSDimitry Andric   RISCVPostLegalizerCombinerImpl(
565f757f3fSDimitry Andric       MachineFunction &MF, CombinerInfo &CInfo, const TargetPassConfig *TPC,
575f757f3fSDimitry Andric       GISelKnownBits &KB, GISelCSEInfo *CSEInfo,
585f757f3fSDimitry Andric       const RISCVPostLegalizerCombinerImplRuleConfig &RuleConfig,
595f757f3fSDimitry Andric       const RISCVSubtarget &STI, MachineDominatorTree *MDT,
605f757f3fSDimitry Andric       const LegalizerInfo *LI);
615f757f3fSDimitry Andric 
625f757f3fSDimitry Andric   static const char *getName() { return "RISCVPostLegalizerCombiner"; }
635f757f3fSDimitry Andric 
645f757f3fSDimitry Andric   bool tryCombineAll(MachineInstr &I) const override;
655f757f3fSDimitry Andric 
665f757f3fSDimitry Andric private:
675f757f3fSDimitry Andric #define GET_GICOMBINER_CLASS_MEMBERS
685f757f3fSDimitry Andric #include "RISCVGenPostLegalizeGICombiner.inc"
695f757f3fSDimitry Andric #undef GET_GICOMBINER_CLASS_MEMBERS
705f757f3fSDimitry Andric };
715f757f3fSDimitry Andric 
725f757f3fSDimitry Andric #define GET_GICOMBINER_IMPL
735f757f3fSDimitry Andric #include "RISCVGenPostLegalizeGICombiner.inc"
745f757f3fSDimitry Andric #undef GET_GICOMBINER_IMPL
755f757f3fSDimitry Andric 
765f757f3fSDimitry Andric RISCVPostLegalizerCombinerImpl::RISCVPostLegalizerCombinerImpl(
775f757f3fSDimitry Andric     MachineFunction &MF, CombinerInfo &CInfo, const TargetPassConfig *TPC,
785f757f3fSDimitry Andric     GISelKnownBits &KB, GISelCSEInfo *CSEInfo,
795f757f3fSDimitry Andric     const RISCVPostLegalizerCombinerImplRuleConfig &RuleConfig,
805f757f3fSDimitry Andric     const RISCVSubtarget &STI, MachineDominatorTree *MDT,
815f757f3fSDimitry Andric     const LegalizerInfo *LI)
825f757f3fSDimitry Andric     : Combiner(MF, CInfo, TPC, &KB, CSEInfo),
835f757f3fSDimitry Andric       Helper(Observer, B, /*IsPreLegalize*/ false, &KB, MDT, LI),
845f757f3fSDimitry Andric       RuleConfig(RuleConfig), STI(STI),
855f757f3fSDimitry Andric #define GET_GICOMBINER_CONSTRUCTOR_INITS
865f757f3fSDimitry Andric #include "RISCVGenPostLegalizeGICombiner.inc"
875f757f3fSDimitry Andric #undef GET_GICOMBINER_CONSTRUCTOR_INITS
885f757f3fSDimitry Andric {
895f757f3fSDimitry Andric }
905f757f3fSDimitry Andric 
915f757f3fSDimitry Andric class RISCVPostLegalizerCombiner : public MachineFunctionPass {
925f757f3fSDimitry Andric public:
935f757f3fSDimitry Andric   static char ID;
945f757f3fSDimitry Andric 
955f757f3fSDimitry Andric   RISCVPostLegalizerCombiner();
965f757f3fSDimitry Andric 
975f757f3fSDimitry Andric   StringRef getPassName() const override {
985f757f3fSDimitry Andric     return "RISCVPostLegalizerCombiner";
995f757f3fSDimitry Andric   }
1005f757f3fSDimitry Andric 
1015f757f3fSDimitry Andric   bool runOnMachineFunction(MachineFunction &MF) override;
1025f757f3fSDimitry Andric   void getAnalysisUsage(AnalysisUsage &AU) const override;
1035f757f3fSDimitry Andric 
1045f757f3fSDimitry Andric private:
1055f757f3fSDimitry Andric   RISCVPostLegalizerCombinerImplRuleConfig RuleConfig;
1065f757f3fSDimitry Andric };
1075f757f3fSDimitry Andric } // end anonymous namespace
1085f757f3fSDimitry Andric 
1095f757f3fSDimitry Andric void RISCVPostLegalizerCombiner::getAnalysisUsage(AnalysisUsage &AU) const {
1105f757f3fSDimitry Andric   AU.addRequired<TargetPassConfig>();
1115f757f3fSDimitry Andric   AU.setPreservesCFG();
1125f757f3fSDimitry Andric   getSelectionDAGFallbackAnalysisUsage(AU);
1135f757f3fSDimitry Andric   AU.addRequired<GISelKnownBitsAnalysis>();
1145f757f3fSDimitry Andric   AU.addPreserved<GISelKnownBitsAnalysis>();
115*0fca6ea1SDimitry Andric   AU.addRequired<MachineDominatorTreeWrapperPass>();
116*0fca6ea1SDimitry Andric   AU.addPreserved<MachineDominatorTreeWrapperPass>();
1175f757f3fSDimitry Andric   AU.addRequired<GISelCSEAnalysisWrapperPass>();
1185f757f3fSDimitry Andric   AU.addPreserved<GISelCSEAnalysisWrapperPass>();
1195f757f3fSDimitry Andric   MachineFunctionPass::getAnalysisUsage(AU);
1205f757f3fSDimitry Andric }
1215f757f3fSDimitry Andric 
1225f757f3fSDimitry Andric RISCVPostLegalizerCombiner::RISCVPostLegalizerCombiner()
1235f757f3fSDimitry Andric     : MachineFunctionPass(ID) {
1245f757f3fSDimitry Andric   initializeRISCVPostLegalizerCombinerPass(*PassRegistry::getPassRegistry());
1255f757f3fSDimitry Andric 
1265f757f3fSDimitry Andric   if (!RuleConfig.parseCommandLineOption())
1275f757f3fSDimitry Andric     report_fatal_error("Invalid rule identifier");
1285f757f3fSDimitry Andric }
1295f757f3fSDimitry Andric 
1305f757f3fSDimitry Andric bool RISCVPostLegalizerCombiner::runOnMachineFunction(MachineFunction &MF) {
1315f757f3fSDimitry Andric   if (MF.getProperties().hasProperty(
1325f757f3fSDimitry Andric           MachineFunctionProperties::Property::FailedISel))
1335f757f3fSDimitry Andric     return false;
1345f757f3fSDimitry Andric   assert(MF.getProperties().hasProperty(
1355f757f3fSDimitry Andric              MachineFunctionProperties::Property::Legalized) &&
1365f757f3fSDimitry Andric          "Expected a legalized function?");
1375f757f3fSDimitry Andric   auto *TPC = &getAnalysis<TargetPassConfig>();
1385f757f3fSDimitry Andric   const Function &F = MF.getFunction();
1395f757f3fSDimitry Andric   bool EnableOpt =
1405f757f3fSDimitry Andric       MF.getTarget().getOptLevel() != CodeGenOptLevel::None && !skipFunction(F);
1415f757f3fSDimitry Andric 
1425f757f3fSDimitry Andric   const RISCVSubtarget &ST = MF.getSubtarget<RISCVSubtarget>();
1435f757f3fSDimitry Andric   const auto *LI = ST.getLegalizerInfo();
1445f757f3fSDimitry Andric 
1455f757f3fSDimitry Andric   GISelKnownBits *KB = &getAnalysis<GISelKnownBitsAnalysis>().get(MF);
146*0fca6ea1SDimitry Andric   MachineDominatorTree *MDT =
147*0fca6ea1SDimitry Andric       &getAnalysis<MachineDominatorTreeWrapperPass>().getDomTree();
1485f757f3fSDimitry Andric   GISelCSEAnalysisWrapper &Wrapper =
1495f757f3fSDimitry Andric       getAnalysis<GISelCSEAnalysisWrapperPass>().getCSEWrapper();
1505f757f3fSDimitry Andric   auto *CSEInfo = &Wrapper.get(TPC->getCSEConfig());
1515f757f3fSDimitry Andric 
1525f757f3fSDimitry Andric   CombinerInfo CInfo(/*AllowIllegalOps*/ true, /*ShouldLegalizeIllegal*/ false,
1535f757f3fSDimitry Andric                      /*LegalizerInfo*/ nullptr, EnableOpt, F.hasOptSize(),
1545f757f3fSDimitry Andric                      F.hasMinSize());
1555f757f3fSDimitry Andric   RISCVPostLegalizerCombinerImpl Impl(MF, CInfo, TPC, *KB, CSEInfo,
1565f757f3fSDimitry Andric                                         RuleConfig, ST, MDT, LI);
1575f757f3fSDimitry Andric   return Impl.combineMachineInstrs();
1585f757f3fSDimitry Andric }
1595f757f3fSDimitry Andric 
1605f757f3fSDimitry Andric char RISCVPostLegalizerCombiner::ID = 0;
1615f757f3fSDimitry Andric INITIALIZE_PASS_BEGIN(RISCVPostLegalizerCombiner, DEBUG_TYPE,
1625f757f3fSDimitry Andric                       "Combine RISC-V MachineInstrs after legalization", false,
1635f757f3fSDimitry Andric                       false)
1645f757f3fSDimitry Andric INITIALIZE_PASS_DEPENDENCY(TargetPassConfig)
1655f757f3fSDimitry Andric INITIALIZE_PASS_DEPENDENCY(GISelKnownBitsAnalysis)
1665f757f3fSDimitry Andric INITIALIZE_PASS_END(RISCVPostLegalizerCombiner, DEBUG_TYPE,
1675f757f3fSDimitry Andric                     "Combine RISC-V MachineInstrs after legalization", false,
1685f757f3fSDimitry Andric                     false)
1695f757f3fSDimitry Andric 
1705f757f3fSDimitry Andric namespace llvm {
1715f757f3fSDimitry Andric FunctionPass *createRISCVPostLegalizerCombiner() {
1725f757f3fSDimitry Andric   return new RISCVPostLegalizerCombiner();
1735f757f3fSDimitry Andric }
1745f757f3fSDimitry Andric } // end namespace llvm
175