L2Regenerator
This is used to transform and embed a called function's chunk's control flow graph into the calling function's chunk's control flow graph. Doing so:
eliminates the basic cost of the call and return,
passes parameters in and result out with moves that are easily eliminated,
allows stronger call-site types to narrow method lookups,
exposes primitive cancellation patterns like
<x,y>[1] → x,exposes L1 instruction cancellation, like avoiding creation of closures and label continuations,
allows nearly all conditional and loop control flow to be expressed as simple jumps,
exposes opportunities to operate on intermediate values in an unboxed form.
In addition, this class also gives the opportunity to postpone the transformation of certain virtualized L2Instructions like L2_VIRTUAL_CREATE_LABEL into a subgraph of real instructions, after they have been moved and duplicated as a unit through L2ControlFlowGraph.
Finally, it can be used for code-splitting, where a section of code is duplicated and specialized to take advantage of stronger type knowledge at a point where merging control flow paths would destroy that extra information.
Author
Mark van Gulik
Types
An AbstractOperandTransformer is an L2OperandDispatcher suitable for transforming operands for the enclosing L2Regenerator. Subclasses may choose different strategies for mapping the registers underlying the read and write operands.
An OperandRegisterTransformer is an L2OperandDispatcher suitable for copying operands for the enclosing L2Regenerator, when operand equivalency is via L2Register identity (i.e., when generatePhis is false).
An OperandSemanticTransformer is an L2OperandDispatcher suitable for copying operands for the enclosing L2Regenerator, when operand equivalency is via L2SemanticValues (i.e., when generatePhis is true).
Properties
An inverse mapping from source block to SpecialBlock. This is used to detect when we need to record a corresponding target block as a SpecialBlock.
The L2Generator on which to output the transformed L2 code.
Functions
Transform the instruction's operands, updating the isomorphism, and emit the same kind of instruction to the targetGenerator.
Emit an L2Instruction into the L1Translator's current block. Use the given L2Operation and L2Operands to construct the instruction. The operands should have been transformed by this inliner already.
Force all postponed instructions to be generated now. Some of these may end up being considered dead code, and will be removed by a later pass.
During a control flow merge, the phi creation mechanism detected that the incoming edges all provided a particular L2SemanticValue for a RegisterKind, at least one source was a postponed instruction, and not all of the incoming edges had their values postponed by the same instruction.
A helper method for instruction postponement. Given an L2Regenerator and an L2Instruction from the old graph being regenerated, emit a translated version of that instruction. If the instruction uses values that are not yet available in registers due to postponement, first translate the instructions that produce those values.
Generate a number unique within the targetGenerator.
Process the single instruction from the source graph, transforming it as needed. Subclasses should override this to accomplish postponed instruction rewriting, code splitting, and inlining. The typical result is to rewrite some translation of the instruction to the target graph.
Given an L2Instruction from the source L2ControlFlowGraph, start translating and emitting to the target graph from that point, until nothing else is reachable. Process any encountered back-edges after all forward edges and blocks have completed.