summaryrefslogtreecommitdiff
path: root/llvm/lib/Target/Hexagon/HexagonInstrInfo.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'llvm/lib/Target/Hexagon/HexagonInstrInfo.cpp')
-rw-r--r--llvm/lib/Target/Hexagon/HexagonInstrInfo.cpp179
1 files changed, 90 insertions, 89 deletions
diff --git a/llvm/lib/Target/Hexagon/HexagonInstrInfo.cpp b/llvm/lib/Target/Hexagon/HexagonInstrInfo.cpp
index 767538f92ed60..39ec8936214e7 100644
--- a/llvm/lib/Target/Hexagon/HexagonInstrInfo.cpp
+++ b/llvm/lib/Target/Hexagon/HexagonInstrInfo.cpp
@@ -786,8 +786,8 @@ bool HexagonInstrInfo::isProfitableToDupForIfCvt(MachineBasicBlock &MBB,
void HexagonInstrInfo::copyPhysReg(MachineBasicBlock &MBB,
MachineBasicBlock::iterator I,
- const DebugLoc &DL, unsigned DestReg,
- unsigned SrcReg, bool KillSrc) const {
+ const DebugLoc &DL, MCRegister DestReg,
+ MCRegister SrcReg, bool KillSrc) const {
const HexagonRegisterInfo &HRI = *Subtarget.getRegisterInfo();
unsigned KillFlag = getKillRegState(KillSrc);
@@ -888,10 +888,7 @@ void HexagonInstrInfo::storeRegToStackSlot(MachineBasicBlock &MBB,
MachineFunction &MF = *MBB.getParent();
MachineFrameInfo &MFI = MF.getFrameInfo();
unsigned SlotAlign = MFI.getObjectAlignment(FI);
- unsigned RegAlign = TRI->getSpillAlignment(*RC);
unsigned KillFlag = getKillRegState(isKill);
- bool HasAlloca = MFI.hasVarSizedObjects();
- const HexagonFrameLowering &HFI = *Subtarget.getFrameLowering();
MachineMemOperand *MMO = MF.getMachineMemOperand(
MachinePointerInfo::getFixedStack(MF, FI), MachineMemOperand::MOStore,
@@ -918,29 +915,13 @@ void HexagonInstrInfo::storeRegToStackSlot(MachineBasicBlock &MBB,
.addFrameIndex(FI).addImm(0)
.addReg(SrcReg, KillFlag).addMemOperand(MMO);
} else if (Hexagon::HvxVRRegClass.hasSubClassEq(RC)) {
- // If there are variable-sized objects, spills will not be aligned.
- if (HasAlloca)
- SlotAlign = HFI.getStackAlignment();
- unsigned Opc = SlotAlign < RegAlign ? Hexagon::V6_vS32Ub_ai
- : Hexagon::V6_vS32b_ai;
- MachineMemOperand *MMOA = MF.getMachineMemOperand(
- MachinePointerInfo::getFixedStack(MF, FI), MachineMemOperand::MOStore,
- MFI.getObjectSize(FI), SlotAlign);
- BuildMI(MBB, I, DL, get(Opc))
+ BuildMI(MBB, I, DL, get(Hexagon::PS_vstorerv_ai))
.addFrameIndex(FI).addImm(0)
- .addReg(SrcReg, KillFlag).addMemOperand(MMOA);
+ .addReg(SrcReg, KillFlag).addMemOperand(MMO);
} else if (Hexagon::HvxWRRegClass.hasSubClassEq(RC)) {
- // If there are variable-sized objects, spills will not be aligned.
- if (HasAlloca)
- SlotAlign = HFI.getStackAlignment();
- unsigned Opc = SlotAlign < RegAlign ? Hexagon::PS_vstorerwu_ai
- : Hexagon::PS_vstorerw_ai;
- MachineMemOperand *MMOA = MF.getMachineMemOperand(
- MachinePointerInfo::getFixedStack(MF, FI), MachineMemOperand::MOStore,
- MFI.getObjectSize(FI), SlotAlign);
- BuildMI(MBB, I, DL, get(Opc))
+ BuildMI(MBB, I, DL, get(Hexagon::PS_vstorerw_ai))
.addFrameIndex(FI).addImm(0)
- .addReg(SrcReg, KillFlag).addMemOperand(MMOA);
+ .addReg(SrcReg, KillFlag).addMemOperand(MMO);
} else {
llvm_unreachable("Unimplemented");
}
@@ -954,9 +935,6 @@ void HexagonInstrInfo::loadRegFromStackSlot(
MachineFunction &MF = *MBB.getParent();
MachineFrameInfo &MFI = MF.getFrameInfo();
unsigned SlotAlign = MFI.getObjectAlignment(FI);
- unsigned RegAlign = TRI->getSpillAlignment(*RC);
- bool HasAlloca = MFI.hasVarSizedObjects();
- const HexagonFrameLowering &HFI = *Subtarget.getFrameLowering();
MachineMemOperand *MMO = MF.getMachineMemOperand(
MachinePointerInfo::getFixedStack(MF, FI), MachineMemOperand::MOLoad,
@@ -978,27 +956,11 @@ void HexagonInstrInfo::loadRegFromStackSlot(
BuildMI(MBB, I, DL, get(Hexagon::PS_vloadrq_ai), DestReg)
.addFrameIndex(FI).addImm(0).addMemOperand(MMO);
} else if (Hexagon::HvxVRRegClass.hasSubClassEq(RC)) {
- // If there are variable-sized objects, spills will not be aligned.
- if (HasAlloca)
- SlotAlign = HFI.getStackAlignment();
- unsigned Opc = SlotAlign < RegAlign ? Hexagon::V6_vL32Ub_ai
- : Hexagon::V6_vL32b_ai;
- MachineMemOperand *MMOA = MF.getMachineMemOperand(
- MachinePointerInfo::getFixedStack(MF, FI), MachineMemOperand::MOLoad,
- MFI.getObjectSize(FI), SlotAlign);
- BuildMI(MBB, I, DL, get(Opc), DestReg)
- .addFrameIndex(FI).addImm(0).addMemOperand(MMOA);
+ BuildMI(MBB, I, DL, get(Hexagon::PS_vloadrv_ai), DestReg)
+ .addFrameIndex(FI).addImm(0).addMemOperand(MMO);
} else if (Hexagon::HvxWRRegClass.hasSubClassEq(RC)) {
- // If there are variable-sized objects, spills will not be aligned.
- if (HasAlloca)
- SlotAlign = HFI.getStackAlignment();
- unsigned Opc = SlotAlign < RegAlign ? Hexagon::PS_vloadrwu_ai
- : Hexagon::PS_vloadrw_ai;
- MachineMemOperand *MMOA = MF.getMachineMemOperand(
- MachinePointerInfo::getFixedStack(MF, FI), MachineMemOperand::MOLoad,
- MFI.getObjectSize(FI), SlotAlign);
- BuildMI(MBB, I, DL, get(Opc), DestReg)
- .addFrameIndex(FI).addImm(0).addMemOperand(MMOA);
+ BuildMI(MBB, I, DL, get(Hexagon::PS_vloadrw_ai), DestReg)
+ .addFrameIndex(FI).addImm(0).addMemOperand(MMO);
} else {
llvm_unreachable("Can't store this register to stack slot");
}
@@ -1040,6 +1002,15 @@ bool HexagonInstrInfo::expandPostRAPseudo(MachineInstr &MI) const {
return true;
};
+ auto UseAligned = [&] (const MachineInstr &MI, unsigned NeedAlign) {
+ if (MI.memoperands().empty())
+ return false;
+ return all_of(MI.memoperands(),
+ [NeedAlign] (const MachineMemOperand *MMO) {
+ return NeedAlign <= MMO->getAlignment();
+ });
+ };
+
switch (Opc) {
case TargetOpcode::COPY: {
MachineOperand &MD = MI.getOperand(0);
@@ -1086,47 +1057,78 @@ bool HexagonInstrInfo::expandPostRAPseudo(MachineInstr &MI) const {
MRI.clearKillFlags(SrcSubHi);
return true;
}
- case Hexagon::PS_vstorerw_ai:
- case Hexagon::PS_vstorerwu_ai: {
- bool Aligned = Opc == Hexagon::PS_vstorerw_ai;
- Register SrcReg = MI.getOperand(2).getReg();
- Register SrcSubHi = HRI.getSubReg(SrcReg, Hexagon::vsub_hi);
- Register SrcSubLo = HRI.getSubReg(SrcReg, Hexagon::vsub_lo);
- unsigned NewOpc = Aligned ? Hexagon::V6_vS32b_ai : Hexagon::V6_vS32Ub_ai;
- unsigned Offset = HRI.getSpillSize(Hexagon::HvxVRRegClass);
-
- MachineInstr *MI1New = BuildMI(MBB, MI, DL, get(NewOpc))
- .add(MI.getOperand(0))
- .addImm(MI.getOperand(1).getImm())
- .addReg(SrcSubLo)
- .cloneMemRefs(MI);
- MI1New->getOperand(0).setIsKill(false);
- BuildMI(MBB, MI, DL, get(NewOpc))
- .add(MI.getOperand(0))
- // The Vectors are indexed in multiples of vector size.
- .addImm(MI.getOperand(1).getImm() + Offset)
- .addReg(SrcSubHi)
+ case Hexagon::PS_vloadrv_ai: {
+ Register DstReg = MI.getOperand(0).getReg();
+ const MachineOperand &BaseOp = MI.getOperand(1);
+ assert(BaseOp.getSubReg() == 0);
+ int Offset = MI.getOperand(2).getImm();
+ unsigned NeedAlign = HRI.getSpillAlignment(Hexagon::HvxVRRegClass);
+ unsigned NewOpc = UseAligned(MI, NeedAlign) ? Hexagon::V6_vL32b_ai
+ : Hexagon::V6_vL32Ub_ai;
+ BuildMI(MBB, MI, DL, get(NewOpc), DstReg)
+ .addReg(BaseOp.getReg(), getRegState(BaseOp))
+ .addImm(Offset)
.cloneMemRefs(MI);
MBB.erase(MI);
return true;
}
- case Hexagon::PS_vloadrw_ai:
- case Hexagon::PS_vloadrwu_ai: {
- bool Aligned = Opc == Hexagon::PS_vloadrw_ai;
+ case Hexagon::PS_vloadrw_ai: {
Register DstReg = MI.getOperand(0).getReg();
- unsigned NewOpc = Aligned ? Hexagon::V6_vL32b_ai : Hexagon::V6_vL32Ub_ai;
- unsigned Offset = HRI.getSpillSize(Hexagon::HvxVRRegClass);
-
- MachineInstr *MI1New = BuildMI(MBB, MI, DL, get(NewOpc),
- HRI.getSubReg(DstReg, Hexagon::vsub_lo))
- .add(MI.getOperand(1))
- .addImm(MI.getOperand(2).getImm())
- .cloneMemRefs(MI);
- MI1New->getOperand(1).setIsKill(false);
- BuildMI(MBB, MI, DL, get(NewOpc), HRI.getSubReg(DstReg, Hexagon::vsub_hi))
- .add(MI.getOperand(1))
- // The Vectors are indexed in multiples of vector size.
- .addImm(MI.getOperand(2).getImm() + Offset)
+ const MachineOperand &BaseOp = MI.getOperand(1);
+ assert(BaseOp.getSubReg() == 0);
+ int Offset = MI.getOperand(2).getImm();
+ unsigned VecOffset = HRI.getSpillSize(Hexagon::HvxVRRegClass);
+ unsigned NeedAlign = HRI.getSpillAlignment(Hexagon::HvxVRRegClass);
+ unsigned NewOpc = UseAligned(MI, NeedAlign) ? Hexagon::V6_vL32b_ai
+ : Hexagon::V6_vL32Ub_ai;
+ BuildMI(MBB, MI, DL, get(NewOpc),
+ HRI.getSubReg(DstReg, Hexagon::vsub_lo))
+ .addReg(BaseOp.getReg(), getRegState(BaseOp) & ~RegState::Kill)
+ .addImm(Offset)
+ .cloneMemRefs(MI);
+ BuildMI(MBB, MI, DL, get(NewOpc),
+ HRI.getSubReg(DstReg, Hexagon::vsub_hi))
+ .addReg(BaseOp.getReg(), getRegState(BaseOp))
+ .addImm(Offset + VecOffset)
+ .cloneMemRefs(MI);
+ MBB.erase(MI);
+ return true;
+ }
+ case Hexagon::PS_vstorerv_ai: {
+ const MachineOperand &SrcOp = MI.getOperand(2);
+ assert(SrcOp.getSubReg() == 0);
+ const MachineOperand &BaseOp = MI.getOperand(0);
+ assert(BaseOp.getSubReg() == 0);
+ int Offset = MI.getOperand(1).getImm();
+ unsigned NeedAlign = HRI.getSpillAlignment(Hexagon::HvxVRRegClass);
+ unsigned NewOpc = UseAligned(MI, NeedAlign) ? Hexagon::V6_vS32b_ai
+ : Hexagon::V6_vS32Ub_ai;
+ BuildMI(MBB, MI, DL, get(NewOpc))
+ .addReg(BaseOp.getReg(), getRegState(BaseOp))
+ .addImm(Offset)
+ .addReg(SrcOp.getReg(), getRegState(SrcOp))
+ .cloneMemRefs(MI);
+ MBB.erase(MI);
+ return true;
+ }
+ case Hexagon::PS_vstorerw_ai: {
+ Register SrcReg = MI.getOperand(2).getReg();
+ const MachineOperand &BaseOp = MI.getOperand(0);
+ assert(BaseOp.getSubReg() == 0);
+ int Offset = MI.getOperand(1).getImm();
+ unsigned VecOffset = HRI.getSpillSize(Hexagon::HvxVRRegClass);
+ unsigned NeedAlign = HRI.getSpillAlignment(Hexagon::HvxVRRegClass);
+ unsigned NewOpc = UseAligned(MI, NeedAlign) ? Hexagon::V6_vS32b_ai
+ : Hexagon::V6_vS32Ub_ai;
+ BuildMI(MBB, MI, DL, get(NewOpc))
+ .addReg(BaseOp.getReg(), getRegState(BaseOp) & ~RegState::Kill)
+ .addImm(Offset)
+ .addReg(HRI.getSubReg(SrcReg, Hexagon::vsub_lo))
+ .cloneMemRefs(MI);
+ BuildMI(MBB, MI, DL, get(NewOpc))
+ .addReg(BaseOp.getReg(), getRegState(BaseOp))
+ .addImm(Offset + VecOffset)
+ .addReg(HRI.getSubReg(SrcReg, Hexagon::vsub_hi))
.cloneMemRefs(MI);
MBB.erase(MI);
return true;
@@ -2145,7 +2147,7 @@ bool HexagonInstrInfo::isDuplexPair(const MachineInstr &MIa,
}
bool HexagonInstrInfo::isEarlySourceInstr(const MachineInstr &MI) const {
- if (MI.mayLoad() || MI.mayStore() || MI.isCompare())
+ if (MI.mayLoadOrStore() || MI.isCompare())
return true;
// Multiply
@@ -2683,9 +2685,11 @@ bool HexagonInstrInfo::isValidOffset(unsigned Opcode, int Offset,
// misaligns with respect to load size.
switch (Opcode) {
case Hexagon::PS_vstorerq_ai:
+ case Hexagon::PS_vstorerv_ai:
case Hexagon::PS_vstorerw_ai:
case Hexagon::PS_vstorerw_nt_ai:
case Hexagon::PS_vloadrq_ai:
+ case Hexagon::PS_vloadrv_ai:
case Hexagon::PS_vloadrw_ai:
case Hexagon::PS_vloadrw_nt_ai:
case Hexagon::V6_vL32b_ai:
@@ -2941,10 +2945,7 @@ bool HexagonInstrInfo::getMemOperandWithOffset(
const TargetRegisterInfo *TRI) const {
unsigned AccessSize = 0;
BaseOp = getBaseAndOffset(LdSt, Offset, AccessSize);
- assert((!BaseOp || BaseOp->isReg()) &&
- "getMemOperandWithOffset only supports base "
- "operands of type register.");
- return BaseOp != nullptr;
+ return BaseOp != nullptr && BaseOp->isReg();
}
/// Can these instructions execute at the same time in a bundle.