diff --git a/llvm/lib/Target/RISCV/CMakeLists.txt b/llvm/lib/Target/RISCV/CMakeLists.txt index 124bc239451ae..7d02d630a2819 100644 --- a/llvm/lib/Target/RISCV/CMakeLists.txt +++ b/llvm/lib/Target/RISCV/CMakeLists.txt @@ -24,6 +24,8 @@ tablegen(LLVM RISCVGenPreLegalizeGICombiner.inc -gen-global-isel-combiner -combiners="RISCVPreLegalizerCombiner") tablegen(LLVM RISCVGenPostLegalizeGICombiner.inc -gen-global-isel-combiner -combiners="RISCVPostLegalizerCombiner") +tablegen(LLVM RISCVGenPostLegalizeGILowering.inc -gen-global-isel-combiner + -combiners="RISCVPostLegalizerLowering") add_public_tablegen_target(RISCVCommonTableGen) @@ -63,6 +65,7 @@ add_llvm_target(RISCVCodeGen GISel/RISCVInstructionSelector.cpp GISel/RISCVLegalizerInfo.cpp GISel/RISCVPostLegalizerCombiner.cpp + GISel/RISCVPostLegalizerLowering.cpp GISel/RISCVO0PreLegalizerCombiner.cpp GISel/RISCVPreLegalizerCombiner.cpp GISel/RISCVRegisterBankInfo.cpp diff --git a/llvm/lib/Target/RISCV/GISel/RISCVPostLegalizerLowering.cpp b/llvm/lib/Target/RISCV/GISel/RISCVPostLegalizerLowering.cpp new file mode 100644 index 0000000000000..66db15e3a2e28 --- /dev/null +++ b/llvm/lib/Target/RISCV/GISel/RISCVPostLegalizerLowering.cpp @@ -0,0 +1,154 @@ +//===--------------- RISCVPostLegalizerLowering.cpp -------------*- C++ -*-===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// +/// +/// \file +/// Post-legalization lowering for instructions. +/// +/// This is used to offload pattern matching from the selector. +/// +/// General optimization combines should be handled by either the +/// RISCVPostLegalizerCombiner or the RISCVPreLegalizerCombiner. +/// +//===----------------------------------------------------------------------===// + +#include "RISCVSubtarget.h" + +#include "llvm/CodeGen/GlobalISel/Combiner.h" +#include "llvm/CodeGen/GlobalISel/CombinerHelper.h" +#include "llvm/CodeGen/GlobalISel/GIMatchTableExecutorImpl.h" +#include "llvm/CodeGen/GlobalISel/GISelChangeObserver.h" +#include "llvm/CodeGen/MachineFunctionPass.h" +#include "llvm/CodeGen/TargetPassConfig.h" +#include "llvm/InitializePasses.h" +#include "llvm/Support/Debug.h" + +#define GET_GICOMBINER_DEPS +#include "RISCVGenPostLegalizeGILowering.inc" +#undef GET_GICOMBINER_DEPS + +#define DEBUG_TYPE "riscv-postlegalizer-lowering" + +using namespace llvm; + +namespace { + +#define GET_GICOMBINER_TYPES +#include "RISCVGenPostLegalizeGILowering.inc" +#undef GET_GICOMBINER_TYPES + +class RISCVPostLegalizerLoweringImpl : public Combiner { +protected: + // TODO: Make CombinerHelper methods const. + mutable CombinerHelper Helper; + const RISCVPostLegalizerLoweringImplRuleConfig &RuleConfig; + const RISCVSubtarget &STI; + +public: + RISCVPostLegalizerLoweringImpl( + MachineFunction &MF, CombinerInfo &CInfo, const TargetPassConfig *TPC, + GISelCSEInfo *CSEInfo, + const RISCVPostLegalizerLoweringImplRuleConfig &RuleConfig, + const RISCVSubtarget &STI); + + static const char *getName() { return "RISCVPreLegalizerCombiner"; } + + bool tryCombineAll(MachineInstr &I) const override; + +private: +#define GET_GICOMBINER_CLASS_MEMBERS +#include "RISCVGenPostLegalizeGILowering.inc" +#undef GET_GICOMBINER_CLASS_MEMBERS +}; + +#define GET_GICOMBINER_IMPL +#include "RISCVGenPostLegalizeGILowering.inc" +#undef GET_GICOMBINER_IMPL + +RISCVPostLegalizerLoweringImpl::RISCVPostLegalizerLoweringImpl( + MachineFunction &MF, CombinerInfo &CInfo, const TargetPassConfig *TPC, + GISelCSEInfo *CSEInfo, + const RISCVPostLegalizerLoweringImplRuleConfig &RuleConfig, + const RISCVSubtarget &STI) + : Combiner(MF, CInfo, TPC, /*KB*/ nullptr, CSEInfo), + Helper(Observer, B, /*IsPreLegalize*/ true), RuleConfig(RuleConfig), + STI(STI), +#define GET_GICOMBINER_CONSTRUCTOR_INITS +#include "RISCVGenPostLegalizeGILowering.inc" +#undef GET_GICOMBINER_CONSTRUCTOR_INITS +{ +} + +class RISCVPostLegalizerLowering : public MachineFunctionPass { +public: + static char ID; + + RISCVPostLegalizerLowering(); + + StringRef getPassName() const override { + return "RISCVPostLegalizerLowering"; + } + + bool runOnMachineFunction(MachineFunction &MF) override; + void getAnalysisUsage(AnalysisUsage &AU) const override; + +private: + RISCVPostLegalizerLoweringImplRuleConfig RuleConfig; +}; +} // end anonymous namespace + +void RISCVPostLegalizerLowering::getAnalysisUsage(AnalysisUsage &AU) const { + AU.addRequired(); + AU.setPreservesCFG(); + getSelectionDAGFallbackAnalysisUsage(AU); + MachineFunctionPass::getAnalysisUsage(AU); +} + +RISCVPostLegalizerLowering::RISCVPostLegalizerLowering() + : MachineFunctionPass(ID) { + if (!RuleConfig.parseCommandLineOption()) + report_fatal_error("Invalid rule identifier"); +} + +bool RISCVPostLegalizerLowering::runOnMachineFunction(MachineFunction &MF) { + if (MF.getProperties().hasProperty( + MachineFunctionProperties::Property::FailedISel)) + return false; + assert(MF.getProperties().hasProperty( + MachineFunctionProperties::Property::Legalized) && + "Expected a legalized function?"); + auto *TPC = &getAnalysis(); + const Function &F = MF.getFunction(); + + const RISCVSubtarget &ST = MF.getSubtarget(); + CombinerInfo CInfo(/*AllowIllegalOps*/ true, /*ShouldLegalizeIllegal*/ false, + /*LegalizerInfo*/ nullptr, /*OptEnabled=*/true, + F.hasOptSize(), F.hasMinSize()); + // Disable fixed-point iteration to reduce compile-time + CInfo.MaxIterations = 1; + CInfo.ObserverLvl = CombinerInfo::ObserverLevel::SinglePass; + // PostLegalizerCombiner performs DCE, so a full DCE pass is unnecessary. + CInfo.EnableFullDCE = false; + RISCVPostLegalizerLoweringImpl Impl(MF, CInfo, TPC, /*CSEInfo*/ nullptr, + RuleConfig, ST); + return Impl.combineMachineInstrs(); +} + +char RISCVPostLegalizerLowering::ID = 0; +INITIALIZE_PASS_BEGIN(RISCVPostLegalizerLowering, DEBUG_TYPE, + "Lower RISC-V MachineInstrs after legalization", false, + false) +INITIALIZE_PASS_DEPENDENCY(TargetPassConfig) +INITIALIZE_PASS_END(RISCVPostLegalizerLowering, DEBUG_TYPE, + "Lower RISC-V MachineInstrs after legalization", false, + false) + +namespace llvm { +FunctionPass *createRISCVPostLegalizerLowering() { + return new RISCVPostLegalizerLowering(); +} +} // end namespace llvm diff --git a/llvm/lib/Target/RISCV/RISCV.h b/llvm/lib/Target/RISCV/RISCV.h index 5a94ada8f8dd4..561e4895e1942 100644 --- a/llvm/lib/Target/RISCV/RISCV.h +++ b/llvm/lib/Target/RISCV/RISCV.h @@ -99,6 +99,9 @@ void initializeRISCVO0PreLegalizerCombinerPass(PassRegistry &); FunctionPass *createRISCVPreLegalizerCombiner(); void initializeRISCVPreLegalizerCombinerPass(PassRegistry &); + +FunctionPass *createRISCVPostLegalizerLowering(); +void initializeRISCVPostLegalizerLoweringPass(PassRegistry &); } // namespace llvm #endif diff --git a/llvm/lib/Target/RISCV/RISCVCombine.td b/llvm/lib/Target/RISCV/RISCVCombine.td index 3a5afb1b075c9..d48698ae6f2bf 100644 --- a/llvm/lib/Target/RISCV/RISCVCombine.td +++ b/llvm/lib/Target/RISCV/RISCVCombine.td @@ -19,6 +19,13 @@ def RISCVO0PreLegalizerCombiner: GICombiner< "RISCVO0PreLegalizerCombinerImpl", [optnone_combines]> { } +// Post-legalization combines which should happen at all optimization levels. +// (E.g. ones that facilitate matching for the selector) For example, matching +// pseudos. +def RISCVPostLegalizerLowering + : GICombiner<"RISCVPostLegalizerLoweringImpl", []> { +} + // Post-legalization combines which are primarily optimizations. // TODO: Add more combines. def RISCVPostLegalizerCombiner diff --git a/llvm/lib/Target/RISCV/RISCVTargetMachine.cpp b/llvm/lib/Target/RISCV/RISCVTargetMachine.cpp index 794df2212dfa5..5cb9fbc8a9eb9 100644 --- a/llvm/lib/Target/RISCV/RISCVTargetMachine.cpp +++ b/llvm/lib/Target/RISCV/RISCVTargetMachine.cpp @@ -111,6 +111,7 @@ extern "C" LLVM_EXTERNAL_VISIBILITY void LLVMInitializeRISCVTarget() { initializeRISCVO0PreLegalizerCombinerPass(*PR); initializeRISCVPreLegalizerCombinerPass(*PR); initializeRISCVPostLegalizerCombinerPass(*PR); + initializeRISCVPostLegalizerLoweringPass(*PR); initializeKCFIPass(*PR); initializeRISCVDeadRegisterDefinitionsPass(*PR); initializeRISCVMakeCompressibleOptPass(*PR); @@ -482,6 +483,7 @@ bool RISCVPassConfig::addLegalizeMachineIR() { void RISCVPassConfig::addPreRegBankSelect() { if (getOptLevel() != CodeGenOptLevel::None) addPass(createRISCVPostLegalizerCombiner()); + addPass(createRISCVPostLegalizerLowering()); } bool RISCVPassConfig::addRegBankSelect() { diff --git a/llvm/test/CodeGen/RISCV/GlobalISel/gisel-commandline-option.ll b/llvm/test/CodeGen/RISCV/GlobalISel/gisel-commandline-option.ll index 82c66c23b26ba..75607bb81ff51 100644 --- a/llvm/test/CodeGen/RISCV/GlobalISel/gisel-commandline-option.ll +++ b/llvm/test/CodeGen/RISCV/GlobalISel/gisel-commandline-option.ll @@ -23,6 +23,7 @@ ; ENABLED-NEXT: Legalizer ; ENABLED-O1-NEXT: MachineDominator Tree Construction ; ENABLED-O1-NEXT: RISCVPostLegalizerCombiner +; ENABLED-NEXT: RISCVPostLegalizerLowering ; ENABLED-NEXT: RegBankSelect ; ENABLED-NEXT: Analysis for ComputingKnownBits ; ENABLED-O1-NEXT: Lazy Branch Probability Analysis