Skip to content

Commit 8e87dc1

Browse files
authored
[RISCV][GISel] Add a post legalizer combiner and enable a couple comb… (llvm#67053)
…ines. We have an existing test that shows benefit from redundant_and and identity combines so use them as a starting point.
1 parent ec5b0ef commit 8e87dc1

File tree

9 files changed

+200
-13
lines changed

9 files changed

+200
-13
lines changed

llvm/lib/Target/RISCV/CMakeLists.txt

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,8 @@ tablegen(LLVM RISCVGenO0PreLegalizeGICombiner.inc -gen-global-isel-combiner
2121
-combiners="RISCVO0PreLegalizerCombiner")
2222
tablegen(LLVM RISCVGenPreLegalizeGICombiner.inc -gen-global-isel-combiner
2323
-combiners="RISCVPreLegalizerCombiner")
24+
tablegen(LLVM RISCVGenPostLegalizeGICombiner.inc -gen-global-isel-combiner
25+
-combiners="RISCVPostLegalizerCombiner")
2426

2527
add_public_tablegen_target(RISCVCommonTableGen)
2628

@@ -54,6 +56,7 @@ add_llvm_target(RISCVCodeGen
5456
GISel/RISCVCallLowering.cpp
5557
GISel/RISCVInstructionSelector.cpp
5658
GISel/RISCVLegalizerInfo.cpp
59+
GISel/RISCVPostLegalizerCombiner.cpp
5760
GISel/RISCVO0PreLegalizerCombiner.cpp
5861
GISel/RISCVPreLegalizerCombiner.cpp
5962
GISel/RISCVRegisterBankInfo.cpp

llvm/lib/Target/RISCV/GISel/RISCVO0PreLegalizerCombiner.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -139,13 +139,13 @@ bool RISCVO0PreLegalizerCombiner::runOnMachineFunction(MachineFunction &MF) {
139139

140140
char RISCVO0PreLegalizerCombiner::ID = 0;
141141
INITIALIZE_PASS_BEGIN(RISCVO0PreLegalizerCombiner, DEBUG_TYPE,
142-
"Combine RISCV machine instrs before legalization", false,
142+
"Combine RISC-V machine instrs before legalization", false,
143143
false)
144144
INITIALIZE_PASS_DEPENDENCY(TargetPassConfig)
145145
INITIALIZE_PASS_DEPENDENCY(GISelKnownBitsAnalysis)
146146
INITIALIZE_PASS_DEPENDENCY(GISelCSEAnalysisWrapperPass)
147147
INITIALIZE_PASS_END(RISCVO0PreLegalizerCombiner, DEBUG_TYPE,
148-
"Combine RISCV machine instrs before legalization", false,
148+
"Combine RISC-V machine instrs before legalization", false,
149149
false)
150150

151151
namespace llvm {
Lines changed: 173 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,173 @@
1+
//=== RISCVPostLegalizerCombiner.cpp --------------------------*- C++ -*-===//
2+
//
3+
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4+
// See https://llvm.org/LICENSE.txt for license information.
5+
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6+
//
7+
//===----------------------------------------------------------------------===//
8+
///
9+
/// \file
10+
/// Post-legalization combines on generic MachineInstrs.
11+
///
12+
/// The combines here must preserve instruction legality.
13+
///
14+
/// Combines which don't rely on instruction legality should go in the
15+
/// RISCVPreLegalizerCombiner.
16+
///
17+
//===----------------------------------------------------------------------===//
18+
19+
#include "RISCVTargetMachine.h"
20+
#include "llvm/CodeGen/GlobalISel/CSEInfo.h"
21+
#include "llvm/CodeGen/GlobalISel/Combiner.h"
22+
#include "llvm/CodeGen/GlobalISel/CombinerHelper.h"
23+
#include "llvm/CodeGen/GlobalISel/CombinerInfo.h"
24+
#include "llvm/CodeGen/GlobalISel/GIMatchTableExecutorImpl.h"
25+
#include "llvm/CodeGen/GlobalISel/GISelKnownBits.h"
26+
#include "llvm/CodeGen/GlobalISel/GenericMachineInstrs.h"
27+
#include "llvm/CodeGen/GlobalISel/MachineIRBuilder.h"
28+
#include "llvm/CodeGen/MachineDominators.h"
29+
#include "llvm/CodeGen/MachineFunctionPass.h"
30+
#include "llvm/CodeGen/MachineRegisterInfo.h"
31+
#include "llvm/CodeGen/TargetPassConfig.h"
32+
33+
#define GET_GICOMBINER_DEPS
34+
#include "RISCVGenPostLegalizeGICombiner.inc"
35+
#undef GET_GICOMBINER_DEPS
36+
37+
#define DEBUG_TYPE "riscv-postlegalizer-combiner"
38+
39+
using namespace llvm;
40+
41+
namespace {
42+
43+
#define GET_GICOMBINER_TYPES
44+
#include "RISCVGenPostLegalizeGICombiner.inc"
45+
#undef GET_GICOMBINER_TYPES
46+
47+
class RISCVPostLegalizerCombinerImpl : public Combiner {
48+
protected:
49+
// TODO: Make CombinerHelper methods const.
50+
mutable CombinerHelper Helper;
51+
const RISCVPostLegalizerCombinerImplRuleConfig &RuleConfig;
52+
const RISCVSubtarget &STI;
53+
54+
public:
55+
RISCVPostLegalizerCombinerImpl(
56+
MachineFunction &MF, CombinerInfo &CInfo, const TargetPassConfig *TPC,
57+
GISelKnownBits &KB, GISelCSEInfo *CSEInfo,
58+
const RISCVPostLegalizerCombinerImplRuleConfig &RuleConfig,
59+
const RISCVSubtarget &STI, MachineDominatorTree *MDT,
60+
const LegalizerInfo *LI);
61+
62+
static const char *getName() { return "RISCVPostLegalizerCombiner"; }
63+
64+
bool tryCombineAll(MachineInstr &I) const override;
65+
66+
private:
67+
#define GET_GICOMBINER_CLASS_MEMBERS
68+
#include "RISCVGenPostLegalizeGICombiner.inc"
69+
#undef GET_GICOMBINER_CLASS_MEMBERS
70+
};
71+
72+
#define GET_GICOMBINER_IMPL
73+
#include "RISCVGenPostLegalizeGICombiner.inc"
74+
#undef GET_GICOMBINER_IMPL
75+
76+
RISCVPostLegalizerCombinerImpl::RISCVPostLegalizerCombinerImpl(
77+
MachineFunction &MF, CombinerInfo &CInfo, const TargetPassConfig *TPC,
78+
GISelKnownBits &KB, GISelCSEInfo *CSEInfo,
79+
const RISCVPostLegalizerCombinerImplRuleConfig &RuleConfig,
80+
const RISCVSubtarget &STI, MachineDominatorTree *MDT,
81+
const LegalizerInfo *LI)
82+
: Combiner(MF, CInfo, TPC, &KB, CSEInfo),
83+
Helper(Observer, B, /*IsPreLegalize*/ false, &KB, MDT, LI),
84+
RuleConfig(RuleConfig), STI(STI),
85+
#define GET_GICOMBINER_CONSTRUCTOR_INITS
86+
#include "RISCVGenPostLegalizeGICombiner.inc"
87+
#undef GET_GICOMBINER_CONSTRUCTOR_INITS
88+
{
89+
}
90+
91+
class RISCVPostLegalizerCombiner : public MachineFunctionPass {
92+
public:
93+
static char ID;
94+
95+
RISCVPostLegalizerCombiner();
96+
97+
StringRef getPassName() const override {
98+
return "RISCVPostLegalizerCombiner";
99+
}
100+
101+
bool runOnMachineFunction(MachineFunction &MF) override;
102+
void getAnalysisUsage(AnalysisUsage &AU) const override;
103+
104+
private:
105+
RISCVPostLegalizerCombinerImplRuleConfig RuleConfig;
106+
};
107+
} // end anonymous namespace
108+
109+
void RISCVPostLegalizerCombiner::getAnalysisUsage(AnalysisUsage &AU) const {
110+
AU.addRequired<TargetPassConfig>();
111+
AU.setPreservesCFG();
112+
getSelectionDAGFallbackAnalysisUsage(AU);
113+
AU.addRequired<GISelKnownBitsAnalysis>();
114+
AU.addPreserved<GISelKnownBitsAnalysis>();
115+
AU.addRequired<MachineDominatorTree>();
116+
AU.addPreserved<MachineDominatorTree>();
117+
AU.addRequired<GISelCSEAnalysisWrapperPass>();
118+
AU.addPreserved<GISelCSEAnalysisWrapperPass>();
119+
MachineFunctionPass::getAnalysisUsage(AU);
120+
}
121+
122+
RISCVPostLegalizerCombiner::RISCVPostLegalizerCombiner()
123+
: MachineFunctionPass(ID) {
124+
initializeRISCVPostLegalizerCombinerPass(*PassRegistry::getPassRegistry());
125+
126+
if (!RuleConfig.parseCommandLineOption())
127+
report_fatal_error("Invalid rule identifier");
128+
}
129+
130+
bool RISCVPostLegalizerCombiner::runOnMachineFunction(MachineFunction &MF) {
131+
if (MF.getProperties().hasProperty(
132+
MachineFunctionProperties::Property::FailedISel))
133+
return false;
134+
assert(MF.getProperties().hasProperty(
135+
MachineFunctionProperties::Property::Legalized) &&
136+
"Expected a legalized function?");
137+
auto *TPC = &getAnalysis<TargetPassConfig>();
138+
const Function &F = MF.getFunction();
139+
bool EnableOpt =
140+
MF.getTarget().getOptLevel() != CodeGenOptLevel::None && !skipFunction(F);
141+
142+
const RISCVSubtarget &ST = MF.getSubtarget<RISCVSubtarget>();
143+
const auto *LI = ST.getLegalizerInfo();
144+
145+
GISelKnownBits *KB = &getAnalysis<GISelKnownBitsAnalysis>().get(MF);
146+
MachineDominatorTree *MDT = &getAnalysis<MachineDominatorTree>();
147+
GISelCSEAnalysisWrapper &Wrapper =
148+
getAnalysis<GISelCSEAnalysisWrapperPass>().getCSEWrapper();
149+
auto *CSEInfo = &Wrapper.get(TPC->getCSEConfig());
150+
151+
CombinerInfo CInfo(/*AllowIllegalOps*/ true, /*ShouldLegalizeIllegal*/ false,
152+
/*LegalizerInfo*/ nullptr, EnableOpt, F.hasOptSize(),
153+
F.hasMinSize());
154+
RISCVPostLegalizerCombinerImpl Impl(MF, CInfo, TPC, *KB, CSEInfo,
155+
RuleConfig, ST, MDT, LI);
156+
return Impl.combineMachineInstrs();
157+
}
158+
159+
char RISCVPostLegalizerCombiner::ID = 0;
160+
INITIALIZE_PASS_BEGIN(RISCVPostLegalizerCombiner, DEBUG_TYPE,
161+
"Combine RISC-V MachineInstrs after legalization", false,
162+
false)
163+
INITIALIZE_PASS_DEPENDENCY(TargetPassConfig)
164+
INITIALIZE_PASS_DEPENDENCY(GISelKnownBitsAnalysis)
165+
INITIALIZE_PASS_END(RISCVPostLegalizerCombiner, DEBUG_TYPE,
166+
"Combine RISC-V MachineInstrs after legalization", false,
167+
false)
168+
169+
namespace llvm {
170+
FunctionPass *createRISCVPostLegalizerCombiner() {
171+
return new RISCVPostLegalizerCombiner();
172+
}
173+
} // end namespace llvm

llvm/lib/Target/RISCV/GISel/RISCVPreLegalizerCombiner.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -153,13 +153,13 @@ bool RISCVPreLegalizerCombiner::runOnMachineFunction(MachineFunction &MF) {
153153

154154
char RISCVPreLegalizerCombiner::ID = 0;
155155
INITIALIZE_PASS_BEGIN(RISCVPreLegalizerCombiner, DEBUG_TYPE,
156-
"Combine RISCV machine instrs before legalization", false,
156+
"Combine RISC-V machine instrs before legalization", false,
157157
false)
158158
INITIALIZE_PASS_DEPENDENCY(TargetPassConfig)
159159
INITIALIZE_PASS_DEPENDENCY(GISelKnownBitsAnalysis)
160160
INITIALIZE_PASS_DEPENDENCY(GISelCSEAnalysisWrapperPass)
161161
INITIALIZE_PASS_END(RISCVPreLegalizerCombiner, DEBUG_TYPE,
162-
"Combine RISCV machine instrs before legalization", false,
162+
"Combine RISC-V machine instrs before legalization", false,
163163
false)
164164

165165
namespace llvm {

llvm/lib/Target/RISCV/RISCV.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -84,6 +84,9 @@ InstructionSelector *createRISCVInstructionSelector(const RISCVTargetMachine &,
8484
RISCVRegisterBankInfo &);
8585
void initializeRISCVDAGToDAGISelPass(PassRegistry &);
8686

87+
FunctionPass *createRISCVPostLegalizerCombiner();
88+
void initializeRISCVPostLegalizerCombinerPass(PassRegistry &);
89+
8790
FunctionPass *createRISCVO0PreLegalizerCombiner();
8891
void initializeRISCVO0PreLegalizerCombinerPass(PassRegistry &);
8992

llvm/lib/Target/RISCV/RISCVCombine.td

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,3 +18,10 @@ def RISCVPreLegalizerCombiner: GICombiner<
1818
def RISCVO0PreLegalizerCombiner: GICombiner<
1919
"RISCVO0PreLegalizerCombinerImpl", [optnone_combines]> {
2020
}
21+
22+
// Post-legalization combines which are primarily optimizations.
23+
// TODO: Add more combines.
24+
def RISCVPostLegalizerCombiner
25+
: GICombiner<"RISCVPostLegalizerCombinerImpl",
26+
[redundant_and, identity_combines]> {
27+
}

llvm/lib/Target/RISCV/RISCVTargetMachine.cpp

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -85,6 +85,7 @@ extern "C" LLVM_EXTERNAL_VISIBILITY void LLVMInitializeRISCVTarget() {
8585
initializeGlobalISel(*PR);
8686
initializeRISCVO0PreLegalizerCombinerPass(*PR);
8787
initializeRISCVPreLegalizerCombinerPass(*PR);
88+
initializeRISCVPostLegalizerCombinerPass(*PR);
8889
initializeKCFIPass(*PR);
8990
initializeRISCVDeadRegisterDefinitionsPass(*PR);
9091
initializeRISCVMakeCompressibleOptPass(*PR);
@@ -275,6 +276,7 @@ class RISCVPassConfig : public TargetPassConfig {
275276
bool addIRTranslator() override;
276277
void addPreLegalizeMachineIR() override;
277278
bool addLegalizeMachineIR() override;
279+
void addPreRegBankSelect() override;
278280
bool addRegBankSelect() override;
279281
bool addGlobalInstructionSelect() override;
280282
void addPreEmitPass() override;
@@ -345,6 +347,11 @@ bool RISCVPassConfig::addLegalizeMachineIR() {
345347
return false;
346348
}
347349

350+
void RISCVPassConfig::addPreRegBankSelect() {
351+
if (getOptLevel() != CodeGenOptLevel::None)
352+
addPass(createRISCVPostLegalizerCombiner());
353+
}
354+
348355
bool RISCVPassConfig::addRegBankSelect() {
349356
addPass(new RegBankSelect());
350357
return false;

llvm/test/CodeGen/RISCV/GlobalISel/alu-roundtrip.ll

Lines changed: 1 addition & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -391,7 +391,6 @@ define i64 @add_i64(i64 %a, i64 %b) {
391391
; RV32IM-NEXT: add a0, a0, a2
392392
; RV32IM-NEXT: sltu a2, a0, a2
393393
; RV32IM-NEXT: add a1, a1, a3
394-
; RV32IM-NEXT: andi a2, a2, 1
395394
; RV32IM-NEXT: add a1, a1, a2
396395
; RV32IM-NEXT: ret
397396
;
@@ -409,8 +408,6 @@ define i64 @addi_i64(i64 %a) {
409408
; RV32IM: # %bb.0: # %entry
410409
; RV32IM-NEXT: addi a0, a0, 1234
411410
; RV32IM-NEXT: sltiu a2, a0, 1234
412-
; RV32IM-NEXT: mv a1, a1
413-
; RV32IM-NEXT: andi a2, a2, 1
414411
; RV32IM-NEXT: add a1, a1, a2
415412
; RV32IM-NEXT: ret
416413
;
@@ -429,7 +426,6 @@ define i64 @sub_i64(i64 %a, i64 %b) {
429426
; RV32IM-NEXT: sub a4, a0, a2
430427
; RV32IM-NEXT: sltu a0, a0, a2
431428
; RV32IM-NEXT: sub a1, a1, a3
432-
; RV32IM-NEXT: andi a0, a0, 1
433429
; RV32IM-NEXT: sub a1, a1, a0
434430
; RV32IM-NEXT: mv a0, a4
435431
; RV32IM-NEXT: ret
@@ -450,8 +446,6 @@ define i64 @subi_i64(i64 %a) {
450446
; RV32IM-NEXT: addi a3, a2, 1548
451447
; RV32IM-NEXT: sub a2, a0, a3
452448
; RV32IM-NEXT: sltu a0, a0, a3
453-
; RV32IM-NEXT: mv a1, a1
454-
; RV32IM-NEXT: andi a0, a0, 1
455449
; RV32IM-NEXT: sub a1, a1, a0
456450
; RV32IM-NEXT: mv a0, a2
457451
; RV32IM-NEXT: ret
@@ -489,7 +483,7 @@ define i64 @andi_i64(i64 %a) {
489483
; RV32IM-LABEL: andi_i64:
490484
; RV32IM: # %bb.0: # %entry
491485
; RV32IM-NEXT: andi a0, a0, 1234
492-
; RV32IM-NEXT: andi a1, a1, 0
486+
; RV32IM-NEXT: li a1, 0
493487
; RV32IM-NEXT: ret
494488
;
495489
; RV64IM-LABEL: andi_i64:
@@ -521,7 +515,6 @@ define i64 @ori_i64(i64 %a) {
521515
; RV32IM-LABEL: ori_i64:
522516
; RV32IM: # %bb.0: # %entry
523517
; RV32IM-NEXT: ori a0, a0, 1234
524-
; RV32IM-NEXT: ori a1, a1, 0
525518
; RV32IM-NEXT: ret
526519
;
527520
; RV64IM-LABEL: ori_i64:
@@ -553,7 +546,6 @@ define i64 @xori_i64(i64 %a) {
553546
; RV32IM-LABEL: xori_i64:
554547
; RV32IM: # %bb.0: # %entry
555548
; RV32IM-NEXT: xori a0, a0, 1234
556-
; RV32IM-NEXT: xori a1, a1, 0
557549
; RV32IM-NEXT: ret
558550
;
559551
; RV64IM-LABEL: xori_i64:

llvm/test/CodeGen/RISCV/GlobalISel/gisel-commandline-option.ll

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,8 @@
2121
; ENABLED-NEXT: Analysis containing CSE Info
2222
; ENABLED-O1-NEXT: RISCVPreLegalizerCombiner
2323
; ENABLED-NEXT: Legalizer
24+
; ENABLED-O1-NEXT: MachineDominator Tree Construction
25+
; ENABLED-O1-NEXT: RISCVPostLegalizerCombiner
2426
; ENABLED-NEXT: RegBankSelect
2527
; ENABLED-NEXT: Analysis for ComputingKnownBits
2628
; ENABLED-O1-NEXT: Lazy Branch Probability Analysis

0 commit comments

Comments
 (0)