Skip to content

Commit

Permalink
[ARM] Add MQQPR and MQQQQPR spill and reload pseudo instructions
Browse files Browse the repository at this point in the history
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.
  • Loading branch information
davemgreen committed Aug 17, 2021
1 parent e73f4e1 commit 62e892f
Show file tree
Hide file tree
Showing 3 changed files with 101 additions and 4 deletions.
40 changes: 36 additions & 4 deletions llvm/lib/Target/ARM/ARMBaseInstrInfo.cpp
Expand Up @@ -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))
Expand All @@ -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))
Expand Down Expand Up @@ -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;
Expand Down Expand Up @@ -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)
Expand All @@ -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))
Expand Down Expand Up @@ -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;
Expand Down
45 changes: 45 additions & 0 deletions llvm/lib/Target/ARM/ARMExpandPseudoInsts.cpp
Expand Up @@ -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,
Expand Down Expand Up @@ -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.
Expand Down Expand Up @@ -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,
Expand Down
20 changes: 20 additions & 0 deletions llvm/lib/Target/ARM/ARMInstrMVE.td
Expand Up @@ -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
//===----------------------------------------------------------------------===//
Expand Down

0 comments on commit 62e892f

Please sign in to comment.