@@ -60,13 +60,12 @@ struct AArch64MIPeepholeOpt : public MachineFunctionPass {
60
60
MachineLoopInfo *MLI;
61
61
MachineRegisterInfo *MRI;
62
62
63
- using OpcodePair = std::pair<unsigned , unsigned >;
64
63
template <typename T>
65
64
using SplitAndOpcFunc =
66
- std::function<Optional<OpcodePair >(T, unsigned , T &, T &)>;
65
+ std::function<Optional<unsigned >(T, unsigned , T &, T &)>;
67
66
using BuildMIFunc =
68
- std::function<void (MachineInstr &, OpcodePair , unsigned , unsigned ,
69
- Register, Register, Register )>;
67
+ std::function<void (MachineInstr &, unsigned , unsigned , unsigned , Register ,
68
+ Register, Register)>;
70
69
71
70
// / For instructions where an immediate operand could be split into two
72
71
// / separate immediate instructions, use the splitTwoPartImm two handle the
@@ -94,10 +93,6 @@ struct AArch64MIPeepholeOpt : public MachineFunctionPass {
94
93
bool visitADDSUB (unsigned PosOpc, unsigned NegOpc, MachineInstr &MI,
95
94
SmallSetVector<MachineInstr *, 8 > &ToBeRemoved);
96
95
template <typename T>
97
- bool visitADDSSUBS (OpcodePair PosOpcs, OpcodePair NegOpcs, MachineInstr &MI,
98
- SmallSetVector<MachineInstr *, 8 > &ToBeRemoved);
99
-
100
- template <typename T>
101
96
bool visitAND (unsigned Opc, MachineInstr &MI,
102
97
SmallSetVector<MachineInstr *, 8 > &ToBeRemoved);
103
98
bool visitORR (MachineInstr &MI,
@@ -176,20 +171,20 @@ bool AArch64MIPeepholeOpt::visitAND(
176
171
177
172
return splitTwoPartImm<T>(
178
173
MI, ToBeRemoved,
179
- [Opc](T Imm, unsigned RegSize, T &Imm0, T &Imm1) -> Optional<OpcodePair > {
174
+ [Opc](T Imm, unsigned RegSize, T &Imm0, T &Imm1) -> Optional<unsigned > {
180
175
if (splitBitmaskImm (Imm, RegSize, Imm0, Imm1))
181
- return std::make_pair ( Opc, Opc) ;
176
+ return Opc;
182
177
return None;
183
178
},
184
- [&TII = TII](MachineInstr &MI, OpcodePair Opcode, unsigned Imm0,
179
+ [&TII = TII](MachineInstr &MI, unsigned Opcode, unsigned Imm0,
185
180
unsigned Imm1, Register SrcReg, Register NewTmpReg,
186
181
Register NewDstReg) {
187
182
DebugLoc DL = MI.getDebugLoc ();
188
183
MachineBasicBlock *MBB = MI.getParent ();
189
- BuildMI (*MBB, MI, DL, TII->get (Opcode. first ), NewTmpReg)
184
+ BuildMI (*MBB, MI, DL, TII->get (Opcode), NewTmpReg)
190
185
.addReg (SrcReg)
191
186
.addImm (Imm0);
192
- BuildMI (*MBB, MI, DL, TII->get (Opcode. second ), NewDstReg)
187
+ BuildMI (*MBB, MI, DL, TII->get (Opcode), NewDstReg)
193
188
.addReg (NewTmpReg)
194
189
.addImm (Imm1);
195
190
});
@@ -278,64 +273,23 @@ bool AArch64MIPeepholeOpt::visitADDSUB(
278
273
return splitTwoPartImm<T>(
279
274
MI, ToBeRemoved,
280
275
[PosOpc, NegOpc](T Imm, unsigned RegSize, T &Imm0,
281
- T &Imm1) -> Optional<OpcodePair > {
276
+ T &Imm1) -> Optional<unsigned > {
282
277
if (splitAddSubImm (Imm, RegSize, Imm0, Imm1))
283
- return std::make_pair ( PosOpc, PosOpc) ;
278
+ return PosOpc;
284
279
if (splitAddSubImm (-Imm, RegSize, Imm0, Imm1))
285
- return std::make_pair ( NegOpc, NegOpc) ;
280
+ return NegOpc;
286
281
return None;
287
282
},
288
- [&TII = TII](MachineInstr &MI, OpcodePair Opcode, unsigned Imm0,
289
- unsigned Imm1, Register SrcReg, Register NewTmpReg,
290
- Register NewDstReg) {
291
- DebugLoc DL = MI.getDebugLoc ();
292
- MachineBasicBlock *MBB = MI.getParent ();
293
- BuildMI (*MBB, MI, DL, TII->get (Opcode.first ), NewTmpReg)
294
- .addReg (SrcReg)
295
- .addImm (Imm0)
296
- .addImm (12 );
297
- BuildMI (*MBB, MI, DL, TII->get (Opcode.second ), NewDstReg)
298
- .addReg (NewTmpReg)
299
- .addImm (Imm1)
300
- .addImm (0 );
301
- });
302
- }
303
-
304
- template <typename T>
305
- bool AArch64MIPeepholeOpt::visitADDSSUBS (
306
- OpcodePair PosOpcs, OpcodePair NegOpcs, MachineInstr &MI,
307
- SmallSetVector<MachineInstr *, 8 > &ToBeRemoved) {
308
- // Try the same transformation as ADDSUB but with additional requirement
309
- // that the condition code usages are only for Equal and Not Equal
310
- return splitTwoPartImm<T>(
311
- MI, ToBeRemoved,
312
- [PosOpcs, NegOpcs, &MI, &TRI = TRI, &MRI = MRI](
313
- T Imm, unsigned RegSize, T &Imm0, T &Imm1) -> Optional<OpcodePair> {
314
- OpcodePair OP;
315
- if (splitAddSubImm (Imm, RegSize, Imm0, Imm1))
316
- OP = PosOpcs;
317
- else if (splitAddSubImm (-Imm, RegSize, Imm0, Imm1))
318
- OP = NegOpcs;
319
- else
320
- return None;
321
- // Check conditional uses last since it is expensive for scanning
322
- // proceeding instructions
323
- MachineInstr &SrcMI = *MRI->getUniqueVRegDef (MI.getOperand (1 ).getReg ());
324
- Optional<UsedNZCV> NZCVUsed = examineCFlagsUse (SrcMI, MI, *TRI);
325
- if (!NZCVUsed || NZCVUsed->C || NZCVUsed->V )
326
- return None;
327
- return OP;
328
- },
329
- [&TII = TII](MachineInstr &MI, OpcodePair Opcode, unsigned Imm0,
283
+ [&TII = TII](MachineInstr &MI, unsigned Opcode, unsigned Imm0,
330
284
unsigned Imm1, Register SrcReg, Register NewTmpReg,
331
285
Register NewDstReg) {
332
286
DebugLoc DL = MI.getDebugLoc ();
333
287
MachineBasicBlock *MBB = MI.getParent ();
334
- BuildMI (*MBB, MI, DL, TII->get (Opcode. first ), NewTmpReg)
288
+ BuildMI (*MBB, MI, DL, TII->get (Opcode), NewTmpReg)
335
289
.addReg (SrcReg)
336
290
.addImm (Imm0)
337
291
.addImm (12 );
338
- BuildMI (*MBB, MI, DL, TII->get (Opcode. second ), NewDstReg)
292
+ BuildMI (*MBB, MI, DL, TII->get (Opcode), NewDstReg)
339
293
.addReg (NewTmpReg)
340
294
.addImm (Imm1)
341
295
.addImm (0 );
@@ -403,49 +357,32 @@ bool AArch64MIPeepholeOpt::splitTwoPartImm(
403
357
// number since it was sign extended when we assign to the 64-bit Imm.
404
358
if (SubregToRegMI)
405
359
Imm &= 0xFFFFFFFF ;
406
- OpcodePair Opcode;
360
+ unsigned Opcode;
407
361
if (auto R = SplitAndOpc (Imm, RegSize, Imm0, Imm1))
408
362
Opcode = R.getValue ();
409
363
else
410
364
return false ;
411
365
412
- // Create new MIs using the first and second opcodes. Opcodes might differ for
413
- // flag setting operations that should only set flags on second instruction.
414
- // NewTmpReg = Opcode.first SrcReg Imm0
415
- // NewDstReg = Opcode.second NewTmpReg Imm1
416
-
417
- // Determine register classes for destinations and register operands
366
+ // Create new ADD/SUB MIs.
418
367
MachineFunction *MF = MI.getMF ();
419
- const TargetRegisterClass *FirstInstrDstRC =
420
- TII->getRegClass (TII->get (Opcode.first ), 0 , TRI, *MF);
421
- const TargetRegisterClass *FirstInstrOperandRC =
422
- TII->getRegClass (TII->get (Opcode.first ), 1 , TRI, *MF);
423
- const TargetRegisterClass *SecondInstrDstRC =
424
- (Opcode.first == Opcode.second )
425
- ? FirstInstrDstRC
426
- : TII->getRegClass (TII->get (Opcode.second ), 0 , TRI, *MF);
427
- const TargetRegisterClass *SecondInstrOperandRC =
428
- (Opcode.first == Opcode.second )
429
- ? FirstInstrOperandRC
430
- : TII->getRegClass (TII->get (Opcode.second ), 1 , TRI, *MF);
431
-
432
- // Get old registers destinations and new register destinations
368
+ const TargetRegisterClass *RC =
369
+ TII->getRegClass (TII->get (Opcode), 0 , TRI, *MF);
370
+ const TargetRegisterClass *ORC =
371
+ TII->getRegClass (TII->get (Opcode), 1 , TRI, *MF);
433
372
Register DstReg = MI.getOperand (0 ).getReg ();
434
373
Register SrcReg = MI.getOperand (1 ).getReg ();
435
- Register NewTmpReg = MRI->createVirtualRegister (FirstInstrDstRC );
436
- Register NewDstReg = MRI->createVirtualRegister (SecondInstrDstRC );
374
+ Register NewTmpReg = MRI->createVirtualRegister (RC );
375
+ Register NewDstReg = MRI->createVirtualRegister (RC );
437
376
438
- // Constrain registers based on their new uses
439
- MRI->constrainRegClass (SrcReg, FirstInstrOperandRC);
440
- MRI->constrainRegClass (NewTmpReg, SecondInstrOperandRC);
377
+ MRI->constrainRegClass (SrcReg, RC);
378
+ MRI->constrainRegClass (NewTmpReg, ORC);
441
379
MRI->constrainRegClass (NewDstReg, MRI->getRegClass (DstReg));
442
380
443
- // Call the delegating operation to build the instruction
444
381
BuildInstr (MI, Opcode, Imm0, Imm1, SrcReg, NewTmpReg, NewDstReg);
445
382
383
+ MRI->replaceRegWith (DstReg, NewDstReg);
446
384
// replaceRegWith changes MI's definition register. Keep it for SSA form until
447
385
// deleting MI.
448
- MRI->replaceRegWith (DstReg, NewDstReg);
449
386
MI.getOperand (0 ).setReg (DstReg);
450
387
451
388
// Record the MIs need to be removed.
@@ -502,26 +439,6 @@ bool AArch64MIPeepholeOpt::runOnMachineFunction(MachineFunction &MF) {
502
439
Changed = visitADDSUB<uint64_t >(AArch64::SUBXri, AArch64::ADDXri, MI,
503
440
ToBeRemoved);
504
441
break ;
505
- case AArch64::ADDSWrr:
506
- Changed = visitADDSSUBS<uint32_t >({AArch64::ADDWri, AArch64::ADDSWri},
507
- {AArch64::SUBWri, AArch64::SUBSWri},
508
- MI, ToBeRemoved);
509
- break ;
510
- case AArch64::SUBSWrr:
511
- Changed = visitADDSSUBS<uint32_t >({AArch64::SUBWri, AArch64::SUBSWri},
512
- {AArch64::ADDWri, AArch64::ADDSWri},
513
- MI, ToBeRemoved);
514
- break ;
515
- case AArch64::ADDSXrr:
516
- Changed = visitADDSSUBS<uint64_t >({AArch64::ADDXri, AArch64::ADDSXri},
517
- {AArch64::SUBXri, AArch64::SUBSXri},
518
- MI, ToBeRemoved);
519
- break ;
520
- case AArch64::SUBSXrr:
521
- Changed = visitADDSSUBS<uint64_t >({AArch64::SUBXri, AArch64::SUBSXri},
522
- {AArch64::ADDXri, AArch64::ADDSXri},
523
- MI, ToBeRemoved);
524
- break ;
525
442
}
526
443
}
527
444
}
0 commit comments