Skip to content

Commit

Permalink
Optimizer docs: Remove detailed info about hard prerequisites for eac…
Browse files Browse the repository at this point in the history
…h step

- From user's perspective it's more useful to assume that all other steps implicitly depend on these prerequisites.
- For development the info is still available in docstrings of steps.
  • Loading branch information
cameel committed May 11, 2024
1 parent 45035a8 commit 9fabbda
Show file tree
Hide file tree
Showing 2 changed files with 48 additions and 92 deletions.
68 changes: 34 additions & 34 deletions docs/cheatsheet.rst
Original file line number Diff line number Diff line change
Expand Up @@ -171,41 +171,41 @@ Modifiers
Optimizer Step Dependencies
===========================

=========================================== ===================================================== =============================================================== ===========================================
Step Hard prerequisites Steps that should run before Steps that should run after
=========================================== ===================================================== =============================================================== ===========================================
:ref:`a <ssa-transform>` Disambiguator, ForLoopInitRewriter ExpressionSplitter, CommonSubexpressionEliminator UnusedAssignEliminator
:ref:`C <conditional-simplifier>` Disambiguator SSATransform, DeadCodeEliminator
:ref:`c <common-subexpression-eliminator>` Disambiguator, ForLoopInitRewriter ExpressionSplitter, SSATransform [#]_ UnusedPruner, UnusedAssignEliminator
:ref:`D <dead-code-eliminator>` ForLoopInitRewriter, FunctionHoister, FunctionGrouper
=========================================== =============================================================== ===========================================
Step Steps that should run before Steps that should run after
=========================================== =============================================================== ===========================================
:ref:`a <ssa-transform>` ExpressionSplitter, CommonSubexpressionEliminator UnusedAssignEliminator
:ref:`C <conditional-simplifier>` SSATransform, DeadCodeEliminator
:ref:`c <common-subexpression-eliminator>` ExpressionSplitter, SSATransform [#]_ UnusedPruner, UnusedAssignEliminator
:ref:`D <dead-code-eliminator>`
:ref:`d <var-decl-initializer>`
:ref:`E <equal-store-eliminator>` Disambiguator, ForLoopInitRewriter ExpressionSplitter, SSATransform, CommonSubexpressionEliminator
:ref:`e <expression-inliner>` Disambiguator
:ref:`F <function-specializer>` Disambiguator, FunctionHoister LiteralRematerialiser
:ref:`f <block-flattener>` Disambiguator, FunctionGrouper
:ref:`g <function-grouper>` Disambiguator, FunctionHoister
:ref:`h <function-hoister>` Disambiguator
:ref:`I <for-loop-condition-into-body>` Disambiguator StructuralSimplifier
:ref:`i <full-inliner>` Disambiguator FunctionHoister, ExpressionSplitter
:ref:`j <expression-joiner>` Disambiguator
:ref:`L <load-resolver>` Disambiguator, ForLoopInitRewriter SSATransform
:ref:`l <circular-references-pruner>` Disambiguator, FunctionHoister
:ref:`M <loop-invariant-code-motion>` Disambiguator, ForLoopInitRewriter, FunctionHoister ExpressionSplitter, SSATransform, ForLoopConditionIntoBody
:ref:`m <rematerialiser>` Disambiguator, ForLoopInitRewriter
:ref:`n <control-flow-simplifier>` Disambiguator, ForLoopInitRewriter, FunctionHoister
:ref:`O <for-loop-condition-out-of-body>` LiteralRematerialiser
:ref:`o <for-loop-init-rewriter>` Disambiguator
:ref:`p <unused-function-parameter-pruner>` Disambiguator, FunctionHoister LiteralRematerialiser FullInliner, UnusedPruner
:ref:`r <unused-assign-eliminator>` Disambiguator, ForLoopInitRewriter
:ref:`S <unused-store-eliminator>` Disambiguator, ForLoopInitRewriter SSATransform
:ref:`s <expression-simplifier>` Disambiguator, ForLoopInitRewriter ExpressionSplitter, SSATransform, CommonSubexpressionEliminator
:ref:`T <literal-rematerialiser>` Disambiguator, ForLoopInitRewriter
:ref:`t <structural-simplifier>` Disambiguator LiteralRematerialiser
:ref:`E <equal-store-eliminator>` ExpressionSplitter, SSATransform, CommonSubexpressionEliminator
:ref:`e <expression-inliner>`
:ref:`F <function-specializer>` LiteralRematerialiser
:ref:`f <block-flattener>`
:ref:`g <function-grouper>`
:ref:`h <function-hoister>`
:ref:`I <for-loop-condition-into-body>` StructuralSimplifier
:ref:`i <full-inliner>` FunctionHoister, ExpressionSplitter
:ref:`j <expression-joiner>`
:ref:`L <load-resolver>` SSATransform
:ref:`l <circular-references-pruner>`
:ref:`M <loop-invariant-code-motion>` ExpressionSplitter, SSATransform, ForLoopConditionIntoBody
:ref:`m <rematerialiser>`
:ref:`n <control-flow-simplifier>`
:ref:`O <for-loop-condition-out-of-body>` LiteralRematerialiser
:ref:`o <for-loop-init-rewriter>`
:ref:`p <unused-function-parameter-pruner>` LiteralRematerialiser FullInliner, UnusedPruner
:ref:`r <unused-assign-eliminator>`
:ref:`S <unused-store-eliminator>` SSATransform
:ref:`s <expression-simplifier>` ExpressionSplitter, SSATransform, CommonSubexpressionEliminator
:ref:`T <literal-rematerialiser>`
:ref:`t <structural-simplifier>` LiteralRematerialiser
:ref:`U <conditional-unsimplifier>`
:ref:`u <unused-pruner>` Disambiguator
:ref:`V <ssa-reverser>` Disambiguator CommonSubexpressionEliminator, UnusedPruner
:ref:`v <equivalent-function-combiner>` Disambiguator, FunctionHoister UnusedPruner
:ref:`x <expression-splitter>` ForLoopConditionIntoBody
=========================================== ===================================================== =============================================================== ===========================================
:ref:`u <unused-pruner>`
:ref:`V <ssa-reverser>` CommonSubexpressionEliminator, UnusedPruner
:ref:`v <equivalent-function-combiner>` UnusedPruner
:ref:`x <expression-splitter>` ForLoopConditionIntoBody
=========================================== =============================================================== ===========================================

.. [#] It is enough if SSATransform was used once at any point before running the step.
72 changes: 14 additions & 58 deletions docs/internals/optimizer.rst
Original file line number Diff line number Diff line change
Expand Up @@ -385,6 +385,20 @@ The preprocessing components perform transformations to get the program
into a certain normal form that is easier to work with. This normal
form is kept during the rest of the optimization process.

Some of the steps in this group should be considered prerequisites for all other components.
Currently these are:

- :ref:`disambiguator`
- :ref:`function-hoister`
- :ref:`function-grouper`
- :ref:`for-loop-init-rewriter`

Each one establishes a certain property that all other steps preserve and implicitly assume
to be always satisfied by the code.
Not satisfying the property will not only make optimization less effective but in some cases may also
lead to the produced code being wrong.
For this reason the optimizer always runs these prerequisites before applying the main sequence.

.. _disambiguator:

Disambiguator
Expand All @@ -411,8 +425,6 @@ its visibility and it is impossible to reference variables defined in a differen
The benefit of this stage is that function definitions can be looked up more easily
and functions can be optimized in isolation without having to traverse the AST completely.

Prerequisites: Disambiguator.

.. _function-grouper:

FunctionGrouper
Expand All @@ -433,8 +445,6 @@ and ``F`` is a list of function definitions such that no function contains a fun

The benefit of this stage is that we always know where the list of functions begins.

Prerequisites: Disambiguator, FunctionHoister.

.. _for-loop-condition-into-body:

ForLoopConditionIntoBody
Expand Down Expand Up @@ -468,8 +478,6 @@ To avoid unnecessary rewriting, it is recommended to run this step after Structu

May destroy the :ref:`expression-split <expression-splitter>` form.

Prerequisites: Disambiguator.

.. _for-loop-init-rewriter:

ForLoopInitRewriter
Expand All @@ -496,8 +504,6 @@ is transformed to
This eases the rest of the optimization process because we can ignore
the complicated scoping rules of the ``for`` loop initialization block.

Prerequisites: Disambiguator.

.. _var-decl-initializer:

VarDeclInitializer
Expand Down Expand Up @@ -674,8 +680,6 @@ are run right before it, because then it does not generate excessive amounts of
On the other hand, the CommonSubexpressionEliminator could be more efficient if run after the
SSA transform.

Prerequisites: Disambiguator, ForLoopInitRewriter.

.. _unused-assign-eliminator:

UnusedAssignEliminator
Expand Down Expand Up @@ -790,8 +794,6 @@ In the second traversal, all assignments that are in the "unused" state are remo
This step is usually run right after the SSA transform to complete
the generation of the pseudo-SSA.

Prerequisites: Disambiguator, ForLoopInitRewriter.

Tools
-----

Expand Down Expand Up @@ -825,8 +827,6 @@ in any of the control-flow paths. For instance, upon entering a
``for`` loop, all variables are cleared that will be assigned during the
body or the post block.

Prerequisites: Disambiguator, ForLoopInitRewriter.

Expression-Scale Simplifications
--------------------------------

Expand Down Expand Up @@ -863,8 +863,6 @@ This step is especially efficient if the ExpressionSplitter is run before.
The ExpressionSimplifier will be able to perform better replacements
if the CommonSubexpressionEliminator was run right before it.

Prerequisites: Disambiguator, ForLoopInitRewriter.

.. _expression-simplifier:

ExpressionSimplifier
Expand All @@ -888,8 +886,6 @@ in :ref:`expression-split <expression-splitter>` or :ref:`pseudo-SSA <ssa-transf

Some of the simplifications destroy the :ref:`expression-split <expression-splitter>` form.

Prerequisites: Disambiguator, ForLoopInitRewriter.

.. _literal-rematerialiser:

LiteralRematerialiser
Expand All @@ -904,8 +900,6 @@ While the step destroys the :ref:`expression-split <expression-splitter>` form i
it does not introduce any nested function calls, which may be good enough for many steps that require
this property.

Prerequisites: Disambiguator, ForLoopInitRewriter.

.. _load-resolver:

LoadResolver
Expand All @@ -919,8 +913,6 @@ is a constant ``<= 32``.

Works best if the code is in SSA form.

Prerequisites: Disambiguator, ForLoopInitRewriter.

Statement-Scale Simplifications
-------------------------------

Expand All @@ -932,8 +924,6 @@ CircularReferencesPruner
This stage removes functions that call each other but are
neither externally referenced nor referenced from the outermost context.

Prerequisites: Disambiguator, FunctionHoister.

.. _conditional-simplifier:

ConditionalSimplifier
Expand All @@ -960,8 +950,6 @@ Future features:

Works best with SSA form and if DeadCodeEliminator has run before.

Prerequisites: Disambiguator.

.. _conditional-unsimplifier:

ConditionalUnsimplifier
Expand Down Expand Up @@ -992,8 +980,6 @@ performs similar tasks that do depend on data flow.
The ControlFlowSimplifier does record the presence or absence of ``break``
and ``continue`` statements during its traversal.

Prerequisites: Disambiguator, FunctionHoister, ForLoopInitRewriter.

.. _dead-code-eliminator:

DeadCodeEliminator
Expand All @@ -1011,8 +997,6 @@ code and thus are considered reachable.
Because variables declared in a ``for`` loop's init block have their scope extended to the loop body,
we require ForLoopInitRewriter to run before this step.

Prerequisites: ForLoopInitRewriter, FunctionHoister, FunctionGrouper.

.. _equal-store-eliminator:

EqualStoreEliminator
Expand All @@ -1030,8 +1014,6 @@ variable if the value is known to be the same.
Works best on code without literal arguments, which is the case when the code is in the
:ref:`expression-split <expression-splitter>` form.

Prerequisites: Disambiguator, ForLoopInitRewriter.

.. _unused-pruner:

UnusedPruner
Expand All @@ -1047,8 +1029,6 @@ All movable expression statements (expressions that are not assigned) are remove

Does not remove circular references.

Prerequisites: Disambiguator.

.. _structural-simplifier:

StructuralSimplifier
Expand All @@ -1069,8 +1049,6 @@ This component uses the DataflowAnalyzer.

LiteralRematerialiser should be run before this step.

Prerequisites: Disambiguator.

.. _block-flattener:

BlockFlattener
Expand Down Expand Up @@ -1108,8 +1086,6 @@ is transformed to
As long as the code is disambiguated, this does not cause a problem because
the scopes of variables can only grow.

Prerequisites: Disambiguator, FunctionGrouper.

.. _loop-invariant-code-motion:

LoopInvariantCodeMotion
Expand All @@ -1124,8 +1100,6 @@ ExpressionSplitter and SSATransform should be run upfront to obtain better resul
The transformation will not move loop-invariant condition out of the condition block of the loop.
This can be addressed by running ForLoopConditionIntoBody beforehand.

Prerequisites: Disambiguator, ForLoopInitRewriter, FunctionHoister.


Function-Level Optimizations
----------------------------
Expand All @@ -1151,8 +1125,6 @@ function ``f_1`` that takes only one argument, i.e.,
Other optimization steps will be able to make more simplifications to the function. The
optimization step is mainly useful for functions that would not be inlined.

Prerequisites: Disambiguator, FunctionHoister.

LiteralRematerialiser is recommended before, even though it's not required for
correctness.

Expand All @@ -1175,8 +1147,6 @@ and replace all references to ``f`` by ``f2``.
FullInliner should be run afterwards to make sure that all references to ``f2`` are replaced by
``f``.

Prerequisites: Disambiguator, FunctionHoister.

The step LiteralRematerialiser is recommended but not required for correctness. It helps deal with cases such as:
``function f(x) -> y { revert(y, y} }`` where the literal ``y`` will be replaced by its value ``0``,
allowing us to rewrite the function.
Expand Down Expand Up @@ -1225,8 +1195,6 @@ be read once we leave the function's scope, so the statement will be removed onl

Best run in SSA form.

Prerequisites: Disambiguator, ForLoopInitRewriter.

.. _equivalent-function-combiner:

EquivalentFunctionCombiner
Expand All @@ -1238,8 +1206,6 @@ functions is replaced by the other.

The actual removal of the function is performed by the UnusedPruner.

Prerequisites: Disambiguator, FunctionHoister.

Function Inlining
-----------------

Expand All @@ -1266,8 +1232,6 @@ Example: The function to be inlined has the form of ``function f(...) -> r { r :

The result of this inlining is always a single expression.

Prerequisites: Disambiguator.

.. _full-inliner:

FullInliner
Expand Down Expand Up @@ -1341,8 +1305,6 @@ more efficient, but are not required for correctness.
In particular, function calls with other function calls as arguments are not inlined, but running
ExpressionSplitter beforehand ensures that there are no such calls in the input.

Prerequisites: Disambiguator.

Cleanup
-------

Expand Down Expand Up @@ -1394,8 +1356,6 @@ would be executed after the evaluation of the literal ``3``.

Destroys the :ref:`expression-split <expression-splitter>` form.

Prerequisites: Disambiguator.

.. _ssa-reverser:

SSAReverser
Expand Down Expand Up @@ -1448,8 +1408,6 @@ SSATransform.

Destroys the :ref:`SSA <ssa-transform>` form.

Prerequisites: Disambiguator.

.. _stack-compressor:

StackCompressor
Expand Down Expand Up @@ -1488,8 +1446,6 @@ the variable reference is replaced by its current value.

Destroys the :ref:`expression-split <expression-splitter>` form.

Prerequisites: Disambiguator, ForLoopInitRewriter.

.. _for-loop-condition-out-of-body:

ForLoopConditionOutOfBody
Expand Down

0 comments on commit 9fabbda

Please sign in to comment.