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

public Class FirstFitLocalCombiningAllocator

extends RegisterAllocator
Class Inheritance
Imports
org.droidparts.dexmaker.dx.rop.code.*, org.droidparts.dexmaker.dx.rop.cst.CstInteger, org.droidparts.dexmaker.dx.ssa.*, org.droidparts.dexmaker.dx.util.IntIterator, .IntSet, java.util.ArrayList, .BitSet, .Map, .TreeMap

Allocates registers in a first-fit fashion, with the bottom reserved for method parameters and all SSAregisters representing the same local variable kept together if possible.

Nested and Inner Type Summary

Modifier and TypeClass and Description
private static class

Field Summary

Modifier and TypeField and Description
private static final boolean
DEBUG

local debug flag

private final ArrayList<NormalSsaInsn>
invokeRangeInsns

list of invoke-range instructions seen in this method

private final Map<LocalItem, ArrayList<RegisterSpec>>
localVariables

maps local variable to a list of associated SSA registers

private final InterferenceRegisterMapper
mapper

Register mapper which will be our result

private final boolean
minimizeRegisters

true if converter should take steps to minimize rop-form registers

private final ArrayList<NormalSsaInsn>
moveResultPseudoInsns

list of move-result-pesudo instructions seen in this method

private final int
paramRangeEnd

end of rop registers range (starting at 0) reserved for parameters

private final ArrayList<PhiInsn>
phiInsns

list of phi instructions seen in this method

private final BitSet
reservedRopRegs

set of rop registers reserved for parameters or local variables

private final BitSet
ssaRegsMapped

indexed by SSA reg; the set of SSA regs we've mapped

private final BitSet
usedRopRegs

set of rop registers that have been used by anything

Inherited from org.droidparts.dexmaker.dx.ssa.back.RegisterAllocator:
interferencessaMeth

Constructor Summary

AccessConstructor and Description
public
FirstFitLocalCombiningAllocator(SsaMethod
non-null; method to process
ssaMeth
,
InterferenceGraph
non-null interference graph for SSA registers
interference
,
boolean
true if converter should take steps to minimize rop-form registers
minimizeRegisters
)

Constructs instance.

Method Summary

Modifier and TypeMethod and Description
private void
addMapping(RegisterSpec
non-null; SSA register to map from
ssaSpec
,
int
>=0; rop register to map to
ropReg
)

Adds a mapping from an SSA register to a rop register.

private void
adjustAndMapSourceRangeRange(NormalSsaInsn
non-null; insn whos sources to process
insn
)

Maps the source registers of the specified instruction such that they will fall in a contiguous range in rop form.

public RegisterMapper
private void
analyzeInstructions()

Analyze each instruction and find out all the local variable assignments and move-result-pseudo/invoke-range instrucitons.

private boolean

Returns:

true if mapping is possible
canMapReg
(RegisterSpec
non-null; SSA spec
ssaSpec
,
int
prosepctive new-namespace reg
ropReg
)

Checks to see if ssaSpec can be mapped to ropReg.

private boolean

Returns:

true if all unmapped registers can be mapped
canMapRegs
(ArrayList<RegisterSpec>
non-null; SSA registers to check
specs
,
int
>=0; rop register to check mapping to
ropReg
)

Checks to see if a list of SSA registers can all be mapped into the same rop reg. Ignores registers that have already been mapped, and checks the interference graph and ensures the range does not cross the parameter range.

private int

Returns:

the rop register that starts the fitting range
findAnyFittingRange
(NormalSsaInsn
non-null; insn to build range for
insn
,
int
>=0; length required in register units
rangeLength
,
int[]
non-null; indexed by source index; the category for each source
categoriesForIndex
,
BitSet
non-null; an output parameter indexed by source index that will contain the set of sources which need moves inserted
outMovesRequired
)

Finds an unreserved range that will fit the sources of the specified instruction.

private int

Returns:

>= 0; start of available register range.
findNextUnreservedRopReg
(int
>= 0; a rop register to start the search at
startReg
,
int
> 0; the width, in registers, required.
width
)

Finds a range of unreserved rop registers.

private int

Returns:

>= 0; rop register of start of range
findRangeAndAdjust
(NormalSsaInsn
non-null; the insn whose sources need to fit. Must be last insn in basic block.
insn
)

Find a contiguous rop register range that fits the specified instruction's sources.

private int

Returns:

