This is the mail archive of the
systemtap@sourceware.org
mailing list for the systemtap project.
#SW2600
- From: Stan Cox <scox at redhat dot com>
- To: systemtap at sources dot redhat dot com
- Date: Fri, 16 May 2008 12:01:53 -0400
- Subject: #SW2600
Here is a proposed patch for the array index piece of #SW2600 (should
optimize away assignments in other contexts). For example: arr2[i = 1]
= 10 can potentially become arr2[1] = 10
diff --git a/elaborate.cxx b/elaborate.cxx
index 306baff..5f148f6 100644
--- a/elaborate.cxx
+++ b/elaborate.cxx
@@ -1690,6 +1690,8 @@ struct dead_assignment_remover: public traversing_visitor
// called with null current_expr.
void visit_assignment (assignment* e);
+
+ void visit_arrayindex (arrayindex* e);
};
@@ -1714,6 +1716,8 @@ 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
{
+ e->left->visit (this);
+ e->right->visit (this);
if (vut.read.find(leftvar) == vut.read.end()) // var never read?
{
// NB: Not so fast! The left side could be an array whose
@@ -1744,6 +1748,24 @@ 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;
+ }
+}
// 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 0000000..8480f39
--- /dev/null
+++ b/testsuite/systemtap.base/optim_arridx.exp
@@ -0,0 +1,50 @@
+# 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)
+fnb:long (a:long, b:long)
+exit:unknown ()
+# probes
+begin /* <- begin */
+ # locals
+ idx2:long
+ j:long
+ k:long
+ b:long
+ m:long
+ arr1:long [long]
+ arr2:long [long, long]
+WARNING: eliding unused variable identifier 'elide_i'.*
+WARNING: eliding unused variable identifier 'elide_c'.*
+WARNING: eliding unused variable identifier 'elide_n'.*
+WARNING: eliding unused variable identifier 'elide_idx1'.*
+}
+
+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 2>/dev/null
diff --git a/testsuite/systemtap.base/optim_arridx.stp b/testsuite/systemtap.base/optim_arridx.stp
new file mode 100644
index 0000000..f6ec96c
--- /dev/null
+++ b/testsuite/systemtap.base/optim_arridx.stp
@@ -0,0 +1,21 @@
+global arr1, arr2, arr3, elide_idx1
+
+function fna(a:long) {return a}
+function fnb(a:long, b:long) {return a+b}
+
+probe begin {
+ 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)
+
+ exit ()
+}