Top Description Inners Fields Constructors Methods
org.droidparts.dexmaker.dx.ssa

public final Class SsaBasicBlock

extends Object
Class Inheritance
Imports
org.droidparts.dexmaker.dx.rop.code.*, org.droidparts.dexmaker.dx.util.Hex, .IntList, .IntSet, java.util.*

An SSA representation of a basic block.

Nested and Inner Type Summary

Modifier and TypeClass and Description
public static class
public static interface
SsaBasicBlock.Visitor

Visitor interface for basic blocks.

Field Summary

Modifier and TypeField and Description
private final ArrayList<SsaBasicBlock>
domChildren

list of dom children

private int
index

our index into parent.getBlock()

private ArrayList<SsaInsn>
insns

non-null; insn list associated with this instance

public static final Comparator<SsaBasicBlock>
LABEL_COMPARATOR

non-null; comparator for instances of this class that just compares block labels

private IntSet
liveIn

null-ok; indexed by reg: the regs that are live-in at this block

private IntSet
liveOut

null-ok; indexed by reg: the regs that are live-out at this block

private int
movesFromPhisAtBeginning

the number of moves added to the beginning of the block during the phi-removal process.

private int
movesFromPhisAtEnd

the number of moves added to the end of the block during the phi-removal process.

private SsaMethod
parent

non-null; method we belong to

private BitSet
predecessors

non-null; predecessor set (by block list index)

private int
primarySuccessor

block list index of primary successor, or -1 for no primary successor

private int
reachable

contains last computed value of reachability of this block, or -1 if reachability hasn't been calculated yet

private int
ropLabel

label of block in rop form

private IntList
successorList

non-null; ordered successor list (same block may be listed more than once)

private BitSet
successors

non-null; successor set (by block list index)

Constructor Summary

AccessConstructor and Description
public
SsaBasicBlock(final int
index this block will have
basicBlockIndex
,
final int
original rop-form label
ropLabel
,
final SsaMethod
method of this block
parent
)

Creates a new empty basic block.

Method Summary

Modifier and TypeMethod and Description
public void
addDomChild(SsaBasicBlock
non-null; new dom child
child
)

Adds a basic block as a dom child for this block.

public void
addInsnToHead(Insn
non-null; rop-form insn to add
insn
)

Adds an insn to the head of this basic block, just after any phi insns.

public void
addLiveIn(int
register that is live-in for this block.
regV
)

Adds regV to the live-in list for this block.

public void
addLiveOut(int
register that is live-out for this block.
regV
)

Adds regV to the live-out list for this block.

public void
addMoveToBeginning(RegisterSpec
move destination
result
,
RegisterSpec
move source
source
)

Adds a move instruction after the phi insn block.

public void
addMoveToEnd(RegisterSpec
move destination
result
,
RegisterSpec
move source
source
)

Adds a move instruction to the end of this basic block, just before the last instruction.

public void
addPhiInsnForReg(int
>=0; result reg
reg
)

Adds a phi insn to the beginning of this block.

public void
addPhiInsnForReg(RegisterSpec
non-null; reg
resultSpec
)

Adds a phi insn to the beginning of this block.

private static boolean

Returns:

true if register is fully or partially (for the case of wide registers) used.
checkRegUsed
(BitSet
set, indexed by register number
regsUsed
,
RegisterSpec
register to mark as used
rs
)

Checks to see if the register is used in a bitset, taking into account its category/width.

public void
exitBlockFixup(SsaBasicBlock
non-null; exit block
exitBlock
)

Attaches block to an exit block if necessary.

public void
forEachInsn(SsaInsn.Visitor
non-null; callback interface
visitor
)

Visits all insns in this block.

public void
forEachPhiInsn(PhiInsn.Visitor
non-null; the callback
v
)

Visits each phi insn.

private int

Returns:

count of phi insns
getCountPhiInsns
()

Gets the number of phi insns at the top of this basic block.

public ArrayList<SsaBasicBlock>

Returns:

non-null; list of dom children
getDomChildren
()

Gets the dom children for this node.

public int

Returns:

the block index of this block
getIndex
()

public ArrayList<SsaInsn>

Returns:

non-null; the (mutable) instruction list for this block, with phi insns at the beginning
getInsns
()

public IntSet

Returns:

non-null; live-in register set.
getLiveInRegs
()

