python / python/cpython

`LOAD_FAST` is not always converted to `LOAD_FAST_BORROW` in a `basicblock`

Ouverte
#145,629 5 commentaires 0 réactions 0 personnes assignées Voir sur GitHub

Personne n'a encore pris cette issue.

interpreter-core performance type-feature
Langage dominant
Python
Étoiles
77.2k
Forks
35.9k
Métriques de merge des PR
Métriques de PR en attente

Description

Bug report

Bug description:

Originally addressed in Issue #144388, the bytecode compiler does not always convert a LOAD_FAST instruction into a LOAD_FAST_BORROW. For example, the following python code, which gets compiled into only one basicblock, has a LOAD_FAST when it could have a LOAD_FAST_BORROW:

from dis import dis

def f(a,b):
    return a if a < b else b

dis(f)

Byte code

  3           RESUME                   0

  4           LOAD_FAST_BORROW_LOAD_FAST_BORROW 1 (a, b)
              COMPARE_OP              18 (bool(<))
              POP_JUMP_IF_FALSE        3 (to L1)
              NOT_TAKEN
              LOAD_FAST_BORROW         0 (a)
              RETURN_VALUE
      L1:     LOAD_FAST                1 (b)
              RETURN_VALUE

In contrast, the following expanded version of f does convert all LOAD_FAST instructions into LOAD_FAST_BORROW and has three different basic blocks:


from dis import dis

def g(a,b):
    if a < b:
        return a
    else:
        return b

dis(g)

Byte code

   3           RESUME                   0

  4           LOAD_FAST_BORROW_LOAD_FAST_BORROW 1 (a, b)
              COMPARE_OP              18 (bool(<))
              POP_JUMP_IF_FALSE        3 (to L1)
              NOT_TAKEN

  5           LOAD_FAST_BORROW         0 (a)
              RETURN_VALUE

  7   L1:     LOAD_FAST_BORROW         1 (b)
              RETURN_VALUE

The function of interest is optimize_load_fast in Python/flowgraph.c. I have tried to fix this bug but have not been able to yet. All I have found so far is that the LOAD_FAST instruction is misclassified as REF_UNCONSUMED here for the case of function f:
https://github.com/python/cpython/blob/149c4657507d17f78dd0938419a5a24ed71dc07e/Python/flowgraph.c#L3006-L3011

CPython versions tested on:

CPython main branch

Operating systems tested on:

Linux

Linked PRs
  • gh-146503

Guide de contribution

Ouvrir le guide de contribution

Par où commencer

  1. Lisez l'issue en entier, puis le guide de contribution du projet.
  2. Signalez en commentaire que vous la prenez — cela évite que deux personnes fassent le même travail.
  3. Forkez le dépôt et travaillez sur une branche.
  4. Ouvrez une pull request qui référence le numéro de l'issue.

Piste de recherche

Commencez dans Python/flowgraph.c, au niveau de optimize_load_fast, en particulier avec la classification autour des lignes 3006–3011. Comparez le bytecode produit pour la fonction f à un seul basicblock et pour la fonction g étendue, puis vérifiez que l’instruction LOAD_FAST concernée est convertie en LOAD_FAST_BORROW sans modifier le flux de contrôle généré.

Rédigé par le modèle d'indexation à partir du texte de l'issue.

Évaluation

Stack technique
python
Domaine
compilers
Type d'issue
Bug
Difficulté
3/5
Temps estimé
1-2 jours
Activité
À l'abandon
Clarté
Plutôt claire
Accessibilité débutants
35/100

Recevez les nouvelles issues par e-mail

Un résumé court des issues GitHub adaptées aux débutants.