org.jikesrvm.compilers.opt.regalloc.ia32
Class StackManager

java.lang.Object
  extended by org.jikesrvm.compilers.opt.ir.IRTools
      extended by org.jikesrvm.compilers.opt.regalloc.GenericStackManager
          extended by org.jikesrvm.compilers.opt.regalloc.ia32.StackManager
Direct Known Subclasses:
ArchitectureSpecificOpt.StackManager

public abstract class StackManager
extends GenericStackManager

Class to manage the allocation of the "compiler-specific" portion of the stackframe. This class holds only the architecture-specific functions.


Nested Class Summary
 
Nested classes/interfaces inherited from class org.jikesrvm.compilers.opt.regalloc.GenericStackManager
GenericStackManager.ScratchRegister
 
Field Summary
private  int ESPOffset
          We allow the stack pointer to float from its normal position at the bottom of the frame.
private static boolean FLOAT_ESP
          Should we allow the stack pointer to float in order to avoid scratch registers in move instructions.
private  int fsaveLocation
          A frame offset for 108 bytes of stack space to store the floating point state in the SaveVolatile protocol.
 
Fields inherited from class org.jikesrvm.compilers.opt.regalloc.GenericStackManager
allocFrame, DEBUG, frameSize, ir, nonVolatileFPRLocation, nonVolatileGPRLocation, pref, restrict, saveVolatileFPRLocation, saveVolatileGPRLocation, scratchInUse, scratchMap, spillPointer, VERBOSE, VERBOSE_DEBUG, WORDSIZE
 
Constructor Summary
StackManager()
           
 
Method Summary
 int allocateNewSpillLocation(int type)
          Allocate a new spill location and grow the frame size to reflect the new layout.
private  boolean canModifyEFLAGS(Instruction s)
           
 void cleanUpAndInsertEpilogue()
          Clean up some junk that's left in the IR after register allocation, and add epilogue code.
 void computeNonVolatileArea()
          Compute the number of stack words needed to hold nonvolatile registers.
private  int FPOffset2SPOffset(int fpOffset)
          PRECONDITION: The final frameSize is calculated before calling this routine.
 int getFrameFixedSize()
          Return the size of the fixed portion of the stack.
private static Operator getMoveOperator(byte type)
          Return the move operator for a type of value.
private static byte getSizeOfType(byte type)
          Return the size of a type of value, in bytes.
private  boolean hasSymbolicRegister(MemoryOperand M)
          Does a memory operand hold a symbolic register?
 void initForArch(IR ir)
          Initialize some architecture-specific state needed for register allocation.
private  void insertBigFrameStackOverflowCheck(Instruction plg)
          Insert an explicit stack overflow check in the prologue before buying the stack frame.
private  void insertEpilogue(Instruction ret)
          Insert the epilogue before a particular return instruction.
 void insertNormalPrologue()
          Insert the prologue for a normal method.
private  void insertNormalStackOverflowCheck(Instruction plg)
          Insert an explicit stack overflow check in the prologue after buying the stack frame.
 void insertSpillBefore(Instruction s, Register r, byte type, int location)
          Insert a spill of a physical register before instruction s.
 void insertUnspillBefore(Instruction s, Register r, byte type, int location)
          Insert a load of a physical register from a spill location before instruction s.
private  boolean isScratchFreeMove(Instruction s)
          Is s a MOVE instruction that can be generated without resorting to scratch registers?
 boolean isSysCall(Instruction s)
          Is a particular instruction a system call?
private  void moveESPBefore(Instruction s, int desiredOffset)
          Before instruction s, insert code to adjust ESP so that it lies at a particular offset from its usual location.
private  boolean mutateMoveToNop(Instruction s)
          Attempt to rewrite a move instruction to a NOP.
 boolean needScratch(Register r, Instruction s)
          Given symbolic register r in instruction s, do we need to ensure that r is in a scratch register is s (as opposed to a memory operand)
 void replaceOperandWithSpillLocation(Instruction s, RegisterOperand symb)
          In instruction s, replace all appearances of a symbolic register operand with uses of the appropriate spill location, as cached by the register allocator.
private  void restoreFloatingPointState(Instruction inst)
          Insert code into the epilogue to restore the floating point state.
private  void restoreNonVolatiles(Instruction inst)
          Insert code before a return instruction to restore the nonvolatile registers.
 void restoreScratchRegistersBefore(Instruction s)
          Walk over the currently available scratch registers.
private  void restoreVolatileRegisters(Instruction inst)
          Insert code before a return instruction to restore the volatile and volatile registers.
private  void rewriteMoveInstruction(Instruction s)
          Rewrite a move instruction if it has 2 memory operands.
private  void rewriteStackLocations()
          Walk through the IR.
private  void saveFloatingPointState(Instruction inst)
          Insert code into the prologue to save the floating point state.
private  void saveNonVolatiles(Instruction inst)
          Insert code into the prologue to save any used non-volatile registers.