Returns the set of live-in registers.

public IntSet

Returns:

non-null; live-out register set
getLiveOutRegs
()

Returns the set of live-out registers.

public SsaMethod

Returns:

non-null; method that contains this block
getParent
()

public List<SsaInsn>

Returns:

non-null; the (mutable) list of phi insns for this block
getPhiInsns
()

public BitSet

Returns:

non-null; predecessors set, indexed by block index
getPredecessors
()

public SsaBasicBlock

Returns:

null-ok; the primary successor block or null if there is none
getPrimarySuccessor
()

public int

Returns:

>= -1; block index of primary successor or -1 if no primary successor
getPrimarySuccessorIndex
()

public int

Returns:

rop label of primary successor
getPrimarySuccessorRopLabel
()

public int

Returns:

the label of this block in rop form
getRopLabel
()

public String

Returns:

the label of this block in rop form as a hex string
getRopLabelString
()

public IntList

Returns:

successor list of rop labels
getRopLabelSuccessorList
()

public IntList

Returns:

non-null; ordered successor list, containing block indicies
getSuccessorList
()

public BitSet

Returns:

non-null; successors set, indexed by block index
getSuccessors
()

public SsaBasicBlock

Returns:

non-null; an appropriately-constructed instance
insertNewPredecessor
()

Inserts a new empty GOTO block as a predecessor to this block.

public SsaBasicBlock

Returns:

non-null; an appropriately-constructed instance
insertNewSuccessor
(SsaBasicBlock
current successor (B)
other
)

Constructs and inserts a new empty GOTO block Z between this block (A) and a current successor block (B).

public boolean

Returns:

true if this is the one-and-only exit block for this method
isExitBlock
()

public boolean

Returns:

true if reachable
isReachable
()

Returns true if this block was last calculated to be reachable.

public static SsaBasicBlock

Returns:

new instance
newFromRop
(RopMethod
original method
rmeth
,
int
index this block will have
basicBlockIndex
,
final SsaMethod
method of this block predecessor set will be updated
parent
)

Creates a new SSA basic block from a ROP form basic block.

public void
removeAllPhiInsns()

Deletes all phi insns.

public void
removeSuccessor(int
index of successor block to remove
oldIndex
)

Removes a successor from this block's successor list.

public void
replaceLastInsn(Insn
non-null; rop-form insn to add, which must branch.
insn
)

Replaces the last insn in this block.

public void
replaceSuccessor(int
index of old successor block
oldIndex
,
int
index of new successor block
newIndex
)

Replaces an old successor with a new successor.

public void
scheduleMovesFromPhis()

Sorts move instructions added via addMoveToEnd during phi removal so that results don't overwrite sources that are used.

private void
scheduleUseBeforeAssigned(List<SsaInsn>
List of instructions. Must consist only of moves.
toSchedule
)

Ensures that all move operations in this block occur such that reads of any register happen before writes to that register.

public void
setReachable(int
new value of reachability for block
reach
)

Sets reachability of block to specified value

private static void
setRegsUsed(BitSet
set, indexed by register number
regsUsed
,
RegisterSpec
register to mark as used
rs
)

Sets the register as used in a bitset, taking into account its category/width.

public String
toString()

Overrides java.lang.Object.toString.

Returns a string representation of the object.
Inherited from java.lang.Object:
cloneequalsfinalizegetClasshashCodenotifynotifyAllwaitwaitwait

Field Detail

domChildrenback to summary
private final ArrayList<SsaBasicBlock> domChildren

list of dom children

indexback to summary
private int index

our index into parent.getBlock()

insnsback to summary
private ArrayList<SsaInsn> insns

non-null; insn list associated with this instance

LABEL_COMPARATORback to summary
public static final Comparator<SsaBasicBlock> LABEL_COMPARATOR

non-null; comparator for instances of this class that just compares block labels

liveInback to summary
private IntSet liveIn

null-ok; indexed by reg: the regs that are live-in at this block

liveOutback to summary
private IntSet liveOut

null-ok; indexed by reg: the regs that are live-out at this block

movesFromPhisAtBeginningback to summary
private int movesFromPhisAtBeginning

the number of moves added to the beginning of the block during the phi-removal process. Retained for subsequent move scheduling.

movesFromPhisAtEndback to summary
private int movesFromPhisAtEnd

