|
|||||||||||
PREV CLASS NEXT CLASS | FRAMES NO FRAMES | ||||||||||
SUMMARY: NESTED | FIELD | CONSTR | METHOD | DETAIL: FIELD | CONSTR | METHOD |
java.lang.Object org.jikesrvm.compilers.opt.bc2ir.BBSet
final class BBSet
A somewhat complex subtask of IR generation is to discover and maintain the set of basic blocks that are being generated. This class encapsulates that functionality. The backing data store is a red/black tree, but there are a number of very specialized operations that are performed during search/insertion so we roll our own instead of using one from the standard library.
Nested Class Summary | |
---|---|
private static class |
BBSet.TreeEnumerator
|
Field Summary | |
---|---|
private BytecodeStream |
bcodes
associated bytecodes |
private int[] |
endPCs
End bytecode index for each exception handler range |
private BasicBlockLE |
entry
entry block of the CFG |
private TypeOperand[] |
exceptionTypes
Type of exception handled by each exception handler range. |
private GenerationContext |
gc
associated generation context |
private int[] |
handlerPCs
Start bytecode index of each the exception handler |
private boolean |
noJSR
is it the case that we can ignore JSR processing because BC2IR has not yet generated a JSR bytecode in this method? |
private BasicBlockLE |
root
root of the backing red/black tree |
private int[] |
startPCs
Start bytecode index for each exception handler ranges |
Fields inherited from interface org.jikesrvm.compilers.opt.bc2ir.IRGenOptions |
---|
CF_CHECKCAST, CF_CHECKSTORE, CF_DOUBLECMP, CF_FLOATCMP, CF_INSTANCEOF, CF_INTIF, CF_INTIFCMP, CF_LONGCMP, CF_LOOKUPSWITCH, CF_REFIF, CF_REFIFCMP, CF_TABLESWITCH, CP_IN_LOCALS, DBG_ALL, DBG_BB, DBG_BBSET, DBG_BCPARSE, DBG_CF, DBG_CFG, DBG_ELIMCOPY, DBG_ELIMNULL, DBG_EX, DBG_FLATTEN, DBG_INLINE_JSR, DBG_INSTR, DBG_LOCAL, DBG_OPERAND_LATTICE, DBG_REGEN, DBG_STACK, DBG_TYPE, ELIM_COPY_LOCALS, LOCALS_ON_STACK, MAX_RETURN_ADDRESSES |
Constructor Summary | |
---|---|
BBSet(GenerationContext gc,
BytecodeStream bcodes,
Operand[] localState)
Initialize the BBSet to handle basic block generation for the argument generation context and bytecode info. |
Method Summary | |
---|---|
private BasicBlockLE |
_createBBLE(int bcIndex,
Operand[] simLocals,
BasicBlockLE parent,
boolean left)
Allocate a new BBLE at the given bcIndex. |
private BasicBlockLE |
condCreateAndInit(BasicBlockLE x,
boolean shouldCreate,
int target,
BasicBlockLE from,
OperandStack simStack,
Operand[] simLocals,
boolean left)
Conditionally create a block at the specified target as a child of x. |
(package private) Enumeration<BasicBlockLE> |
contents()
Return a enumeration of the BasicBlockLE's currently in the BBSet. |
private int |
countBlack(BasicBlockLE node)
|
private void |
db(String val)
Print a debug string to the sysWrite stream. |
private int |
exceptionEndRange(int bcIndex)
Given a starting bytecode index, find the greatest bcIndex that is still has the same inscope exception handlers. |
(package private) void |
finalPass(boolean inlinedSomething)
Do a final pass over the generated basic blocks to create the initial code ordering. |
private void |
fixupBBSet(BasicBlockLE x)
Performs tree fixup (restore Red/Black invariants) after adding a new node to the tree. |
(package private) BasicBlockLE |
getEntry()
return the entry BBLE |
(package private) int |
getNextBlockBytecodeIndex(BasicBlockLE x)
Gets the bytecode index of the block in the set which has the next-higher bytecode index. |
(package private) BasicBlockLE |
getNextEmptyBlock(BasicBlockLE start)
Finds the next ungenerated block, starting at the argument block and searching forward, wrapping around to the beginning. |
private BasicBlockLE |
getOrCreateBlock(BasicBlockLE x,
boolean shouldCreate,
int target,
BasicBlockLE from,
OperandStack simStack,
Operand[] simLocals)
Get or create a block at the specified target. |
(package private) BasicBlockLE |
getOrCreateBlock(int target,
BasicBlockLE from,
OperandStack simStack,
Operand[] simLocals)
Get or create a block at the specified target. |
private BasicBlockLE |
getSuccessor(BasicBlockLE x,
int value)
Returns the basic block which has the next-higher bytecode index. |
private void |
initializeExceptionHandlers(BasicBlockLE bble,
Operand[] simLocals)
Initialize bble's handlers array based on startPCs/endPCs. |
private void |
injectMove(BasicBlock block,
RegisterOperand res,
Operand val)
|
private void |
leftRotateBBSet(BasicBlockLE x)
|
private void |
markBlockForRegeneration(BasicBlockLE p)
Mark a previously generated block for regeneration. |
private boolean |
matchingJSRcontext(OperandStack simStack,
Operand[] simLocals,
BasicBlockLE candBBLE)
We specialize basic blocks with respect to the return addresses they have on their expression stack and/or in their local variables on entry to the block. |
private BasicBlockLE |
minimumBB(BasicBlockLE x,
int value)
|
private void |
parseExceptionTables()
Initialize the global exception handler arrays for the method. |
(package private) void |
rectifyLocals(Operand[] localState,
BasicBlockLE p)
Rectify the given local variable state with the local variable state stored in the given BBLE. |
(package private) void |
rectifyStacks(BasicBlock block,
OperandStack stack,
BasicBlockLE p)
Rectify the given stack state with the state contained in the given BBLE, adding the necessary move instructions to the end of the given basic block to make register numbers agree and rectify mis-matched constants. |
private void |
rightRotateBBSet(BasicBlockLE x)
|
(package private) void |
seenJSR()
Notify the BBSet that BC2IR has encountered a JSR bytecode. |
private void |
treeInsert(BasicBlockLE parent,
BasicBlockLE newBBLE,
boolean left)
Insert newBBLE as a child of parent in our Red/Black tree. |
private void |
verifyTree()
|
private void |
verifyTree(BasicBlockLE node,
int min,
int max)
|
Methods inherited from class java.lang.Object |
---|
clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait |
Field Detail |
---|
private BasicBlockLE root
private boolean noJSR
private final BasicBlockLE entry
private final GenerationContext gc
private final BytecodeStream bcodes
private int[] startPCs
private int[] endPCs
private int[] handlerPCs
private TypeOperand[] exceptionTypes
Constructor Detail |
---|
BBSet(GenerationContext gc, BytecodeStream bcodes, Operand[] localState)
gc
- the generation context to generate blocks forbcodes
- the bytecodes of said generation contextlocalState
- the state of the local variables for the block
beginning at bytecode 0.Method Detail |
---|
BasicBlockLE getEntry()
void seenJSR()
Enumeration<BasicBlockLE> contents()
int getNextBlockBytecodeIndex(BasicBlockLE x)
x
- basic block to start at.BasicBlockLE getNextEmptyBlock(BasicBlockLE start)
start
- the basic block at which to start looking.BasicBlockLE getOrCreateBlock(int target, BasicBlockLE from, OperandStack simStack, Operand[] simLocals)
target
- target indexfrom
- the block from which control is being transfered
and to which rectification instructions are added.simStack
- stack state to rectify, or nullsimLocals
- local state to rectify, or nullprivate void markBlockForRegeneration(BasicBlockLE p)
void rectifyStacks(BasicBlock block, OperandStack stack, BasicBlockLE p)
block
- basic block to append move instructions tostack
- stack to copyp
- BBLE to copy stack state intoprivate void injectMove(BasicBlock block, RegisterOperand res, Operand val)
void rectifyLocals(Operand[] localState, BasicBlockLE p)
localState
- local variable state to rectifyp
- target BBLE to rectify state tovoid finalPass(boolean inlinedSomething)
NOTE: Only some CFG edges are created here..... we're mainly just patching together a code linearization.
private void db(String val)
val
- string to printprivate void parseExceptionTables()
private void initializeExceptionHandlers(BasicBlockLE bble, Operand[] simLocals)
PRECONDITION: bble.low and bble.max have already been correctly set to reflect the invariant that a basic block is in exactly one "handler range."
Also initializes bble.block.exceptionHandlers.
private int exceptionEndRange(int bcIndex)
bcIndex
- the start bytecode indexprivate boolean matchingJSRcontext(OperandStack simStack, Operand[] simLocals, BasicBlockLE candBBLE)
The main motivation for inlining away all JSR's is that it eliminates the "JSR problem" for type accurate GC. It is also simpler to implement and arguably results in more efficient generated code (assuming that we don't get horrific code bloat). To deal with the code bloat, we detect excessive code duplication and stop IR generation (bail out to the baseline compiler).
simStack
- The expression stack to matchsimLocals
- The local variables to matchcandBBLE
- The candidate BaseicBlockLEprivate BasicBlockLE getOrCreateBlock(BasicBlockLE x, boolean shouldCreate, int target, BasicBlockLE from, OperandStack simStack, Operand[] simLocals)
x
- starting node for search.shouldCreate
- should we create the block if we run off the tree?target
- target indexfrom
- the block from which control is being transfered
and to which rectification instructions are added.simStack
- stack state to rectify, or null
simLocals
- local state to rectify, or null
private BasicBlockLE condCreateAndInit(BasicBlockLE x, boolean shouldCreate, int target, BasicBlockLE from, OperandStack simStack, Operand[] simLocals, boolean left)
null
, rectifies stack state with target stack state.
If simLocals is non-null
, rectifies local state with target local state.
Any instructions needed to rectify stack/local state are appended to
from.
x
- starting node for search.shouldCreate
- should we create the block if we run off the tree?target
- target indexfrom
- the block from which control is being transfered
and to which rectification instructions are added.simStack
- stack state to rectify, or null
simLocals
- local state to rectify, or null
left
- are we creating a left child of parent?
null
if !shouldCreateprivate BasicBlockLE _createBBLE(int bcIndex, Operand[] simLocals, BasicBlockLE parent, boolean left)
bcIndex
- the bytecode index at which the block should be created.simLocals
- the localState to pass (via initializeExceptionHandler)to
to getOrCreateBlock if we need to create BBLEs for
exception handlers. This is only actually used if
!noJSR. We don't need the expression stack, since
the only thing on the expression stack on entry to
a handler block is the exception object (and thus
we can skip scanning the expression stack for
return addresses when creating a handler block).parent
- parent in Red/Black treeleft
- are we creating a left child of parent?private BasicBlockLE getSuccessor(BasicBlockLE x, int value)
null
if x is the highest block.
x
- basic block at which to start the search for a higher blockvalue
- the contents of x.low (makes tail call elim work better
if we avoid the obvious 1 argument wrapper function)private BasicBlockLE minimumBB(BasicBlockLE x, int value)
private void treeInsert(BasicBlockLE parent, BasicBlockLE newBBLE, boolean left)
newBBLE
as a child of parent in our Red/Black tree.
parent
- the parent nodenewBBLE
- the new child nodeleft
- is the child the left or right child of parent?private void fixupBBSet(BasicBlockLE x)
x
- node that was added.private void leftRotateBBSet(BasicBlockLE x)
private void rightRotateBBSet(BasicBlockLE x)
private void verifyTree()
private void verifyTree(BasicBlockLE node, int min, int max)
private int countBlack(BasicBlockLE node)
|
|||||||||||
PREV CLASS NEXT CLASS | FRAMES NO FRAMES | ||||||||||
SUMMARY: NESTED | FIELD | CONSTR | METHOD | DETAIL: FIELD | CONSTR | METHOD |