>= 0; start of available register range.
findRopRegForLocal
(int
>= 0; a rop register to start the search at
startReg
,
int
> 0; the width, in registers, required.
width
)

Finds a range of rop regs that can be used for local variables.

private int

Returns:

the width of the fit that that does not involve added moves or -1 if "no fit possible"
fitPlanForRange
(int
>= 0; rop reg that begins range
ropReg
,
NormalSsaInsn
non-null; insn to plan range for
insn
,
int[]
non-null; indexed by source index; the category for each source
categoriesForIndex
,
BitSet
non-null; an output parameter indexed by source index that will contain the set of sources which need moves inserted
outMovesRequired
)

Attempts to build a plan for fitting a range of sources into rop registers.

private LocalItem

Returns:

null-ok; associated local item or null
getLocalItemForReg
(int
>= 0; SSA register
ssaReg
)

Gets a local item associated with an ssa register, if one exists.

private int

Returns:

parameter index or -1 if not a parameter
getParameterIndexForReg
(int
>=0; SSA register to look up
ssaReg
)

Gets the parameter index for SSA registers that are method parameters.

private void
handleCheckCastResults()

Handles check cast results to reuse the same source register.

private void
handleInvokeRangeInsns()

Handles all insns that want a register range for their sources.

private void
handleLocalAssociatedOther()

Maps all local-associated registers that are not parameters.

private void
handleLocalAssociatedParams()

Maps all local-associated parameters to rop registers.

private void
handleNormalUnassociated()

Maps all non-parameter, non-local variable registers.

private void
handlePhiInsns()

Handles all phi instructions, trying to map them to a common register.

private void
handleUnassociatedParameters()

Maps any parameter that isn't local-associated, which can happen in the case where there is no java debug info.

private boolean

Returns:

true if the "this" pointer is located here.
isThisPointerReg
(int
rop register
startReg
)

Returns true if given rop register represents the this pointer for a non-static method.

private void
markReserved(int
>= 0; rop register to reserve
ropReg
,
int
> 0; width to reserve
category
)

Marks a range of rop registers as "reserved for a local variable."

private void
printLocalVars()

Dumps local variable table to stdout for debugging.

private void
processPhiInsn(PhiInsn insn)

Attempts to map the sources and result of a phi to a common register.

private boolean

Returns:

true if any register in range is marked reserved
rangeContainsReserved
(int
>= 0; lowest rop register
ropRangeStart
,
int
> 0; number of rop registers in range.
width
)

Checks to see if any rop registers in the specified range are reserved for local variables or parameters.

private boolean

Returns:

true in the case noted above
spansParamRange
(int
register in new namespace
ssaReg
,
int
width that the register will have
category
)

Returns true if the specified rop register + category will cross the boundry between the lower paramWidth registers reserved for method params and the upper registers.

pack-priv RegisterSpecList

Returns:

list of RegisterSpecs as noted above
ssaSetToSpecs
(IntSet
non-null; set of SSA registers
ssaSet
)

Converts a bit set of SSA registers into a RegisterSpecList containing the definition specs of all the registers.

private boolean

Returns:

true if map succeeded, false if not
tryMapReg
(RegisterSpec
non-null; SSA register
ssaSpec
,
int
>=0; rop register
ropReg
,
int
1..2; the maximum category that the SSA register is allowed to be
maxAllowedCategory
)

Tries to map an SSA register to a rop register.

private boolean

Returns:

true if all registers were mapped, false if some remain unmapped
tryMapRegs
(ArrayList<RegisterSpec>
non-null; SSA registers to attempt to map
specs
,
int
>=0; rop register to map to
ropReg
,
int
1..2; maximum category allowed in mapping.
maxAllowedCategory
,
boolean
do so if true
markReserved
)

Tries to map a list of SSA registers into the a rop reg, marking used rop space as reserved.

public boolean
wantsParamsMovedHigh()

Implements abstract org.droidparts.dexmaker.dx.ssa.back.RegisterAllocator.wantsParamsMovedHigh.

Indicates whether the method params were allocated at the bottom of the namespace, and thus should be moved up to the top of the namespace after phi removal.
Inherited from org.droidparts.dexmaker.dx.ssa.back.RegisterAllocator:
getCategoryForSsaReggetDefinitionSpecForSsaReginsertMoveBeforeisDefinitionMoveParam

Field Detail

