AST Manipulation and Common Subexpression Elimination

Duncan Booth duncan at NOSPAMrcp.co.uk
Mon Oct 20 05:49:30 EDT 2003


Robert Kern <kern at ugcs.caltech.edu> wrote in
news:bmqovv$o2f$1 at naig.caltech.edu: 

> 
> 1. Can I do better than brute-force traversing the AST and trying to
> match each subtree to the other subtrees (using something like the
> match() function given in the parser module example)?

Use a dictionary.

If you convert the AST to nested tuples, then a code fragment such as the 
one below will suffice to make all common subexpressions share the same 
tuples. It fills 'info' with exactly one entry for each unique tuple in the 
original ast and counts the number of times it occurs. It should be easy 
enough then to go through the dictionary in order of increasing tuple 
length) and if an expression occurs more than once create a new AST to 
precalculate the value and assign to a temporary.

import parser

def optimise(ast, info):
    new = []
    for t in ast:
        if isinstance(t, tuple):
            new.append(optimise(t, info))
        else:
            new.append(t)
        
    new = tuple(new)
    new, oldcount = info.get(new, (new, 0))
    info[new] = (new, oldcount+1)
    return new

t = parser.ast2tuple(parser.expr("(1-x)*(1-x)/(1-x)"))
t_info = {}
t1 = optimise(t, t_info)
for node,v in t_info.values():
    print v,repr(node)[:50]

            


-- 
Duncan Booth                                             duncan at rcp.co.uk
int month(char *p){return(124864/((p[0]+p[1]-p[2]&0x1f)+1)%12)["\5\x8\3"
"\6\7\xb\1\x9\xa\2\0\4"];} // Who said my code was obscure?




More information about the Python-list mailing list