the number of moves added to the end of the block during the phi-removal process. Retained for subsequent move scheduling.

parentback to summary
private SsaMethod parent

non-null; method we belong to

predecessorsback to summary
private BitSet predecessors

non-null; predecessor set (by block list index)

primarySuccessorback to summary
private int primarySuccessor

block list index of primary successor, or -1 for no primary successor

reachableback to summary
private int reachable

contains last computed value of reachability of this block, or -1 if reachability hasn't been calculated yet

ropLabelback to summary
private int ropLabel

label of block in rop form

successorListback to summary
private IntList successorList

non-null; ordered successor list (same block may be listed more than once)

successorsback to summary
private BitSet successors

non-null; successor set (by block list index)

Constructor Detail

SsaBasicBlockback to summary
public SsaBasicBlock(final int basicBlockIndex, final int ropLabel, final SsaMethod parent)

Creates a new empty basic block.

Parameters
basicBlockIndex:int

index this block will have

ropLabel:int

original rop-form label

parent:SsaMethod

method of this block

Method Detail

addDomChildback to summary
public void addDomChild(SsaBasicBlock child)

Adds a basic block as a dom child for this block. Used when constructing the dom tree.

Parameters
child:SsaBasicBlock

non-null; new dom child

addInsnToHeadback to summary
public void addInsnToHead(Insn insn)

Adds an insn to the head of this basic block, just after any phi insns.

Parameters
insn:Insn

non-null; rop-form insn to add

addLiveInback to summary
public void addLiveIn(int regV)

Adds regV to the live-in list for this block. This is called by the liveness analyzer.

Parameters
regV:int

register that is live-in for this block.

addLiveOutback to summary
public void addLiveOut(int regV)

Adds regV to the live-out list for this block. This is called by the liveness analyzer.

Parameters
regV:int

register that is live-out for this block.

addMoveToBeginningback to summary
public void addMoveToBeginning(RegisterSpec result, RegisterSpec source)

Adds a move instruction after the phi insn block.

Parameters
result:RegisterSpec

move destination

source:RegisterSpec

move source

addMoveToEndback to summary
public void addMoveToEnd(RegisterSpec result, RegisterSpec source)

Adds a move instruction to the end of this basic block, just before the last instruction. If the result of the final instruction is the source in question, then the move is placed at the beginning of the primary successor block. This is for unversioned registers.

Parameters
result:RegisterSpec

move destination

source:RegisterSpec

move source

addPhiInsnForRegback to summary
public void addPhiInsnForReg(int reg)

Adds a phi insn to the beginning of this block. The result type of the phi will be set to void, to indicate that it's currently unknown.

Parameters
reg:int

>=0; result reg

addPhiInsnForRegback to summary
public void addPhiInsnForReg(RegisterSpec resultSpec)

Adds a phi insn to the beginning of this block. This is to be used when the result type or local-association can be determined at phi insert time.

Parameters
resultSpec:RegisterSpec

non-null; reg

checkRegUsedback to summary
private static boolean checkRegUsed(BitSet regsUsed, RegisterSpec rs)

Checks to see if the register is used in a bitset, taking into account its category/width.

Parameters
regsUsed:BitSet

set, indexed by register number

rs:RegisterSpec

register to mark as used

Returns:boolean

true if register is fully or partially (for the case of wide registers) used.

exitBlockFixupback to summary
public void exitBlockFixup(SsaBasicBlock exitBlock)

Attaches block to an exit block if necessary. If this block is not an exit predecessor or is the exit block, this block does nothing. For use by org.droidparts.dexmaker.dx.ssa.SsaMethod#makeExitBlock

Parameters
exitBlock:SsaBasicBlock

non-null; exit block

forEachInsnback to summary
public void forEachInsn(SsaInsn.Visitor visitor)

Visits all insns in this block.

Parameters
visitor:SsaInsn.Visitor

non-null; callback interface

forEachPhiInsnback to summary
public void forEachPhiInsn(PhiInsn.Visitor v)

Visits each phi insn.

Parameters
v:PhiInsn.Visitor

non-null; the callback

getCountPhiInsnsback to summary
private int getCountPhiInsns()

Gets the number of phi insns at the top of this basic block.

Returns:int

count of phi insns

getDomChildrenback to summary
public ArrayList<SsaBasicBlock> getDomChildren()

