[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