From 1b07c728305a32a8d1fa1bb5da9d428e34dddf4e Mon Sep 17 00:00:00 2001 From: fche Date: Tue, 25 Apr 2006 17:40:53 +0000 Subject: 2006-04-25 Frank Ch. Eigler PR 2427. * staptree.cxx (varuse_collecting_visitor::visit_embeddedcode): Support /* pure */ declaration. Stop using __tvar_ naming hack. (v_c_u::visit_print_format): Mark sprint and sprintf as side-effect-free. (deep_copy_visitor::visit_print_format): Propagate raw_components. * stap.1.in: Document declaration. * elaborate.cxx (semantic_pass_opt2): Verbose message tweak. (dead_stmtexpr_remover): Extend for more aggressive optimization. * tapsets.cxx (dwarf,mark_var_expanding_copy_visotor): Add /* pure */ declaration to rvalue expansions. * tapset/*.stp: Added /* pure */ declarations to many functions. * testsuite/parseok/unparsers.stp: Propagate guru mode flag. * testsuite/buildok/twentyfour.stp: New test. --- elaborate.cxx | 56 +++++++++++++++++++++++++++++++++++++++++++++++++------- 1 file changed, 49 insertions(+), 7 deletions(-) (limited to 'elaborate.cxx') diff --git a/elaborate.cxx b/elaborate.cxx index 61e63cb1..976becd6 100644 --- a/elaborate.cxx +++ b/elaborate.cxx @@ -21,6 +21,9 @@ extern "C" { #include #include #include +#include +#include + using namespace std; @@ -1247,7 +1250,7 @@ void semantic_pass_opt2 (systemtap_session& s, bool& relaxed_p) { if (s.verbose>2) clog << "Eliding unused local variable " - << l->name << " in probe #" << i << endl; + << l->name << " in " << s.probes[i]->name << endl; s.probes[i]->locals.erase(s.probes[i]->locals.begin() + j); relaxed_p = false; // don't increment j @@ -1379,6 +1382,7 @@ struct dead_stmtexpr_remover: public traversing_visitor systemtap_session& session; bool& relaxed_p; statement** current_stmt; // pointer to current stmt* being iterated + set focal_vars; // vars considered subject to side-effects dead_stmtexpr_remover(systemtap_session& s, bool& r): session(s), relaxed_p(r), current_stmt(0) {} @@ -1421,7 +1425,23 @@ dead_stmtexpr_remover::visit_expr_statement (expr_statement *s) varuse_collecting_visitor vut; s->value->visit (& vut); - if (vut.written.empty() && !vut.embedded_seen) + + // Note that side-effect-freeness is not simply this test: + // + // (vut.written.empty() && !vut.embedded_seen) + // + // That's because the vut.written list may consist of local + // variables of called functions. Visible side-effects occur if + // *our* locals, or any *globals* are written-to. + + + set intersection; + insert_iterator > int_it (intersection, intersection.begin()); + set_intersection (vut.written.begin(), vut.written.end(), + focal_vars.begin(), focal_vars.end(), + int_it); + + if (intersection.empty() && ! vut.embedded_seen) { if (session.verbose>2) clog << "Eliding side-effect-free expression " @@ -1437,6 +1457,15 @@ dead_stmtexpr_remover::visit_expr_statement (expr_statement *s) relaxed_p = false; } + else if(session.verbose>3) + { + clog << "keeping expression " << *s->tok + << " because it writes: "; + for (std::set::iterator k = intersection.begin(); + k != intersection.end(); k++) + clog << (*k)->name << " "; + clog << "and/or embedded: " << vut.embedded_seen << endl; + } } @@ -1450,9 +1479,25 @@ void semantic_pass_opt4 (systemtap_session& s, bool& relaxed_p) // This instance may be reused for multiple probe/function body trims. for (unsigned i=0; ibody->visit (& duv); + { + duv.focal_vars.clear (); + duv.focal_vars.insert (s.globals.begin(), + s.globals.end()); + duv.focal_vars.insert (s.probes[i]->locals.begin(), + s.probes[i]->locals.end()); + s.probes[i]->body->visit (& duv); + } for (unsigned i=0; ibody->visit (& duv); + { + duv.focal_vars.clear (); + duv.focal_vars.insert (s.functions[i]->locals.begin(), + s.functions[i]->locals.end()); + duv.focal_vars.insert (s.functions[i]->formal_args.begin(), + s.functions[i]->formal_args.end()); + duv.focal_vars.insert (s.globals.begin(), + s.globals.end()); + s.functions[i]->body->visit (& duv); + } } @@ -1974,9 +2019,6 @@ typeresolution_info::visit_functioncall (functioncall* e) if (e->type == pe_stats) invalid (e->tok, e->type); - // XXX: but what about functions that return no value, - // and are used only as an expression-statement for side effects? - // now resolve the function parameters if (e->args.size() != e->referent->formal_args.size()) unresolved (e->tok); // symbol resolution should prevent this -- cgit