private  void saveVolatiles(Instruction inst)
          Insert code into the prologue to save all volatile registers.
 
Methods inherited from class org.jikesrvm.compilers.opt.regalloc.GenericStackManager
align, allocateNonVolatileRegister, allocateOnStackFrame, allocateParameterSpace, allocateSpaceForCaughtException, allocateSpaceForConversion, allocateSpaceForSysCall, allocateVolatileRegister, computeRestrictions, forceFrameAllocation, frameIsRequired, getNonvolatileFPROffset, getNonvolatileGPROffset, getOffsetForSysCall, getValueType, hasPrologueYieldpoint, insertPrologueAndEpilogue, insertSpillAfter, insertSpillCode, insertSpillCode, insertUnspillAfter, isDeadBefore, isLegal, prepare, reloadScratchRegisterBefore, setFrameRequired, unloadScratchRegisterBefore
 
Methods inherited from class org.jikesrvm.compilers.opt.ir.IRTools
A, AC, AC, CPOS, CR, D, DC, defDoublesAsUse, definedIn, F, FC, getCondMoveOp, getDefaultOperand, getLoadOp, getLoadOp, getMoveOp, getStoreOp, getStoreOp, I, IC, insertInstructionsAfter, L, LC, makeBlockOnEdge, mayBeVolatileFieldLoad, moveInstruction, moveIntoRegister, moveIntoRegister, nonPEIGC, TG, usedIn, useDoublesAsDef
 
Methods inherited from class java.lang.Object
clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait
 

Field Detail

fsaveLocation

private int fsaveLocation
A frame offset for 108 bytes of stack space to store the floating point state in the SaveVolatile protocol.


ESPOffset

private int ESPOffset
We allow the stack pointer to float from its normal position at the bottom of the frame. This field holds the 'current' offset of the SP.


FLOAT_ESP

private static boolean FLOAT_ESP
Should we allow the stack pointer to float in order to avoid scratch registers in move instructions. Note: as of Feb. 02, we think this is a bad idea.

Constructor Detail

StackManager

public StackManager()
Method Detail

getFrameFixedSize

public final int getFrameFixedSize()
Description copied from class: GenericStackManager
Return the size of the fixed portion of the stack. (in other words, the difference between the framepointer and the stackpointer after the prologue of the method completes).

Specified by:
getFrameFixedSize in class GenericStackManager
Returns:
size in bytes of the fixed portion of the stackframe

getSizeOfType

private static byte getSizeOfType(byte type)
Return the size of a type of value, in bytes. NOTE: For the purpose of register allocation, an x87 FLOAT_VALUE is 64 bits!

Parameters:
type - one of INT_VALUE, FLOAT_VALUE, or DOUBLE_VALUE

getMoveOperator

private static Operator getMoveOperator(byte type)
Return the move operator for a type of value.

Parameters:
type - one of INT_VALUE, FLOAT_VALUE, or DOUBLE_VALUE

allocateNewSpillLocation

public final int allocateNewSpillLocation(int type)
Description copied from class: GenericStackManager
Allocate a new spill location and grow the frame size to reflect the new layout.

Specified by:
allocateNewSpillLocation in class GenericStackManager
Parameters:
type - the type to spill
Returns:
the spill location

insertSpillBefore

public final void insertSpillBefore(Instruction s,
                                    Register r,
                                    byte type,
                                    int location)
Description copied from class: GenericStackManager
Insert a spill of a physical register before instruction s.

Specified by:
insertSpillBefore in class GenericStackManager
Parameters:
s - the instruction before which the spill should occur
r - the register (should be physical) to spill
type - one of INT_VALUE, FLOAT_VALUE, DOUBLE_VALUE, or CONDITION_VALUE
location - the spill location

insertUnspillBefore

public final void insertUnspillBefore(Instruction s,
                                      Register r,
                                      byte type,
                                      int location)
Description copied from class: GenericStackManager
Insert a load of a physical register from a spill location before instruction s.

Specified by:
insertUnspillBefore in class GenericStackManager
Parameters:
s - the instruction before which the spill should occur
r - the register (should be physical) to spill
type - one of INT_VALUE, FLOAT_VALUE, DOUBLE_VALUE, or CONDITION_VALUE
location - the spill location

computeNonVolatileArea

public void computeNonVolatileArea()
Description copied from class: GenericStackManager
Compute the number of stack words needed to hold nonvolatile registers. Side effects:

Specified by:
computeNonVolatileArea in class GenericStackManager

cleanUpAndInsertEpilogue

public void cleanUpAndInsertEpilogue()
Description copied from class: GenericStackManager
Clean up some junk that's left in the IR after register allocation, and add epilogue code.

Specified by:
cleanUpAndInsertEpilogue in class GenericStackManager

insertNormalStackOverflowCheck

private void insertNormalStackOverflowCheck(Instruction plg)
Insert an explicit stack overflow check in the prologue after buying the stack frame.

