Moderately tested patch for the LOAD_GLOBAL optimization

Tim Peters (tim@ksr.com)
Mon, 04 Apr 94 22:22:05 -0400

If anyone wants to try this, take the patch file below (or this whole
msg), and

cd $YOUR_PYTHON_ROOT_DIRECTORY/Python
patch < this_file
cd .. # i.e., back up to the root
make # i.e., rebuild python; hope you left .o's behind from last time

All my code runs fine with this installed, but despite the fun I have
spewing sickness to the list I avoid pathological stuff in real life. If
it breaks any of your code, I'll be surprised enough to try to find out
why <wink>.

Note that the bulk of the patch is just bringing the comments into synch
with the code. There are only two _code_ changes. One implements the
LOAD_GLOBAL optimization, and the other removes the current "skip
optimization if there are no locals" test (because there may still be
non-local loads to optimize; actually, there are so few functions with
_no_ locals that it may always have cost more to special-case that ...).

demanding-a-secret-python-guru-hat-if-this-works<grin>-ly y'rs - tim

Tim Peters tim@ksr.com
not speaking for Kendall Square Research Corp

*** compile.c Mon Apr 4 21:32:42 1994
--- compile.c.new Mon Apr 4 21:39:09 1994
***************
*** 2222,2244 ****
instructions that refer to local variables with LOAD_FAST etc.
The latter instructions are much faster because they don't need to
look up the variable name in a dictionary.
-
- To find all local variables, we check all STORE_NAME and IMPORT_FROM
- instructions. This yields all local variables, including arguments,
- function definitions, class definitions and import statements.
- (We don't check DELETE_NAME instructions, since if there's no
- STORE_NAME the DELETE_NAME will surely fail.)
-
- There is one problem: 'from foo import *' introduces local variables
- that we can't know while compiling. If this is the case, wo don't
- optimize at all (this rarely happens, since this form of import
- statement is mostly used at the module level).

! Note that, because of this optimization, code like the following
! won't work:
! eval('x = 1')
! print x
!
NB: this modifies the string object co->co_code!
*/

--- 2222,2242 ----
instructions that refer to local variables with LOAD_FAST etc.
The latter instructions are much faster because they don't need to
look up the variable name in a dictionary.

! To find all local variables, we check all STORE_NAME, IMPORT_FROM and
! DELETE_NAME instructions. This yields all local variables, including
! arguments, function definitions, class definitions and import
! statements.
!
! All remaining LOAD_NAME instructions must refer to non-local (global
! or builtin) variables, so are replaced by LOAD_GLOBAL.
!
! There are two problems: 'from foo import *' and 'exec' may introduce
! local variables that we can't know while compiling. If this is the
! case, we don't optimize at all (this rarely happens, since exec is
! rare, & this form of import statement is mostly used at the module
! level).
!
NB: this modifies the string object co->co_code!
*/

***************
*** 2300,2306 ****
}
}

! if (nlocals == 0 || dictlookup(locals, "*") != NULL) {
/* Don't optimize anything */
goto end;
}
--- 2298,2304 ----
}
}

! if (dictlookup(locals, "*") != NULL) {
/* Don't optimize anything */
goto end;
}
***************
*** 2332,2337 ****
--- 2330,2337 ----
v = dict2lookup(locals, name);
if (v == NULL) {
err_clear();
+ if (opcode == LOAD_NAME)
+ cur_instr[0] = LOAD_GLOBAL;
continue;
}
i = getintvalue(v);