o_cse.sa
Generated by gen_html_sa_files from ICSI. Contact gomes@icsi.berkeley.edu for details
---------------------------> Sather 1.1 source file <--------------------------
class CSE_DOUBLE_EXPRS < $HASH
class CSE_DOUBLE_EXPRS < $HASH is
include COMPARABLE;
readonly attr expr:FLIST{$AM_EXPR};
readonly attr pos:FLIST{AM_CURSOR};
readonly attr locals:FLIST{AM_LOCAL_EXPR};
create(e:$AM_EXPR,c:AM_CURSOR):SAME is
r::=new;
r.expr:=r.expr.push(e);-- CSE_DOUBLE_EXPRS::expr CSE_DOUBLE_EXPRS::expr FLIST{1}::push
r.pos:=r.pos.push(#(c));-- CSE_DOUBLE_EXPRS::pos CSE_DOUBLE_EXPRS::pos FLIST{1}::push AM_CURSOR::create
r.locals:=r.locals.push(void);-- CSE_DOUBLE_EXPRS::locals CSE_DOUBLE_EXPRS::locals FLIST{1}::push
return r;
end;
add_loc(e:$AM_EXPR,c:AM_CURSOR) is
expr:=expr.push(e);-- CSE_DOUBLE_EXPRS::expr CSE_DOUBLE_EXPRS::expr FLIST{1}::push
pos:=pos.push(#(c));-- CSE_DOUBLE_EXPRS::pos CSE_DOUBLE_EXPRS::pos FLIST{1}::push AM_CURSOR::create
locals:=locals.push(void);-- CSE_DOUBLE_EXPRS::locals CSE_DOUBLE_EXPRS::locals FLIST{1}::push
end;
hash:INT is return expr[0].hash; end;-- CSE_DOUBLE_EXPRS::expr FLIST{1}::aget
is_eq(e:CSE_DOUBLE_EXPRS):BOOL is return expr[0] = e.expr[0]; end;-- CSE_DOUBLE_EXPRS::expr FLIST{1}::aget CSE_DOUBLE_EXPRS::expr FLIST{1}::aget
is_neq(e:CSE_DOUBLE_EXPRS):BOOL is return ~(expr[0] = e.expr[0]); end;
end;
class OPT_CSE
class OPT_CSE is
include OPT_HELPER;
remove_cse(func:AM_ROUT_DEF) is
c::=#AM_CURSOR(prog,func.code);-- AM_CURSOR::create OPT_CSE::prog AM_ROUT_DEF::code
c.ignore_pre:=true;-- AM_CURSOR::ignore_pre
c.ignore_post:=true;-- AM_CURSOR::ignore_post
c.ignore_assert:=true;-- AM_CURSOR::ignore_assert
c.assign_in_order:=true;-- AM_CURSOR::assign_in_order
exprs:FSET{CSE_DOUBLE_EXPRS};
replacements:FLIST{TUP{AM_CURSOR,$AM_EXPR}};
found_double::=false;
loop
if prog.opt_debug then-- OPT_CSE::prog PROG::opt_debug
#OUT+"O:CSE: current C: "+c.str;-- OUT::create OUT::plus OUT::plus AM_CURSOR::str
end;
am::=c.next!;-- AM_CURSOR::next!
if prog.opt_debug then-- OPT_CSE::prog PROG::opt_debug
#OUT+"O_CSE: "+SYS::str_for_tp(SYS::tp(am))+"\n";-- OUT::create OUT::plus OUT::plus SYS::str_for_tp SYS::tp OUT::plus
#OUT+"current C: "+c.str;-- OUT::create OUT::plus OUT::plus AM_CURSOR::str
end;
typecase am
-- some expressions are never replaced with locals
when AM_LOCAL_EXPR then
when AM_GLOBAL_EXPR then
when AM_CLUSTER_EXPR then
when AM_HERE_EXPR then
when $AM_CONST then
when $AM_EXPR then
if ~c.is_current_lhs and ~void(am.tp) then-- AM_CURSOR::is_current_lhs BOOL::not BOOL::not
e:CSE_DOUBLE_EXPRS:=#(am,c);-- CSE_DOUBLE_EXPRS::create
ee::=exprs.get(e);-- FSET{1}::get
if void(ee) then
exprs:=exprs.insert(e);-- FSET{1}::insert
if prog.opt_debug then-- OPT_CSE::prog PROG::opt_debug
#OUT+"inserting into CSE stack: ";AM_OUT::AM_out(am);#OUT+"\n";-- OUT::create OUT::plus AM_OUT::AM_out OUT::create OUT::plus
end;
else
e:=ee;
done::=false;
loop
i::=e.pos.ind!;-- CSE_DOUBLE_EXPRS::pos FLIST{1}::ind!
if SYS::id(e.expr[i])/=SYS::id(am) and-- SYS::id CSE_DOUBLE_EXPRS::expr FLIST{1}::aget INT::is_eq SYS::id BOOL::not
c.is_exec_after_and_const_from_there(e.pos[i],am) then-- AM_CURSOR::is_exec_after_and_const_from_there CSE_DOUBLE_EXPRS::pos FLIST{1}::aget
if void(e.locals[i]) then-- CSE_DOUBLE_EXPRS::locals FLIST{1}::aget
e.locals[i]:=new_local(func,am.tp,am.source);-- CSE_DOUBLE_EXPRS::locals FLIST{1}::aset OPT_CSE::new_local
as::=#AM_ASSIGN_STMT(e.locals[i].source);-- AM_ASSIGN_STMT::create CSE_DOUBLE_EXPRS::locals FLIST{1}::aget AM_LOCAL_EXPR::source
as.dest:=e.locals[i];-- AM_ASSIGN_STMT::dest CSE_DOUBLE_EXPRS::locals FLIST{1}::aget
as.src:=e.expr[i];-- AM_ASSIGN_STMT::src CSE_DOUBLE_EXPRS::expr FLIST{1}::aget
st::=#AM_STMT_EXPR(e.locals[i].source);-- AM_STMT_EXPR::create CSE_DOUBLE_EXPRS::locals FLIST{1}::aget AM_LOCAL_EXPR::source
st.stmts:=as;-- AM_STMT_EXPR::stmts
st.expr:=e.locals[i];-- AM_STMT_EXPR::expr CSE_DOUBLE_EXPRS::locals FLIST{1}::aget
replacements:=replacements.push(#TUP{AM_CURSOR,$AM_EXPR}(e.pos[i],st))-- FLIST{1}::push TUP{2}::create CSE_DOUBLE_EXPRS::pos FLIST{1}::aget
end;
prog.stat.incr("O: # of cse");-- OPT_CSE::prog PROG::stat
if prog.opt_debug then-- OPT_CSE::prog PROG::opt_debug
#OUT+"replacing ";-- OUT::create OUT::plus
AM_OUT::AM_out(am);-- AM_OUT::AM_out
#OUT+" with ";AM_OUT::AM_out(e.locals[i]);-- OUT::create OUT::plus AM_OUT::AM_out CSE_DOUBLE_EXPRS::locals FLIST{1}::aget
#OUT+"\n";-- OUT::create OUT::plus
end;
replacements:=replacements.push(#TUP{AM_CURSOR,$AM_EXPR}(#(c),e.locals[i]));-- FLIST{1}::push TUP{2}::create AM_CURSOR::create CSE_DOUBLE_EXPRS::locals FLIST{1}::aget
done:=true;
break!;
end;
end;
if ~done then-- BOOL::not
if prog.opt_debug then #OUT+"add_loc CSE stack: ";AM_OUT::AM_out(am);#OUT+"\n"; end;-- OPT_CSE::prog PROG::opt_debug OUT::create OUT::plus AM_OUT::AM_out OUT::create OUT::plus
e.add_loc(am,c);-- CSE_DOUBLE_EXPRS::add_loc
end;
end;
end;
else
end;
end;
if ~void(replacements) then-- BOOL::not
loop
tp::=replacements.elt!;-- FLIST{1}::elt!
if prog.opt_debug then-- OPT_CSE::prog PROG::opt_debug
#OUT+"replacing (lhs="+tp.t1.is_current_lhs+"):";-- OUT::create OUT::plus OUT::plus TUP{2}::t1 AM_CURSOR::is_current_lhs OUT::plus
AM_OUT::AM_out(tp.t1.cur);-- AM_OUT::AM_out TUP{2}::t1 AM_CURSOR::cur
#OUT+"\nwith: ";-- OUT::create OUT::plus
AM_OUT::AM_out(tp.t2);-- AM_OUT::AM_out TUP{2}::t2
#OUT+"\n";-- OUT::create OUT::plus
end;
tp.t1.replace_expr(tp.t2);-- TUP{2}::t1 AM_CURSOR::replace_expr TUP{2}::t2
end;
SYS::destroy(replacements);-- SYS::destroy
end;
if ~void(exprs) then SYS::destroy(exprs); end;-- BOOL::not SYS::destroy
end;
end;
-- vim:sw=3:nosmartindent