Skip to content

[RISCV][GISel] Add a post legalizer combiner and enable a couple comb… #67053

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Sep 22, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions llvm/lib/Target/RISCV/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -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)

Expand Down Expand Up @@ -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
Expand Down
4 changes: 2 additions & 2 deletions llvm/lib/Target/RISCV/GISel/RISCVO0PreLegalizerCombiner.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand Down
173 changes: 173 additions & 0 deletions llvm/lib/Target/RISCV/GISel/RISCVPostLegalizerCombiner.cpp
Original file line number Diff line number Diff line change
@@ -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
4 changes: 2 additions & 2 deletions llvm/lib/Target/RISCV/GISel/RISCVPreLegalizerCombiner.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand Down
3 changes: 3 additions & 0 deletions llvm/lib/Target/RISCV/RISCV.h
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,9 @@ InstructionSelector *createRISCVInstructionSelector(const RISCVTargetMachine &,
RISCVRegisterBankInfo &);
void initializeRISCVDAGToDAGISelPass(PassRegistry &);

FunctionPass *createRISCVPostLegalizerCombiner();
void initializeRISCVPostLegalizerCombinerPass(PassRegistry &);

FunctionPass *createRISCVO0PreLegalizerCombiner();
void initializeRISCVO0PreLegalizerCombinerPass(PassRegistry &);

Expand Down
7 changes: 7 additions & 0 deletions llvm/lib/Target/RISCV/RISCVCombine.td
Original file line number Diff line number Diff line change
Expand Up @@ -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]> {
}
7 changes: 7 additions & 0 deletions llvm/lib/Target/RISCV/RISCVTargetMachine.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down Expand Up @@ -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;
Expand Down Expand Up @@ -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;
Expand Down
10 changes: 1 addition & 9 deletions llvm/test/CodeGen/RISCV/GlobalISel/alu-roundtrip.ll
Original file line number Diff line number Diff line change
Expand Up @@ -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
;
Expand All @@ -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
;
Expand All @@ -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
Expand All @@ -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
Expand Down Expand Up @@ -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:
Expand Down Expand Up @@ -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:
Expand Down Expand Up @@ -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:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down