Skip to content

Dataflow analysis in the compiler to avoid runtime NULL checks #93143

Description

@sweeneyde

LOAD_FAST accounts for 14.6% of all bytecodes executed. Including superinstructions brings this up to 14.6+4.7+4.6+2.4+0.9 = 27.1%

cpython/Python/ceval.c

Lines 1864 to 1872 in 202ed25

TARGET(LOAD_FAST) {
PyObject *value = GETLOCAL(oparg);
if (value == NULL) {
goto unbound_local_error;
}
Py_INCREF(value);
PUSH(value);
DISPATCH();
}

We can turn this NULL-check into an assertion in many cases, where we can determine at compile time that the local variable is already initialized. Preliminary tests show that almost all LOAD_FAST instructions can be statically analyzed to be loading already-initialized variables.

The one twist is handling del frame.f_locals["x"] or frame.f_lineno = 17, where previously-safe loads could become unsafe. For now, we can just replace all the LOAD_FAST (no null check) with LOAD_FAST_CHECK in that particular code object.

See also faster-cpython/ideas#306

Activity

  1. added
    type-featureA feature request or enhancement
    performancePerformance or resource usage
    interpreter-core(Objects, Python, Grammar, and Parser dirs)
    on May 23, 2022
  2. added a commit that references this issue on May 31, 2022
  3. sweeneyde commented on Jun 1, 2022

    @sweeneyde
    MemberAuthor

    TODO: documentation

  4. added a commit that references this issue on Nov 8, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    interpreter-core(Objects, Python, Grammar, and Parser dirs)performancePerformance or resource usagetype-featureA feature request or enhancement

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions