18
18
19
19
using namespace llvm ;
20
20
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
+
21
105
// Fuse LUI followed by ADDI or ADDIW.
22
106
// rd = imm[31:0] which decomposes to
23
107
// lui rd, imm[31:12]
@@ -27,29 +111,18 @@ static bool isLUIADDI(const MachineInstr *FirstMI,
27
111
if (SecondMI.getOpcode () != RISCV::ADDI &&
28
112
SecondMI.getOpcode () != RISCV::ADDIW)
29
113
return false ;
30
-
31
114
// Assume the 1st instr to be a wildcard if it is unspecified.
32
115
if (!FirstMI)
33
116
return true ;
34
117
35
118
if (FirstMI->getOpcode () != RISCV::LUI)
36
119
return false ;
37
120
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 ())
42
123
return false ;
43
124
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);
53
126
}
54
127
55
128
static bool shouldScheduleAdjacent (const TargetInstrInfo &TII,
@@ -61,6 +134,15 @@ static bool shouldScheduleAdjacent(const TargetInstrInfo &TII,
61
134
if (ST.hasLUIADDIFusion () && isLUIADDI (FirstMI, SecondMI))
62
135
return true ;
63
136
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
+
64
146
return false ;
65
147
}
66
148
0 commit comments