-
Notifications
You must be signed in to change notification settings - Fork 13.5k
Rebased save csr in ra #131845
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
base: main
Are you sure you want to change the base?
Rebased save csr in ra #131845
Conversation
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.
Thanks for posting this. It really helps to see the full picture here because the additional context is necessary in giving review.
I'd really like to see you split this into a series of patches, all stacked on top of eachother. That way, we can review in small chunks but refer to the stacked components for context.
Please see #119359 for an example. The stacking of PRs makes the job as a reviewer much easier, and it will allow me to give feedback faster.
I left some comments here. Some are questions I hope you can answer here, and some are comments I hope can be useful as you split into stacked patches. Lastly, I think some of the changes in this PR have already made it in (like the reaching def stuff)
MachineBasicBlock::iterator InsertPos = | ||
Info.InsertAfterMI ? ++(Info.InsertAfterMI->getIterator()) | ||
: Info.MBB->begin(); | ||
BuildMI(*Info.MBB, InsertPos, Info.DL, |
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.
It looks like we are emitting CFI instruction here. Why did this not occur in trackRegisterandEmitCFIs
?
BitVector &SavedRegs) const { | ||
const TargetRegisterInfo &TRI = *MF.getSubtarget().getRegisterInfo(); | ||
|
||
// Resize before the early returns. Some backends expect that |
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.
What do you mean some backends expect this? IIUC, there is no other subtarget that has this function and this function for the RISC-V backend.
BitVector &SavedRegs, | ||
RegScavenger *RS) const { | ||
const auto &ST = MF.getSubtarget<RISCVSubtarget>(); | ||
determineMustCalleeSaves(MF, SavedRegs); |
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.
It looks like we're doing additional logic that did not exist before in the case that !ST.doCSRSavesInRA()
. All the logic before
if (hasFP(MF)) {
SavedRegs.set(RISCV::X1);
SavedRegs.set(RISCV::X8);
}
in determineMustCalleeSaves
is new. Is all of that additional logic desired when !doCSRSavesInRA?
if (hasFP(MF)) { | ||
SavedRegs.set(RAReg); | ||
SavedRegs.set(FPReg); | ||
SavedRegs.set(RISCV::X1); |
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.
Why did this code change? Isn't it the same?
return; | ||
} | ||
|
||
int RISCVFrameLowering::getInitialCFAOffset(const MachineFunction &MF) const { |
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.
Is this used? I assume its used somewhere in the CFIInserter already. I'm trying to understand why we didn't need to implement these before wanting to do SaveCSRInRA.
unsigned CFIIndex; | ||
}; | ||
|
||
static void trackRegisterAndEmitCFIs( |
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.
Can you help me understand what this function is doing. Why is it needed? How does it work?
if (Defs.empty()) { | ||
// it's a live-in register at the entry block. | ||
// unsigned CFIIndex = | ||
// MF.addFrameInst(MCCFIInstruction::createSameValue(nullptr, |
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.
Why is this commented out? Do we need it?
const RISCVRegisterInfo &TRI = *Subtarget.getRegisterInfo(); | ||
const RISCVFrameLowering &TFI = *Subtarget.getFrameLowering(); | ||
|
||
SmallVector<MachineInstr *, 4> RestorePoints; |
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.
Why didn't we do this in prologepilog when we inserted the CFI instructions?
We turn the problem of saving and restoring callee-saved registers efficiently into a register allocation problem. This has the advantage that the register allocator can essentialy do shrink-wrapping on per register basis. Currently, shrink-wrapping pass saves all CSR in the same place which may be suboptimal. Also, improvements to register allocation / coalescing will translate to improvements in shrink-wrapping. In finalizeLowering() we copy all callee-saved registers from a physical register to a virtual one. In all return blocks we copy do the reverse.
f843602
to
ef9ee46
Compare
@@ -582,6 +582,8 @@ void RISCVPassConfig::addPreEmitPass2() { | |||
addPass(createUnpackMachineBundles([&](const MachineFunction &MF) { | |||
return MF.getFunction().getParent()->getModuleFlag("kcfi"); | |||
})); | |||
|
|||
addPass(createCFIInstrInserter()); |
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.
Why did we previously not need this pass? Didn't we used to emit CFI Instrs?
Sure, I'll work on splitting everything into commits and stack them all on top of each other. |
No description provided.