Gets the dom children for this node. Don't modify this list.

Returns:ArrayList<SsaBasicBlock>

non-null; list of dom children

getIndexback to summary
public int getIndex()
Returns:int

the block index of this block

getInsnsback to summary
public ArrayList<SsaInsn> getInsns()
Returns:ArrayList<SsaInsn>

non-null; the (mutable) instruction list for this block, with phi insns at the beginning

getLiveInRegsback to summary
public IntSet getLiveInRegs()

Returns the set of live-in registers. Valid after register interference graph has been generated, otherwise empty.

Returns:IntSet

non-null; live-in register set.

getLiveOutRegsback to summary
public IntSet getLiveOutRegs()

Returns the set of live-out registers. Valid after register interference graph has been generated, otherwise empty.

Returns:IntSet

non-null; live-out register set

getParentback to summary
public SsaMethod getParent()
Returns:SsaMethod

non-null; method that contains this block

getPhiInsnsback to summary
public List<SsaInsn> getPhiInsns()
Returns:List<SsaInsn>

non-null; the (mutable) list of phi insns for this block

getPredecessorsback to summary
public BitSet getPredecessors()
Returns:BitSet

non-null; predecessors set, indexed by block index

getPrimarySuccessorback to summary
public SsaBasicBlock getPrimarySuccessor()
Returns:SsaBasicBlock

null-ok; the primary successor block or null if there is none

getPrimarySuccessorIndexback to summary
public int getPrimarySuccessorIndex()
Returns:int

>= -1; block index of primary successor or -1 if no primary successor

getPrimarySuccessorRopLabelback to summary
public int getPrimarySuccessorRopLabel()
Returns:int

rop label of primary successor

getRopLabelback to summary
public int getRopLabel()
Returns:int

the label of this block in rop form

getRopLabelStringback to summary
public String getRopLabelString()
Returns:String

the label of this block in rop form as a hex string

getRopLabelSuccessorListback to summary
public IntList getRopLabelSuccessorList()
Returns:IntList

successor list of rop labels

getSuccessorListback to summary
public IntList getSuccessorList()
Returns:IntList

non-null; ordered successor list, containing block indicies

getSuccessorsback to summary
public BitSet getSuccessors()
Returns:BitSet

non-null; successors set, indexed by block index

insertNewPredecessorback to summary
public SsaBasicBlock insertNewPredecessor()

Inserts a new empty GOTO block as a predecessor to this block. All previous predecessors will be predecessors to the new block.

Returns:SsaBasicBlock

non-null; an appropriately-constructed instance

insertNewSuccessorback to summary
public SsaBasicBlock insertNewSuccessor(SsaBasicBlock other)

Constructs and inserts a new empty GOTO block Z between this block (A) and a current successor block (B). The new block will replace B as A's successor and A as B's predecessor. A and B will no longer be directly connected. If B is listed as a successor multiple times, all references are replaced.

Parameters
other:SsaBasicBlock

current successor (B)

Returns:SsaBasicBlock

non-null; an appropriately-constructed instance

isExitBlockback to summary
public boolean isExitBlock()
Returns:boolean

true if this is the one-and-only exit block for this method

isReachableback to summary
public boolean isReachable()

Returns true if this block was last calculated to be reachable. Recalculates reachability if value has never been computed.

Returns:boolean

true if reachable

newFromRopback to summary
public static SsaBasicBlock newFromRop(RopMethod rmeth, int basicBlockIndex, final SsaMethod parent)

Creates a new SSA basic block from a ROP form basic block.

Parameters
rmeth:RopMethod

original method

basicBlockIndex:int

index this block will have

parent:SsaMethod

method of this block predecessor set will be updated

Returns:SsaBasicBlock

new instance

removeAllPhiInsnsback to summary
public void removeAllPhiInsns()

Deletes all phi insns. Do this after adding appropriate move insns.

removeSuccessorback to summary
public void removeSuccessor(int oldIndex)

Removes a successor from this block's successor list.

Parameters
oldIndex:int

index of successor block to remove

replaceLastInsnback to summary
public void replaceLastInsn(Insn insn)

Replaces the last insn in this block. The provided insn must have some branchingness.

Parameters
insn:Insn

non-null; rop-form insn to add, which must branch.

replaceSuccessorback to summary
public void replaceSuccessor(int oldIndex, int newIndex)

