|
|||||||||||
PREV CLASS NEXT CLASS | FRAMES NO FRAMES | ||||||||||
SUMMARY: NESTED | FIELD | CONSTR | METHOD | DETAIL: FIELD | CONSTR | METHOD |
java.lang.Object org.jikesrvm.compilers.opt.ir.IRTools org.jikesrvm.compilers.opt.regalloc.GenericStackManager
public abstract class GenericStackManager
Class to manage the allocation of the "compiler-independent" portion of the stackframe.
Nested Class Summary | |
---|---|
protected static class |
GenericStackManager.ScratchRegister
Class to represent a physical register currently allocated as a scratch register. |
Field Summary | |
---|---|
private LinearScan.ActiveSet |
activeSet
We may rely on information from linear scan to choose scratch registers. |
protected boolean |
allocFrame
|
private int |
caughtExceptionOffset
Memory location (4 bytes) to be used for caughtExceptions |
private int |
conversionOffset
Memory location (8 bytes) to be used for type conversions |
protected static boolean |
DEBUG
|
private boolean |
frameRequired
Have we decided that a stack frame is required for this method? |
protected int |
frameSize
|
protected IR |
ir
|
protected int[] |
nonVolatileFPRLocation
|
protected int[] |
nonVolatileGPRLocation
An array which holds the spill location number used to stash nonvolatile registers. |
protected ArchitectureSpecificOpt.RegisterPreferences |
pref
Object holding register preferences |
private boolean |
prologueYieldpoint
Is there a prologue yieldpoint in this method? |
protected ArchitectureSpecificOpt.RegisterRestrictions |
restrict
Object holding register restrictions |
protected int[] |
saveVolatileFPRLocation
|
protected int[] |
saveVolatileGPRLocation
An array which holds the spill location number used to stash volatile registers in the SaveVolatile protocol. |
protected ArrayList<GenericStackManager.ScratchRegister> |
scratchInUse
For each physical register, holds a ScratchRegister which records the current scratch assignment for the physical register. |
protected ScratchMap |
scratchMap
An object used to track adjustments to the GC maps induced by scratch registers |
protected int |
spillPointer
Spill pointer (in bytes) relative to the beginning of the stack frame (starts after the header). |
private int |
sysCallOffset
We will have to save and restore all non-volatile registers around system calls, to protect ourselve from malicious native code that may bash these registers. |
private static boolean |
USE_LINEAR_SCAN
Should we use information from linear scan in choosing scratch registers? |
protected static boolean |
VERBOSE
|
protected static boolean |
VERBOSE_DEBUG
|
protected static int |
WORDSIZE
Size of a word, in bytes |
Constructor Summary | |
---|---|
GenericStackManager()
|
Method Summary | |
---|---|
protected static int |
align(int number,
int alignment)
|
abstract int |
allocateNewSpillLocation(int type)
Allocate a new spill location and grow the frame size to reflect the new layout. |
Register |
allocateNonVolatileRegister(Register symbReg)
Find a nonvolatile register to allocate starting at the reg corresponding to the symbolic register passed TODO: Clean up this interface. |
int |
allocateOnStackFrame(int size)
Allocate the specified number of bytes in the stackframe, returning the offset to the start of the allocated space. |
void |
allocateParameterSpace(int s)
Ensure param passing area of size - STACKFRAME_HEADER_SIZE bytes |
int |
allocateSpaceForCaughtException()
We encountered a catch block that actually uses its caught exception object; allocate a stack slot for the exception delivery code to use to pass the exception object to us. |
int |
allocateSpaceForConversion()
We encountered a float/int conversion that uses the stack as temporary storage. |
int |
allocateSpaceForSysCall(int n)
We will have to save and restore all non-volatile registers around system calls, to protect ourselves from malicious native code that may bash these registers. |
Register |
allocateVolatileRegister(Register symbReg)
Find an volatile register to allocate starting at the reg corresponding to the symbolic register passed |
private boolean |
appearsIn(Register r,
Instruction s)
Does register r appear in instruction s? |
abstract void |
cleanUpAndInsertEpilogue()
Clean up some junk that's left in the IR after register allocation, and add epilogue code. |
abstract void |
computeNonVolatileArea()
Compute the number of stack words needed to hold nonvolatile registers. |
void |
computeRestrictions(IR ir)
Set up register restrictions |
private GenericStackManager.ScratchRegister |
createScratchBefore(Instruction s,
Register r,
Register symb)
Make physical register r available to be used as a scratch register before instruction s. |
private boolean |
definesSpillLocation(int loc,
Instruction s)
Does instruction s define spill location loc? |
private boolean |
definesSpillLocation(Register r,
Instruction s)
Does instruction s define the spill location for a given register? |
void |
forceFrameAllocation()
We encountered a magic (get/set framepointer) that is going to force us to acutally create the stack frame. |
protected boolean |
frameIsRequired()
Are we required to allocate a stack frame for this method? |
private GenericStackManager.ScratchRegister |
getCurrentScratchRegister(Register r,
Instruction s)
If there is a scratch register available which currently holds the value of symbolic register r, then return that scratch register. |
private GenericStackManager.ScratchRegister |
getFirstAvailableScratchRegister(Register r,
Instruction s)
Find the first available register which can serve as a scratch register for symbolic register r in instruction s. |
private Register |
getFirstDeadFPRNotUsedIn(Register r,
Instruction s,
ArrayList<Register> reserved)
Return a FPR that does not appear in instruction s, and is dead before instruction s, to hold symbolic register r. |
private Register |
getFirstDeadGPRNotUsedIn(Register r,
Instruction s,
ArrayList<Register> reserved)
Return a GPR that does not appear in instruction s, and is dead before instruction s, to hold symbolic register r. |
private Register |
getFirstFPRNotUsedIn(Register r,
Instruction s,
ArrayList<Register> reserved)
Return a FPR that does not appear in instruction s, to be used as a scratch register to hold register r. |
private Register |
getFirstGPRNotUsedIn(Register r,
Instruction s,
ArrayList<Register> reserved)
Return a GPR that does not appear in instruction s, to hold symbolic register r. |
abstract int |
getFrameFixedSize()
Return the size of the fixed portion of the stack. |
protected int |
getNonvolatileFPROffset(int n)
Return the offset from the frame pointer for the place to store the nth nonvolatile FPR. |
protected int |
getNonvolatileGPROffset(int n)
Return the offset from the frame pointer for the place to store the nth nonvolatile GPR. |
int |
getOffsetForSysCall()
We will have to save and restore all non-volatile registers around system calls, to protect ourselves from malicious native code that may bash these registers. |
private GenericStackManager.ScratchRegister |
getPhysicalScratchRegister(Register r)
If register r is currently in use as a scratch register, then return that scratch register. |
(package private) ArchitectureSpecificOpt.RegisterPreferences |
getPreferences()
|
private ArrayList<Register> |
getReservedScratchRegisters(Instruction s)
Return the set of scratch registers which are currently reserved for use in instruction s. |
(package private) ArchitectureSpecificOpt.RegisterRestrictions |
getRestrictions()
|
(package private) ScratchMap |
getScratchMap()
|
private GenericStackManager.ScratchRegister |
getScratchRegister(Register symb,
Instruction s,
boolean beCheap)
Get a scratch register to hold symbolic register symb in instruction s. |
private GenericStackManager.ScratchRegister |
getScratchRegisterUsingIntervals(Register r,
Instruction s)
Find a register which can serve as a scratch register for symbolic register r in instruction s. |
byte |
getValueType(Register r)
Given a symbolic register, return a code that indicates the type of the value stored in the register. |
protected boolean |
hasPrologueYieldpoint()
Does this IR have a prologue yieldpoint? |
private GenericStackManager.ScratchRegister |
holdInScratchAfter(Instruction s,
Register symb,
boolean beCheap)
Insert code as needed so that after instruction s, the value of a symbolic register will be held in a particular scratch physical register. |
abstract void |
initForArch(IR ir)
Perform some architecture-specific initialization. |
abstract void |
insertNormalPrologue()
Insert the prologue for a normal method. |
private void |
insertPrologue()
Insert the prologue. |
void |
insertPrologueAndEpilogue()
PROLOGUE/EPILOGUE. must be done after register allocation |
void |
insertSpillAfter(Instruction s,
Register r,
byte type,
int location)
Insert a spill of a physical register after instruction s. |
abstract void |
insertSpillBefore(Instruction s,
Register r,
byte type,
int location)
Insert a spill of a physical register before instruction s. |
void |
insertSpillCode()
After register allocation, go back through the IR and insert compensating code to deal with spills. |
void |
insertSpillCode(LinearScan.ActiveSet set)
After register allocation, go back through the IR and insert compensating code to deal with spills. |
void |
insertUnspillAfter(Instruction s,
Register r,
byte type,
int location)
Insert a load of a physical register from a spill location before instruction s. |
abstract void |
insertUnspillBefore(Instruction s,
Register r,
byte type,
int location)
Insert a load of a physical register from a spill location before instruction s. |
boolean |
isDeadBefore(Register r,
Instruction s)
Is a particular register dead immediately before instruction s. |
protected boolean |
isLegal(Register symb,
Register phys,
Instruction s)
Is it legal to assign symbolic register symb to scratch register phys in instruction s? |
private boolean |
isPEIWithCatch(Instruction s)
Is s a PEI with a reachable catch block? |
abstract boolean |
isSysCall(Instruction s)
Is a particular instruction a system call? |
private void |
markDirtyScratchRegisters(Instruction s)
Walk over the currently available scratch registers. |
private GenericStackManager.ScratchRegister |
moveToScratchBefore(Instruction s,
Register symb,
boolean beCheap)
Assign symbolic register symb to a physical register, and insert code before instruction s to load the register from the appropriate stack location. |
abstract 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 |
prepare(IR ir)
Called as part of the register allocator startup |
protected void |
reloadScratchRegisterBefore(Instruction s,
GenericStackManager.ScratchRegister scratch)
Restore the contents of a scratch register before instruction s. |
abstract 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 |
replaceRegisterWithScratch(Instruction s,
Register r1,
Register r2)
Replace all occurrences of register r1 in an instruction with register r2. |
private void |
restoreAllScratchRegistersBefore(Instruction s)
Walk over the currently available scratch registers, and spill their contents to memory before instruction s. |
abstract void |
restoreScratchRegistersBefore(Instruction s)
Walk over the currently available scratch registers. |
protected void |
setFrameRequired()
Record that we need a stack frame for this method. |
private Register |
spillLocationUse(int loc,
Instruction s)
Assuming instruction s uses the spill location loc, return the symbolic register that embodies that use. |
private Register |
spillLocationUse(Register r,
Instruction s)
Assuming instruction s uses the spill location for a given register, return the symbolic register that embodies that use. |
protected void |
unloadScratchRegisterBefore(Instruction s,
GenericStackManager.ScratchRegister scratch)
Spill the contents of a scratch register to memory before instruction s. |
private boolean |
usesSpillLocation(int loc,
Instruction s)
Does instruction s use spill location loc? |
private boolean |
usesSpillLocation(Register r,
Instruction s)
Does instruction s use the spill location for a given register? |
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 |
---|
protected static final boolean DEBUG
protected static final boolean VERBOSE
protected static final boolean VERBOSE_DEBUG
protected static final int WORDSIZE
protected IR ir
protected int frameSize
protected boolean allocFrame
protected final ArchitectureSpecificOpt.RegisterPreferences pref
protected ArchitectureSpecificOpt.RegisterRestrictions restrict
protected int spillPointer
private boolean frameRequired
private int conversionOffset
private int caughtExceptionOffset
private boolean prologueYieldpoint
private int sysCallOffset
protected final ArrayList<GenericStackManager.ScratchRegister> scratchInUse
protected final int[] nonVolatileGPRLocation
protected final int[] nonVolatileFPRLocation
protected final int[] saveVolatileGPRLocation
protected final int[] saveVolatileFPRLocation
protected final ScratchMap scratchMap
private static boolean USE_LINEAR_SCAN
private LinearScan.ActiveSet activeSet
Constructor Detail |
---|
public GenericStackManager()
Method Detail |
---|
ArchitectureSpecificOpt.RegisterPreferences getPreferences()
ArchitectureSpecificOpt.RegisterRestrictions getRestrictions()
ScratchMap getScratchMap()
public abstract void initForArch(IR ir)
public abstract boolean isSysCall(Instruction s)
public abstract boolean needScratch(Register r, Instruction s)
public abstract int allocateNewSpillLocation(int type)
type
- the type to spill
public abstract void cleanUpAndInsertEpilogue()
public abstract int getFrameFixedSize()
public abstract void computeNonVolatileArea()
frameSize
field of this object
frameRequired
field of this object
public abstract void insertNormalPrologue()
public abstract void restoreScratchRegistersBefore(Instruction s)
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.
public abstract void replaceOperandWithSpillLocation(Instruction s, RegisterOperand symb)
s
- the instruction to mutate.symb
- the symbolic register operand to replaceprivate void replaceRegisterWithScratch(Instruction s, Register r1, Register r2)
public int allocateSpaceForSysCall(int n)
n
- the number of GPR registers to save and restore.
public int getOffsetForSysCall()
protected void unloadScratchRegisterBefore(Instruction s, GenericStackManager.ScratchRegister scratch)
protected void reloadScratchRegisterBefore(Instruction s, GenericStackManager.ScratchRegister scratch)
private ArrayList<Register> getReservedScratchRegisters(Instruction s)
private GenericStackManager.ScratchRegister getCurrentScratchRegister(Register r, Instruction s)
Additionally, if there is a scratch register available which is mapped to the same stack location as r, then return that scratch register.
Else return null
.
r
- the symbolic register to holds
- the instruction for which we need r in a registerprivate GenericStackManager.ScratchRegister getPhysicalScratchRegister(Register r)
Else return null
.
private void markDirtyScratchRegisters(Instruction s)
For any register which is dirty, note this in the scratch map for instruction s.
private void restoreAllScratchRegistersBefore(Instruction s)
SPECIAL CASE: If s is a return instruction, only restore the scratch registers that are used by s. The others are dead.
public boolean isDeadBefore(Register r, Instruction s)
private GenericStackManager.ScratchRegister holdInScratchAfter(Instruction s, Register symb, boolean beCheap)
beCheap
- don't expend much effort optimizing scratch
assignments
protected boolean isLegal(Register symb, Register phys, Instruction s)
private GenericStackManager.ScratchRegister getScratchRegister(Register symb, Instruction s, boolean beCheap)
beCheap
- don't expend too much effortprivate GenericStackManager.ScratchRegister getScratchRegisterUsingIntervals(Register r, Instruction s)
Insert spills if necessary to ensure that the returned scratch register is free for use.
private GenericStackManager.ScratchRegister getFirstAvailableScratchRegister(Register r, Instruction s)
Insert spills if necessary to ensure that the returned scratch register is free for use.
private GenericStackManager.ScratchRegister moveToScratchBefore(Instruction s, Register symb, boolean beCheap)
beCheap
- don't expend to much effort to optimize scratch
assignments
private GenericStackManager.ScratchRegister createScratchBefore(Instruction s, Register r, Register symb)
private boolean usesSpillLocation(Register r, Instruction s)
private Register spillLocationUse(Register r, Instruction s)
private boolean definesSpillLocation(Register r, Instruction s)
private boolean definesSpillLocation(int loc, Instruction s)
private boolean usesSpillLocation(int loc, Instruction s)
private Register spillLocationUse(int loc, Instruction s)
Note that at most one such register can be used, since at most one live register can use a given spill location.
private Register getFirstFPRNotUsedIn(Register r, Instruction s, ArrayList<Register> reserved)
Throw an exception if none found.
private Register getFirstDeadFPRNotUsedIn(Register r, Instruction s, ArrayList<Register> reserved)
Return null
if none found
private Register getFirstGPRNotUsedIn(Register r, Instruction s, ArrayList<Register> reserved)
private Register getFirstDeadGPRNotUsedIn(Register r, Instruction s, ArrayList<Register> reserved)
return null
if none found.
private boolean appearsIn(Register r, Instruction s)
private boolean isPEIWithCatch(Instruction s)
protected int getNonvolatileGPROffset(int n)
protected int getNonvolatileFPROffset(int n)
public final void insertPrologueAndEpilogue()
private void insertPrologue()
public void insertSpillCode()
public void insertSpillCode(LinearScan.ActiveSet set)
set
- information from linear scan analysispublic abstract void insertSpillBefore(Instruction s, Register r, byte type, int location)
s
- the instruction before which the spill should occurr
- the register (should be physical) to spilltype
- one of INT_VALUE, FLOAT_VALUE, DOUBLE_VALUE, or
CONDITION_VALUElocation
- the spill locationpublic final void insertSpillAfter(Instruction s, Register r, byte type, int location)
s
- the instruction after which the spill should occurr
- the register (should be physical) to spilltype
- one of INT_VALUE, FLOAT_VALUE, DOUBLE_VALUE, or
CONDITION_VALUElocation
- the spill locationpublic abstract void insertUnspillBefore(Instruction s, Register r, byte type, int location)
s
- the instruction before which the spill should occurr
- the register (should be physical) to spilltype
- one of INT_VALUE, FLOAT_VALUE, DOUBLE_VALUE, or
CONDITION_VALUElocation
- the spill locationpublic final void insertUnspillAfter(Instruction s, Register r, byte type, int location)
s
- the instruction before which the spill should occurr
- the register (should be physical) to spilltype
- one of INT_VALUE, FLOAT_VALUE, DOUBLE_VALUE, or
CONDITION_VALUElocation
- the spill locationprotected boolean frameIsRequired()
protected void setFrameRequired()
protected boolean hasPrologueYieldpoint()
public void allocateParameterSpace(int s)
public int allocateOnStackFrame(int size)
size
- the number of bytes to allocate
public void forceFrameAllocation()
public int allocateSpaceForConversion()
public int allocateSpaceForCaughtException()
public void prepare(IR ir)
ir
- the IRpublic final void computeRestrictions(IR ir)
public final Register allocateVolatileRegister(Register symbReg)
symbReg
- the place to start the search
public final byte getValueType(Register r)
protected static int align(int number, int alignment)
public final Register allocateNonVolatileRegister(Register symbReg)
symbReg
- the place to start the search
|
|||||||||||
PREV CLASS NEXT CLASS | FRAMES NO FRAMES | ||||||||||
SUMMARY: NESTED | FIELD | CONSTR | METHOD | DETAIL: FIELD | CONSTR | METHOD |