<commit_before>.. _live variable analysis:

======================
Live Variable Analysis
======================

(Releated issue https://github.com/numba/numba/pull/1611)

Numba uses reference-counting for garbage collection, a technique that
requires cooperation by the compiler.  The Numba IR encodes the location
where a decref must be inserted.  These locations are determined by live
variable analysis.  The corresponding source code is the ``_insert_var_dels()``
method in https://github.com/numba/numba/blob/master/numba/interpreter.py.


In Python semantic, once a variable is defined inside a function, it is alive
until the variable is explicitly deleted or the function scope is ended.
However, Numba analyzes the code to determine the minimum bound of the lifetime
of each variable by its definition and usages during compilation.
As soon as a variable is unreachable, a ``del`` instruction is inserted at the
closest basic-block (either at the start of the next block(s) or at the
end of the current block).  This means variables can be released earlier than in
regular Python code.

The behavior of the live variable analysis affects memory usage of the compiled
code.  Internally, Numba does not differentiate temporary variables and user
variables.  Since each operation generates at least one temporary variable,
a function can accumulate a high number of temporary variables if they are not
released as soon as possible.
Our generator implementation can benefit from early releasing of variables,
which reduces the size of the state to suspend at each yeild point.


Notes on behavior of the live variable analysis
================================================


Variable deleted before definition
-----------------------------------

(Related issue: https://github.com/numba/numba/pull/1738)

When a variable lifetime is confined within the loop body (its definition and
usage does not escape the loop body), like:

.. code-block:: python

    def f(arr):
      # BB 0
      res = 0
      # BB 1
      for i in (0, 1):
          # BB 2
          t = arr[i]<commit_msg>Fix typo<commit_after>.. _live variable analysis:

======================
Live Variable Analysis
======================

(Releated issue https://github.com/numba/numba/pull/1611)

Numba uses reference-counting for garbage collection, a technique that
requires cooperation by the compiler.  The Numba IR encodes the location
where a decref must be inserted.  These locations are determined by live
variable analysis.  The corresponding source code is the ``_insert_var_dels()``
method in https://github.com/numba/numba/blob/master/numba/interpreter.py.


In Python semantic, once a variable is defined inside a function, it is alive
until the variable is explicitly deleted or the function scope is ended.
However, Numba analyzes the code to determine the minimum bound of the lifetime
of each variable by its definition and usages during compilation.
As soon as a variable is unreachable, a ``del`` instruction is inserted at the
closest basic-block (either at the start of the next block(s) or at the
end of the current block).  This means variables can be released earlier than in
regular Python code.

The behavior of the live variable analysis affects memory usage of the compiled
code.  Internally, Numba does not differentiate temporary variables and user
variables.  Since each operation generates at least one temporary variable,
a function can accumulate a high number of temporary variables if they are not
released as soon as possible.
Our generator implementation can benefit from early releasing of variables,
which reduces the size of the state to suspend at each yield point.


Notes on behavior of the live variable analysis
================================================


Variable deleted before definition
-----------------------------------

(Related issue: https://github.com/numba/numba/pull/1738)

When a variable lifetime is confined within the loop body (its definition and
usage does not escape the loop body), like:

.. code-block:: python

    def f(arr):
      # BB 0
      res = 0
      # BB 1
      for i in (0, 1):
          # BB 2
          t = arr[i]
{'fraction_non_alphanumeric': 0.10725401005506344, 'fraction_numerical': 0.006703375628441465, 'mean_word_length': 3.8244803695150114, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 3, 'https://': 6, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '4732745', 'n_tokens_mistral': 1037, 'n_tokens_neox': 992, 'n_words': 554}