Skip to content

Commit 783a2ad

Browse files
committed
[RISCV] Macro-fusion support for veyron-v1 CPU.
Support was added for the following fusions: auipc-addi, slli-srli, ld-add Some parts of the code became repetative, so small refactoring of existing lui-addi fusion was done.
1 parent b88b480 commit 783a2ad

File tree

3 files changed

+120
-15
lines changed

3 files changed

+120
-15
lines changed

llvm/lib/Target/RISCV/RISCVFeatures.td

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -970,6 +970,16 @@ def TuneLUIADDIFusion
970970
: SubtargetFeature<"lui-addi-fusion", "HasLUIADDIFusion",
971971
"true", "Enable LUI+ADDI macrofusion">;
972972

973+
def TuneAUIPCADDIFusion
974+
: SubtargetFeature<"auipc-addi-fusion", "HasAUIPCADDIFusion",
975+
"true", "Enable AUIPC+ADDI macrofusion">;
976+
def TuneSLLISRLIFusion
977+
: SubtargetFeature<"slli-srli-fusion", "HasSLLISRLIFusion",
978+
"true", "Enable SLLI+SRLI macrofusion">;
979+
def TuneLDADDFusion
980+
: SubtargetFeature<"ld-add-fusion", "HasLDADDFusion",
981+
"true", "Enable fusion of load with the last instruction of the address calculation">;
982+
973983
def TuneNoDefaultUnroll
974984
: SubtargetFeature<"no-default-unroll", "EnableDefaultUnroll", "false",
975985
"Disable default unroll preference.">;
@@ -987,9 +997,19 @@ def TuneSiFive7 : SubtargetFeature<"sifive7", "RISCVProcFamily", "SiFive7",
987997
[TuneNoDefaultUnroll,
988998
TuneShortForwardBranchOpt]>;
989999

1000+
<<<<<<< HEAD
9901001
def TuneVentanaVeyron : SubtargetFeature<"ventana-veyron", "RISCVProcFamily", "VentanaVeyron",
9911002
"Ventana-Veyron Series processors",
9921003
[TuneLUIADDIFusion]>;
1004+
=======
1005+
def TuneVeyronFusions : SubtargetFeature<"ventana-veyron", "RISCVProcFamily", "VentanaVeyron",
1006+
"Ventana Veyron-Series processors",
1007+
[TuneLUIADDIFusion,
1008+
TuneAUIPCADDIFusion,
1009+
TuneSLLISRLIFusion,
1010+
TuneLDADDFusion]>;
1011+
1012+
>>>>>>> bbf0196a7d42 ([RISCV] Macro-fusion support for veyron-v1 CPU.)
9931013

9941014
// Assume that lock-free native-width atomics are available, even if the target
9951015
// and operating system combination would not usually provide them. The user

llvm/lib/Target/RISCV/RISCVMacroFusion.cpp

Lines changed: 96 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,90 @@
1818

1919
using namespace llvm;
2020

