Skip to content

Commit ab62cbd

Browse files
committed
Try to use foldMemoryOperand from optimizeLoadInstr
1 parent 4df14d3 commit ab62cbd

File tree

5 files changed

+86
-79
lines changed

5 files changed

+86
-79
lines changed

llvm/include/llvm/CodeGen/TargetInstrInfo.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1710,7 +1710,7 @@ class TargetInstrInfo : public MCInstrInfo {
17101710
/// instruction that defines FoldAsLoadDefReg, and the function returns
17111711
/// the machine instruction generated due to folding.
17121712
virtual MachineInstr *optimizeLoadInstr(MachineInstr &MI,
1713-
MachineRegisterInfo *MRI,
1713+
const MachineRegisterInfo *MRI,
17141714
Register &FoldAsLoadDefReg,
17151715
MachineInstr *&DefMI) const {
17161716
return nullptr;

llvm/lib/Target/SystemZ/SystemZInstrInfo.cpp

Lines changed: 82 additions & 75 deletions
Original file line numberDiff line numberDiff line change
@@ -625,12 +625,9 @@ static void transferMIFlag(MachineInstr *OldMI, MachineInstr *NewMI,
625625
}
626626

627627
MachineInstr *SystemZInstrInfo::optimizeLoadInstr(MachineInstr &MI,
628-
MachineRegisterInfo *MRI,
628+
const MachineRegisterInfo *MRI,
629629
Register &FoldAsLoadDefReg,
630630
MachineInstr *&DefMI) const {
631-
const TargetRegisterInfo *TRI = MRI->getTargetRegisterInfo();
632-
MachineBasicBlock *MBB = MI.getParent();
633-
634631
// Check whether we can move the DefMI load, and that it only has one use.
635632
DefMI = MRI->getVRegDef(FoldAsLoadDefReg);
636633
assert(DefMI);
@@ -639,76 +636,9 @@ MachineInstr *SystemZInstrInfo::optimizeLoadInstr(MachineInstr &MI,
639636
!MRI->hasOneNonDBGUse(FoldAsLoadDefReg))
640637
return nullptr;
641638

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);
712642
}
713643

714644
bool SystemZInstrInfo::foldImmediate(MachineInstr &UseMI, MachineInstr &DefMI,
@@ -1486,7 +1416,84 @@ MachineInstr *SystemZInstrInfo::foldMemoryOperandImpl(
14861416
MachineFunction &MF, MachineInstr &MI, ArrayRef<unsigned> Ops,
14871417
MachineBasicBlock::iterator InsertPt, MachineInstr &LoadMI,
14881418
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;
14901497
}
14911498

14921499
bool SystemZInstrInfo::expandPostRAPseudo(MachineInstr &MI) const {

llvm/lib/Target/SystemZ/SystemZInstrInfo.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -255,7 +255,7 @@ class SystemZInstrInfo : public SystemZGenInstrInfo {
255255
ArrayRef<MachineOperand> Cond, Register TrueReg,
256256
Register FalseReg) const override;
257257
MachineInstr *optimizeLoadInstr(MachineInstr &MI,
258-
MachineRegisterInfo *MRI,
258+
const MachineRegisterInfo *MRI,
259259
Register &FoldAsLoadDefReg,
260260
MachineInstr *&DefMI) const override;
261261
bool foldImmediate(MachineInstr &UseMI, MachineInstr &DefMI, Register Reg,

llvm/lib/Target/X86/X86InstrInfo.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5499,7 +5499,7 @@ bool X86InstrInfo::optimizeCompareInstr(MachineInstr &CmpInstr, Register SrcReg,
54995499
/// register, the virtual register is used once in the same BB, and the
55005500
/// instructions in-between do not load or store, and have no side effects.
55015501
MachineInstr *X86InstrInfo::optimizeLoadInstr(MachineInstr &MI,
5502-
MachineRegisterInfo *MRI,
5502+
const MachineRegisterInfo *MRI,
55035503
Register &FoldAsLoadDefReg,
55045504
MachineInstr *&DefMI) const {
55055505
// Check whether we can move DefMI here.

llvm/lib/Target/X86/X86InstrInfo.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -559,7 +559,7 @@ class X86InstrInfo final : public X86GenInstrInfo {
559559
const MachineRegisterInfo *MRI) const override;
560560

561561
MachineInstr *optimizeLoadInstr(MachineInstr &MI,
562-
MachineRegisterInfo *MRI,
562+
const MachineRegisterInfo *MRI,
563563
Register &FoldAsLoadDefReg,
564564
MachineInstr *&DefMI) const override;
565565

0 commit comments

Comments
 (0)