L2Optimizer

An L2Optimizer optimizes its L2ControlFlowGraph. This is a control graph. The vertices are L2BasicBlocks, which are connected via their successor and predecessor lists.

Author

Mark van Gulik

Parameters

generator

An L2Generator used for splicing in short sequences of new code as part of optimization.

Types

Link copied to clipboard
object Companion

Properties

Link copied to clipboard

The mutable list of blocks taken from the controlFlowGraph.

Link copied to clipboard

An L2Generator used for splicing short sequences of code as part of optimization.

Functions

Link copied to clipboard

Any control flow edges that land on jumps should be redirected to the ultimate target of the jump, taking into account chains of jumps.

Link copied to clipboard

Assert that each of the specified StateFlags has been set in the controlFlowGraph.

Link copied to clipboard

Assert that each of the specified StateFlags has been cleared in the controlFlowGraph.

Link copied to clipboard

Clear each of the specified StateFlags from the controlFlowGraph.

Link copied to clipboard

For each L2_MOVE instruction, if the register groups associated with the source and destination registers don't have an interference edge between them then merge the groups together. The resulting merged group should have interferences with each group that the either the source register's group or the destination register's group had interferences with.

Link copied to clipboard

Assign final coloring to each register based on the interference graph and coalescing map.

Link copied to clipboard

Determine which pairs of registers have to be simultaneously live and potentially holding distinct values.

Link copied to clipboard

Determine which registers are live-in for each block. We distinguish between always-live-in, where all future paths from the start of a block lead to a use of the register, and sometimes-live-in, where at least one future path from the start of the block leads to a use of the register.

Link copied to clipboard

For every phi operation, insert a move at the end of the block that leads to it. Because of our version of edge splitting, that block always contains just a jump. The CFG will no longer be in SSA form, because the phi variables will have multiple defining instructions (the moves).

Link copied to clipboard
fun optimize(interpreter: Interpreter)

Optimize the graph of instructions.

Link copied to clipboard

Re-order the blocks to minimize the number of pointless jumps. When we start generating JVM code, this should also try to make one of the paths from conditional branches come after the branch, otherwise an extra jump instruction has to be generated.

Link copied to clipboard

Remove information from the L2ControlFlowGraph that will no longer be needed. Note that during subsequent inlining of this chunk at a call site, the type information will be reconstructed without too much cost.

Link copied to clipboard

Regenerate the edge-split SSA graph, postponing emission of side-effectless instructions until just before they're needed.

Link copied to clipboard
fun removeDeadCode(dataCouplingMode: DataCouplingMode, generatePhis: Boolean = true)

Remove all unreachable blocks and all instructions that don't either have a side-effect or produce a value ultimately used by an instruction that has a side-effect.

Link copied to clipboard

Eliminate any L2_MOVEs between registers of the same color. The graph must have been colored already, and is not expected to be in SSA form, and is certainly not after this, since removed moves are the SSA definition points for their target registers.

Link copied to clipboard

Find the L2BasicBlock that are actually reachable recursively from the blocks marked as L2BasicBlock.isIrremovable.

Link copied to clipboard

Replace constant-valued registers with fresh registers that have no definitions. The JVM code generator will recognize that these are constants, and produce code to produce them on the JVM stack by reading the constants pool or via special instructions for int/double constants.

Link copied to clipboard

Find any remaining occurrences of L2_VIRTUAL_CREATE_LABEL, or any other L2Instruction using an L2Operation that says it L2Operation.isPlaceholder. This happens in a fresh control flow graph, as part of the injected behavior of an L2Regenerator.

Link copied to clipboard

Create a new register for every (i.e., color) of an existing register, then transform every instruction of this control flow graph to use the new registers. The new registers have a L2Register.uniqueValue that's the same as its finalIndex.

Link copied to clipboard

Set each of the specified StateFlags in the controlFlowGraph.

Link copied to clipboard
open override fun toString(): String
Link copied to clipboard

For every edge leading from a multiple-out block to a multiple-in block, split it by inserting a new block along it. Note that we do this regardless of whether the target block has any phi functions.