class OPTIMIZE < $OPTIMIZE
****
This optimizer moves as many expressions as possible out of loops. An expression is movable if it is either * a constant * a constant from the beginning of the loop to its first call
___and_it_is_not_in_a_conditional_expression._We_have_to_check_two_cases:
____if_it_is_possible_that_the_expression_is_never_evaluated,_because_the_loop
____terminates_early_(iter_call,_return,_raise),_we_have_to_make_sure_that
____during_the_evaluation_of_the_code_there_is_no_fatal_error._Hence_we_
____move_only_local,_global_and_attr_expressions_out_of_the_loop._Attr_expressions
____are_guarded_against_void_accesses.
* if the code is in a conditional expression, we check that all it consists only of
___local,_global_or_attr_expressions_that_are_constant_during_the_whole_loop
___Attr_expressions_have_to_be_guarded_against_void_accesses.
NOTE: if an attr expression is guarded against void accesses, the program
_______will_not_stop_with_an_"void_access"_but_silently_continue._Therefore
_______you_should_not_use_-O_if_you_need_to_check_all_accesses.


Ancestors
$OPTIMIZE OPT_HELPER



Public


Features
check_leftover_functions(am:$AM_EXPR)
create(p:PROG):SAME
cs_options:CS_OPTIONS
do_loop_opt(func:AM_ROUT_DEF)
**** if func.sig.is_iter then mark_hot_args(func); end; unfortunatly it is very hard to do any optimizations within iters. The problem is that it not possible to move code or evaluate expressions before or after the yield statement where they were. It is for example impossible to move the expression 'a*b' out of a loop, as you don't know if the caller may change it or not:
____loop_yield_1.up!*a*b;_end;
This assumes that either a or b are attributes, and not locals of course. As it seems not worth the trouble, iters are not optimized at all (but we do inlining in iters, of course);
finalize
init
is_local(am:$AM):BOOL
m_one:AM_INT_CONST
m_two:AM_INT_CONST
make_sure_emitted(s:SIG)
mark_hot_args(func:AM_ROUT_DEF)
new_local(func:AM_ROUT_DEF,tp:$TP):AM_LOCAL_EXPR
new_local(func:AM_ROUT_DEF,tp:$TP,source:SFILE_ID):AM_LOCAL_EXPR
no_optimize(func:AM_ROUT_DEF)
**** if no optimization option is on, but opt_debug is on the compiler dumps the AM form of all functions. Handy to get them, but definitly the wrong place for this code. This will most certainly be deleted in future versions of the optimizer.
one:AM_INT_CONST
optimize(func:AM_ROUT_DEF)
prog:PROG
tp_bool:$TP
tp_char:$TP
tp_int:$TP
two:AM_INT_CONST
zero:AM_INT_CONST


Private

has_attr_expr(am:$AM):BOOL
has_no_iter(am:$AM):BOOL
hoistable(src:$AM_EXPR,c:AM_CURSOR,need_safe_attr:BOOL,in_conditional:BOOL):BOOL
hoistable_dest(desta:AM_ASSIGN_STMT,c:AM_CURSOR,need_safe_attr:BOOL,in_conditional:BOOL):BOOL
hoistable_init(src:$AM_EXPR,c:AM_CURSOR,need_safe_attr:BOOL,in_conditional:BOOL):BOOL
hoistable_init_dest(dest:$AM_EXPR,c:AM_CURSOR,need_safe_attr:BOOL,in_conditional:BOOL):BOOL
inline_func(func:AM_ROUT_DEF,am:AM_ROUT_CALL_EXPR,c:AM_CURSOR):BOOL
make_safe_attr(a:$AM)
make_unsafe_attr(a:$AM)
move_init_stmts(func:AM_ROUT_DEF,am:AM_ITER_CALL_EXPR,c:AM_CURSOR)