Skip to content

[PATCH] [Xtensa] Implement FrameLowering methods and stack operation lowering. #92960

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 6 commits into from
Jun 4, 2024
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
102 changes: 34 additions & 68 deletions llvm/lib/Target/Xtensa/XtensaFrameLowering.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -33,70 +33,6 @@ bool XtensaFrameLowering::hasFP(const MachineFunction &MF) const {
MFI.hasVarSizedObjects();
}

#ifndef NDEBUG
/* Check whether instruction I stores some callee-saved register from CSI
*/
static bool checkStoreInstruction(MachineBasicBlock::iterator I,
const std::vector<CalleeSavedInfo> &CSI) {
bool IsStoreInstruction = false;

if (I->getOpcode() == TargetOpcode::COPY) {
Register DstReg = I->getOperand(0).getReg();
Register Reg = I->getOperand(1).getReg();
for (const auto &Info : CSI) {
if (Info.isSpilledToReg()) {
IsStoreInstruction =
(Info.getDstReg() == DstReg) && (Info.getReg() == Reg);
}
if (IsStoreInstruction)
break;
}
} else if (I->getOpcode() == Xtensa::S32I) {
Register Reg = I->getOperand(0).getReg();
for (const auto &Info : CSI) {
if (!Info.isSpilledToReg()) {
IsStoreInstruction = (Info.getReg() == Reg);
}
if (IsStoreInstruction)
break;
}
}

return IsStoreInstruction;
}

/* Check whether instruction I restores some callee-saved register from CSI
*/
static bool checkRestoreInstruction(MachineBasicBlock::iterator I,
const std::vector<CalleeSavedInfo> &CSI) {
bool IsRestoreInstruction = false;

if (I->getOpcode() == TargetOpcode::COPY) {
Register Reg = I->getOperand(0).getReg();
Register DstReg = I->getOperand(1).getReg();
for (const auto &Info : CSI) {
if (Info.isSpilledToReg()) {
IsRestoreInstruction =
(Info.getDstReg() == DstReg) && (Info.getReg() == Reg);
}
if (IsRestoreInstruction)
break;
}
} else if (I->getOpcode() == Xtensa::L32I) {
Register Reg = I->getOperand(0).getReg();
for (const auto &Info : CSI) {
if (!Info.isSpilledToReg()) {
IsRestoreInstruction = (Info.getReg() == Reg);
}
if (IsRestoreInstruction)
break;
}
}

return IsRestoreInstruction;
}
#endif

void XtensaFrameLowering::emitPrologue(MachineFunction &MF,
MachineBasicBlock &MBB) const {
assert(&MBB == &MF.front() && "Shrink-wrapping not yet implemented");
Expand Down Expand Up @@ -136,9 +72,24 @@ void XtensaFrameLowering::emitPrologue(MachineFunction &MF,
// instructions are placed at the begin of basic block, so
// iterate over instruction sequence and check that
// save instructions are placed correctly.
for (unsigned i = 0; i < CSI.size(); ++i) {
assert(checkStoreInstruction(MBBI, CSI) &&
for (const auto &Info : CSI) {
int FI = Info.getFrameIdx();
int StoreFI = 0;

#ifndef NDEBUG
// Checking that the instruction is exactly as expected
bool IsStoreInst = false;
if ((MBBI->getOpcode() == TargetOpcode::COPY) && Info.isSpilledToReg()) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

don't need these braces

Copy link
Contributor Author

@andreisfr andreisfr May 30, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I corrected "if-condition", is it what you mean? Also, I'm sorry, I changed loop structure a bit with callee-saved register checks to avoid compiler messages like "unused variable" and fix variable name typo. Could you PTAL? Thanks

Register DstReg = MBBI->getOperand(0).getReg();
Register Reg = MBBI->getOperand(1).getReg();
IsStoreInst = (Info.getDstReg() == DstReg) && (Info.getReg() == Reg);
} else {
Register Reg = TII.isStoreToStackSlot(*MBBI, StoreFI);
IsStoreInst = (Reg == Info.getReg()) && (StoreFI == FI);
}
assert(IsStoreInst &&
"Unexpected callee-saved register store instruction");
#endif
++MBBI;
}

Expand Down Expand Up @@ -204,10 +155,25 @@ void XtensaFrameLowering::emitEpilogue(MachineFunction &MF,

// Find the first instruction at the end that restores a callee-saved
// register.
for (unsigned i = 0, e = CSI.size(); i != e; ++i) {
for (const auto &Info : CSI) {
int FI = Info.getFrameIdx();
int LoadFI = 0;

--I;
assert(checkRestoreInstruction(I, CSI) &&
#ifndef NDEBUG
// Checking that the instruction is exactly as expected
bool IsRestoreInstr = false;
if (I->getOpcode() == TargetOpcode::COPY) {
Register Reg = I->getOperand(0).getReg();
Register DstReg = I->getOperand(1).getReg();
IsRestoreInstr = (Info.getDstReg() == DstReg) && (Info.getReg() == Reg);
} else {
Register Reg = TII.isLoadFromStackSlot(*I, LoadFI);
IsRestoreInst = (Info.getReg() == Reg) && (LoadFI == FI);
}
assert(IsRestoreInstr &&
"Unexpected callee-saved register restore instruction");
#endif
}

BuildMI(MBB, I, DL, TII.get(Xtensa::OR), SP).addReg(FP).addReg(FP);
Expand Down
24 changes: 24 additions & 0 deletions llvm/lib/Target/Xtensa/XtensaInstrInfo.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,30 @@ XtensaInstrInfo::XtensaInstrInfo(const XtensaSubtarget &STI)
: XtensaGenInstrInfo(Xtensa::ADJCALLSTACKDOWN, Xtensa::ADJCALLSTACKUP),
RI(STI), STI(STI) {}

Register XtensaInstrInfo::isLoadFromStackSlot(const MachineInstr &MI,
int &FrameIndex) const {
if (MI.getOpcode() == Xtensa::L32I) {
if (MI.getOperand(1).isFI() && MI.getOperand(2).isImm() &&
MI.getOperand(2).getImm() == 0) {
FrameIndex = MI.getOperand(1).getIndex();
return MI.getOperand(0).getReg();
}
}
return 0;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

return Register()

}

Register XtensaInstrInfo::isStoreToStackSlot(const MachineInstr &MI,
int &FrameIndex) const {
if (MI.getOpcode() == Xtensa::S32I) {
if (MI.getOperand(1).isFI() && MI.getOperand(2).isImm() &&
MI.getOperand(2).getImm() == 0) {
FrameIndex = MI.getOperand(1).getIndex();
return MI.getOperand(0).getReg();
}
}
return 0;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Register()

}

/// Adjust SP by Amount bytes.
void XtensaInstrInfo::adjustStackPtr(unsigned SP, int64_t Amount,
MachineBasicBlock &MBB,
Expand Down
6 changes: 6 additions & 0 deletions llvm/lib/Target/Xtensa/XtensaInstrInfo.h
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,12 @@ class XtensaInstrInfo : public XtensaGenInstrInfo {
// Return the XtensaRegisterInfo, which this class owns.
const XtensaRegisterInfo &getRegisterInfo() const { return RI; }

Register isLoadFromStackSlot(const MachineInstr &MI,
int &FrameIndex) const override;

Register isStoreToStackSlot(const MachineInstr &MI,
int &FrameIndex) const override;

void copyPhysReg(MachineBasicBlock &MBB, MachineBasicBlock::iterator MBBI,
const DebugLoc &DL, MCRegister DestReg, MCRegister SrcReg,
bool KillSrc) const override;
Expand Down
Loading