[llvm-commits] [llvm] r78650 - in /llvm/trunk: include/llvm/CodeGen/RegisterScavenging.h lib/CodeGen/RegisterScavenging.cpp test/CodeGen/Blackfin/2009-08-11-RegScavenger-CSR.ll
Jakob Stoklund Olesen
stoklund at 2pi.dk
Wed Aug 12 10:03:39 PDT 2009
I want to summarise this discussion.
-==- What We Want -==-
Goal #1. Get rid of DistanceMap.
This is currently not possible because the fragile CSR tracking
depends on our scanning to the end of the MBB.
Goal #2. Detect clobbered CSRs in the verifier.
Clobbered CSRs are only detected when running test on real hardware or
a simulator. They sneak past DejaGNU.
Goal #3. Clean up scavenger clients.
All clients (ARM, Blackfin, PowerPC, XCore) implement a variant of
this algorithm:
unsigned gimme(RC) {
unsigned r;
if (r = RS->FindUnusedReg(RC, $CALL_CLOBBERED))
return r;
if (r = RS->FindUnusedReg(RC, $SPILLED_CSRS))
return r;
if (r = RS->scavengeRegister(RC))
return r;
unreachable("waa!")
}
Only ARM tracks $SPILLED_CSRS. It is too optimistic when under shrink
wrap, leading to clobbered CSRs.
Blackfin and PowerPC may miss the opportunity to use an available
spilled CSR.
XCore only calls scavengeRegister().
In any case, this looks like a scavenger method that has escaped to
the wild, and is now multiplying and mutating.
Goal #4. Target callback to extend prologue/epilogue.
The regscavenger can ask for an extra register to be spilled in the
prologue. This is preferable to the local spill+restore done by the
scavenger.
-==- The Plan -==-
Step 1. Track per-MBB pristine CSRs in MachineFrameInfo.
Normally this is simple. Before PEI, pristine = null set. After
PEI::calculateCalleeSavedRegisters(), pristine = All CSRs \setminus
Spilled CSRs.
When using shrink wrapping, the set depends on the MBB. John, is this
information readily available from the shrink wrapper?
Alternatively we can stick the pristine CSRS in live-in lists. I am
not sure which is better.
Step 2. Use pristine info in verifier.
By treating pristine-in CSRs as live-in registers, we can detect
clobbered CSRs.
Step 3. Track pristine CSRs in RegScavenger
Pristine CSRs are treated as live-in, and tracked the same way. Now
the RegsAvailable set is accurate, and we can allocate spilled CSRs
automatically. We can also get rid of DistanceMap at this point.
We can eliminate the FindUnusedReg() 'Candidates' argument without
penalty.
Step 4. Round up the escaped scavenger methods.
All clients should simply call scavengeRegister(). The scavenger is
responsible for finding an unused register, or spilling to the
emergency slot. Now all clients can take advantage of the CSR
tracking, and ARM+shrink wrap should work.
Step 5. Target callback.
This one is not quite clear to me. Should it work with shrink wrapping
as well? It almost seems that the scavenger can do that spill+reload
just as well itself. (When the scavenger grabs a pristine CSR, it can
place the restore just before the first terminator. We don't need to
scan through the MBB to do that.)
If the callback only modifies the function prologue/epilogues, we can
use CalleeSavedInfo to track if there are any unspilled CSRs left.
More information about the llvm-commits
mailing list