diff options
author | Stan Cox <scox@redhat.com> | 2008-05-19 15:39:55 -0400 |
---|---|---|
committer | Stan Cox <scox@redhat.com> | 2008-05-19 16:17:29 -0400 |
commit | e76254815c3adfff1c086beb6a4cfa46c49ac3b3 (patch) | |
tree | c595c752e0de64de2b778adf8e219b58fe18505c | |
parent | 213a54acddb71c6545a5427d198e49ec0426a70a (diff) | |
download | systemtap-steved-e76254815c3adfff1c086beb6a4cfa46c49ac3b3.tar.gz systemtap-steved-e76254815c3adfff1c086beb6a4cfa46c49ac3b3.tar.xz systemtap-steved-e76254815c3adfff1c086beb6a4cfa46c49ac3b3.zip |
Optimize away assignments in other contexts.
-rw-r--r-- | elaborate.cxx | 62 | ||||
-rw-r--r-- | testsuite/systemtap.base/optim_arridx.exp | 85 | ||||
-rw-r--r-- | testsuite/systemtap.base/optim_arridx.stp | 39 |
3 files changed, 186 insertions, 0 deletions
diff --git a/elaborate.cxx b/elaborate.cxx index 9a817cba..4bc43832 100644 --- a/elaborate.cxx +++ b/elaborate.cxx @@ -1696,6 +1696,10 @@ struct dead_assignment_remover: public traversing_visitor // called with null current_expr. void visit_assignment (assignment* 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 +1724,10 @@ 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); + 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 +1758,60 @@ dead_assignment_remover::visit_assignment (assignment* e) } } +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 diff --git a/testsuite/systemtap.base/optim_arridx.exp b/testsuite/systemtap.base/optim_arridx.exp new file mode 100644 index 00000000..447ad1f4 --- /dev/null +++ b/testsuite/systemtap.base/optim_arridx.exp @@ -0,0 +1,85 @@ +# test integer limits. Set and print variables and print constants. + +set test "optim_arridx" +set ::result_string {# globals +arr1:long [long, long] +arr2:long [long] +arr3:long [long] +# functions +fna:long (a:long) +return a +fnb:long (a:long, b:long) +return (a) + (b) +exit:unknown () +%{ + atomic_set (&session_state, STAP_SESSION_STOPPING); + _stp_exit (); +%} +# probes +begin /* <- begin */ + # locals + idx2:long + j:long + k:long + b:long + m:long + arr1:long [long] + arr2:long [long, long] + aa:long + bb:long + cc:long + dd:long + ee:long +{ +(arr2[(idx2) = (2)]) = (20) +(arr2[(j) = (4)]) = (40) +(arr1[fna((k) = (0)), k]) = (1) +(arr1[(b) = (1), b]) = (2) +fnb((arr3[0]) = (4), arr3[0]) +(m) = (1) +for (2; (m) <= (10); (m)++) ; +printf("%d %d %d %d\\n", arr1[0], arr2[0, 0], idx2, j) +(aa) = (fna(1)) +(bb) = (fnb((cc) = (1), 2)) +for (1; (bb) < (10); (bb)++) (cc) += (bb) +for ((dd) = (1); (dd) < (10); 1) (dd) += (1) +if (1) (ee) = (1) + +printf("%d %d %d %d %d", aa, bb, cc, dd, ee) +exit() +} +WARNING: eliding unused variable identifier 'elide_i' at /work/scox/systemtap/src/testsuite/systemtap.base/optim_arridx.stp:10:8 +WARNING: eliding unused variable identifier 'elide_c' at /work/scox/systemtap/src/testsuite/systemtap.base/optim_arridx.stp:14:8 +WARNING: eliding unused variable identifier 'elide_n' at /work/scox/systemtap/src/testsuite/systemtap.base/optim_arridx.stp:17:8 +WARNING: eliding unused variable identifier 'elide_aa' at /work/scox/systemtap/src/testsuite/systemtap.base/optim_arridx.stp:22:12 +WARNING: eliding unused variable identifier 'elide_bb' at /work/scox/systemtap/src/testsuite/systemtap.base/optim_arridx.stp:26:8 +WARNING: eliding unused variable identifier 'elide_ee' at /work/scox/systemtap/src/testsuite/systemtap.base/optim_arridx.stp:28:25 +WARNING: eliding unused variable identifier 'elide_ff' at /work/scox/systemtap/src/testsuite/systemtap.base/optim_arridx.stp:32:7 +WARNING: eliding unused variable identifier 'elide_idx1' at /work/scox/systemtap/src/testsuite/systemtap.base/optim_arridx.stp:1:26 +WARNING: eliding unused variable identifier 'elide_global_a' at /work/scox/systemtap/src/testsuite/systemtap.base/optim_arridx.stp:1:38 +WARNING: eliding unused variable identifier 'elide_global_b' at /work/scox/systemtap/src/testsuite/systemtap.base/optim_arridx.stp:1:54 +} + +proc optim_arridx_run { TEST_NAME args } { + # zap the srcdir prefix + set test_file_name $TEST_NAME + set TEST_NAME [regsub {.*/testsuite/} $TEST_NAME ""] + + set cmd [concat stap $args $test_file_name] + catch {eval exec $cmd} res + + set n 0 + set expected [split $::result_string "\n"] + foreach line [split $res "\n"] { + if {![string equal $line [lindex $expected $n]]} { + fail "$TEST_NAME" + send_log "line [expr $n + 1]: expected \"[lindex $expected $n]\"\n" + send_log "Got \"$line\"\n" + return + } + incr n + } + pass "$TEST_NAME" +} + +optim_arridx_run $srcdir/$subdir/$test.stp -p2 -v 2>/dev/null diff --git a/testsuite/systemtap.base/optim_arridx.stp b/testsuite/systemtap.base/optim_arridx.stp new file mode 100644 index 00000000..4551bb3e --- /dev/null +++ b/testsuite/systemtap.base/optim_arridx.stp @@ -0,0 +1,39 @@ +global arr1, arr2, arr3, elide_idx1, elide_global_a, elide_global_b + +function fna(a:long) {return a} +function fnb(a:long, b:long) {return a+b} + +probe begin { + // array indices + arr2[elide_idx1 = 1] = 10 + arr2[idx2 = 2] = 20 + arr2[elide_i=3] = 30 + arr2[j=4] = 40 + arr1[fna(k = 0), k] = 1 + arr1[b = 1, b] = 2 + arr1[elide_c = 2,2] = 3 + fnb(arr3[0] = 4, arr3[0]) + m = 1 + for (elide_n=2; m <= 10; m++) + arr2[m] = m * 10 + printf ("%d %d %d %d\n", arr1[0], arr2[0,0], idx2, j) + + // function args + aa = fna(elide_aa = 1) + bb = fnb(cc = 1, elide_global_a = 2) + + // loop + for (elide_bb = 1; bb < 10; bb++) + cc += bb + for (dd = 1; dd < 10; elide_ee = 1) + dd += 1 + + // conditional + if (elide_ff = 0) + elide_ff = 1 + if (elide_global_b = 1) + ee = 1 + + printf("%d %d %d %d %d", aa, bb, cc, dd, ee) + exit () +} |