LLVM: lib/Target/Lanai/LanaiMemAluCombiner.cpp Source File (original) (raw)
41STATISTIC(NumLdStAluCombined, "Number of memory and ALU instructions combined");
85 "Lanai memory ALU combiner pass", false, false)
86
87namespace {
88bool isSpls(uint16_t Opcode) { return Lanai::splsIdempotent(Opcode) == Opcode; }
89
90
91
92
93unsigned mergedOpcode(unsigned OldOpcode, bool ImmediateOffset) {
94 switch (OldOpcode) {
95 case Lanai::LDW_RI:
96 case Lanai::LDW_RR:
97 if (ImmediateOffset)
98 return Lanai::LDW_RI;
99 return Lanai::LDW_RR;
100 case Lanai::LDHs_RI:
101 case Lanai::LDHs_RR:
102 if (ImmediateOffset)
103 return Lanai::LDHs_RI;
104 return Lanai::LDHs_RR;
105 case Lanai::LDHz_RI:
106 case Lanai::LDHz_RR:
107 if (ImmediateOffset)
108 return Lanai::LDHz_RI;
109 return Lanai::LDHz_RR;
110 case Lanai::LDBs_RI:
111 case Lanai::LDBs_RR:
112 if (ImmediateOffset)
113 return Lanai::LDBs_RI;
114 return Lanai::LDBs_RR;
115 case Lanai::LDBz_RI:
116 case Lanai::LDBz_RR:
117 if (ImmediateOffset)
118 return Lanai::LDBz_RI;
119 return Lanai::LDBz_RR;
120 case Lanai::SW_RI:
121 case Lanai::SW_RR:
122 if (ImmediateOffset)
123 return Lanai::SW_RI;
124 return Lanai::SW_RR;
125 case Lanai::STB_RI:
126 case Lanai::STB_RR:
127 if (ImmediateOffset)
128 return Lanai::STB_RI;
129 return Lanai::STB_RR;
130 case Lanai::STH_RI:
131 case Lanai::STH_RR:
132 if (ImmediateOffset)
133 return Lanai::STH_RI;
134 return Lanai::STH_RR;
135 default:
136 return 0;
137 }
138}
139
140
141
143 if (.hasOneMemOperand())
144 return false;
145
146
147
148 if (mergedOpcode(MI.getOpcode(), false) == 0)
149 return false;
150
152
153
154
156 return false;
157
158 return true;
159}
160
161
162
165 return false;
166
172 default:
173 return false;
174 }
175}
176
178 return ((Op.isReg() && Op.getReg() == Lanai::R0) ||
179 (Op.isImm() && Op.getImm() == 0));
180}
181
182
183bool InstrUsesReg(const MbbIterator &Instr, const MachineOperand *Reg) {
185 Mop != Instr->operands_end(); ++Mop) {
186 if (isSameOperand(*Mop, *Reg))
187 return true;
188 }
189 return false;
190}
191
192
193
194
196 switch (AluOpcode) {
197 case Lanai::ADD_I_LO:
198 case Lanai::ADD_R:
200 case Lanai::SUB_I_LO:
201 case Lanai::SUB_R:
203 case Lanai::AND_I_LO:
204 case Lanai::AND_R:
206 case Lanai::OR_I_LO:
207 case Lanai::OR_R:
209 case Lanai::XOR_I_LO:
210 case Lanai::XOR_R:
212 case Lanai::SHL_R:
214 case Lanai::SRL_R:
216 case Lanai::SRA_R:
218 case Lanai::SA_I:
219 case Lanai::SL_I:
220 default:
222 }
223}
224
225
226
227
228
229void LanaiMemAluCombiner::insertMergedInstruction(MachineBasicBlock *BB,
230 const MbbIterator &MemInstr,
231 const MbbIterator &AluInstr,
232 bool Before) {
233
238
239
241 "Unsupported operand type in merge");
242
243
244 LPAC::AluCode AluOpcode = mergedAluCode(AluInstr->getOpcode());
245 unsigned NewOpc = mergedOpcode(MemInstr->getOpcode(), AluOffset.isImm());
246
248 assert(NewOpc != 0 && "Unknown merged node opcode");
249
250
252 BuildMI(*BB, MemInstr, MemInstr->getDebugLoc(), TII->get(NewOpc));
255
256
257 if (AluOffset.isReg())
259 else if (AluOffset.isImm())
261 else
263
264
265
266
267 if (Before || !isZeroOperand(MemOffset))
269 else
271
272
273 InstrBuilder.setMemRefs(MemInstr->memoperands());
274}
275
276
277
278bool isSuitableAluInstr(bool IsSpls, const MbbIterator &AluIter,
281
282 if (AluIter->getNumOperands() != 3)
283 return false;
284
288
289
290
291 if (!isSameOperand(Dest, Base) || !isSameOperand(Dest, Op1))
292 return false;
293
294 if (Op2.isImm()) {
295
296
297 if (AluIter->getOpcode() != Lanai::ADD_I_LO)
298 return false;
299
300 if (Offset.isReg() && Offset.getReg() == Lanai::R0)
301 return true;
302
303 if (Offset.isImm() &&
304 ((Offset.getImm() == 0 &&
305
306
310 return true;
311 } else if (Op2.isReg()) {
312
314 return true;
315 } else
316
317 return false;
318
319 return false;
320}
321
322MbbIterator LanaiMemAluCombiner::findClosestSuitableAluInstr(
323 MachineBasicBlock *BB, const MbbIterator &MemInstr, const bool Decrement) {
326 bool IsSpls = isSpls(MemInstr->getOpcode());
327
328 MbbIterator First = MemInstr;
329 MbbIterator Last = Decrement ? BB->begin() : BB->end();
330
333
335 break;
336
337
338 if (First->isDebugInstr())
339 continue;
340
343 }
344
345
348 break;
350 break;
351 }
352 }
353
354 return MemInstr;
355}
356
357bool LanaiMemAluCombiner::combineMemAluInBasicBlock(MachineBasicBlock *BB) {
359
360 MbbIterator MBBIter = BB->begin(), End = BB->end();
361 while (MBBIter != End) {
362 bool IsMemOp = isNonVolatileMemoryOp(*MBBIter);
363
364 if (IsMemOp) {
366 unsigned int DestReg = MBBIter->getOperand(0).getReg(),
367 BaseReg = MBBIter->getOperand(1).getReg();
368 assert(AluOperand.isImm() && "Unexpected memory operator type");
370
371
372
374 for (int Inc = 0; Inc <= 1; ++Inc) {
375 MbbIterator AluIter =
376 findClosestSuitableAluInstr(BB, MBBIter, Inc == 0);
377 if (AluIter != MBBIter) {
378 insertMergedInstruction(BB, MBBIter, AluIter, Inc == 0);
379
380 ++NumLdStAluCombined;
382
383
384 BB->erase(AluIter);
385
386 BB->erase(MBBIter++);
387 break;
388 }
389 }
390 }
391 }
392 if (MBBIter == End)
393 break;
394 ++MBBIter;
395 }
396
398}
399
400
401
402bool LanaiMemAluCombiner::runOnMachineFunction(MachineFunction &MF) {
404 return false;
405
409 Modified |= combineMemAluInBasicBlock(&MBB);
411}
412}
415 return new LanaiMemAluCombiner();
416}