[llvm] [RISCV][GISel] Add a post legalizer combiner and enable a couple comb… (PR #67053)
Craig Topper via llvm-commits
llvm-commits at lists.llvm.org
Thu Sep 21 12:02:57 PDT 2023
https://github.com/topperc created https://github.com/llvm/llvm-project/pull/67053
…ines.
We have an existing test that shows benefit from redundant_and and identity combines so use them as a starting point.
>From f6b93e7ea917370ffb642ef0b82d0d9ea21b6cf3 Mon Sep 17 00:00:00 2001
From: Craig Topper <craig.topper at sifive.com>
Date: Thu, 21 Sep 2023 11:52:11 -0700
Subject: [PATCH] [RISCV][GISel] Add a post legalizer combiner and enable a
couple combines.
We have an existing test that shows benefit from redundant_and and
identity combines so use them as a starting point.
---
llvm/lib/Target/RISCV/CMakeLists.txt | 3 +
.../GISel/RISCVO0PreLegalizerCombiner.cpp | 4 +-
.../GISel/RISCVPostLegalizerCombiner.cpp | 173 ++++++++++++++++++
.../RISCV/GISel/RISCVPreLegalizerCombiner.cpp | 4 +-
llvm/lib/Target/RISCV/RISCV.h | 3 +
llvm/lib/Target/RISCV/RISCVCombine.td | 7 +
llvm/lib/Target/RISCV/RISCVTargetMachine.cpp | 7 +
.../CodeGen/RISCV/GlobalISel/alu-roundtrip.ll | 10 +-
.../GlobalISel/gisel-commandline-option.ll | 2 +
9 files changed, 200 insertions(+), 13 deletions(-)
create mode 100644 llvm/lib/Target/RISCV/GISel/RISCVPostLegalizerCombiner.cpp
diff --git a/llvm/lib/Target/RISCV/CMakeLists.txt b/llvm/lib/Target/RISCV/CMakeLists.txt
index abe2f5a6246fc25..fd5a5244486ab18 100644
--- a/llvm/lib/Target/RISCV/CMakeLists.txt
+++ b/llvm/lib/Target/RISCV/CMakeLists.txt
@@ -21,6 +21,8 @@ tablegen(LLVM RISCVGenO0PreLegalizeGICombiner.inc -gen-global-isel-combiner
-combiners="RISCVO0PreLegalizerCombiner")
tablegen(LLVM RISCVGenPreLegalizeGICombiner.inc -gen-global-isel-combiner
-combiners="RISCVPreLegalizerCombiner")
+tablegen(LLVM RISCVGenPostLegalizeGICombiner.inc -gen-global-isel-combiner
+ -combiners="RISCVPostLegalizerCombiner")
add_public_tablegen_target(RISCVCommonTableGen)
@@ -54,6 +56,7 @@ add_llvm_target(RISCVCodeGen
GISel/RISCVCallLowering.cpp
GISel/RISCVInstructionSelector.cpp
GISel/RISCVLegalizerInfo.cpp
+ GISel/RISCVPostLegalizerCombiner.cpp
GISel/RISCVO0PreLegalizerCombiner.cpp
GISel/RISCVPreLegalizerCombiner.cpp
GISel/RISCVRegisterBankInfo.cpp
diff --git a/llvm/lib/Target/RISCV/GISel/RISCVO0PreLegalizerCombiner.cpp b/llvm/lib/Target/RISCV/GISel/RISCVO0PreLegalizerCombiner.cpp
index d94edbc402e6156..be77979512e00c5 100644
--- a/llvm/lib/Target/RISCV/GISel/RISCVO0PreLegalizerCombiner.cpp
+++ b/llvm/lib/Target/RISCV/GISel/RISCVO0PreLegalizerCombiner.cpp
@@ -139,13 +139,13 @@ bool RISCVO0PreLegalizerCombiner::runOnMachineFunction(MachineFunction &MF) {
char RISCVO0PreLegalizerCombiner::ID = 0;
INITIALIZE_PASS_BEGIN(RISCVO0PreLegalizerCombiner, DEBUG_TYPE,
- "Combine RISCV machine instrs before legalization", false,
+ "Combine RISC-V machine instrs before legalization", false,
false)
INITIALIZE_PASS_DEPENDENCY(TargetPassConfig)
INITIALIZE_PASS_DEPENDENCY(GISelKnownBitsAnalysis)
INITIALIZE_PASS_DEPENDENCY(GISelCSEAnalysisWrapperPass)
INITIALIZE_PASS_END(RISCVO0PreLegalizerCombiner, DEBUG_TYPE,
- "Combine RISCV machine instrs before legalization", false,
+ "Combine RISC-V machine instrs before legalization", false,
false)
namespace llvm {
diff --git a/llvm/lib/Target/RISCV/GISel/RISCVPostLegalizerCombiner.cpp b/llvm/lib/Target/RISCV/GISel/RISCVPostLegalizerCombiner.cpp
new file mode 100644
index 000000000000000..9c28944abc76721
--- /dev/null
+++ b/llvm/lib/Target/RISCV/GISel/RISCVPostLegalizerCombiner.cpp
@@ -0,0 +1,173 @@
+//=== RISCVPostLegalizerCombiner.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 combines on generic MachineInstrs.
+///
+/// The combines here must preserve instruction legality.
+///
+/// Combines which don't rely on instruction legality should go in the
+/// RISCVPreLegalizerCombiner.
+///
+//===----------------------------------------------------------------------===//
+
+#include "RISCVTargetMachine.h"
+#include "llvm/CodeGen/GlobalISel/CSEInfo.h"
+#include "llvm/CodeGen/GlobalISel/Combiner.h"
+#include "llvm/CodeGen/GlobalISel/CombinerHelper.h"
+#include "llvm/CodeGen/GlobalISel/CombinerInfo.h"
+#include "llvm/CodeGen/GlobalISel/GIMatchTableExecutorImpl.h"
+#include "llvm/CodeGen/GlobalISel/GISelKnownBits.h"
+#include "llvm/CodeGen/GlobalISel/GenericMachineInstrs.h"
+#include "llvm/CodeGen/GlobalISel/MachineIRBuilder.h"
+#include "llvm/CodeGen/MachineDominators.h"
+#include "llvm/CodeGen/MachineFunctionPass.h"
+#include "llvm/CodeGen/MachineRegisterInfo.h"
+#include "llvm/CodeGen/TargetPassConfig.h"
+
+#define GET_GICOMBINER_DEPS
+#include "RISCVGenPostLegalizeGICombiner.inc"
+#undef GET_GICOMBINER_DEPS
+
+#define DEBUG_TYPE "riscv-postlegalizer-combiner"
+
+using namespace llvm;
+
+namespace {
+
+#define GET_GICOMBINER_TYPES
+#include "RISCVGenPostLegalizeGICombiner.inc"
+#undef GET_GICOMBINER_TYPES
+
+class RISCVPostLegalizerCombinerImpl : public Combiner {
+protected:
+ // TODO: Make CombinerHelper methods const.
+ mutable CombinerHelper Helper;
+ const RISCVPostLegalizerCombinerImplRuleConfig &RuleConfig;
+ const RISCVSubtarget &STI;
+
+public:
+ RISCVPostLegalizerCombinerImpl(
+ MachineFunction &MF, CombinerInfo &CInfo, const TargetPassConfig *TPC,
+ GISelKnownBits &KB, GISelCSEInfo *CSEInfo,
+ const RISCVPostLegalizerCombinerImplRuleConfig &RuleConfig,
+ const RISCVSubtarget &STI, MachineDominatorTree *MDT,
+ const LegalizerInfo *LI);
+
+ static const char *getName() { return "RISCVPostLegalizerCombiner"; }
+
+ bool tryCombineAll(MachineInstr &I) const override;
+
+private:
+#define GET_GICOMBINER_CLASS_MEMBERS
+#include "RISCVGenPostLegalizeGICombiner.inc"
+#undef GET_GICOMBINER_CLASS_MEMBERS
+};
+
+#define GET_GICOMBINER_IMPL
+#include "RISCVGenPostLegalizeGICombiner.inc"
+#undef GET_GICOMBINER_IMPL
+
+RISCVPostLegalizerCombinerImpl::RISCVPostLegalizerCombinerImpl(
+ MachineFunction &MF, CombinerInfo &CInfo, const TargetPassConfig *TPC,
+ GISelKnownBits &KB, GISelCSEInfo *CSEInfo,
+ const RISCVPostLegalizerCombinerImplRuleConfig &RuleConfig,
+ const RISCVSubtarget &STI, MachineDominatorTree *MDT,
+ const LegalizerInfo *LI)
+ : Combiner(MF, CInfo, TPC, &KB, CSEInfo),
+ Helper(Observer, B, /*IsPreLegalize*/ false, &KB, MDT, LI),
+ RuleConfig(RuleConfig), STI(STI),
+#define GET_GICOMBINER_CONSTRUCTOR_INITS
+#include "RISCVGenPostLegalizeGICombiner.inc"
+#undef GET_GICOMBINER_CONSTRUCTOR_INITS
+{
+}
+
+class RISCVPostLegalizerCombiner : public MachineFunctionPass {
+public:
+ static char ID;
+
+ RISCVPostLegalizerCombiner();
+
+ StringRef getPassName() const override {
+ return "RISCVPostLegalizerCombiner";
+ }
+
+ bool runOnMachineFunction(MachineFunction &MF) override;
+ void getAnalysisUsage(AnalysisUsage &AU) const override;
+
+private:
+ RISCVPostLegalizerCombinerImplRuleConfig RuleConfig;
+};
+} // end anonymous namespace
+
+void RISCVPostLegalizerCombiner::getAnalysisUsage(AnalysisUsage &AU) const {
+ AU.addRequired<TargetPassConfig>();
+ AU.setPreservesCFG();
+ getSelectionDAGFallbackAnalysisUsage(AU);
+ AU.addRequired<GISelKnownBitsAnalysis>();
+ AU.addPreserved<GISelKnownBitsAnalysis>();
+ AU.addRequired<MachineDominatorTree>();
+ AU.addPreserved<MachineDominatorTree>();
+ AU.addRequired<GISelCSEAnalysisWrapperPass>();
+ AU.addPreserved<GISelCSEAnalysisWrapperPass>();
+ MachineFunctionPass::getAnalysisUsage(AU);
+}
+
+RISCVPostLegalizerCombiner::RISCVPostLegalizerCombiner()
+ : MachineFunctionPass(ID) {
+ initializeRISCVPostLegalizerCombinerPass(*PassRegistry::getPassRegistry());
+
+ if (!RuleConfig.parseCommandLineOption())
+ report_fatal_error("Invalid rule identifier");
+}
+
+bool RISCVPostLegalizerCombiner::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<TargetPassConfig>();
+ const Function &F = MF.getFunction();
+ bool EnableOpt =
+ MF.getTarget().getOptLevel() != CodeGenOptLevel::None && !skipFunction(F);
+
+ const RISCVSubtarget &ST = MF.getSubtarget<RISCVSubtarget>();
+ const auto *LI = ST.getLegalizerInfo();
+
+ GISelKnownBits *KB = &getAnalysis<GISelKnownBitsAnalysis>().get(MF);
+ MachineDominatorTree *MDT = &getAnalysis<MachineDominatorTree>();
+ GISelCSEAnalysisWrapper &Wrapper =
+ getAnalysis<GISelCSEAnalysisWrapperPass>().getCSEWrapper();
+ auto *CSEInfo = &Wrapper.get(TPC->getCSEConfig());
+
+ CombinerInfo CInfo(/*AllowIllegalOps*/ true, /*ShouldLegalizeIllegal*/ false,
+ /*LegalizerInfo*/ nullptr, EnableOpt, F.hasOptSize(),
+ F.hasMinSize());
+ RISCVPostLegalizerCombinerImpl Impl(MF, CInfo, TPC, *KB, CSEInfo,
+ RuleConfig, ST, MDT, LI);
+ return Impl.combineMachineInstrs();
+}
+
+char RISCVPostLegalizerCombiner::ID = 0;
+INITIALIZE_PASS_BEGIN(RISCVPostLegalizerCombiner, DEBUG_TYPE,
+ "Combine RISC-V MachineInstrs after legalization", false,
+ false)
+INITIALIZE_PASS_DEPENDENCY(TargetPassConfig)
+INITIALIZE_PASS_DEPENDENCY(GISelKnownBitsAnalysis)
+INITIALIZE_PASS_END(RISCVPostLegalizerCombiner, DEBUG_TYPE,
+ "Combine RISC-V MachineInstrs after legalization", false,
+ false)
+
+namespace llvm {
+FunctionPass *createRISCVPostLegalizerCombiner() {
+ return new RISCVPostLegalizerCombiner();
+}
+} // end namespace llvm
diff --git a/llvm/lib/Target/RISCV/GISel/RISCVPreLegalizerCombiner.cpp b/llvm/lib/Target/RISCV/GISel/RISCVPreLegalizerCombiner.cpp
index 36f5d957832218c..9a35fffae05890a 100644
--- a/llvm/lib/Target/RISCV/GISel/RISCVPreLegalizerCombiner.cpp
+++ b/llvm/lib/Target/RISCV/GISel/RISCVPreLegalizerCombiner.cpp
@@ -153,13 +153,13 @@ bool RISCVPreLegalizerCombiner::runOnMachineFunction(MachineFunction &MF) {
char RISCVPreLegalizerCombiner::ID = 0;
INITIALIZE_PASS_BEGIN(RISCVPreLegalizerCombiner, DEBUG_TYPE,
- "Combine RISCV machine instrs before legalization", false,
+ "Combine RISC-V machine instrs before legalization", false,
false)
INITIALIZE_PASS_DEPENDENCY(TargetPassConfig)
INITIALIZE_PASS_DEPENDENCY(GISelKnownBitsAnalysis)
INITIALIZE_PASS_DEPENDENCY(GISelCSEAnalysisWrapperPass)
INITIALIZE_PASS_END(RISCVPreLegalizerCombiner, DEBUG_TYPE,
- "Combine RISCV machine instrs before legalization", false,
+ "Combine RISC-V machine instrs before legalization", false,
false)
namespace llvm {
diff --git a/llvm/lib/Target/RISCV/RISCV.h b/llvm/lib/Target/RISCV/RISCV.h
index 702f69bcd4780a9..0efc915ea52c550 100644
--- a/llvm/lib/Target/RISCV/RISCV.h
+++ b/llvm/lib/Target/RISCV/RISCV.h
@@ -84,6 +84,9 @@ InstructionSelector *createRISCVInstructionSelector(const RISCVTargetMachine &,
RISCVRegisterBankInfo &);
void initializeRISCVDAGToDAGISelPass(PassRegistry &);
+FunctionPass *createRISCVPostLegalizerCombiner();
+void initializeRISCVPostLegalizerCombinerPass(PassRegistry &);
+
FunctionPass *createRISCVO0PreLegalizerCombiner();
void initializeRISCVO0PreLegalizerCombinerPass(PassRegistry &);
diff --git a/llvm/lib/Target/RISCV/RISCVCombine.td b/llvm/lib/Target/RISCV/RISCVCombine.td
index b632a4f54f202c9..3a5afb1b075c9e2 100644
--- a/llvm/lib/Target/RISCV/RISCVCombine.td
+++ b/llvm/lib/Target/RISCV/RISCVCombine.td
@@ -18,3 +18,10 @@ def RISCVPreLegalizerCombiner: GICombiner<
def RISCVO0PreLegalizerCombiner: GICombiner<
"RISCVO0PreLegalizerCombinerImpl", [optnone_combines]> {
}
+
+// Post-legalization combines which are primarily optimizations.
+// TODO: Add more combines.
+def RISCVPostLegalizerCombiner
+ : GICombiner<"RISCVPostLegalizerCombinerImpl",
+ [redundant_and, identity_combines]> {
+}
diff --git a/llvm/lib/Target/RISCV/RISCVTargetMachine.cpp b/llvm/lib/Target/RISCV/RISCVTargetMachine.cpp
index 30d559a4958c320..69a0569fccc4eca 100644
--- a/llvm/lib/Target/RISCV/RISCVTargetMachine.cpp
+++ b/llvm/lib/Target/RISCV/RISCVTargetMachine.cpp
@@ -85,6 +85,7 @@ extern "C" LLVM_EXTERNAL_VISIBILITY void LLVMInitializeRISCVTarget() {
initializeGlobalISel(*PR);
initializeRISCVO0PreLegalizerCombinerPass(*PR);
initializeRISCVPreLegalizerCombinerPass(*PR);
+ initializeRISCVPostLegalizerCombinerPass(*PR);
initializeKCFIPass(*PR);
initializeRISCVDeadRegisterDefinitionsPass(*PR);
initializeRISCVMakeCompressibleOptPass(*PR);
@@ -275,6 +276,7 @@ class RISCVPassConfig : public TargetPassConfig {
bool addIRTranslator() override;
void addPreLegalizeMachineIR() override;
bool addLegalizeMachineIR() override;
+ void addPreRegBankSelect() override;
bool addRegBankSelect() override;
bool addGlobalInstructionSelect() override;
void addPreEmitPass() override;
@@ -345,6 +347,11 @@ bool RISCVPassConfig::addLegalizeMachineIR() {
return false;
}
+void RISCVPassConfig::addPreRegBankSelect() {
+ if (getOptLevel() != CodeGenOptLevel::None)
+ addPass(createRISCVPostLegalizerCombiner());
+}
+
bool RISCVPassConfig::addRegBankSelect() {
addPass(new RegBankSelect());
return false;
diff --git a/llvm/test/CodeGen/RISCV/GlobalISel/alu-roundtrip.ll b/llvm/test/CodeGen/RISCV/GlobalISel/alu-roundtrip.ll
index 9557f581be4ecec..4fe1691714bb958 100644
--- a/llvm/test/CodeGen/RISCV/GlobalISel/alu-roundtrip.ll
+++ b/llvm/test/CodeGen/RISCV/GlobalISel/alu-roundtrip.ll
@@ -391,7 +391,6 @@ define i64 @add_i64(i64 %a, i64 %b) {
; RV32IM-NEXT: add a0, a0, a2
; RV32IM-NEXT: sltu a2, a0, a2
; RV32IM-NEXT: add a1, a1, a3
-; RV32IM-NEXT: andi a2, a2, 1
; RV32IM-NEXT: add a1, a1, a2
; RV32IM-NEXT: ret
;
@@ -409,8 +408,6 @@ define i64 @addi_i64(i64 %a) {
; RV32IM: # %bb.0: # %entry
; RV32IM-NEXT: addi a0, a0, 1234
; RV32IM-NEXT: sltiu a2, a0, 1234
-; RV32IM-NEXT: mv a1, a1
-; RV32IM-NEXT: andi a2, a2, 1
; RV32IM-NEXT: add a1, a1, a2
; RV32IM-NEXT: ret
;
@@ -429,7 +426,6 @@ define i64 @sub_i64(i64 %a, i64 %b) {
; RV32IM-NEXT: sub a4, a0, a2
; RV32IM-NEXT: sltu a0, a0, a2
; RV32IM-NEXT: sub a1, a1, a3
-; RV32IM-NEXT: andi a0, a0, 1
; RV32IM-NEXT: sub a1, a1, a0
; RV32IM-NEXT: mv a0, a4
; RV32IM-NEXT: ret
@@ -450,8 +446,6 @@ define i64 @subi_i64(i64 %a) {
; RV32IM-NEXT: addi a3, a2, 1548
; RV32IM-NEXT: sub a2, a0, a3
; RV32IM-NEXT: sltu a0, a0, a3
-; RV32IM-NEXT: mv a1, a1
-; RV32IM-NEXT: andi a0, a0, 1
; RV32IM-NEXT: sub a1, a1, a0
; RV32IM-NEXT: mv a0, a2
; RV32IM-NEXT: ret
@@ -489,7 +483,7 @@ define i64 @andi_i64(i64 %a) {
; RV32IM-LABEL: andi_i64:
; RV32IM: # %bb.0: # %entry
; RV32IM-NEXT: andi a0, a0, 1234
-; RV32IM-NEXT: andi a1, a1, 0
+; RV32IM-NEXT: li a1, 0
; RV32IM-NEXT: ret
;
; RV64IM-LABEL: andi_i64:
@@ -521,7 +515,6 @@ define i64 @ori_i64(i64 %a) {
; RV32IM-LABEL: ori_i64:
; RV32IM: # %bb.0: # %entry
; RV32IM-NEXT: ori a0, a0, 1234
-; RV32IM-NEXT: ori a1, a1, 0
; RV32IM-NEXT: ret
;
; RV64IM-LABEL: ori_i64:
@@ -553,7 +546,6 @@ define i64 @xori_i64(i64 %a) {
; RV32IM-LABEL: xori_i64:
; RV32IM: # %bb.0: # %entry
; RV32IM-NEXT: xori a0, a0, 1234
-; RV32IM-NEXT: xori a1, a1, 0
; RV32IM-NEXT: ret
;
; RV64IM-LABEL: xori_i64:
diff --git a/llvm/test/CodeGen/RISCV/GlobalISel/gisel-commandline-option.ll b/llvm/test/CodeGen/RISCV/GlobalISel/gisel-commandline-option.ll
index 016779689d737f2..82c66c23b26ba94 100644
--- a/llvm/test/CodeGen/RISCV/GlobalISel/gisel-commandline-option.ll
+++ b/llvm/test/CodeGen/RISCV/GlobalISel/gisel-commandline-option.ll
@@ -21,6 +21,8 @@
; ENABLED-NEXT: Analysis containing CSE Info
; ENABLED-O1-NEXT: RISCVPreLegalizerCombiner
; ENABLED-NEXT: Legalizer
+; ENABLED-O1-NEXT: MachineDominator Tree Construction
+; ENABLED-O1-NEXT: RISCVPostLegalizerCombiner
; ENABLED-NEXT: RegBankSelect
; ENABLED-NEXT: Analysis for ComputingKnownBits
; ENABLED-O1-NEXT: Lazy Branch Probability Analysis
More information about the llvm-commits
mailing list