Skip to content

Commit 1e9ba4c

Browse files
committed
Use common register class
Remove target hook. Instead, use common register class to check if two phis are allowed to reuse the same temp.
1 parent 9190ad1 commit 1e9ba4c

File tree

3 files changed

+56
-14
lines changed

3 files changed

+56
-14
lines changed

llvm/include/llvm/CodeGen/TargetInstrInfo.h

Lines changed: 2 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -2169,7 +2169,7 @@ class LLVM_ABI TargetInstrInfo : public MCInstrInfo {
21692169
return TargetOpcode::COPY;
21702170
}
21712171

2172-
/// During PHI elimination lets target to make necessary checks and
2172+
/// During PHI eleimination lets target to make necessary checks and
21732173
/// insert the copy to the PHI destination register in a target specific
21742174
/// manner.
21752175
virtual MachineInstr *createPHIDestinationCopy(
@@ -2179,7 +2179,7 @@ class LLVM_ABI TargetInstrInfo : public MCInstrInfo {
21792179
.addReg(Src);
21802180
}
21812181

2182-
/// During PHI elimination lets target to make necessary checks and
2182+
/// During PHI eleimination lets target to make necessary checks and
21832183
/// insert the copy to the PHI destination register in a target specific
21842184
/// manner.
21852185
virtual MachineInstr *createPHISourceCopy(MachineBasicBlock &MBB,
@@ -2191,17 +2191,6 @@ class LLVM_ABI TargetInstrInfo : public MCInstrInfo {
21912191
.addReg(Src, 0, SrcSubReg);
21922192
}
21932193

2194-
/// During PHI elimination lets target to decide if two phis can use the
2195-
/// same register \p Reg when they have the same rhs. Register \p Reg has
2196-
/// been used for the first phi and \p PHIReg is the DestReg of the second
2197-
/// Phi. This function is to check if the second phi can reuse \p Reg as
2198-
/// its temporary register.
2199-
/// The default is to allow reuse.
2200-
virtual bool allowPHIReuse(Register Reg, Register PHIReg,
2201-
const MachineFunction &MF) const {
2202-
return true;
2203-
}
2204-
22052194
/// Returns a \p outliner::OutlinedFunction struct containing target-specific
22062195
/// information for a set of outlining candidates. Returns std::nullopt if the
22072196
/// candidates are not suitable for outlining. \p MinRepeats is the minimum

llvm/lib/CodeGen/PHIElimination.cpp

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -377,10 +377,21 @@ void PHIEliminationImpl::LowerPHINode(MachineBasicBlock &MBB,
377377
// typically those created by tail duplication. Typically, an identical PHI
378378
// node can't occur, so avoid hashing/storing such PHIs, which is somewhat
379379
// expensive.
380+
381+
// canReuse() checks if two phis of the same rhs have the common sub class
382+
// for their lhs's and allow reuse if so. (useful for some GPU targets)
383+
auto canReuse = [](Register Reg0, Register Reg1, MachineFunction &MF) {
384+
auto &MRI = MF.getRegInfo();
385+
auto *RC0 = MRI.getRegClass(Reg0);
386+
auto *RC1 = MRI.getRegClass(Reg1);
387+
return MF.getSubtarget().getRegisterInfo()->getCommonSubClass(RC0, RC1) !=
388+
nullptr;
389+
};
390+
380391
Register *Entry = nullptr;
381392
if (AllEdgesCritical)
382393
Entry = &LoweredPHIs[MPhi];
383-
if (Entry && *Entry && TII->allowPHIReuse(*Entry, DestReg, MF)) {
394+
if (Entry && *Entry && canReuse(*Entry, DestReg, MF)) {
384395
// An identical PHI node was already lowered. Reuse the incoming register.
385396
IncomingReg = *Entry;
386397
reusedIncoming = true;
Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
# RUN: llc -mtriple amdgcn -run-pass phi-node-elimination -o - %s | FileCheck %s
2+
3+
---
4+
# The test is to make sure that two phis, with the same right-hand-site but different
5+
# register classes for their left-hand-sites, are not doing phi reuse optimization.
6+
# Not sure whether this test makes any sense for the AMDGPU target, but it is a valid
7+
# case for aother GPU target that is not in LLVM trunk yet. Thus, this test uses the
8+
# ADMGPU target as a proof of concept.
9+
10+
# Because of no reuse for the two phis, there are two temps: CP0 and CP1
11+
# They are translated to:
12+
# phi1 (%1:sreg_32) = CP0
13+
# phi2 (%4:vgpr_32) = CP1
14+
#
15+
# CHECK-LABEL: check-phi-reuse
16+
# CHECK-LABEL: bb.1:
17+
# CHECK: %1:sreg_32 = COPY %[[#CP0:]]
18+
# CHECK: %[[#CP0]]:sreg_32 = COPY {{.+}}
19+
# CHECK: %[[#CP1:]]:vgpr_32 = COPY {{.+}}
20+
# CHECK-LABEL: bb.2:
21+
# CHECK: %4:vgpr_32 = COPY %[[#CP1]]
22+
23+
24+
25+
name: check-phi-reuse
26+
tracksRegLiveness: true
27+
body: |
28+
bb.0:
29+
%1:sreg_32 = S_MOV_B32 255
30+
S_CBRANCH_SCC0 %bb.2, implicit undef $scc
31+
32+
bb.1:
33+
%3:sreg_32 = PHI %4, %bb.1, %1, %bb.0
34+
%2:sreg_32 = S_ADD_I32 %3, 1, implicit-def $scc
35+
%4:vgpr_32 = COPY %2
36+
S_CBRANCH_SCC0 %bb.1, implicit killed $scc
37+
S_BRANCH %bb.2
38+
39+
bb.2:
40+
%5:vgpr_32 = PHI %4, %bb.1, %1, %bb.0
41+
...
42+

0 commit comments

Comments
 (0)