21+
static bool checkRegisters(Register FirstDest, const MachineInstr &SecondMI) {
22+
if (SecondMI.getOperand(1).getReg() != FirstDest)
23+
return false;
24+
25+
// If the input is virtual make sure this is the only user.
26+
if (FirstDest.isVirtual()) {
27+
auto &MRI = SecondMI.getMF()->getRegInfo();
28+
return MRI.hasOneNonDBGUse(FirstDest);
29+
}
30+
31+
return SecondMI.getOperand(0).getReg() == FirstDest;
32+
}
33+
34+
// Fuse Load
35+
static bool isLDADD(const MachineInstr *FirstMI, const MachineInstr &SecondMI) {
36+
if (SecondMI.getOpcode() != RISCV::LD)
37+
return false;
38+
39+
if (!SecondMI.getOperand(2).isImm())
40+
return false;
41+
42+
if (SecondMI.getOperand(2).getImm() != 0)
43+
return false;
44+
45+
// Given SecondMI, when FirstMI is unspecified, we must return
46+
// if SecondMI may be part of a fused pair at all.
47+
if (!FirstMI)
48+
return true;
49+
50+
if (FirstMI->getOpcode() != RISCV::ADD)
51+
return true;
52+
53+
return checkRegisters(FirstMI->getOperand(0).getReg(), SecondMI);
54+
}
55+
56+
// Fuse SLLI by 32 feeding into SRLI by 32 or less or
57+
// SLLI by exactly 48 feeding into SRLI by exactly 48.
58+
static bool isSLLISRLI(const MachineInstr *FirstMI,
59+
const MachineInstr &SecondMI) {
60+
if (SecondMI.getOpcode() != RISCV::SRLI)
61+
return false;
62+
63+
if (!SecondMI.getOperand(2).isImm())
64+
return false;
65+
66+
unsigned SRLIImm = SecondMI.getOperand(2).getImm();
67+
bool IsShiftBy48 = SRLIImm == 48;
68+
if (SRLIImm > 32 && !IsShiftBy48)
69+
return false;
70+
71+
// Given SecondMI, when FirstMI is unspecified, we must return
72+
// if SecondMI may be part of a fused pair at all.
73+
if (!FirstMI)
74+
return true;
75+
76+
if (FirstMI->getOpcode() != RISCV::SLLI)
77+
return false;
78+
79+
unsigned SLLIImm = FirstMI->getOperand(2).getImm();
80+
if (IsShiftBy48 ? (SLLIImm != 48) : (SLLIImm > 32))
81+
return false;
82+
83+
return checkRegisters(FirstMI->getOperand(0).getReg(), SecondMI);
84+
}
85+
86+
// Fuse AUIPC followed by ADDI
87+
static bool isAUIPCADDI(const MachineInstr *FirstMI,
88+
const MachineInstr &SecondMI) {
89+
if (SecondMI.getOpcode() != RISCV::ADDI)
90+
return false;
91+
// Assume the 1st instr to be a wildcard if it is unspecified.
92+
if (!FirstMI)
93+
return true;
94+
95+
if (FirstMI->getOpcode() != RISCV::AUIPC)
96+
return false;
97+
98+
// The first operand of ADDI might be a frame index.
99+
if (!SecondMI.getOperand(1).isReg())
100+
return false;
101+
102+
return checkRegisters(FirstMI->getOperand(0).getReg(), SecondMI);
103+
}
104+
21105
// Fuse LUI followed by ADDI or ADDIW.
22106
// rd = imm[31:0] which decomposes to
23107
// lui rd, imm[31:12]
@@ -27,29 +111,18 @@ static bool isLUIADDI(const MachineInstr *FirstMI,
27111
if (SecondMI.getOpcode() != RISCV::ADDI &&
28112
SecondMI.getOpcode() != RISCV::ADDIW)
29113
return false;
30-
31114
// Assume the 1st instr to be a wildcard if it is unspecified.
32115
if (!FirstMI)
33116
return true;
34117

35118
if (FirstMI->getOpcode() != RISCV::LUI)
36119
return false;
37120

38-
Register FirstDest = FirstMI->getOperand(0).getReg();
39-
40-
// Destination of LUI should be the ADDI(W) source register.
41-
if (SecondMI.getOperand(1).getReg() != FirstDest)
121+
// The first operand of ADDI might be a frame index.
122+
if (!SecondMI.getOperand(1).isReg())
42123
return false;
43124

44-
// If the input is virtual make sure this is the only user.
45-
if (FirstDest.isVirtual()) {
46-
auto &MRI = SecondMI.getMF()->getRegInfo();
47-
return MRI.hasOneNonDBGUse(FirstDest);
48-
}
49-
50-
// If the FirstMI destination is non-virtual, it should match the SecondMI
51-
// destination.
52-
return SecondMI.getOperand(0).getReg() == FirstDest;
125+
return checkRegisters(FirstMI->getOperand(0).getReg(), SecondMI);
53126
}
54127

55128
static bool shouldScheduleAdjacent(const TargetInstrInfo &TII,
@@ -61,6 +134,15 @@ static bool shouldScheduleAdjacent(const TargetInstrInfo &TII,
61134
if (ST.hasLUIADDIFusion() && isLUIADDI(FirstMI, SecondMI))
62135
return true;
63136

137+
if (ST.hasAUIPCADDIFusion() && isAUIPCADDI(FirstMI, SecondMI))
138+
return true;
139+
140+
if (ST.hasSLLISRLIFusion() && isSLLISRLI(FirstMI, SecondMI))
141+
return true;
142+
143+
if (ST.hasLDADDFusion() && isLDADD(FirstMI, SecondMI))
144+
return true;
145+
64146
return false;
65147
}
66148

llvm/lib/Target/RISCV/RISCVSubtarget.h

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -192,7 +192,10 @@ class RISCVSubtarget : public RISCVGenSubtargetInfo {
192192
return UserReservedRegister[i];
193193
}
194194

195-
bool hasMacroFusion() const { return hasLUIADDIFusion(); }
195+
bool hasMacroFusion() const {
196+
return hasLUIADDIFusion() || hasAUIPCADDIFusion() || hasSLLISRLIFusion() ||
197+
hasLDADDFusion();
198+
}
196199

197200
// Vector codegen related methods.
198201
bool hasVInstructions() const { return HasStdExtZve32x; }

0 commit comments

Comments
 (0)