DEBUGback to summary
private static final boolean DEBUG

local debug flag

invokeRangeInsnsback to summary
private final ArrayList<NormalSsaInsn> invokeRangeInsns

list of invoke-range instructions seen in this method

localVariablesback to summary
private final Map<LocalItem, ArrayList<RegisterSpec>> localVariables

maps local variable to a list of associated SSA registers

mapperback to summary
private final InterferenceRegisterMapper mapper

Register mapper which will be our result

minimizeRegistersback to summary
private final boolean minimizeRegisters

true if converter should take steps to minimize rop-form registers

moveResultPseudoInsnsback to summary
private final ArrayList<NormalSsaInsn> moveResultPseudoInsns

list of move-result-pesudo instructions seen in this method

paramRangeEndback to summary
private final int paramRangeEnd

end of rop registers range (starting at 0) reserved for parameters

phiInsnsback to summary
private final ArrayList<PhiInsn> phiInsns

list of phi instructions seen in this method

reservedRopRegsback to summary
private final BitSet reservedRopRegs

set of rop registers reserved for parameters or local variables

ssaRegsMappedback to summary
private final BitSet ssaRegsMapped

indexed by SSA reg; the set of SSA regs we've mapped

usedRopRegsback to summary
private final BitSet usedRopRegs

set of rop registers that have been used by anything

Constructor Detail

FirstFitLocalCombiningAllocatorback to summary
public FirstFitLocalCombiningAllocator(SsaMethod ssaMeth, InterferenceGraph interference, boolean minimizeRegisters)

Constructs instance.

Parameters
ssaMeth:SsaMethod

non-null; method to process

interference:InterferenceGraph

non-null interference graph for SSA registers

minimizeRegisters:boolean

true if converter should take steps to minimize rop-form registers

Method Detail

addMappingback to summary
private void addMapping(RegisterSpec ssaSpec, int ropReg)

Adds a mapping from an SSA register to a rop register. canMapReg should have already been called.

Parameters
ssaSpec:RegisterSpec

non-null; SSA register to map from

ropReg:int

>=0; rop register to map to

adjustAndMapSourceRangeRangeback to summary
private void adjustAndMapSourceRangeRange(NormalSsaInsn insn)

Maps the source registers of the specified instruction such that they will fall in a contiguous range in rop form. Moves are inserted as necessary to allow the range to be allocated.

Parameters
insn:NormalSsaInsn

non-null; insn whos sources to process

allocateRegistersback to summary
public RegisterMapper allocateRegisters()

Implements abstract org.droidparts.dexmaker.dx.ssa.back.RegisterAllocator.allocateRegisters.

Doc from org.droidparts.dexmaker.dx.ssa.back.RegisterAllocator.allocateRegisters.

Runs the algorithm.

Returns:RegisterMapper

a register mapper to apply to the SsaMethod

Annotations
@Override
analyzeInstructionsback to summary
private void analyzeInstructions()

Analyze each instruction and find out all the local variable assignments and move-result-pseudo/invoke-range instrucitons.

canMapRegback to summary
private boolean canMapReg(RegisterSpec ssaSpec, int ropReg)

Checks to see if ssaSpec can be mapped to ropReg. Checks interference graph and ensures the range does not cross the parameter range.

Parameters
ssaSpec:RegisterSpec

non-null; SSA spec

ropReg:int

prosepctive new-namespace reg

Returns:boolean

true if mapping is possible

canMapRegsback to summary
private boolean canMapRegs(ArrayList<RegisterSpec> specs, int ropReg)

Checks to see if a list of SSA registers can all be mapped into the same rop reg. Ignores registers that have already been mapped, and checks the interference graph and ensures the range does not cross the parameter range.

Parameters
specs:ArrayList<RegisterSpec>

non-null; SSA registers to check

ropReg:int

>=0; rop register to check mapping to

Returns:boolean

true if all unmapped registers can be mapped

findAnyFittingRangeback to summary
private int findAnyFittingRange(NormalSsaInsn insn, int rangeLength, int[] categoriesForIndex, BitSet outMovesRequired)

Finds an unreserved range that will fit the sources of the specified instruction. Does not bother trying to center the range around an already-mapped source register;

Parameters
insn:NormalSsaInsn

non-null; insn to build range for

rangeLength:int

>=0; length required in register units

categoriesForIndex:int[]

non-null; indexed by source index; the category for each source

