Skip to content

Commit 720007e

Browse files
authored
[NFC] [SPIRV] Add SPIRVCombinerHelper and refactor pre legalizer combiner to use it (llvm#162735)
Lots of the code/structure was based off `AMDGPUCombinerHelper`, `AMDGPUPreLegalizerCombiner`, etc. Tasks completed: - Create new `SPIRVCombinerHelper` inheriting from `CombinerHelper` - Move combiner logic in `SPIRVPreLegalizerCombiner` to helper methods in `SPIRVCombinerHelper` - Update `SPIRVPreLegalizerCombiner` to use the new helper class - Simplify `applySPIRVDistance` code
1 parent 8faeed0 commit 720007e

File tree

5 files changed

+104
-76
lines changed

5 files changed

+104
-76
lines changed

llvm/lib/Target/SPIRV/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,7 @@ add_llvm_target(SPIRVCodeGen
3636
SPIRVMetadata.cpp
3737
SPIRVModuleAnalysis.cpp
3838
SPIRVStructurizer.cpp
39+
SPIRVCombinerHelper.cpp
3940
SPIRVPreLegalizer.cpp
4041
SPIRVPreLegalizerCombiner.cpp
4142
SPIRVPostLegalizer.cpp

llvm/lib/Target/SPIRV/SPIRVCombine.td

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,8 +11,8 @@ include "llvm/Target/GlobalISel/Combine.td"
1111
def vector_length_sub_to_distance_lowering : GICombineRule <
1212
(defs root:$root),
1313
(match (wip_match_opcode G_INTRINSIC):$root,
14-
[{ return matchLengthToDistance(*${root}, MRI); }]),
15-
(apply [{ applySPIRVDistance(*${root}, MRI, B); }])
14+
[{ return Helper.matchLengthToDistance(*${root}); }]),
15+
(apply [{ Helper.applySPIRVDistance(*${root}); }])
1616
>;
1717

1818
def SPIRVPreLegalizerCombiner
Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
1+
//===-- SPIRVCombinerHelper.cpp -------------------------------------------===//
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+
#include "SPIRVCombinerHelper.h"
10+
#include "llvm/CodeGen/GlobalISel/GenericMachineInstrs.h"
11+
#include "llvm/CodeGen/GlobalISel/MIPatternMatch.h"
12+
#include "llvm/IR/IntrinsicsSPIRV.h"
13+
#include "llvm/Target/TargetMachine.h"
14+
15+
using namespace llvm;
16+
using namespace MIPatternMatch;
17+
18+
SPIRVCombinerHelper::SPIRVCombinerHelper(
19+
GISelChangeObserver &Observer, MachineIRBuilder &B, bool IsPreLegalize,
20+
GISelValueTracking *VT, MachineDominatorTree *MDT, const LegalizerInfo *LI,
21+
const SPIRVSubtarget &STI)
22+
: CombinerHelper(Observer, B, IsPreLegalize, VT, MDT, LI), STI(STI) {}
23+
24+
/// This match is part of a combine that
25+
/// rewrites length(X - Y) to distance(X, Y)
26+
/// (f32 (g_intrinsic length
27+
/// (g_fsub (vXf32 X) (vXf32 Y))))
28+
/// ->
29+
/// (f32 (g_intrinsic distance
30+
/// (vXf32 X) (vXf32 Y)))
31+
///
32+
bool SPIRVCombinerHelper::matchLengthToDistance(MachineInstr &MI) const {
33+
if (MI.getOpcode() != TargetOpcode::G_INTRINSIC ||
34+
cast<GIntrinsic>(MI).getIntrinsicID() != Intrinsic::spv_length)
35+
return false;
36+
37+
// First operand of MI is `G_INTRINSIC` so start at operand 2.
38+
Register SubReg = MI.getOperand(2).getReg();
39+
MachineInstr *SubInstr = MRI.getVRegDef(SubReg);
40+
if (SubInstr->getOpcode() != TargetOpcode::G_FSUB)
41+
return false;
42+
43+
return true;
44+
}
45+
46+
void SPIRVCombinerHelper::applySPIRVDistance(MachineInstr &MI) const {
47+
// Extract the operands for X and Y from the match criteria.
48+
Register SubDestReg = MI.getOperand(2).getReg();
49+
MachineInstr *SubInstr = MRI.getVRegDef(SubDestReg);
50+
Register SubOperand1 = SubInstr->getOperand(1).getReg();
51+
Register SubOperand2 = SubInstr->getOperand(2).getReg();
52+
Register ResultReg = MI.getOperand(0).getReg();
53+
54+
Builder.setInstrAndDebugLoc(MI);
55+
Builder.buildIntrinsic(Intrinsic::spv_distance, ResultReg)
56+
.addUse(SubOperand1)
57+
.addUse(SubOperand2);
58+
59+
MI.eraseFromParent();
60+
}
Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
//===-- SPIRVCombinerHelper.h -----------------------------------*- 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+
/// This contains common combine transformations that may be used in a combine
10+
/// pass.
11+
///
12+
//===----------------------------------------------------------------------===//
13+
14+
#ifndef LLVM_LIB_TARGET_SPIRV_SPIRVCOMBINERHELPER_H
15+
#define LLVM_LIB_TARGET_SPIRV_SPIRVCOMBINERHELPER_H
16+
17+
#include "SPIRVSubtarget.h"
18+
#include "llvm/CodeGen/GlobalISel/CombinerHelper.h"
19+
20+
namespace llvm {
21+
class SPIRVCombinerHelper : public CombinerHelper {
22+
protected:
23+
const SPIRVSubtarget &STI;
24+
25+
public:
26+
using CombinerHelper::CombinerHelper;
27+
SPIRVCombinerHelper(GISelChangeObserver &Observer, MachineIRBuilder &B,
28+
bool IsPreLegalize, GISelValueTracking *VT,
29+
MachineDominatorTree *MDT, const LegalizerInfo *LI,
30+
const SPIRVSubtarget &STI);
31+
32+
bool matchLengthToDistance(MachineInstr &MI) const;
33+
void applySPIRVDistance(MachineInstr &MI) const;
34+
};
35+
36+
} // end namespace llvm
37+
38+
#endif // LLVM_LIB_TARGET_SPIRV_SPIRVCOMBINERHELPER_H

llvm/lib/Target/SPIRV/SPIRVPreLegalizerCombiner.cpp

Lines changed: 3 additions & 74 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,3 @@
1-
21
//===-- SPIRVPreLegalizerCombiner.cpp - combine legalization ----*- C++ -*-===//
32
//
43
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
@@ -13,24 +12,17 @@
1312
//===----------------------------------------------------------------------===//
1413

1514
#include "SPIRV.h"
16-
#include "SPIRVTargetMachine.h"
15+
#include "SPIRVCombinerHelper.h"
1716
#include "llvm/CodeGen/GlobalISel/CSEInfo.h"
1817
#include "llvm/CodeGen/GlobalISel/Combiner.h"
19-
#include "llvm/CodeGen/GlobalISel/CombinerHelper.h"
2018
#include "llvm/CodeGen/GlobalISel/CombinerInfo.h"
2119
#include "llvm/CodeGen/GlobalISel/GIMatchTableExecutorImpl.h"
2220
#include "llvm/CodeGen/GlobalISel/GISelChangeObserver.h"
2321
#include "llvm/CodeGen/GlobalISel/GISelValueTracking.h"
24-
#include "llvm/CodeGen/GlobalISel/GenericMachineInstrs.h"
2522
#include "llvm/CodeGen/GlobalISel/MIPatternMatch.h"
26-
#include "llvm/CodeGen/GlobalISel/MachineIRBuilder.h"
27-
#include "llvm/CodeGen/GlobalISel/Utils.h"
2823
#include "llvm/CodeGen/MachineDominators.h"
2924
#include "llvm/CodeGen/MachineFunctionPass.h"
30-
#include "llvm/CodeGen/MachineRegisterInfo.h"
31-
#include "llvm/CodeGen/TargetOpcodes.h"
3225
#include "llvm/CodeGen/TargetPassConfig.h"
33-
#include "llvm/IR/IntrinsicsSPIRV.h"
3426

3527
#define GET_GICOMBINER_DEPS
3628
#include "SPIRVGenPreLegalizeGICombiner.inc"
@@ -47,72 +39,9 @@ namespace {
4739
#include "SPIRVGenPreLegalizeGICombiner.inc"
4840
#undef GET_GICOMBINER_TYPES
4941

50-
/// This match is part of a combine that
51-
/// rewrites length(X - Y) to distance(X, Y)
52-
/// (f32 (g_intrinsic length
53-
/// (g_fsub (vXf32 X) (vXf32 Y))))
54-
/// ->
55-
/// (f32 (g_intrinsic distance
56-
/// (vXf32 X) (vXf32 Y)))
57-
///
58-
bool matchLengthToDistance(MachineInstr &MI, MachineRegisterInfo &MRI) {
59-
if (MI.getOpcode() != TargetOpcode::G_INTRINSIC ||
60-
cast<GIntrinsic>(MI).getIntrinsicID() != Intrinsic::spv_length)
61-
return false;
62-
63-
// First operand of MI is `G_INTRINSIC` so start at operand 2.
64-
Register SubReg = MI.getOperand(2).getReg();
65-
MachineInstr *SubInstr = MRI.getVRegDef(SubReg);
66-
if (!SubInstr || SubInstr->getOpcode() != TargetOpcode::G_FSUB)
67-
return false;
68-
69-
return true;
70-
}
71-
void applySPIRVDistance(MachineInstr &MI, MachineRegisterInfo &MRI,
72-
MachineIRBuilder &B) {
73-
74-
// Extract the operands for X and Y from the match criteria.
75-
Register SubDestReg = MI.getOperand(2).getReg();
76-
MachineInstr *SubInstr = MRI.getVRegDef(SubDestReg);
77-
Register SubOperand1 = SubInstr->getOperand(1).getReg();
78-
Register SubOperand2 = SubInstr->getOperand(2).getReg();
79-
80-
// Remove the original `spv_length` instruction.
81-
82-
Register ResultReg = MI.getOperand(0).getReg();
83-
DebugLoc DL = MI.getDebugLoc();
84-
MachineBasicBlock &MBB = *MI.getParent();
85-
MachineBasicBlock::iterator InsertPt = MI.getIterator();
86-
87-
// Build the `spv_distance` intrinsic.
88-
MachineInstrBuilder NewInstr =
89-
BuildMI(MBB, InsertPt, DL, B.getTII().get(TargetOpcode::G_INTRINSIC));
90-
NewInstr
91-
.addDef(ResultReg) // Result register
92-
.addIntrinsicID(Intrinsic::spv_distance) // Intrinsic ID
93-
.addUse(SubOperand1) // Operand X
94-
.addUse(SubOperand2); // Operand Y
95-
96-
SPIRVGlobalRegistry *GR =
97-
MI.getMF()->getSubtarget<SPIRVSubtarget>().getSPIRVGlobalRegistry();
98-
auto RemoveAllUses = [&](Register Reg) {
99-
SmallVector<MachineInstr *, 4> UsesToErase(
100-
llvm::make_pointer_range(MRI.use_instructions(Reg)));
101-
102-
// calling eraseFromParent to early invalidates the iterator.
103-
for (auto *MIToErase : UsesToErase) {
104-
GR->invalidateMachineInstr(MIToErase);
105-
MIToErase->eraseFromParent();
106-
}
107-
};
108-
RemoveAllUses(SubDestReg); // remove all uses of FSUB Result
109-
GR->invalidateMachineInstr(SubInstr);
110-
SubInstr->eraseFromParent(); // remove FSUB instruction
111-
}
112-
11342
class SPIRVPreLegalizerCombinerImpl : public Combiner {
11443
protected:
115-
const CombinerHelper Helper;
44+
const SPIRVCombinerHelper Helper;
11645
const SPIRVPreLegalizerCombinerImplRuleConfig &RuleConfig;
11746
const SPIRVSubtarget &STI;
11847

@@ -147,7 +76,7 @@ SPIRVPreLegalizerCombinerImpl::SPIRVPreLegalizerCombinerImpl(
14776
const SPIRVSubtarget &STI, MachineDominatorTree *MDT,
14877
const LegalizerInfo *LI)
14978
: Combiner(MF, CInfo, TPC, &VT, CSEInfo),
150-
Helper(Observer, B, /*IsPreLegalize*/ true, &VT, MDT, LI),
79+
Helper(Observer, B, /*IsPreLegalize*/ true, &VT, MDT, LI, STI),
15180
RuleConfig(RuleConfig), STI(STI),
15281
#define GET_GICOMBINER_CONSTRUCTOR_INITS
15382
#include "SPIRVGenPreLegalizeGICombiner.inc"

0 commit comments

Comments
 (0)