summaryrefslogtreecommitdiffstats
path: root/translate.cxx
diff options
context:
space:
mode:
authorfche <fche>2005-12-02 03:21:00 +0000
committerfche <fche>2005-12-02 03:21:00 +0000
commitc0518f8409564c6a3c85ea99d32b8a334c73c3c0 (patch)
tree0b4ba272cd48b6c99b062d058975fe95e957250e /translate.cxx
parentc253c2ea9ff3ff0169c191c20418066c9cf94caa (diff)
downloadsystemtap-steved-c0518f8409564c6a3c85ea99d32b8a334c73c3c0.tar.gz
systemtap-steved-c0518f8409564c6a3c85ea99d32b8a334c73c3c0.tar.xz
systemtap-steved-c0518f8409564c6a3c85ea99d32b8a334c73c3c0.zip
2005-12-01 Frank Ch. Eigler <fche@elastic.org>
PR 1944 improved hack. * translator.cxx (c_tmpcounter::visit_block): New routine, allows overlay of sequential statements' temporaries within context.
Diffstat (limited to 'translate.cxx')
-rw-r--r--translate.cxx24
1 files changed, 22 insertions, 2 deletions
diff --git a/translate.cxx b/translate.cxx
index a55d48a8..1f87f70c 100644
--- a/translate.cxx
+++ b/translate.cxx
@@ -171,6 +171,7 @@ struct c_tmpcounter:
parent->tmpvar_counter = 0;
}
+ void visit_block (block *s);
void visit_for_loop (for_loop* s);
void visit_foreach_loop (foreach_loop* s);
// void visit_return_statement (return_statement* s);
@@ -939,8 +940,8 @@ c_unparser::emit_module_init ()
o->newline() << "if (sizeof (struct context) <= 131072)";
o->newline(1) << "contexts = alloc_percpu (struct context);";
o->newline(-1) << "if (contexts == NULL) {";
- o->newline() << "_stp_error (\"percpu context (size %lu) allocation failed\", sizeof (struct context));";
- o->newline(1) << "rc = -ENOMEM;";
+ o->newline(1) << "_stp_error (\"percpu context (size %lu) allocation failed\", sizeof (struct context));";
+ o->newline() << "rc = -ENOMEM;";
o->newline() << "goto out;";
o->newline(-1) << "}";
@@ -1725,6 +1726,25 @@ c_unparser::visit_if_statement (if_statement *s)
void
+c_tmpcounter::visit_block (block *s)
+{
+ // Key insight: individual statements of a block can reuse
+ // temporary variable slots, since temporaries don't survive
+ // statement boundaries. So we use gcc's anonymous union/struct
+ // facility to explicitly overlay the temporaries.
+ parent->o->newline() << "union {";
+ parent->o->indent(1);
+ for (unsigned i=0; i<s->statements.size(); i++)
+ {
+ parent->o->newline() << "struct {";
+ parent->o->indent(1);
+ s->statements[i]->visit (this);
+ parent->o->newline(-1) << "};";
+ }
+ parent->o->newline(-1) << "};";
+}
+
+void
c_tmpcounter::visit_for_loop (for_loop *s)
{
s->init->visit (this);