outMovesRequired:BitSet

non-null; an output parameter indexed by source index that will contain the set of sources which need moves inserted

Returns:int

the rop register that starts the fitting range

findNextUnreservedRopRegback to summary
private int findNextUnreservedRopReg(int startReg, int width)

Finds a range of unreserved rop registers.

Parameters
startReg:int

>= 0; a rop register to start the search at

width:int

> 0; the width, in registers, required.

Returns:int

>= 0; start of available register range.

findRangeAndAdjustback to summary
private int findRangeAndAdjust(NormalSsaInsn insn)

Find a contiguous rop register range that fits the specified instruction's sources. First, try to center the range around sources that have already been mapped to rop registers. If that fails, just find a new contiguous range that doesn't interfere.

Parameters
insn:NormalSsaInsn

non-null; the insn whose sources need to fit. Must be last insn in basic block.

Returns:int

>= 0; rop register of start of range

findRopRegForLocalback to summary
private int findRopRegForLocal(int startReg, int width)

Finds a range of rop regs that can be used for local variables. If MIX_LOCALS_AND_OTHER is false, this means any rop register that has not yet been used.

Parameters
startReg:int

>= 0; a rop register to start the search at

width:int

> 0; the width, in registers, required.

Returns:int

>= 0; start of available register range.

fitPlanForRangeback to summary
private int fitPlanForRange(int ropReg, NormalSsaInsn insn, int[] categoriesForIndex, BitSet outMovesRequired)

Attempts to build a plan for fitting a range of sources into rop registers.

Parameters
ropReg:int

>= 0; rop reg that begins range

insn:NormalSsaInsn

non-null; insn to plan range for

categoriesForIndex:int[]

non-null; indexed by source index; the category for each source

outMovesRequired:BitSet

non-null; an output parameter indexed by source index that will contain the set of sources which need moves inserted

Returns:int

the width of the fit that that does not involve added moves or -1 if "no fit possible"

getLocalItemForRegback to summary
private LocalItem getLocalItemForReg(int ssaReg)

Gets a local item associated with an ssa register, if one exists.

Parameters
ssaReg:int

>= 0; SSA register

Returns:LocalItem

null-ok; associated local item or null

getParameterIndexForRegback to summary
private int getParameterIndexForReg(int ssaReg)

Gets the parameter index for SSA registers that are method parameters. -1 is returned for non-parameter registers.

Parameters
ssaReg:int

>=0; SSA register to look up

Returns:int

parameter index or -1 if not a parameter

handleCheckCastResultsback to summary
private void handleCheckCastResults()

Handles check cast results to reuse the same source register. Inserts a move if it can't map the same register to both and the check cast is not caught.

handleInvokeRangeInsnsback to summary
private void handleInvokeRangeInsns()

Handles all insns that want a register range for their sources.

handleLocalAssociatedOtherback to summary
private void handleLocalAssociatedOther()

Maps all local-associated registers that are not parameters. Tries to find an unreserved range that's wide enough for all of the SSA registers, and then tries to map them all to that range. If not all fit, a new range is tried until all registers have been fit.

handleLocalAssociatedParamsback to summary
private void handleLocalAssociatedParams()

Maps all local-associated parameters to rop registers.

handleNormalUnassociatedback to summary
private void handleNormalUnassociated()

Maps all non-parameter, non-local variable registers.

handlePhiInsnsback to summary
private void handlePhiInsns()

Handles all phi instructions, trying to map them to a common register.

handleUnassociatedParametersback to summary
private void handleUnassociatedParameters()

Maps any parameter that isn't local-associated, which can happen in the case where there is no java debug info.

isThisPointerRegback to summary
private boolean isThisPointerReg(int startReg)

Returns true if given rop register represents the this pointer for a non-static method.

Parameters
startReg:int

rop register

Returns:boolean

true if the "this" pointer is located here.

markReservedback to summary
private void markReserved(int ropReg, int category)

Marks a range of rop registers as "reserved for a local variable."

Parameters
ropReg:int

>= 0; rop register to reserve

category:int

> 0; width to reserve

printLocalVarsback to summary
private void printLocalVars()

Dumps local variable table to stdout for debugging.

processPhiInsnback to summary
private void processPhiInsn(PhiInsn insn)

Attempts to map the sources and result of a phi to a common register. Will try existing mappings first, from most to least common. If none of the registers have mappings yet, a new mapping is created.

