-
Notifications
You must be signed in to change notification settings - Fork 13.3k
[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
Conversation
✅ With the latest revision this PR passed the C/C++ code formatter. |
… lowering. Implement emitPrologue/emitEpilogue methods, determine/spill/restore callee saved registers functionality with test. Also implement lowering of the DYNAMIC_STACKALLOC/STACKSAVE/STACKRESTORE stack operations with tests.
316fb85
to
78c9f32
Compare
// Find the first instruction that restores a callee-saved register. | ||
MachineBasicBlock::iterator I = MBBI; | ||
|
||
for (unsigned i = 0; i < MFI.getCalleeSavedInfo().size(); ++i) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't see how incrementing the instruction iteration based on this makes sense
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thank you very much for review. I've made some code improvements (added more comments and loop is changed), I hope that I understand correctly your comment. Actually I used the same approach as in Mips architecture
for (unsigned i = 0; i < MFI.getCalleeSavedInfo().size(); ++i) |
Remove redundant code from XtensaFrameLowering and XtensaISelLowering, add comments.
|
||
const std::vector<CalleeSavedInfo> &CSI = MFI.getCalleeSavedInfo(); | ||
|
||
if (CSI.size()) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
!CSI.empty()
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
fixed
// Find the instruction past the last instruction that saves a | ||
// callee-saved register to the stack. | ||
for (unsigned i = 0; i < CSI.size(); ++i) | ||
++MBBI; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This seems like a dubious way to guarantee this. Can you at least assert each instruction is a spill of the appropriate register?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I added check functions for store/restore instructions, PTAL.
// Find the first instruction at the end that restores a callee-saved | ||
// register. | ||
for (auto &Info : MFI.getCalleeSavedInfo()) | ||
--I; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Same as above, can this at least assert the instructions are the expected ones?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I added check functions
Align Alignment = TRI->getSpillAlign(RC); | ||
int FI = MF.getFrameInfo().CreateStackObject(Size, Alignment, false); | ||
|
||
RS->addScavengingFrameIndex(FI); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm not sure it's safe to do this in determineCalleeSaves. Can you create the emergency scavenging index in processFunctionBeforeFrameFinalized instead?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I moved frame index scavenging to processFunctionBeforeFrameFinalized
…emitEpilogue. Check whether store/restore instruciton for callee-saved registers are placed correctly in emitProlgue and emitEpilogue. Also move frame index scavenging from determineCalleeSaves function to processFunctionBeforeFrameFinalized function.
static bool checkStoreInstruction(MachineBasicBlock::iterator I, | ||
const std::vector<CalleeSavedInfo> &CSI) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Name is too general. Also, this is way more code than I expected for this assert. Don't you expect these instructions to appear in order?
Can you use TII->isStoreToStackSlot and isCopyInstr to avoid special casing these specific opcodes?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, I will implement then isStoreToStackSlot /isLoadFromStackSlot functions. Current PrologueEpilogueInsterter implementation places stores in direct order:
.. for (const CalleeSavedInfo &CS : CSI)..
and uses reverse order for placement loads at the end of basic block. So, we can assume that we always have such order and create redundant version which checks instructions. Is it acceptable?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If you're relying on seeing these exact instructions, it's OK to rely on the order. The point of the assert was to verify the instructions exactly match what you expected, which includes the order
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I implemented isStoreToStackSlot /isLoadFromStackSlot functions and simplified callee-saved instructions checking.
return MI.getOperand(0).getReg(); | ||
} | ||
} | ||
return 0; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
return Register()
return MI.getOperand(0).getReg(); | ||
} | ||
} | ||
return 0; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Register()
#ifndef NDEBUG | ||
// Checking that the instruction is exactly as expected | ||
bool IsStoreInst = false; | ||
if ((MBBI->getOpcode() == TargetOpcode::COPY) && Info.isSpilledToReg()) { |
There was a problem hiding this comment.
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
There was a problem hiding this comment.
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
I fixed two warnings in dd82fd4. You might want to build llvm-project with a not-too-ancient clang to ensure that there is no such warning for future patches:)
|
|
Implement emitPrologue/emitEpilogue methods, determine/spill/restore callee saved registers functionality with test. Also implement lowering of the DYNAMIC_STACKALLOC/STACKSAVE/STACKRESTORE stack operations with tests.