SIDE EFFECT: mutates the plg into a trap instruction. We need to mutate so that the trap instruction is in the GC map data structures.

Parameters:
plg - the prologue instruction

insertBigFrameStackOverflowCheck

private void insertBigFrameStackOverflowCheck(Instruction plg)
Insert an explicit stack overflow check in the prologue before buying the stack frame. SIDE EFFECT: mutates the plg into a trap instruction. We need to mutate so that the trap instruction is in the GC map data structures.

Parameters:
plg - the prologue instruction

insertNormalPrologue

public void insertNormalPrologue()
Insert the prologue for a normal method. Assume we are inserting the prologue for method B called from method A.

Specified by:
insertNormalPrologue in class GenericStackManager

saveNonVolatiles

private void saveNonVolatiles(Instruction inst)
Insert code into the prologue to save any used non-volatile registers.

Parameters:
inst - the first instruction after the prologue.

restoreNonVolatiles

private void restoreNonVolatiles(Instruction inst)
Insert code before a return instruction to restore the nonvolatile registers.

Parameters:
inst - the return instruction

saveFloatingPointState

private void saveFloatingPointState(Instruction inst)
Insert code into the prologue to save the floating point state.

Parameters:
inst - the first instruction after the prologue.

restoreFloatingPointState

private void restoreFloatingPointState(Instruction inst)
Insert code into the epilogue to restore the floating point state.

Parameters:
inst - the return instruction after the epilogue.

saveVolatiles

private void saveVolatiles(Instruction inst)
Insert code into the prologue to save all volatile registers.

Parameters:
inst - the first instruction after the prologue.

restoreVolatileRegisters

private void restoreVolatileRegisters(Instruction inst)
Insert code before a return instruction to restore the volatile and volatile registers.

Parameters:
inst - the return instruction

insertEpilogue

private void insertEpilogue(Instruction ret)
Insert the epilogue before a particular return instruction.

Parameters:
ret - the return instruction.

replaceOperandWithSpillLocation

public void replaceOperandWithSpillLocation(Instruction s,
                                            RegisterOperand symb)
Description copied from class: GenericStackManager
In instruction s, replace all appearances of a symbolic register operand with uses of the appropriate spill location, as cached by the register allocator.

Specified by:
replaceOperandWithSpillLocation in class GenericStackManager
Parameters:
s - the instruction to mutate.
symb - the symbolic register operand to replace

hasSymbolicRegister

private boolean hasSymbolicRegister(MemoryOperand M)
Does a memory operand hold a symbolic register?


isScratchFreeMove

private boolean isScratchFreeMove(Instruction s)
Is s a MOVE instruction that can be generated without resorting to scratch registers?


needScratch

public boolean needScratch(Register r,
                           Instruction s)
Description copied from class: GenericStackManager
Given symbolic register r in instruction s, do we need to ensure that r is in a scratch register is s (as opposed to a memory operand)

Specified by:
needScratch in class GenericStackManager

moveESPBefore

private void moveESPBefore(Instruction s,
                           int desiredOffset)
Before instruction s, insert code to adjust ESP so that it lies at a particular offset from its usual location.


canModifyEFLAGS

private boolean canModifyEFLAGS(Instruction s)

mutateMoveToNop

private boolean mutateMoveToNop(Instruction s)
Attempt to rewrite a move instruction to a NOP.

Returns:
true iff the transformation applies

rewriteMoveInstruction

private void rewriteMoveInstruction(Instruction s)
Rewrite a move instruction if it has 2 memory operands. One of the 2 memory operands must be a stack location operand. Move the SP to the appropriate location and use a push or pop instruction.


rewriteStackLocations

private void rewriteStackLocations()
Walk through the IR. For each StackLocationOperand, replace the operand with the appropriate MemoryOperand.


FPOffset2SPOffset

private int FPOffset2SPOffset(int fpOffset)
PRECONDITION: The final frameSize is calculated before calling this routine.

Parameters:
fpOffset - offset in bytes from the top of the stack frame
Returns:
offset in bytes from the stack pointer.

restoreScratchRegistersBefore

public void restoreScratchRegistersBefore(Instruction s)
Description copied from class: GenericStackManager
Walk over the currently available scratch registers.

For any scratch register r which is def'ed by instruction s, spill r before s and remove r from the pool of available scratch registers.

For any scratch register r which is used by instruction s, restore r before s and remove r from the pool of available scratch registers.

For any scratch register r which has current contents symb, and symb is spilled to location M, and s defs M: the old value of symb is dead. Mark this.

Invalidate any scratch register assignments that are illegal in s.

Specified by:
restoreScratchRegistersBefore in class GenericStackManager

initForArch

public void initForArch(IR ir)
Initialize some architecture-specific state needed for register allocation.

Specified by:
initForArch in class GenericStackManager

isSysCall

public boolean isSysCall(Instruction s)
Description copied from class: GenericStackManager
Is a particular instruction a system call?

Specified by:
isSysCall in class GenericStackManager