diff options
author | Frank Ch. Eigler <fche@elastic.org> | 2008-05-21 13:37:07 -0400 |
---|---|---|
committer | Frank Ch. Eigler <fche@elastic.org> | 2008-05-21 13:37:07 -0400 |
commit | e3339150b3c04f50b0abdc4a6d132a6b75b22cb6 (patch) | |
tree | c80892afd79625f95ff0a2543728804464c2961a /elaborate.cxx | |
parent | 332ddc9f7354fe51c32c504087575b3ea2b70990 (diff) | |
parent | aa8a3b1797da54a14d04cd57758a65064056376e (diff) | |
download | systemtap-steved-e3339150b3c04f50b0abdc4a6d132a6b75b22cb6.tar.gz systemtap-steved-e3339150b3c04f50b0abdc4a6d132a6b75b22cb6.tar.xz systemtap-steved-e3339150b3c04f50b0abdc4a6d132a6b75b22cb6.zip |
Merge commit 'origin/master' into pr6429-comp-unwindsyms
* commit 'origin/master':
Fix assignment optimization expected results.
PR6538: more testsuite tweaks for read-only warnings
PR6538: more tapset fixes
PR6538: explain why absentstats.stp logs will contain warnings
PR6538: fix treatment of initialized globals
Use pointer_arg to fetch arguments for syscall.utime and compat_utime.
Optimize compound and binary expression assignments.
Check new (sub) functions of _struct_utimbuf_* and _struct_compat_utimbuf_*.
PR6538: tapset changes
PR6538: testsuite changes
PR5001: fix test suite collateral damage
PR6538: warn about read-only variables
Add some scripts and descriptions to the systemtap.examples.
PR5001: Remove _stp_ctime and always use ctime.
Use tr1/unordered_map instead of the deprecated ext/hash_map.
PR6524: ctime() on bad values hangs system.
Optimize away assignments in other contexts.
Optimize away assignments in other contexts.
dummy commit for testing systemtap-cvs notification
Remove sa_restorer initialization.
Diffstat (limited to 'elaborate.cxx')
-rw-r--r-- | elaborate.cxx | 108 |
1 files changed, 105 insertions, 3 deletions
diff --git a/elaborate.cxx b/elaborate.cxx index 9a817cba..2f246e2c 100644 --- a/elaborate.cxx +++ b/elaborate.cxx @@ -1624,7 +1624,13 @@ void semantic_pass_opt2 (systemtap_session& s, bool& relaxed_p) // don't increment j } else - j++; + { + if (vut.written.find (l) == vut.written.end()) + if (! s.suppress_warnings) + clog << "WARNING: read-only local variable " << *l->tok << endl; + + j++; + } } for (unsigned i=0; i<s.functions.size(); i++) for (unsigned j=0; j<s.functions[i]->locals.size(); /* see below */) @@ -1649,7 +1655,12 @@ void semantic_pass_opt2 (systemtap_session& s, bool& relaxed_p) // don't increment j } else - j++; + { + if (vut.written.find (l) == vut.written.end()) + if (! s.suppress_warnings) + clog << "WARNING: read-only local variable " << *l->tok << endl; + j++; + } } for (unsigned i=0; i<s.globals.size(); /* see below */) { @@ -1671,7 +1682,13 @@ void semantic_pass_opt2 (systemtap_session& s, bool& relaxed_p) // don't increment i } else - i++; + { + if (vut.written.find (l) == vut.written.end() && + ! l->init) // no initializer + if (! s.suppress_warnings) + clog << "WARNING: read-only global variable " << *l->tok << endl; + i++; + } } } @@ -1696,6 +1713,11 @@ struct dead_assignment_remover: public traversing_visitor // called with null current_expr. void visit_assignment (assignment* e); + void visit_binary_expression (binary_expression* e); + void visit_arrayindex (arrayindex* e); + void visit_functioncall (functioncall* e); + void visit_if_statement (if_statement* e); + void visit_for_loop (for_loop* e); }; @@ -1720,6 +1742,11 @@ dead_assignment_remover::visit_assignment (assignment* e) *current_expr == e && // we're not nested any deeper than expected leftvar) // not unresolved $target; intended sideeffect cannot be elided { + expression** last_expr = current_expr; + e->left->visit (this); + current_expr = &e->right; + e->right->visit (this); + current_expr = last_expr; if (vut.read.find(leftvar) == vut.read.end()) // var never read? { // NB: Not so fast! The left side could be an array whose @@ -1750,6 +1777,71 @@ dead_assignment_remover::visit_assignment (assignment* e) } } +void +dead_assignment_remover::visit_binary_expression (binary_expression* e) +{ + expression** last_expr = current_expr; + current_expr = &e->left; + e->left->visit (this); + current_expr = &e->right; + e->right->visit (this); + current_expr = last_expr; +} + +void +dead_assignment_remover::visit_arrayindex (arrayindex *e) +{ + symbol *array = NULL; + hist_op *hist = NULL; + classify_indexable(e->base, array, hist); + + if (array) + { + expression** last_expr = current_expr; + for (unsigned i=0; i < e->indexes.size(); i++) + { + current_expr = & e->indexes[i]; + e->indexes[i]->visit (this); + } + current_expr = last_expr; + } +} + +void +dead_assignment_remover::visit_functioncall (functioncall* e) +{ + expression** last_expr = current_expr; + for (unsigned i=0; i<e->args.size(); i++) + { + current_expr = & e->args[i]; + e->args[i]->visit (this); + } + current_expr = last_expr; +} + +void +dead_assignment_remover::visit_if_statement (if_statement* s) +{ + expression** last_expr = current_expr; + current_expr = & s->condition; + s->condition->visit (this); + s->thenblock->visit (this); + if (s->elseblock) + s->elseblock->visit (this); + current_expr = last_expr; +} + +void +dead_assignment_remover::visit_for_loop (for_loop* s) +{ + expression** last_expr = current_expr; + if (s->init) s->init->visit (this); + current_expr = & s->cond; + s->cond->visit (this); + if (s->incr) s->incr->visit (this); + s->block->visit (this); + current_expr = last_expr; +} // Let's remove assignments to variables that are never read. We // rewrite "(foo = expr)" as "(expr)". This makes foo a candidate to @@ -1772,6 +1864,8 @@ void semantic_pass_opt3 (systemtap_session& s, bool& relaxed_p) for (unsigned i=0; i<s.functions.size(); i++) s.functions[i]->body->visit (& dar); // The rewrite operation is performed within the visitor. + + // XXX: we could also zap write-only globals here } @@ -1995,6 +2089,8 @@ void semantic_pass_opt4 (systemtap_session& s, bool& relaxed_p) p->body = new null_statement(); p->body->tok = p->tok; + + // XXX: possible duplicate warnings; see below } } for (unsigned i=0; i<s.functions.size(); i++) @@ -2018,6 +2114,12 @@ void semantic_pass_opt4 (systemtap_session& s, bool& relaxed_p) fn->body = new null_statement(); fn->body->tok = fn->tok; + + // XXX: the next iteration of the outer optimization loop may + // take this new null_statement away again, and thus give us a + // fresh warning. It would be better if this fixup was performed + // only after the relaxation iterations. + // XXX: or else see bug #6469. } } } |