@@ -625,12 +625,9 @@ static void transferMIFlag(MachineInstr *OldMI, MachineInstr *NewMI,
625
625
}
626
626
627
627
MachineInstr *SystemZInstrInfo::optimizeLoadInstr (MachineInstr &MI,
628
- MachineRegisterInfo *MRI,
628
+ const MachineRegisterInfo *MRI,
629
629
Register &FoldAsLoadDefReg,
630
630
MachineInstr *&DefMI) const {
631
- const TargetRegisterInfo *TRI = MRI->getTargetRegisterInfo ();
632
- MachineBasicBlock *MBB = MI.getParent ();
633
-
634
631
// Check whether we can move the DefMI load, and that it only has one use.
635
632
DefMI = MRI->getVRegDef (FoldAsLoadDefReg);
636
633
assert (DefMI);
@@ -639,76 +636,9 @@ MachineInstr *SystemZInstrInfo::optimizeLoadInstr(MachineInstr &MI,
639
636
!MRI->hasOneNonDBGUse (FoldAsLoadDefReg))
640
637
return nullptr ;
641
638
642
- // For reassociable FP operations, any loads have been purposefully left
643
- // unfolded so that MachineCombiner can do its work on reg/reg
644
- // opcodes. After that, as many loads as possible are now folded.
645
- // TODO: This may be beneficial with other opcodes as well as machine-sink
646
- // can move loads close to their user in a different MBB.
647
- unsigned LoadOpc = 0 ;
648
- unsigned RegMemOpcode = 0 ;
649
- const TargetRegisterClass *FPRC = nullptr ;
650
- RegMemOpcode = MI.getOpcode () == SystemZ::WFADB ? SystemZ::ADB
651
- : MI.getOpcode () == SystemZ::WFSDB ? SystemZ::SDB
652
- : MI.getOpcode () == SystemZ::WFMDB ? SystemZ::MDB
653
- : 0 ;
654
- if (RegMemOpcode) {
655
- LoadOpc = SystemZ::VL64;
656
- FPRC = &SystemZ::FP64BitRegClass;
657
- } else {
658
- RegMemOpcode = MI.getOpcode () == SystemZ::WFASB ? SystemZ::AEB
659
- : MI.getOpcode () == SystemZ::WFSSB ? SystemZ::SEB
660
- : MI.getOpcode () == SystemZ::WFMSB ? SystemZ::MEEB
661
- : 0 ;
662
- if (RegMemOpcode) {
663
- LoadOpc = SystemZ::VL32;
664
- FPRC = &SystemZ::FP32BitRegClass;
665
- }
666
- }
667
- if (!RegMemOpcode || DefMI->getOpcode () != LoadOpc)
668
- return nullptr ;
669
-
670
- // If RegMemOpcode clobbers CC, first make sure CC is not live at this point.
671
- if (get (RegMemOpcode).hasImplicitDefOfPhysReg (SystemZ::CC)) {
672
- assert (DefMI->getParent () == MI.getParent () && " Assuming a local fold." );
673
- for (MachineBasicBlock::iterator MII = std::prev (MI.getIterator ());;
674
- --MII) {
675
- if (MII->definesRegister (SystemZ::CC)) {
676
- if (!MII->registerDefIsDead (SystemZ::CC))
677
- return nullptr ;
678
- break ;
679
- }
680
- if (MII == MBB->begin ()) {
681
- if (MBB->isLiveIn (SystemZ::CC))
682
- return nullptr ;
683
- break ;
684
- }
685
- }
686
- }
687
-
688
- Register DstReg = MI.getOperand (0 ).getReg ();
689
- MachineOperand LHS = MI.getOperand (1 );
690
- MachineOperand RHS = MI.getOperand (2 );
691
- MachineOperand &RegMO = RHS.getReg () == FoldAsLoadDefReg ? LHS : RHS;
692
- if ((RegMemOpcode == SystemZ::SDB || RegMemOpcode == SystemZ::SEB) &&
693
- FoldAsLoadDefReg != RHS.getReg ())
694
- return nullptr ;
695
-
696
- MachineOperand &Base = DefMI->getOperand (1 );
697
- MachineOperand &Disp = DefMI->getOperand (2 );
698
- MachineOperand &Indx = DefMI->getOperand (3 );
699
- MachineInstrBuilder MIB =
700
- BuildMI (*MI.getParent (), MI, MI.getDebugLoc (), get (RegMemOpcode), DstReg)
701
- .add (RegMO)
702
- .add (Base)
703
- .add (Disp)
704
- .add (Indx)
705
- .addMemOperand (*DefMI->memoperands_begin ());
706
- MIB->addRegisterDead (SystemZ::CC, TRI);
707
- MRI->setRegClass (DstReg, FPRC);
708
- MRI->setRegClass (RegMO.getReg (), FPRC);
709
- transferMIFlag (&MI, MIB, MachineInstr::NoFPExcept);
710
-
711
- return MIB;
639
+ int UseOpIdx = MI.findRegisterUseOperandIdx (FoldAsLoadDefReg);
640
+ assert (UseOpIdx != -1 && " Expected FoldAsLoadDefReg to be used by MI." );
641
+ return foldMemoryOperand (MI, {((unsigned ) UseOpIdx)}, *DefMI);
712
642
}
713
643
714
644
bool SystemZInstrInfo::foldImmediate (MachineInstr &UseMI, MachineInstr &DefMI,
@@ -1486,7 +1416,84 @@ MachineInstr *SystemZInstrInfo::foldMemoryOperandImpl(
1486
1416
MachineFunction &MF, MachineInstr &MI, ArrayRef<unsigned > Ops,
1487
1417
MachineBasicBlock::iterator InsertPt, MachineInstr &LoadMI,
1488
1418
LiveIntervals *LIS) const {
1489
- return nullptr ;
1419
+ MachineRegisterInfo *MRI = &MF.getRegInfo ();
1420
+ MachineBasicBlock *MBB = MI.getParent ();
1421
+
1422
+ // For reassociable FP operations, any loads have been purposefully left
1423
+ // unfolded so that MachineCombiner can do its work on reg/reg
1424
+ // opcodes. After that, as many loads as possible are now folded.
1425
+ // TODO: This may be beneficial with other opcodes as well as machine-sink
1426
+ // can move loads close to their user in a different MBB, which the isel
1427
+ // matcher did not see.
1428
+ unsigned LoadOpc = 0 ;
1429
+ unsigned RegMemOpcode = 0 ;
1430
+ const TargetRegisterClass *FPRC = nullptr ;
1431
+ RegMemOpcode = MI.getOpcode () == SystemZ::WFADB ? SystemZ::ADB
1432
+ : MI.getOpcode () == SystemZ::WFSDB ? SystemZ::SDB
1433
+ : MI.getOpcode () == SystemZ::WFMDB ? SystemZ::MDB
1434
+ : 0 ;
1435
+ if (RegMemOpcode) {
1436
+ LoadOpc = SystemZ::VL64;
1437
+ FPRC = &SystemZ::FP64BitRegClass;
1438
+ } else {
1439
+ RegMemOpcode = MI.getOpcode () == SystemZ::WFASB ? SystemZ::AEB
1440
+ : MI.getOpcode () == SystemZ::WFSSB ? SystemZ::SEB
1441
+ : MI.getOpcode () == SystemZ::WFMSB ? SystemZ::MEEB
1442
+ : 0 ;
1443
+ if (RegMemOpcode) {
1444
+ LoadOpc = SystemZ::VL32;
1445
+ FPRC = &SystemZ::FP32BitRegClass;
1446
+ }
1447
+ }
1448
+ if (!RegMemOpcode || LoadMI.getOpcode () != LoadOpc)
1449
+ return nullptr ;
1450
+
1451
+ // If RegMemOpcode clobbers CC, first make sure CC is not live at this point.
1452
+ if (get (RegMemOpcode).hasImplicitDefOfPhysReg (SystemZ::CC)) {
1453
+ assert (LoadMI.getParent () == MI.getParent () && " Assuming a local fold." );
1454
+ assert (LoadMI != InsertPt && " Assuming InsertPt not to be first in MBB." );
1455
+ for (MachineBasicBlock::iterator MII = std::prev (InsertPt);;
1456
+ --MII) {
1457
+ if (MII->definesRegister (SystemZ::CC)) {
1458
+ if (!MII->registerDefIsDead (SystemZ::CC))
1459
+ return nullptr ;
1460
+ break ;
1461
+ }
1462
+ if (MII == MBB->begin ()) {
1463
+ if (MBB->isLiveIn (SystemZ::CC))
1464
+ return nullptr ;
1465
+ break ;
1466
+ }
1467
+ }
1468
+ }
1469
+
1470
+ Register FoldAsLoadDefReg = LoadMI.getOperand (0 ).getReg ();
1471
+ // We don't really need Ops, but do a sanity check:
1472
+ assert (Ops.size () == 1 && FoldAsLoadDefReg == MI.getOperand (Ops[0 ]).getReg () &&
1473
+ " Expected MI to be the only user of the load." );
1474
+ Register DstReg = MI.getOperand (0 ).getReg ();
1475
+ MachineOperand LHS = MI.getOperand (1 );
1476
+ MachineOperand RHS = MI.getOperand (2 );
1477
+ MachineOperand &RegMO = RHS.getReg () == FoldAsLoadDefReg ? LHS : RHS;
1478
+ if ((RegMemOpcode == SystemZ::SDB || RegMemOpcode == SystemZ::SEB) &&
1479
+ FoldAsLoadDefReg != RHS.getReg ())
1480
+ return nullptr ;
1481
+
1482
+ MachineOperand &Base = LoadMI.getOperand (1 );
1483
+ MachineOperand &Disp = LoadMI.getOperand (2 );
1484
+ MachineOperand &Indx = LoadMI.getOperand (3 );
1485
+ MachineInstrBuilder MIB =
1486
+ BuildMI (*MI.getParent (), InsertPt, MI.getDebugLoc (), get (RegMemOpcode), DstReg)
1487
+ .add (RegMO)
1488
+ .add (Base)
1489
+ .add (Disp)
1490
+ .add (Indx);
1491
+ MIB->addRegisterDead (SystemZ::CC, &RI);
1492
+ MRI->setRegClass (DstReg, FPRC);
1493
+ MRI->setRegClass (RegMO.getReg (), FPRC);
1494
+ transferMIFlag (&MI, MIB, MachineInstr::NoFPExcept);
1495
+
1496
+ return MIB;
1490
1497
}
1491
1498
1492
1499
bool SystemZInstrInfo::expandPostRAPseudo (MachineInstr &MI) const {
0 commit comments