o_iter.sa


Generated by gen_html_sa_files from ICSI. Contact gomes@icsi.berkeley.edu for details
 
---------------------------> Sather 1.1 source file <--------------------------
-- this class is included in optimize.sa and cannot be
-- used stand alone

class OPT_ITER

class OPT_ITER is include OPT_HELPER; private opt_inlined_iter(func:AM_ROUT_DEF,n:AM_STMT_EXPR,c:AM_CURSOR, it:AM_ITER_CALL_EXPR,need_safe_attr:BOOL,in_conditional:BOOL) is -- This function tries to move iter initialization -- out of the loop -- -- we search for the first if statement of the form -- if some_bool_local -- we search for all other if some_bool_local statements -- some_bool_local must be a loop constant. -- The last if statement must have an assignment of the -- form some_bool_local:=false -- currently we check only AM_ASSIGN_STMT. AM_PRE, AM_POST and AM_ASSERT_STMT -- are deleted. -- we begin by inlining all functions if possible. -- (this has to be done here, as the code where this -- iter initializations may be moved to has already been checked -- for functions to be inlined. Therefor the iter code that is moved -- will never again be checked for such functions. cc::=#AM_CURSOR(prog,n.stmts);-- AM_CURSOR::create OPT_ITER::prog AM_STMT_EXPR::stmts loop am::=cc.next!; -- AM_CURSOR::next! typecase am when AM_ROUT_CALL_EXPR then dummy::=inline_func(func,am,cc);-- OPT_ITER::inline_func else end; end; am::=n.stmts;-- AM_STMT_EXPR::stmts lbool:AM_LOCAL_EXPR:=void; move_lbool::=true; -- search the bool local loop while!(~void(am) and void(lbool));-- BOOL::not typecase am when AM_IF_STMT then ifx::=am.test;-- AM_IF_STMT::test typecase ifx when AM_LOCAL_EXPR then lbool:=ifx; else end; else end; end; if void(lbool) then if prog.opt_debug then-- OPT_ITER::prog PROG::opt_debug #OUT+"could not move out statements, as I did not find the bool local\n";-- OUT::create OUT::plus end; return; end; if ~c.is_const_in_loop(lbool) then -- AM_CURSOR::is_const_in_loop BOOL::not if prog.opt_debug then-- OPT_ITER::prog PROG::opt_debug #OUT+"sorry, but the local bool var is not a loop const: ";-- OUT::create OUT::plus AM_OUT::AM_out(lbool);#OUT+"\n";-- AM_OUT::AM_out OUT::create OUT::plus end; return; end; if c.loop_stmt.firsts.index_of(lbool)<0 then-- AM_CURSOR::loop_stmt AM_LOOP_STMT::firsts FLIST{1}::index_of INT::is_lt if prog.opt_debug then-- OPT_ITER::prog PROG::opt_debug #OUT+"the local bool constant I found will not be initialized to true at the beginning of the loop\n";-- OUT::create OUT::plus end; return; end; -- find the first and only ASSIGN_STMT for lbool -- check that there are no more. c1::=#AM_CURSOR(prog,n.stmts);-- AM_CURSOR::create OPT_ITER::prog AM_STMT_EXPR::stmts c1.ignore_pre:=true;-- AM_CURSOR::ignore_pre c1.ignore_post:=true;-- AM_CURSOR::ignore_post c1.ignore_assert:=true;-- AM_CURSOR::ignore_assert found_it::=false; ignore_next_reference::=true; loop d::=c1.next!;-- AM_CURSOR::next! typecase d when AM_ASSIGN_STMT then dst::=d.dest;-- AM_ASSIGN_STMT::dest typecase dst when AM_LOCAL_EXPR then if dst=lbool then-- AM_LOCAL_EXPR::is_eq if found_it then if prog.opt_debug then-- OPT_ITER::prog PROG::opt_debug #OUT+"found two assignments to the bool local :-(\n";-- OUT::create OUT::plus end; return; else found_it:=true; -- there is just one reference to the local var left, -- namely the one in this assign stmt. ignore_next_reference:=true; -- the assignment must be within an if stmt, so its -- indent must be 1 if c1.indent/=1 then-- AM_CURSOR::indent INT::is_eq BOOL::not if prog.opt_debug then-- OPT_ITER::prog PROG::opt_debug #OUT+"indent="+c1.indent+", so assignment is not at the first level of an if stmt.\n";-- OUT::create OUT::plus OUT::plus AM_CURSOR::indent OUT::plus end; return ; end; s::=c1.get_surr_stmt;-- AM_CURSOR::get_surr_stmt typecase s when AM_IF_STMT then t::=s.test;-- AM_IF_STMT::test typecase t when AM_LOCAL_EXPR then if t/=lbool then-- AM_LOCAL_EXPR::is_eq BOOL::not if prog.opt_debug then-- OPT_ITER::prog PROG::opt_debug #OUT+"wrong test local expr in if stmt.\n";-- OUT::create OUT::plus end; return; end; else if prog.opt_debug then-- OPT_ITER::prog PROG::opt_debug #OUT+"wrong test clause in if stmt.\n";-- OUT::create OUT::plus end; return; end; tr::=s.if_true;-- AM_IF_STMT::if_true loop while!(~void(tr));-- BOOL::not if SYS::id(tr)=SYS::id(d) then break!; end;-- SYS::id INT::is_eq SYS::id tr:=tr.next; end; if void(tr) then if prog.opt_debug then -- OPT_ITER::prog PROG::opt_debug #OUT+"Assignment is not in the true clause of the if stmt\n";-- OUT::create OUT::plus end; end; src::=d.src;-- AM_ASSIGN_STMT::src typecase src when AM_BOOL_CONST then if src.val/=false then-- AM_BOOL_CONST::val BOOL::is_eq BOOL::not if prog.opt_debug then-- OPT_ITER::prog PROG::opt_debug #OUT+"Assignment is :=true instead of :=false\n";-- OUT::create OUT::plus end; return; end; else if prog.opt_debug then-- OPT_ITER::prog PROG::opt_debug #OUT+"Assignment is not :=true\n";-- OUT::create OUT::plus end; return; end; else if prog.opt_debug then-- OPT_ITER::prog PROG::opt_debug #OUT+"assignment is not within an if stmt\n";-- OUT::create OUT::plus end; return; end; end; end; else end; when AM_LOCAL_EXPR then if found_it then -- check that lbool is not used after the -- assignment lbool:=false; if ignore_next_reference then ignore_next_reference:=false; else if d=lbool then-- AM_LOCAL_EXPR::is_eq if prog.opt_debug then-- OPT_ITER::prog PROG::opt_debug #OUT+"there is a reference to lbool after lbool:=false;\n";-- OUT::create OUT::plus end; return; end; end; end; else end; end; -- When we get here, we know the correct bool local, and -- can proceed to move the statments out of the if if prog.opt_debug then-- OPT_ITER::prog PROG::opt_debug #OUT+"it seems that we can move out some statements\n";-- OUT::create OUT::plus end; comment::=#AM_COMMENT_STMT(it.source);-- AM_COMMENT_STMT::create AM_ITER_CALL_EXPR::source comment.comment:="Initialization of inlined iter "+it.fun.str;-- AM_COMMENT_STMT::comment STR::plus AM_ITER_CALL_EXPR::fun SIG::str c.insert_in_loop_init(comment);-- AM_CURSOR::insert_in_loop_init pr:$AM_STMT:=void; am:=n.stmts;-- AM_STMT_EXPR::stmts inlined::=#AM_CURSOR(prog,n.stmts);-- AM_CURSOR::create OPT_ITER::prog AM_STMT_EXPR::stmts inlined.ignore_pre:=true;-- AM_CURSOR::ignore_pre inlined.ignore_post:=true;-- AM_CURSOR::ignore_post inlined.ignore_assert:=true;-- AM_CURSOR::ignore_assert inlined.init_next;inlined.next;-- AM_CURSOR::init_next AM_CURSOR::next loop while!(~void(am));-- BOOL::not typecase am when AM_IF_STMT then l::=am.test;-- AM_IF_STMT::test typecase l when AM_LOCAL_EXPR then if l=lbool then-- AM_LOCAL_EXPR::is_eq pr:=void; if ~void(am.if_false) then move_lbool:=false; end;-- AM_IF_STMT::if_false BOOL::not ifs::=am.if_true;-- AM_IF_STMT::if_true inlined.next; -- moves to bool local-- AM_CURSOR::next inlined.next; -- moves to first statement-- AM_CURSOR::next loop while!(~void(ifs));-- BOOL::not nifs::=ifs.next; p::=ifs; do_move::=false; ignore_stmt::=false; delete_it::=false; if SYS::id(ifs)/=SYS::id(inlined.cur) then-- SYS::id INT::is_eq SYS::id AM_CURSOR::cur BOOL::not #OUT+"inlined and ifs disagree about the current statement\n";-- OUT::create OUT::plus #OUT+"ifs says:\n";-- OUT::create OUT::plus AM_OUT::AM_out(ifs);-- AM_OUT::AM_out #OUT+"and inlined is at:\n";-- OUT::create OUT::plus AM_OUT::AM_out(inlined.cur);-- AM_OUT::AM_out AM_CURSOR::cur UNIX::exit(-1);-- UNIX::exit end; typecase ifs when AM_ASSIGN_STMT then if (~need_safe_attr or ~prog.void_checks or ~has_attr_expr(ifs))-- BOOL::not OPT_ITER::prog PROG::void_checks BOOL::not OPT_ITER::has_attr_expr BOOL::not and hoistable_init_dest(ifs.dest,c,need_safe_attr,in_conditional)-- OPT_ITER::hoistable_init_dest AM_ASSIGN_STMT::dest and hoistable_init(ifs.src,c,need_safe_attr,in_conditional) -- OPT_ITER::hoistable_init AM_ASSIGN_STMT::src and inlined.is_not_used_in_func_before_eval_cur_expr(ifs.dest)-- AM_CURSOR::is_not_used_in_func_before_eval_cur_expr AM_ASSIGN_STMT::dest and inlined.is_const_in_func_before_eval_cur_expr(ifs.src)-- AM_CURSOR::is_const_in_func_before_eval_cur_expr AM_ASSIGN_STMT::src then adest::=ifs.dest;-- AM_ASSIGN_STMT::dest typecase adest when AM_LOCAL_EXPR then do_move:=true; else if ~need_safe_attr then-- BOOL::not do_move:=true; end; end; if need_safe_attr and do_move then make_safe_attr(ifs);-- OPT_ITER::make_safe_attr end; else adest::=ifs.dest;-- AM_ASSIGN_STMT::dest typecase adest when AM_LOCAL_EXPR then if adest=lbool then-- AM_LOCAL_EXPR::is_eq ignore_stmt:=true; end; else end; if prog.opt_debug then-- OPT_ITER::prog PROG::opt_debug if ~hoistable_init_dest(ifs.dest,c,need_safe_attr,in_conditional) then-- OPT_ITER::hoistable_init_dest AM_ASSIGN_STMT::dest BOOL::not #OUT+"cannot move assign stmt, as it has no hoistable destination\n";-- OUT::create OUT::plus end; if ~hoistable_init(ifs.src,c,need_safe_attr,in_conditional) then-- OPT_ITER::hoistable_init AM_ASSIGN_STMT::src BOOL::not #OUT+"cannot move assign stmt, as it has no hoistable source\n";-- OUT::create OUT::plus end; if ~inlined.is_not_used_in_func_before_eval_cur_expr(ifs.dest) then-- AM_CURSOR::is_not_used_in_func_before_eval_cur_expr AM_ASSIGN_STMT::dest BOOL::not #OUT+"cannot move assign stmt, as dest is used in inlined iter\n";-- OUT::create OUT::plus end; if ~inlined.is_const_in_func_before_eval_cur_expr(ifs.src) then-- AM_CURSOR::is_const_in_func_before_eval_cur_expr AM_ASSIGN_STMT::src BOOL::not #OUT+"cannot move assign stmt, as source is not const in inlined iter\n";-- OUT::create OUT::plus end; end; end; when AM_PRE_STMT then if ~prog.pre_checks then delete_it:=true; end;-- OPT_ITER::prog PROG::pre_checks BOOL::not when AM_POST_STMT then if ~prog.post_checks then delete_it:=true; end;-- OPT_ITER::prog PROG::post_checks BOOL::not when AM_ASSERT_STMT then if ~prog.assert_checks then delete_it:=true; end;-- OPT_ITER::prog PROG::assert_checks BOOL::not else end; -- typecase if do_move then if void(pr) then am.if_true:=ifs.next;-- AM_IF_STMT::if_true else pr.next:=ifs.next; end; nifs:=ifs.next; p:=pr; ifs.next:=void; c.insert_in_loop_init(ifs);-- AM_CURSOR::insert_in_loop_init if prog.opt_debug then-- OPT_ITER::prog PROG::opt_debug #OUT+"moving the assign stmt to the beginning of the loop:\n";-- OUT::create OUT::plus AM_OUT::AM_one_stmt(ifs);-- AM_OUT::AM_one_stmt end; -- well, we removed the current stmt of inlined, so we have -- to trick it a bit and set it to the correct stmt. There is -- just one problem, namely if the next statment is void. in -- this case we "invent" a new statment; if void(nifs) then inlined.cur:=#AM_COMMENT_STMT(void);-- AM_CURSOR::cur AM_COMMENT_STMT::create else inlined.cur:=nifs;-- AM_CURSOR::cur end; elsif delete_it then if void(pr) then am.if_true:=ifs.next;-- AM_IF_STMT::if_true else pr.next:=ifs.next; end; nifs:=ifs.next; p:=pr; ifs.next:=void; -- well, we removed the current stmt of inlined, so we have -- to trick it a bit and set it to the correct stmt. There is -- just one problem, namely if the next statment is void. in -- this case we "invent" a new statment; if void(nifs) then inlined.cur:=#AM_COMMENT_STMT(void);-- AM_CURSOR::cur AM_COMMENT_STMT::create else inlined.cur:=nifs;-- AM_CURSOR::cur end; elsif ~ignore_stmt then -- BOOL::not move_lbool:=false; end; pr:=p; ifs:=nifs; -- if void(ifs) then we move inlined 5 statements below, -- and if do_move, we already moved it 10 statements above. if ~void(ifs) and ~do_move and ~delete_it then inlined.next_stmt; end;-- BOOL::not BOOL::not BOOL::not AM_CURSOR::next_stmt end; -- loop -- we must be careful to move the inlined cursor over the if_false -- part of the if statement. inlined.surr_stmt;-- AM_CURSOR::surr_stmt inlined.after_if;-- AM_CURSOR::after_if end; -- if l=lbool else end; -- AM_LOCAL_EXPR else end; -- AM_IF_STMT am:=am.next; inlined.next_stmt;-- AM_CURSOR::next_stmt end; -- loop -- now we have to delete all empty if statements. -- if move_lbool is true, we can delete them without -- checking, otherwise we must make sure that if_true and -- if_false are both void. pr:=void; am:=n.stmts;-- AM_STMT_EXPR::stmts loop while!(~void(am));-- BOOL::not amm::=am; typecase amm when AM_IF_STMT then l::=amm.test;-- AM_IF_STMT::test typecase l when AM_LOCAL_EXPR then if l=lbool then-- AM_LOCAL_EXPR::is_eq if move_lbool or (void(amm.if_true) and void(amm.if_false)) then-- AM_IF_STMT::if_true AM_IF_STMT::if_false prog.stat.incr("O: # if stmts removed");-- OPT_ITER::prog PROG::stat if void(pr) then n.stmts:=am.next;-- AM_STMT_EXPR::stmts am:=n.stmts;-- AM_STMT_EXPR::stmts else pr.next:=am.next; am:=am.next; end; else pr:=am; am:=am.next; end; else pr:=am; am:=am.next; end; else pr:=am; am:=am.next; end; else pr:=am; am:=am.next; end; end; -- loop -- Well, that's it. end; private inline_iter(func:AM_ROUT_DEF,am:AM_ITER_CALL_EXPR,c:AM_CURSOR, do_optimization:BOOL,need_safe_attr:BOOL,in_conditional:BOOL):BOOL is if ~prog.inline_iters then return false; end;-- OPT_ITER::prog PROG::inline_iters BOOL::not ok::=false; if prog.opt_debug then -- OPT_ITER::prog PROG::opt_debug #OUT+"Trying to inline the iter call "+am.fun.str+":";-- OUT::create OUT::plus OUT::plus AM_ITER_CALL_EXPR::fun SIG::str OUT::plus end; n::=prog.inliner.general_inline(func,c.loop_stmt,am);-- OPT_ITER::prog PROG::inliner AM_CURSOR::loop_stmt if ~SYS::ob_eq(n,am) then-- SYS::ob_eq BOOL::not prog.stat.incr("O: # of iter calls inlined");-- OPT_ITER::prog PROG::stat if prog.opt_debug then -- OPT_ITER::prog PROG::opt_debug #OUT+"done\n";-- OUT::create OUT::plus end; if prog.hoist_iter_init and do_optimization then -- OPT_ITER::prog PROG::hoist_iter_init typecase n when AM_STMT_EXPR then -- we have to remove the iter, as otherwise -- side effects from it may interfere with -- the optimization below. We replace it with a dummy -- is_void_expr, which is removed later (a noop -- expr would be better, of course). if prog.opt_debug then-- OPT_ITER::prog PROG::opt_debug #OUT+"iter code before optimization:\n";-- OUT::create OUT::plus AM_OUT::AM_out(n);-- AM_OUT::AM_out #OUT+"\n";-- OUT::create OUT::plus end; c.replace_expr(#AM_IS_VOID_EXPR(void)); -- AM_CURSOR::replace_expr AM_IS_VOID_EXPR::create opt_inlined_iter(func,n,c,am,need_safe_attr,in_conditional);-- OPT_ITER::opt_inlined_iter if prog.opt_debug then-- OPT_ITER::prog PROG::opt_debug #OUT+"iter code after optimization:\n";-- OUT::create OUT::plus AM_OUT::AM_out(n);-- AM_OUT::AM_out #OUT+"\n";-- OUT::create OUT::plus end; else end; -- we only consider standard inlined iters end; c.replace_expr(n); -- insert the optimized version.-- AM_CURSOR::replace_expr ok:=true; else if prog.opt_debug then-- OPT_ITER::prog PROG::opt_debug #OUT+"no way\n";-- OUT::create OUT::plus end; end; return ok; end; work_on_iter(func:AM_ROUT_DEF,am:AM_ITER_CALL_EXPR,c:AM_CURSOR,after_loop_break:ARRAY{BOOL}) is stmt::=am.init;-- AM_ITER_CALL_EXPR::init do_optimize::=~func.is_iter and c.not_in_a_case_in_a_loop;-- AM_ROUT_DEF::is_iter BOOL::not AM_CURSOR::not_in_a_case_in_a_loop need_safe_attr::=false; has_attr::=false; in_conditional::= ~c.not_in_a_conditional_in_loop;-- AM_CURSOR::not_in_a_conditional_in_loop -- if ~in_conditional the iter can use the loop index am.use_loop_index:=~in_conditional and am.fun.is_builtin and am.fun.builtin_info.use_index;-- AM_ITER_CALL_EXPR::use_loop_index BOOL::not AM_ITER_CALL_EXPR::fun SIG::is_builtin AM_ITER_CALL_EXPR::fun SIG::builtin_info CONFIG_ROUT::use_index if am.use_loop_index then prog.stat.incr("O: iters using a loop index variable"); end;-- AM_ITER_CALL_EXPR::use_loop_index OPT_ITER::prog PROG::stat if am.use_loop_index and void(am.lp.loop_index_var) then-- AM_ITER_CALL_EXPR::use_loop_index AM_ITER_CALL_EXPR::lp AM_LOOP_STMT::loop_index_var prog.stat.incr("O: loops having a loop index variable");-- OPT_ITER::prog PROG::stat am.lp.loop_index_var:=new_local(func,tp_int);-- AM_ITER_CALL_EXPR::lp AM_LOOP_STMT::loop_index_var OPT_ITER::new_local OPT_ITER::tp_int as::=#AM_ASSIGN_STMT(am.lp.source);-- AM_ASSIGN_STMT::create AM_ITER_CALL_EXPR::lp AM_LOOP_STMT::source as.dest:=am.lp.loop_index_var;-- AM_ASSIGN_STMT::dest AM_ITER_CALL_EXPR::lp AM_LOOP_STMT::loop_index_var as.src:=zero;-- AM_ASSIGN_STMT::src OPT_ITER::zero comment::=#AM_COMMENT_STMT(am.source);-- AM_COMMENT_STMT::create AM_ITER_CALL_EXPR::source comment.comment:="loop index variable";-- AM_COMMENT_STMT::comment c.insert_in_loop_init(comment);-- AM_CURSOR::insert_in_loop_init c.insert_in_loop_init(as);-- AM_CURSOR::insert_in_loop_init p::=#AM_ASSIGN_STMT(am.lp.source);-- AM_ASSIGN_STMT::create AM_ITER_CALL_EXPR::lp AM_LOOP_STMT::source p.dest:=am.lp.loop_index_var;-- AM_ASSIGN_STMT::dest AM_ITER_CALL_EXPR::lp AM_LOOP_STMT::loop_index_var mi::=#AM_ROUT_CALL_EXPR(2,am.lp.source);-- AM_ROUT_CALL_EXPR::create AM_ITER_CALL_EXPR::lp AM_LOOP_STMT::source func.calls:=func.calls.push(mi);-- AM_ROUT_DEF::calls AM_ROUT_DEF::calls FLIST{1}::push mi[0]:=#(p.dest);-- AM_ROUT_CALL_EXPR::aset AM_CALL_ARG::create AM_ASSIGN_STMT::dest mi[1]:=#(one);-- AM_ROUT_CALL_EXPR::aset AM_CALL_ARG::create OPT_ITER::one args::=#ARRAY{ARG}(1);-- ARRAY{1}::create args[0]:=#(tp_int);-- ARRAY{1}::aset ARG::create OPT_ITER::tp_int mi.fun:=#SIG(tp_int, #ARRAY{$TP}(0),-- AM_ROUT_CALL_EXPR::fun SIG::create OPT_ITER::tp_int ARRAY{1}::create IDENT_BUILTIN::plus_ident, args, tp_int, true);-- IDENT_BUILTIN::plus_ident OPT_ITER::tp_int prog.generate_am.output_sig(mi.fun);-- OPT_ITER::prog PROG::generate_am AM_ROUT_CALL_EXPR::fun p.src:=mi;-- AM_ASSIGN_STMT::src c.append_to_loop(p);-- AM_CURSOR::append_to_loop end; -- check if we can safely move the initialization of the current iter -- to the beginning of the loop. This assumes that all assignments in the -- ini field of the iter are to local variables which are only used during -- the call of the iter and never somewhere else in the loop. loop while!(~void(stmt) and do_optimize);-- BOOL::not typecase stmt when AM_ASSIGN_STMT then if ~c.is_const(stmt.src) then-- AM_CURSOR::is_const AM_ASSIGN_STMT::src BOOL::not need_safe_attr:=after_loop_break[c.loops] or in_conditional;-- ARRAY{1}::aget AM_CURSOR::loops do_optimize:=hoistable_init(stmt.src,c,need_safe_attr,in_conditional);-- OPT_ITER::hoistable_init AM_ASSIGN_STMT::src has_attr:=has_attr_expr(stmt.src);-- OPT_ITER::has_attr_expr AM_ASSIGN_STMT::src if ~do_optimize and prog.opt_debug then-- BOOL::not OPT_ITER::prog PROG::opt_debug #OUT+"the following expression is not hoistable: (need_safe_attr="+need_safe_attr+" in_cond="+in_conditional+")\n";-- OUT::create OUT::plus OUT::plus OUT::plus OUT::plus OUT::plus AM_OUT::AM_out(stmt.src);-- AM_OUT::AM_out AM_ASSIGN_STMT::src #OUT+"\n";-- OUT::create OUT::plus end; end; else if prog.opt_debug then-- OPT_ITER::prog PROG::opt_debug #OUT+"ignoring iter "+am.fun.str+" because its init_stmt has not only AM_ASSIGN_STMT\n";-- OUT::create OUT::plus OUT::plus AM_ITER_CALL_EXPR::fun SIG::str OUT::plus end; do_optimize:=false; end; stmt:=stmt.next; end; if do_optimize and need_safe_attr and has_attr and prog.void_checks then-- OPT_ITER::prog PROG::void_checks do_optimize:=false; end; if do_optimize then if ~inline_iter(func,am,c,true,need_safe_attr,in_conditional) then-- OPT_ITER::inline_iter BOOL::not prog.stat.incr("O: # of iters not inlined");-- OPT_ITER::prog PROG::stat if prog.opt_verbose and ~am.fun.is_builtin then-- OPT_ITER::prog PROG::opt_verbose AM_ITER_CALL_EXPR::fun SIG::is_builtin BOOL::not #OUT+am.source.str+": INFO: iter "+am.fun.str+" ignored by inliner.\n";-- OUT::create OUT::plus AM_ITER_CALL_EXPR::source SFILE_ID::str OUT::plus OUT::plus AM_ITER_CALL_EXPR::fun SIG::str OUT::plus end; if prog.hoist_iter_init then-- OPT_ITER::prog PROG::hoist_iter_init if need_safe_attr then make_safe_attr(am.init); end;-- OPT_ITER::make_safe_attr AM_ITER_CALL_EXPR::init move_init_stmts(func,am,c);-- OPT_ITER::move_init_stmts end; end; else if prog.opt_verbose and ~am.fun.is_builtin then-- OPT_ITER::prog PROG::opt_verbose AM_ITER_CALL_EXPR::fun SIG::is_builtin BOOL::not #OUT+am.source.str+": INFO: iter "+am.fun.str+" ignored by optimizer.\n";-- OUT::create OUT::plus AM_ITER_CALL_EXPR::source SFILE_ID::str OUT::plus OUT::plus AM_ITER_CALL_EXPR::fun SIG::str OUT::plus end; if ~inline_iter(func,am,c,false,false,in_conditional) then-- OPT_ITER::inline_iter BOOL::not if prog.opt_verbose and ~am.fun.is_builtin then-- OPT_ITER::prog PROG::opt_verbose AM_ITER_CALL_EXPR::fun SIG::is_builtin BOOL::not #OUT+am.source.str+": INFO: iter "+am.fun.str+" ignored by inliner.\n";-- OUT::create OUT::plus AM_ITER_CALL_EXPR::source SFILE_ID::str OUT::plus OUT::plus AM_ITER_CALL_EXPR::fun SIG::str OUT::plus end; prog.stat.incr("O: # of iters not optimized and not inlined");-- OPT_ITER::prog PROG::stat -- if prog.opt_debug then -- #OUT+"do_optimize="+do_optimize+" in_conditional="+in_conditional+"\n"; -- #OUT+"code: "; -- AM_OUT::AM_out(am,0,5); -- #OUT+"\n"; -- end; end; prog.stat.incr("O: # of iters not optimized");-- OPT_ITER::prog PROG::stat end; end; end;