[llvm] 62e892f - [ARM] Add MQQPR and MQQQQPR spill and reload pseudo instructions
David Green via llvm-commits
llvm-commits at lists.llvm.org
Tue Aug 17 05:51:50 PDT 2021
Author: David Green
Date: 2021-08-17T13:51:34+01:00
New Revision: 62e892fa2d4f372fddc5e4ef5134830f8fa20062
URL: https://github.com/llvm/llvm-project/commit/62e892fa2d4f372fddc5e4ef5134830f8fa20062
DIFF: https://github.com/llvm/llvm-project/commit/62e892fa2d4f372fddc5e4ef5134830f8fa20062.diff
LOG: [ARM] Add MQQPR and MQQQQPR spill and reload pseudo instructions
As a part of D107642, this adds pseudo instructions for MQQPR and
MQQQQPR register classes, that can spill and reloads entire registers
whilst keeping them combined, not splitting them into multiple D subregs
that a VLDMIA/VSTMIA would use. This can help certain analyses, and
helps to prevent verifier issues with subreg liveness.
Added:
Modified:
llvm/lib/Target/ARM/ARMBaseInstrInfo.cpp
llvm/lib/Target/ARM/ARMExpandPseudoInsts.cpp
llvm/lib/Target/ARM/ARMInstrMVE.td
Removed:
################################################################################
diff --git a/llvm/lib/Target/ARM/ARMBaseInstrInfo.cpp b/llvm/lib/Target/ARM/ARMBaseInstrInfo.cpp
index 643bc6d2d4e0..971eef1e9353 100644
--- a/llvm/lib/Target/ARM/ARMBaseInstrInfo.cpp
+++ b/llvm/lib/Target/ARM/ARMBaseInstrInfo.cpp
@@ -1254,6 +1254,11 @@ storeRegToStackSlot(MachineBasicBlock &MBB, MachineBasicBlock::iterator I,
.addReg(SrcReg, getKillRegState(isKill))
.addMemOperand(MMO)
.add(predOps(ARMCC::AL));
+ } else if (Subtarget.hasMVEIntegerOps()) {
+ BuildMI(MBB, I, DebugLoc(), get(ARM::MQQPRStore))
+ .addReg(SrcReg, getKillRegState(isKill))
+ .addFrameIndex(FI)
+ .addMemOperand(MMO);
} else {
MachineInstrBuilder MIB = BuildMI(MBB, I, DebugLoc(),
get(ARM::VSTMDIA))
@@ -1269,8 +1274,13 @@ storeRegToStackSlot(MachineBasicBlock &MBB, MachineBasicBlock::iterator I,
llvm_unreachable("Unknown reg class!");
break;
case 64:
- if (ARM::QQQQPRRegClass.hasSubClassEq(RC) ||
- ARM::MQQQQPRRegClass.hasSubClassEq(RC)) {
+ if (ARM::MQQQQPRRegClass.hasSubClassEq(RC) &&
+ Subtarget.hasMVEIntegerOps()) {
+ BuildMI(MBB, I, DebugLoc(), get(ARM::MQQQQPRStore))
+ .addReg(SrcReg, getKillRegState(isKill))
+ .addFrameIndex(FI)
+ .addMemOperand(MMO);
+ } else if (ARM::QQQQPRRegClass.hasSubClassEq(RC)) {
MachineInstrBuilder MIB = BuildMI(MBB, I, DebugLoc(), get(ARM::VSTMDIA))
.addFrameIndex(FI)
.add(predOps(ARMCC::AL))
@@ -1331,6 +1341,13 @@ unsigned ARMBaseInstrInfo::isStoreToStackSlot(const MachineInstr &MI,
return MI.getOperand(0).getReg();
}
break;
+ case ARM::MQQPRStore:
+ case ARM::MQQQQPRStore:
+ if (MI.getOperand(1).isFI()) {
+ FrameIndex = MI.getOperand(1).getIndex();
+ return MI.getOperand(0).getReg();
+ }
+ break;
}
return 0;
@@ -1486,6 +1503,10 @@ loadRegFromStackSlot(MachineBasicBlock &MBB, MachineBasicBlock::iterator I,
.addImm(16)
.addMemOperand(MMO)
.add(predOps(ARMCC::AL));
+ } else if (Subtarget.hasMVEIntegerOps()) {
+ BuildMI(MBB, I, DL, get(ARM::MQQPRLoad), DestReg)
+ .addFrameIndex(FI)
+ .addMemOperand(MMO);
} else {
MachineInstrBuilder MIB = BuildMI(MBB, I, DL, get(ARM::VLDMDIA))
.addFrameIndex(FI)
@@ -1502,8 +1523,12 @@ loadRegFromStackSlot(MachineBasicBlock &MBB, MachineBasicBlock::iterator I,
llvm_unreachable("Unknown reg class!");
break;
case 64:
- if (ARM::QQQQPRRegClass.hasSubClassEq(RC) ||
- ARM::MQQQQPRRegClass.hasSubClassEq(RC)) {
+ if (ARM::MQQQQPRRegClass.hasSubClassEq(RC) &&
+ Subtarget.hasMVEIntegerOps()) {
+ BuildMI(MBB, I, DL, get(ARM::MQQQQPRLoad), DestReg)
+ .addFrameIndex(FI)
+ .addMemOperand(MMO);
+ } else if (ARM::QQQQPRRegClass.hasSubClassEq(RC)) {
MachineInstrBuilder MIB = BuildMI(MBB, I, DL, get(ARM::VLDMDIA))
.addFrameIndex(FI)
.add(predOps(ARMCC::AL))
@@ -1572,6 +1597,13 @@ unsigned ARMBaseInstrInfo::isLoadFromStackSlot(const MachineInstr &MI,
return MI.getOperand(0).getReg();
}
break;
+ case ARM::MQQPRLoad:
+ case ARM::MQQQQPRLoad:
+ if (MI.getOperand(1).isFI()) {
+ FrameIndex = MI.getOperand(1).getIndex();
+ return MI.getOperand(0).getReg();
+ }
+ break;
}
return 0;
diff --git a/llvm/lib/Target/ARM/ARMExpandPseudoInsts.cpp b/llvm/lib/Target/ARM/ARMExpandPseudoInsts.cpp
index e68a3aa8bf47..0e8360814ae2 100644
--- a/llvm/lib/Target/ARM/ARMExpandPseudoInsts.cpp
+++ b/llvm/lib/Target/ARM/ARMExpandPseudoInsts.cpp
@@ -69,6 +69,7 @@ namespace {
void ExpandLaneOp(MachineBasicBlock::iterator &MBBI);
void ExpandVTBL(MachineBasicBlock::iterator &MBBI,
unsigned Opc, bool IsExt);
+ void ExpandMQQPRLoadStore(MachineBasicBlock::iterator &MBBI);
void ExpandMOV32BitImm(MachineBasicBlock &MBB,
MachineBasicBlock::iterator &MBBI);
void CMSEClearGPRegs(MachineBasicBlock &MBB,
@@ -887,6 +888,43 @@ void ARMExpandPseudo::ExpandVTBL(MachineBasicBlock::iterator &MBBI,
LLVM_DEBUG(dbgs() << "To: "; MIB.getInstr()->dump(););
}
+void ARMExpandPseudo::ExpandMQQPRLoadStore(MachineBasicBlock::iterator &MBBI) {
+ MachineInstr &MI = *MBBI;
+ MachineBasicBlock &MBB = *MI.getParent();
+ unsigned NewOpc =
+ MI.getOpcode() == ARM::MQQPRStore || MI.getOpcode() == ARM::MQQQQPRStore
+ ? ARM::VSTMDIA
+ : ARM::VLDMDIA;
+ MachineInstrBuilder MIB =
+ BuildMI(MBB, MBBI, MI.getDebugLoc(), TII->get(NewOpc));
+
+ unsigned Flags = getKillRegState(MI.getOperand(0).isKill()) |
+ getDefRegState(MI.getOperand(0).isDef());
+ Register SrcReg = MI.getOperand(0).getReg();
+
+ // Copy the destination register.
+ MIB.add(MI.getOperand(1));
+ MIB.add(predOps(ARMCC::AL));
+ MIB.addReg(TRI->getSubReg(SrcReg, ARM::dsub_0), Flags);
+ MIB.addReg(TRI->getSubReg(SrcReg, ARM::dsub_1), Flags);
+ MIB.addReg(TRI->getSubReg(SrcReg, ARM::dsub_2), Flags);
+ MIB.addReg(TRI->getSubReg(SrcReg, ARM::dsub_3), Flags);
+ if (MI.getOpcode() == ARM::MQQQQPRStore ||
+ MI.getOpcode() == ARM::MQQQQPRLoad) {
+ MIB.addReg(TRI->getSubReg(SrcReg, ARM::dsub_4), Flags);
+ MIB.addReg(TRI->getSubReg(SrcReg, ARM::dsub_5), Flags);
+ MIB.addReg(TRI->getSubReg(SrcReg, ARM::dsub_6), Flags);
+ MIB.addReg(TRI->getSubReg(SrcReg, ARM::dsub_7), Flags);
+ }
+
+ if (NewOpc == ARM::VSTMDIA)
+ MIB.addReg(SrcReg, RegState::Implicit);
+
+ TransferImpOps(MI, MIB, MIB);
+ MIB.cloneMemRefs(MI);
+ MI.eraseFromParent();
+}
+
static bool IsAnAddressOperand(const MachineOperand &MO) {
// This check is overly conservative. Unless we are certain that the machine
// operand is not a symbol reference, we return that it is a symbol reference.
@@ -2916,6 +2954,13 @@ bool ARMExpandPseudo::ExpandMI(MachineBasicBlock &MBB,
case ARM::VTBX3Pseudo: ExpandVTBL(MBBI, ARM::VTBX3, true); return true;
case ARM::VTBX4Pseudo: ExpandVTBL(MBBI, ARM::VTBX4, true); return true;
+ case ARM::MQQPRLoad:
+ case ARM::MQQPRStore:
+ case ARM::MQQQQPRLoad:
+ case ARM::MQQQQPRStore:
+ ExpandMQQPRLoadStore(MBBI);
+ return true;
+
case ARM::tCMP_SWAP_8:
assert(STI->isThumb());
return ExpandCMP_SWAP(MBB, MBBI, ARM::t2LDREXB, ARM::t2STREXB, ARM::tUXTB,
diff --git a/llvm/lib/Target/ARM/ARMInstrMVE.td b/llvm/lib/Target/ARM/ARMInstrMVE.td
index 5577de05a6e3..0777532e58e0 100644
--- a/llvm/lib/Target/ARM/ARMInstrMVE.td
+++ b/llvm/lib/Target/ARM/ARMInstrMVE.td
@@ -6930,6 +6930,26 @@ def MVE_LCTP : MVE_loltp_end<(outs), (ins pred:$p), "lctp${p}", ""> {
}
+// Pseudo instructions for lowering MQQPR and MQQQQPR stack spills and reloads.
+// They are equivalent to VLDMDIA/VSTMDIA with a single reg, as opposed to multiple
+// dreg subregs.
+
+let Predicates = [HasMVEInt], AM = AddrMode4 in {
+let mayStore = 1, hasSideEffects = 0 in {
+ def MQQPRStore : t2PseudoInst<(outs), (ins MQQPR:$val, GPRnopc:$ptr),
+ 4, NoItinerary, []>;
+ def MQQQQPRStore : t2PseudoInst<(outs), (ins MQQQQPR:$val, GPRnopc:$ptr),
+ 4, NoItinerary, []>;
+}
+let mayLoad = 1, hasSideEffects = 0 in {
+ def MQQPRLoad : t2PseudoInst<(outs MQQPR:$val), (ins GPRnopc:$ptr),
+ 4, NoItinerary, []>;
+ def MQQQQPRLoad : t2PseudoInst<(outs MQQQQPR:$val), (ins GPRnopc:$ptr),
+ 4, NoItinerary, []>;
+}
+}
+
+
//===----------------------------------------------------------------------===//
// Patterns
//===----------------------------------------------------------------------===//
More information about the llvm-commits
mailing list