Replaces an old successor with a new successor. This will throw RuntimeException if oldIndex was not a successor.

Parameters
oldIndex:int

index of old successor block

newIndex:int

index of new successor block

scheduleMovesFromPhisback to summary
public void scheduleMovesFromPhis()

Sorts move instructions added via addMoveToEnd during phi removal so that results don't overwrite sources that are used. For use after all phis have been removed and all calls to addMoveToEnd() have been made.

This is necessary because copy-propogation may have left us in a state where the same basic block has the same register as a phi operand and a result. In this case, the register in the phi operand always refers value before any other phis have executed.

scheduleUseBeforeAssignedback to summary
private void scheduleUseBeforeAssigned(List<SsaInsn> toSchedule)

Ensures that all move operations in this block occur such that reads of any register happen before writes to that register.

Note

caller is expected to returnSpareRegisters()! TODO: See Briggs, et al "Practical Improvements to the Construction and Destruction of Static Single Assignment Form" section 5. a) This can be done in three passes.

Parameters
toSchedule:List<SsaInsn>

List of instructions. Must consist only of moves.

setReachableback to summary
public void setReachable(int reach)

Sets reachability of block to specified value

Parameters
reach:int

new value of reachability for block

setRegsUsedback to summary
private static void setRegsUsed(BitSet regsUsed, RegisterSpec rs)

Sets the register as used in a bitset, taking into account its category/width.

Parameters
regsUsed:BitSet

set, indexed by register number

rs:RegisterSpec

register to mark as used

toStringback to summary
public String toString()

Overrides java.lang.Object.toString.

Doc from java.lang.Object.toString.

Returns a string representation of the object.

Returns:String

a string representation of the object

Annotations
@Override
org.droidparts.dexmaker.dx.ssa back to summary

public final Class SsaBasicBlock.LabelComparator

extends Object
implements Comparator<SsaBasicBlock>
Class Inheritance
All Implemented Interfaces
java.util.Comparator

Label comparator.

Constructor Summary

AccessConstructor and Description
public

Method Summary

Modifier and TypeMethod and Description
public int
compare(SsaBasicBlock
the first object to be compared.
b1
,
SsaBasicBlock
the second object to be compared.
b2
)

Implements java.util.Comparator.compare.

Compares its two arguments for order.
Inherited from java.lang.Object:
cloneequalsfinalizegetClasshashCodenotifynotifyAlltoStringwaitwaitwait

Constructor Detail

LabelComparatorback to summary
public LabelComparator()

Method Detail

compareback to summary
public int compare(SsaBasicBlock b1, SsaBasicBlock b2)

Implements java.util.Comparator.compare.

Doc from java.util.Comparator.compare.

Compares its two arguments for order. Returns a negative integer, zero, or a positive integer as the first argument is less than, equal to, or greater than the second.

The implementor must ensure that signum(compare(x, y)) == -signum(compare(y, x)) for all x and y. (This implies that compare(x, y) must throw an exception if and only if compare(y, x) throws an exception.)

The implementor must also ensure that the relation is transitive: ((compare(x, y)>0) && (compare(y, z)>0)) implies compare(x, z)>0.

Finally, the implementor must ensure that compare(x, y)==0 implies that signum(compare(x, z))==signum(compare(y, z)) for all z.

Parameters
b1:SsaBasicBlock

the first object to be compared.

b2:SsaBasicBlock

the second object to be compared.

Returns:int

a negative integer, zero, or a positive integer as the first argument is less than, equal to, or greater than the second.

org.droidparts.dexmaker.dx.ssa back to summary

public Interface SsaBasicBlock.Visitor

Known Direct Implementers
org.droidparts.dexmaker.dx.ssa.Dominators.DfsWalker

Visitor interface for basic blocks.

Method Summary

Modifier and TypeMethod and Description
public void
visitBlock(SsaBasicBlock
non-null; block visited
v
,
SsaBasicBlock
null-ok; parent node if applicable
parent
)

Indicates a block has been visited by an iterator method.

Method Detail

visitBlockback to summary
public void visitBlock(SsaBasicBlock v, SsaBasicBlock parent)

Indicates a block has been visited by an iterator method.

Parameters
v:SsaBasicBlock

non-null; block visited

parent:SsaBasicBlock

null-ok; parent node if applicable