Skip to content

Commit

Permalink
[docs] Update LoopTerminology.
Browse files Browse the repository at this point in the history
Includes 2 corrections:

 * Update irreducible control flow and add references to CycleTerminology;
   Natural loop is not the only definition of something looping in LLVM anymore.

 * Mention mustprogress loop and function attributes to be used
   instead of the llvm.sideeffect intrinsic.
  • Loading branch information
Meinersbur committed Mar 30, 2022
1 parent 7f81765 commit 793b7f9
Show file tree
Hide file tree
Showing 2 changed files with 31 additions and 11 deletions.
8 changes: 8 additions & 0 deletions llvm/docs/LangRef.rst
Expand Up @@ -1767,6 +1767,9 @@ example:
This function attribute indicates that the function does not call itself
either directly or indirectly down any possible call path. This produces
undefined behavior at runtime if the function ever does recurse.

.. _langref_willreturn:

``willreturn``
This function attribute indicates that a call of this function will
either exhibit undefined behavior or comes back and continues execution
Expand Down Expand Up @@ -2144,6 +2147,9 @@ example:
the function. The instrumentation checks that the return address for the
function has not changed between the function prolog and epilog. It is
currently x86_64-specific.

.. _langref_mustprogress:

``mustprogress``
This attribute indicates that the function is required to return, unwind,
or interact with the environment in an observable way e.g. via a volatile
Expand Down Expand Up @@ -6868,6 +6874,8 @@ It is also possible to have nested parallel loops:
!3 = distinct !{} ; access group for instructions in the inner loop (which are implicitly contained in outer loop as well)
!4 = distinct !{} ; access group for instructions in the outer, but not the inner loop

.. _langref_llvm_loop_mustprogress:

'``llvm.loop.mustprogress``' Metadata
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

Expand Down
34 changes: 23 additions & 11 deletions llvm/docs/LoopTerminology.rst
Expand Up @@ -32,7 +32,8 @@ nodes represent basic blocks) with the following properties:
remain the same.

In computer science literature, this is often called a *natural loop*.
In LLVM, this is the only definition of a loop.
In LLVM, a more generalized definition is called a
:ref:`cycle <cycle-terminology>`.


Terminology
Expand Down Expand Up @@ -139,8 +140,8 @@ detect the loop and ensure separate headers for the outer and inner loop.

The term reducible results from the ability to collapse the CFG into a
single node by successively replacing one of three base structures with
a single node: A sequential execution of basic blocks, a conditional
branching (or switch) with re-joining, and a basic block looping on itself.
a single node: A sequential execution of basic blocks, acyclic conditional
branches (or switches), and a basic block looping on itself.
`Wikipedia <https://en.wikipedia.org/wiki/Control-flow_graph#Reducibility>`_
has a more formal definition, which basically says that every cycle has
a dominating header.
Expand All @@ -151,6 +152,14 @@ a dominating header.
cyclic control flow in its body; a loop that is not nested inside
another loop can still be part of an outer cycle; and there can be
additional cycles between any two loops where one is contained in the other.
However, an LLVM :ref:`cycle<cycle-terminology>` covers both, loops and
irreducible control flow.


* The `FixIrreducible <https://llvm.org/doxygen/FixIrreducible_8h.html>`_
pass can transform irreducible control flow into loops by inserting
new loop headers. It is not inlcuded in any default optimization pass
pipeline, but is required for some back-end targets.


* Exiting edges are not the only way to break out of a loop. Other
Expand Down Expand Up @@ -206,14 +215,17 @@ exiting condition is always false. Because the exiting edge is never
taken, the optimizer can change the conditional branch into an
unconditional one.

Note that under some circumstances the compiler may assume that a loop will
eventually terminate without proving it. For instance, it may remove a loop
that does not do anything in its body. If the loop was infinite, this
optimization resulted in an "infinite" performance speed-up. A call
to the intrinsic :ref:`llvm.sideeffect<llvm_sideeffect>` can be added
into the loop to ensure that the optimizer does not make this assumption
without proof.

If a is loop is annotated with
:ref:`llvm.loop.mustprogress <langref_llvm_loop_mustprogress>` metadata,
the compiler is allowed to assume that it will eventually terminate, even
if it cannot prove it. For instance, it may remove a mustprogress-loop
that does not have any side-effect in its body even though the program
could be stuck in that loop forever. Languages such as C and
`C++ <https://eel.is/c++draft/intro.progress#1>`_ have such
forward-progress guarantees for some loops. Also see the
:ref:`mustprogress <langref_mustprogress>` and
:ref:`willreturn <langref_willreturn>` function attributes, as well as
the older :ref:`llvm.sideeffect <llvm_sideeffect>` intrinsic.

* The number of executions of the loop header before leaving the loop is
the **loop trip count** (or **iteration count**). If the loop should
Expand Down

0 comments on commit 793b7f9

Please sign in to comment.