summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--testsuite/ChangeLog5
-rw-r--r--testsuite/systemtap.base/optim_voidstmt.exp5
-rw-r--r--testsuite/systemtap.base/optim_voidstmt.stp95
3 files changed, 105 insertions, 0 deletions
diff --git a/testsuite/ChangeLog b/testsuite/ChangeLog
index 0dd36d7a..9ab2a353 100644
--- a/testsuite/ChangeLog
+++ b/testsuite/ChangeLog
@@ -1,3 +1,8 @@
+2008-06-18 Josh Stone <joshua.i.stone@intel.com>
+
+ * systemtap.base/optim_voidstmt.stp: Add tests for various statement
+ optimizations that we should now be eliding.
+
2008-06-16 Frank Ch. Eigler <fche@elastic.org>
* systemtap.base/warnings.exp: Adjust warning count again (me1 and
diff --git a/testsuite/systemtap.base/optim_voidstmt.exp b/testsuite/systemtap.base/optim_voidstmt.exp
new file mode 100644
index 00000000..186dabad
--- /dev/null
+++ b/testsuite/systemtap.base/optim_voidstmt.exp
@@ -0,0 +1,5 @@
+# Make sure that optimization works with void statements
+
+set test "optim_voidstmt"
+
+stap_run $srcdir/$subdir/$test.stp no_load $all_pass_string -g
diff --git a/testsuite/systemtap.base/optim_voidstmt.stp b/testsuite/systemtap.base/optim_voidstmt.stp
new file mode 100644
index 00000000..343f81b3
--- /dev/null
+++ b/testsuite/systemtap.base/optim_voidstmt.stp
@@ -0,0 +1,95 @@
+/*
+ * optim_voidstmt.stp
+ *
+ * Verify statement optimizations in void contexts.
+ */
+
+/* The printfs here force it not to be pure. */
+function goodL() { printf(""); return 1 }
+function goodS() { printf(""); return "1" }
+
+/* These two functions lie about being pure, so they should be optimized out.
+ * If they get called, you get an error, and the test fails.
+ */
+function badL:long() %{ /* pure */ CONTEXT->last_error = "NOSEE"; %}
+function badS:string() %{ /* pure */ CONTEXT->last_error = "NOSEE"; %}
+
+function fn1(x) { return x }
+function fn2(x, y) { return x * y }
+
+probe begin {
+ println("systemtap starting probe")
+}
+
+probe end {
+ println("systemtap ending probe")
+
+ // most of these wouldn't have been optimized before, because part of the
+ // expression has an apparant side-effect in the good* calls
+
+ // unary numeric operators
+ (+(goodL() + badL()))
+ (-(goodL() + badL()))
+ (!(goodL() + badL()))
+ (~(goodL() + badL()))
+
+ // binary numeric operators
+ goodL() * badL()
+ goodL() / badL()
+ goodL() % badL()
+ goodL() + badL()
+ goodL() - badL()
+ goodL() >> badL()
+ goodL() << badL()
+ goodL() & badL()
+ goodL() ^ badL()
+ goodL() | badL()
+ goodL() < badL()
+ goodL() > badL()
+ goodL() <= badL()
+ goodL() >= badL()
+ goodL() == badL()
+ goodL() != badL()
+
+ // logical operators
+ goodL() && badL()
+ badL() && badL()
+ goodL() || badL()
+ badL() || badL()
+
+ // ternary operator
+ goodL() ? badL() : goodL()
+ goodL() ? goodL() : badL()
+ badL() ? badL() : badL()
+
+ // binary string operators
+ goodS() . badS()
+ goodS() < badS()
+ goodS() > badS()
+ goodS() <= badS()
+ goodS() >= badS()
+ goodS() == badS()
+ goodS() != badS()
+
+ // string-printing
+ sprintf("%d\n", goodL() + badL())
+ sprintf("%d %d %s %s\n", goodL(), badL(), goodS(), badS())
+
+ // function calls
+ fn1(badL() + goodL())
+ fn2(badL(), goodL())
+
+ // something complex, but harmless enough that only
+ // the good* calls should survive
+ fn1(fn2(goodL() - strlen(badL() + badL() * badL() / strlen(goodS()) ?
+ badS() . badS() . sprint(badL())
+ : sprint(badL(), badS())),
+ badL() < badL() || badS() == badS()) +
+ goodL() % strlen(goodS()))
+
+ println("systemtap test success")
+}
+
+probe never {
+ print(goodL(), badL(), goodS(), badS(), fn1(1), fn2(1, 1))
+}