llvm.org GIT mirror llvm / b496702
AArch64MacroFusion: Factor out some opcode handling code; NFC git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@342521 91177308-0d34-0410-b5e6-96231b3b80d8 Matthias Braun 1 year, 9 months ago
1 changed file(s) with 126 addition(s) and 137 deletion(s). Raw diff Collapse all Expand all
1919
2020 namespace {
2121
22 // Fuse CMN, CMP, TST followed by Bcc.
23 static bool isArithmeticBccPair(const MachineInstr *FirstMI,
24 const MachineInstr &SecondMI) {
25 if (SecondMI.getOpcode() == AArch64::Bcc) {
26 // Assume the 1st instr to be a wildcard if it is unspecified.
27 if (!FirstMI)
28 return true;
29
30 switch (FirstMI->getOpcode()) {
31 case AArch64::ADDSWri:
32 case AArch64::ADDSWrr:
33 case AArch64::ADDSXri:
34 case AArch64::ADDSXrr:
35 case AArch64::ANDSWri:
36 case AArch64::ANDSWrr:
37 case AArch64::ANDSXri:
38 case AArch64::ANDSXrr:
39 case AArch64::SUBSWri:
40 case AArch64::SUBSWrr:
41 case AArch64::SUBSXri:
42 case AArch64::SUBSXrr:
43 case AArch64::BICSWrr:
44 case AArch64::BICSXrr:
45 return true;
46 case AArch64::ADDSWrs:
47 case AArch64::ADDSXrs:
48 case AArch64::ANDSWrs:
49 case AArch64::ANDSXrs:
50 case AArch64::SUBSWrs:
51 case AArch64::SUBSXrs:
52 case AArch64::BICSWrs:
53 case AArch64::BICSXrs:
54 // Shift value can be 0 making these behave like the "rr" variant...
55 return (!AArch64InstrInfo::hasShiftedReg(*FirstMI));
56 }
57 }
58 return false;
59 }
60
61 // Fuse ALU operations followed by CBZ/CBNZ.
62 static bool isArithmeticCbzPair(const MachineInstr *FirstMI,
63 const MachineInstr &SecondMI) {
64 unsigned SecondOpcode = SecondMI.getOpcode();
65
66 if (SecondOpcode == AArch64::CBNZW || SecondOpcode == AArch64::CBNZX ||
67 SecondOpcode == AArch64::CBZW || SecondOpcode == AArch64::CBZX) {
68 // Assume the 1st instr to be a wildcard if it is unspecified.
69 if (!FirstMI)
70 return true;
71
72 switch (FirstMI->getOpcode()) {
73 case AArch64::ADDWri:
74 case AArch64::ADDWrr:
75 case AArch64::ADDXri:
76 case AArch64::ADDXrr:
77 case AArch64::ANDWri:
78 case AArch64::ANDWrr:
79 case AArch64::ANDXri:
80 case AArch64::ANDXrr:
81 case AArch64::EORWri:
82 case AArch64::EORWrr:
83 case AArch64::EORXri:
84 case AArch64::EORXrr:
85 case AArch64::ORRWri:
86 case AArch64::ORRWrr:
87 case AArch64::ORRXri:
88 case AArch64::ORRXrr:
89 case AArch64::SUBWri:
90 case AArch64::SUBWrr:
91 case AArch64::SUBXri:
92 case AArch64::SUBXrr:
93 return true;
94 case AArch64::ADDWrs:
95 case AArch64::ADDXrs:
96 case AArch64::ANDWrs:
97 case AArch64::ANDXrs:
98 case AArch64::SUBWrs:
99 case AArch64::SUBXrs:
100 case AArch64::BICWrs:
101 case AArch64::BICXrs:
102 // Shift value can be 0 making these behave like the "rr" variant...
103 return (!AArch64InstrInfo::hasShiftedReg(*FirstMI));
104 }
105 }
106 return false;
107 }
108
109 // Fuse AES crypto encoding or decoding.
110 static bool isAESPair(const MachineInstr *FirstMI,
111 const MachineInstr &SecondMI) {
112 // Assume the 1st instr to be a wildcard if it is unspecified.
113 unsigned FirstOpcode =
114 FirstMI ? FirstMI->getOpcode()
115 : static_cast(AArch64::INSTRUCTION_LIST_END);
116 unsigned SecondOpcode = SecondMI.getOpcode();
117
22 /// CMN, CMP, TST followed by Bcc
23 static bool isArithmeticBccPair(unsigned FirstOpcode, unsigned SecondOpcode,
24 const MachineInstr *FirstMI) {
25 if (SecondOpcode != AArch64::Bcc)
26 return false;
27
28 switch (FirstOpcode) {
29 case AArch64::INSTRUCTION_LIST_END:
30 return true;
31 case AArch64::ADDSWri:
32 case AArch64::ADDSWrr:
33 case AArch64::ADDSXri:
34 case AArch64::ADDSXrr:
35 case AArch64::ANDSWri:
36 case AArch64::ANDSWrr:
37 case AArch64::ANDSXri:
38 case AArch64::ANDSXrr:
39 case AArch64::SUBSWri:
40 case AArch64::SUBSWrr:
41 case AArch64::SUBSXri:
42 case AArch64::SUBSXrr:
43 case AArch64::BICSWrr:
44 case AArch64::BICSXrr:
45 return true;
46 case AArch64::ADDSWrs:
47 case AArch64::ADDSXrs:
48 case AArch64::ANDSWrs:
49 case AArch64::ANDSXrs:
50 case AArch64::SUBSWrs:
51 case AArch64::SUBSXrs:
52 case AArch64::BICSWrs:
53 case AArch64::BICSXrs:
54 // Shift value can be 0 making these behave like the "rr" variant...
55 return !AArch64InstrInfo::hasShiftedReg(*FirstMI);
56 }
57 return false;
58 }
59
60 /// ALU operations followed by CBZ/CBNZ.
61 static bool isArithmeticCbzPair(unsigned FirstOpcode, unsigned SecondOpcode,
62 const MachineInstr *FirstMI) {
63 if (SecondOpcode != AArch64::CBNZW &&
64 SecondOpcode != AArch64::CBNZX &&
65 SecondOpcode != AArch64::CBZW &&
66 SecondOpcode != AArch64::CBZX)
67 return false;
68
69 switch (FirstOpcode) {
70 case AArch64::INSTRUCTION_LIST_END:
71 return true;
72 case AArch64::ADDWri:
73 case AArch64::ADDWrr:
74 case AArch64::ADDXri:
75 case AArch64::ADDXrr:
76 case AArch64::ANDWri:
77 case AArch64::ANDWrr:
78 case AArch64::ANDXri:
79 case AArch64::ANDXrr:
80 case AArch64::EORWri:
81 case AArch64::EORWrr:
82 case AArch64::EORXri:
83 case AArch64::EORXrr:
84 case AArch64::ORRWri:
85 case AArch64::ORRWrr:
86 case AArch64::ORRXri:
87 case AArch64::ORRXrr:
88 case AArch64::SUBWri:
89 case AArch64::SUBWrr:
90 case AArch64::SUBXri:
91 case AArch64::SUBXrr:
92 return true;
93 case AArch64::ADDWrs:
94 case AArch64::ADDXrs:
95 case AArch64::ANDWrs:
96 case AArch64::ANDXrs:
97 case AArch64::SUBWrs:
98 case AArch64::SUBXrs:
99 case AArch64::BICWrs:
100 case AArch64::BICXrs:
101 // Shift value can be 0 making these behave like the "rr" variant...
102 return !AArch64InstrInfo::hasShiftedReg(*FirstMI);
103 }
104 return false;
105 }
106
107 /// AES crypto encoding or decoding.
108 static bool isAESPair(unsigned FirstOpcode, unsigned SecondOpcode) {
118109 // AES encode.
119110 if ((FirstOpcode == AArch64::INSTRUCTION_LIST_END ||
120111 FirstOpcode == AArch64::AESErr) &&
131122 return false;
132123 }
133124
134 // Fuse literal generation.
135 static bool isLiteralsPair(const MachineInstr *FirstMI,
125 /// Literal generation.
126 static bool isLiteralsPair(unsigned FirstOpcode, unsigned SecondOpcode,
127 const MachineInstr *FirstMI,
136128 const MachineInstr &SecondMI) {
137 // Assume the 1st instr to be a wildcard if it is unspecified.
138 unsigned FirstOpcode =
139 FirstMI ? FirstMI->getOpcode()
140 : static_cast(AArch64::INSTRUCTION_LIST_END);
141 unsigned SecondOpcode = SecondMI.getOpcode();
142
143129 // PC relative address.
144130 if ((FirstOpcode == AArch64::INSTRUCTION_LIST_END ||
145131 FirstOpcode == AArch64::ADRP) &&
169155 }
170156
171157 // Fuse address generation and loads or stores.
172 static bool isAddressLdStPair(const MachineInstr *FirstMI,
158 static bool isAddressLdStPair(unsigned FirstOpcode, unsigned SecondOpcode,
173159 const MachineInstr &SecondMI) {
174 unsigned SecondOpcode = SecondMI.getOpcode();
175
176160 switch (SecondOpcode) {
177161 case AArch64::STRBBui:
178162 case AArch64::STRBui:
197181 case AArch64::LDRSHWui:
198182 case AArch64::LDRSHXui:
199183 case AArch64::LDRSWui:
200 // Assume the 1st instr to be a wildcard if it is unspecified.
201 if (!FirstMI)
202 return true;
203
204 switch (FirstMI->getOpcode()) {
184 switch (FirstOpcode) {
185 case AArch64::INSTRUCTION_LIST_END:
186 return true;
205187 case AArch64::ADR:
206 return (SecondMI.getOperand(2).getImm() == 0);
188 return SecondMI.getOperand(2).getImm() == 0;
207189 case AArch64::ADRP:
208190 return true;
209191 }
211193 return false;
212194 }
213195
214 // Fuse compare and conditional select.
215 static bool isCCSelectPair(const MachineInstr *FirstMI,
216 const MachineInstr &SecondMI) {
217 unsigned SecondOpcode = SecondMI.getOpcode();
218
196 // Compare and conditional select.
197 static bool isCCSelectPair(unsigned FirstOpcode, unsigned SecondOpcode,
198 const MachineInstr *FirstMI) {
219199 // 32 bits
220200 if (SecondOpcode == AArch64::CSELWr) {
221201 // Assume the 1st instr to be a wildcard if it is unspecified.
222 if (!FirstMI)
202 if (FirstOpcode == AArch64::INSTRUCTION_LIST_END)
223203 return true;
224204
225205 if (FirstMI->definesRegister(AArch64::WZR))
226 switch (FirstMI->getOpcode()) {
206 switch (FirstOpcode) {
227207 case AArch64::SUBSWrs:
228 return (!AArch64InstrInfo::hasShiftedReg(*FirstMI));
208 return !AArch64InstrInfo::hasShiftedReg(*FirstMI);
229209 case AArch64::SUBSWrx:
230 return (!AArch64InstrInfo::hasExtendedReg(*FirstMI));
210 return !AArch64InstrInfo::hasExtendedReg(*FirstMI);
231211 case AArch64::SUBSWrr:
232212 case AArch64::SUBSWri:
233213 return true;
236216 // 64 bits
237217 else if (SecondOpcode == AArch64::CSELXr) {
238218 // Assume the 1st instr to be a wildcard if it is unspecified.
239 if (!FirstMI)
219 if (FirstOpcode == AArch64::INSTRUCTION_LIST_END)
240220 return true;
241221
242222 if (FirstMI->definesRegister(AArch64::XZR))
243 switch (FirstMI->getOpcode()) {
223 switch (FirstOpcode) {
244224 case AArch64::SUBSXrs:
245 return (!AArch64InstrInfo::hasShiftedReg(*FirstMI));
225 return !AArch64InstrInfo::hasShiftedReg(*FirstMI);
246226 case AArch64::SUBSXrx:
247227 case AArch64::SUBSXrx64:
248 return (!AArch64InstrInfo::hasExtendedReg(*FirstMI));
228 return !AArch64InstrInfo::hasExtendedReg(*FirstMI);
249229 case AArch64::SUBSXrr:
250230 case AArch64::SUBSXri:
251231 return true;
263243 const MachineInstr &SecondMI) {
264244 const AArch64Subtarget &ST = static_cast(TSI);
265245
266 if (ST.hasArithmeticBccFusion() && isArithmeticBccPair(FirstMI, SecondMI))
267 return true;
268 if (ST.hasArithmeticCbzFusion() && isArithmeticCbzPair(FirstMI, SecondMI))
269 return true;
270 if (ST.hasFuseAES() && isAESPair(FirstMI, SecondMI))
271 return true;
272 if (ST.hasFuseLiterals() && isLiteralsPair(FirstMI, SecondMI))
273 return true;
274 if (ST.hasFuseAddress() && isAddressLdStPair(FirstMI, SecondMI))
275 return true;
276 if (ST.hasFuseCCSelect() && isCCSelectPair(FirstMI, SecondMI))
246 // Assume the 1st instr to be a wildcard if it is unspecified.
247 unsigned FirstOpc =
248 FirstMI ? FirstMI->getOpcode()
249 : static_cast(AArch64::INSTRUCTION_LIST_END);
250 unsigned SecondOpc = SecondMI.getOpcode();
251
252 if (ST.hasArithmeticBccFusion() &&
253 isArithmeticBccPair(FirstOpc, SecondOpc, FirstMI))
254 return true;
255 if (ST.hasArithmeticCbzFusion() &&
256 isArithmeticCbzPair(FirstOpc, SecondOpc, FirstMI))
257 return true;
258 if (ST.hasFuseAES() && isAESPair(FirstOpc, SecondOpc))
259 return true;
260 if (ST.hasFuseLiterals() &&
261 isLiteralsPair(FirstOpc, SecondOpc, FirstMI, SecondMI))
262 return true;
263 if (ST.hasFuseAddress() && isAddressLdStPair(FirstOpc, SecondOpc, SecondMI))
264 return true;
265 if (ST.hasFuseCCSelect() && isCCSelectPair(FirstOpc, SecondOpc, FirstMI))
277266 return true;
278267
279268 return false;