rangeContainsReservedback to summary
private boolean rangeContainsReserved(int ropRangeStart, int width)

Checks to see if any rop registers in the specified range are reserved for local variables or parameters.

Parameters
ropRangeStart:int

>= 0; lowest rop register

width:int

> 0; number of rop registers in range.

Returns:boolean

true if any register in range is marked reserved

spansParamRangeback to summary
private boolean spansParamRange(int ssaReg, int category)

Returns true if the specified rop register + category will cross the boundry between the lower paramWidth registers reserved for method params and the upper registers. We cannot allocate a register that spans the param block and the normal block, because we will be moving the param block to high registers later.

Parameters
ssaReg:int

register in new namespace

category:int

width that the register will have

Returns:boolean

true in the case noted above

ssaSetToSpecsback to summary
pack-priv RegisterSpecList ssaSetToSpecs(IntSet ssaSet)

Converts a bit set of SSA registers into a RegisterSpecList containing the definition specs of all the registers.

Parameters
ssaSet:IntSet

non-null; set of SSA registers

Returns:RegisterSpecList

list of RegisterSpecs as noted above

tryMapRegback to summary
private boolean tryMapReg(RegisterSpec ssaSpec, int ropReg, int maxAllowedCategory)

Tries to map an SSA register to a rop register.

Parameters
ssaSpec:RegisterSpec

non-null; SSA register

ropReg:int

>=0; rop register

maxAllowedCategory:int

1..2; the maximum category that the SSA register is allowed to be

Returns:boolean

true if map succeeded, false if not

tryMapRegsback to summary
private boolean tryMapRegs(ArrayList<RegisterSpec> specs, int ropReg, int maxAllowedCategory, boolean markReserved)

Tries to map a list of SSA registers into the a rop reg, marking used rop space as reserved. SSA registers that don't fit are left unmapped.

Parameters
specs:ArrayList<RegisterSpec>

non-null; SSA registers to attempt to map

ropReg:int

>=0; rop register to map to

maxAllowedCategory:int

1..2; maximum category allowed in mapping.

markReserved:boolean

do so if true

Returns:boolean

true if all registers were mapped, false if some remain unmapped

wantsParamsMovedHighback to summary
public boolean wantsParamsMovedHigh()

Implements abstract org.droidparts.dexmaker.dx.ssa.back.RegisterAllocator.wantsParamsMovedHigh.

Doc from org.droidparts.dexmaker.dx.ssa.back.RegisterAllocator.wantsParamsMovedHigh.

Indicates whether the method params were allocated at the bottom of the namespace, and thus should be moved up to the top of the namespace after phi removal.

Returns:boolean

true if params should be moved from low to high

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

private Class FirstFitLocalCombiningAllocator.Multiset

extends Object
Class Inheritance
  • java.lang.Object
  • org.droidparts.dexmaker.dx.ssa.back.FirstFitLocalCombiningAllocator.Multiset

Field Summary

Modifier and TypeField and Description
private final int[]
private final int[]
private int

Constructor Summary

AccessConstructor and Description
public
Multiset(int
the maximum distinct elements the set may have
maxSize
)

Constructs an instance.

Method Summary

Modifier and TypeMethod and Description
public void
add(int
element to add
element
)

Adds an element to the set.

public int

Returns:

element with the highest count
getAndRemoveHighestCount
()

Searches the set for the element that has been added the most.

public int

Returns:

size of the set
getSize
()

Gets the number of distinct elements in the set.

Inherited from java.lang.Object:
cloneequalsfinalizegetClasshashCodenotifynotifyAlltoStringwaitwaitwait

Field Detail

countback to summary
private final int[] count
regback to summary
private final int[] reg
sizeback to summary
private int size

Constructor Detail

Multisetback to summary
public Multiset(int maxSize)

Constructs an instance.

Parameters
maxSize:int

the maximum distinct elements the set may have

Method Detail

addback to summary
public void add(int element)

Adds an element to the set.

Parameters
element:int

element to add

getAndRemoveHighestCountback to summary
public int getAndRemoveHighestCount()

Searches the set for the element that has been added the most. In the case of a tie, the element that was added first is returned. Then, it clears the count on that element. The size of the set remains unchanged.

Returns:int

element with the highest count

getSizeback to summary
public int getSize()

Gets the number of distinct elements in the set.

Returns:int

size of the set