diff options
author | fche <fche> | 2006-01-24 17:58:02 +0000 |
---|---|---|
committer | fche <fche> | 2006-01-24 17:58:02 +0000 |
commit | cbfbbf6996cbe3b9fe57ac2014aa7262bb6890d6 (patch) | |
tree | 89b507411bd828b12142f0962be3eb4a33c3a45d /staptree.cxx | |
parent | 46746514a6943520ff73b6f77d35477e2abb30ba (diff) | |
download | systemtap-steved-cbfbbf6996cbe3b9fe57ac2014aa7262bb6890d6.tar.gz systemtap-steved-cbfbbf6996cbe3b9fe57ac2014aa7262bb6890d6.tar.xz systemtap-steved-cbfbbf6996cbe3b9fe57ac2014aa7262bb6890d6.zip |
2006-01-24 Frank Ch. Eigler <fche@elastic.org>
PR 2060 etc.
* tapsets.cxx (visit_target_symbol): Tolerate failed resolution by
letting target_symbol instance pass through to optimizer and
type checker.
* elaborate.cxx (semantic_pass_optimize): New family of functions and
associated visitor classes.
(visit_for_loop): Tolerate absent init/incr clauses.
(semantic_pass): Invoke unless unoptimized (-u) option given.
* main.cxx, session.h: Add support for flag.
* staptree.cxx (visit_for_loop): Tolerate absent init/incr clauses.
(traversing_visitor::visit_arrayindex): Visit the index expressions.
(functioncall_traversing_visitor): New class.
(varuse_tracking_visitor): New class.
* staptree.h: Corresponding changes.
* parse.cxx (parse_for_loop): Represent absent init/incr expressions
with null statement pointer instead of optimized-out dummy numbers.
* stap.1.in: Document optimization.
* testsuite/{semko,transko}/*.stp: Added "-u" or other code to many
tests to check bad code without optimizer elision.
* testsuite/semok/optimize.stp: New test.
* elaborate.cxx (unresolved, invalid, mismatch): Standardize error
message wording.
* stapfuncs.5.in: Tweak print/printf docs.
* tapset/logging.stp: Remove redundant "print" auxiliary function,
since it's a translator built-in.
* testsuite/transok/five.stp: Extend test.
* translate.cxx (emit_symbol_data): Put symbol table into a separate
temporary header file, to make "-p3" output easier on the eyes.
* buildrun.cxx (compile_pass): Eliminate test-mode support throughout.
* main.cxx, session.h, translate.cxx: Ditto.
* main.cxx (main): For last-pass=2 runs, print post-optimization ASTs.
Diffstat (limited to 'staptree.cxx')
-rw-r--r-- | staptree.cxx | 149 |
1 files changed, 143 insertions, 6 deletions
diff --git a/staptree.cxx b/staptree.cxx index 0eb898ac..97b4bcc1 100644 --- a/staptree.cxx +++ b/staptree.cxx @@ -691,11 +691,11 @@ void block::print (ostream& o) const void for_loop::print (ostream& o) const { o << "for ("; - init->print (o); + if (init) init->print (o); o << "; "; cond->print (o); o << "; "; - incr->print (o); + if (incr) incr->print (o); o << ") "; block->print (o); } @@ -1262,9 +1262,9 @@ traversing_visitor::visit_if_statement (if_statement* s) void traversing_visitor::visit_for_loop (for_loop* s) { - s->init->visit (this); + if (s->init) s->init->visit (this); s->cond->visit (this); - s->incr->visit (this); + if (s->incr) s->incr->visit (this); s->block->visit (this); } @@ -1409,6 +1409,9 @@ traversing_visitor::visit_target_symbol (target_symbol* e) void traversing_visitor::visit_arrayindex (arrayindex* e) { + for (unsigned i=0; i<e->indexes.size(); i++) + e->indexes[i]->visit (this); + symbol *array = NULL; hist_op *hist = NULL; classify_indexable(e->base, array, hist); @@ -1416,8 +1419,6 @@ traversing_visitor::visit_arrayindex (arrayindex* e) return array->visit(this); else return hist->visit(this); - for (unsigned i=0; i<e->indexes.size(); i++) - e->indexes[i]->visit (this); } void @@ -1449,6 +1450,142 @@ traversing_visitor::visit_hist_op (hist_op* e) } +void +functioncall_traversing_visitor::visit_functioncall (functioncall* e) +{ + traversing_visitor::visit_functioncall (e); + + // prevent infinite recursion + if (traversed.find (e->referent) == traversed.end ()) + { + traversed.insert (e->referent); + // recurse + e->referent->body->visit (this); + } +} + + +void +varuse_collecting_visitor::visit_embeddedcode (embeddedcode *s) +{ + embedded_seen = true; +} + + +void +varuse_collecting_visitor::visit_print_format (print_format* e) +{ + // NB: Instead of being top-level statements, "print" and "printf" + // are implemented as statement-expressions containing a + // print_format. They have side-effects, but not via the + // embedded-code detection method above. + embedded_seen = true; + functioncall_traversing_visitor::visit_print_format (e); +} + + +void +varuse_collecting_visitor::visit_assignment (assignment *e) +{ + if (e->op == "=" || e->op == "<<<") // pure writes + { + expression* last_lvalue = current_lrvalue; + current_lvalue = e->left; // leave a mark for ::visit_symbol + functioncall_traversing_visitor::visit_assignment (e); + current_lvalue = last_lvalue; + } + else // read-modify-writes + { + expression* last_lrvalue = current_lrvalue; + current_lrvalue = e->left; // leave a mark for ::visit_symbol + functioncall_traversing_visitor::visit_assignment (e); + current_lrvalue = last_lrvalue; + } +} + +void +varuse_collecting_visitor::visit_symbol (symbol *e) +{ + if (e->referent == 0) + throw semantic_error ("symbol without referent", e->tok); + + if (current_lvalue == e || current_lrvalue == e) + { + written.insert (e->referent); + // clog << "write "; + } + if (current_lvalue != e || current_lrvalue == e) + { + read.insert (e->referent); + // clog << "read "; + } + // clog << *e->tok << endl; +} + +// NB: stat_op need not be overridden, since it will get to +// visit_symbol and only as a possible rvalue. + +void +varuse_collecting_visitor::visit_arrayindex (arrayindex *e) +{ + // Hooking this callback is necessary because of the hacky + // statistics representation. For the expression "i[4] = 5", the + // incoming lvalue will point to this arrayindex. However, the + // symbol corresponding to the "i[4]" is multiply inherited with + // arrayindex. If the symbol base part of this object is not at + // offset 0, then static_cast<symbol*>(e) may result in a different + // address, and not match lvalue by number when we recurse that way. + // So we explicitly override the incoming lvalue/lrvalue values to + // point at the embedded objects' actual base addresses. + + expression* last_lrvalue = current_lrvalue; + expression* last_lvalue = current_lvalue; + + symbol *array = NULL; + hist_op *hist = NULL; + classify_indexable(e->base, array, hist); + + if (array) + { + if (current_lrvalue == e) current_lrvalue = array; + if (current_lvalue == e) current_lvalue = array; + functioncall_traversing_visitor::visit_arrayindex (e); + } + else // if (hist) + { + if (current_lrvalue == e) current_lrvalue = hist->stat; + if (current_lvalue == e) current_lvalue = hist->stat; + functioncall_traversing_visitor::visit_arrayindex (e); + } + + current_lrvalue = last_lrvalue; + current_lvalue = last_lvalue; +} + + +void +varuse_collecting_visitor::visit_pre_crement (pre_crement *e) +{ + expression* last_lrvalue = current_lrvalue; + current_lrvalue = e->operand; // leave a mark for ::visit_symbol + functioncall_traversing_visitor::visit_pre_crement (e); + current_lrvalue = last_lrvalue; +} + +void +varuse_collecting_visitor::visit_post_crement (post_crement *e) +{ + expression* last_lrvalue = current_lrvalue; + current_lrvalue = e->operand; // leave a mark for ::visit_symbol + functioncall_traversing_visitor::visit_post_crement (e); + current_lrvalue = last_lrvalue; +} + + + + + + // ------------------------------------------------------------------------ |