/work/scox/systemtap/src /work/scox/systemtap/bld/x86_64-redhat-linux ~ diff --git a/elaborate.cxx b/elaborate.cxx index 0950b08..ae4b42d 100644 --- a/elaborate.cxx +++ b/elaborate.cxx @@ -1620,6 +1620,93 @@ void semantic_pass_opt1 (systemtap_session& s, bool& relaxed_p) } } +void +add_global_var_display (systemtap_session& s, vardecl* l) +{ + int idx_count = l->index_types.size(); + + // Create a foreach loop + token* fe_tok = new token; + fe_tok->type = tok_identifier; + fe_tok->content = "foreach"; + foreach_loop* fe = new foreach_loop; + fe->sort_direction = 0; + fe->limit = NULL; + + // Create indices for the foreach loop + // XXX: Create multiple indices + token* idx_tok = new token; + idx_tok->type = tok_identifier; + idx_tok->content = "idx"; + symbol* idx_sym = new symbol; + idx_sym->tok = idx_tok; + idx_sym->name = "idx"; + vardecl* idx_v = new vardecl; + idx_v->name = "idx"; + idx_v->tok = idx_tok; + idx_sym->referent = idx_v; + fe->indexes.push_back (idx_sym); + + // Create a printf for the foreach loop + print_format* pf = new print_format; + token* tmp_tok = new token; + tmp_tok->type = tok_identifier; + tmp_tok->content = "printf"; + pf->tok = tmp_tok; + pf->print_to_stream = true; + pf->print_with_format = true; + pf->print_with_delim = false; + pf->print_with_newline = false; + pf->print_char = false; + // XXX: Allow for multiple indices in format + pf->raw_components += l->name + "[%#s]=%#x "; + + // Create an array symbol + symbol* arr_sym = new symbol; + arr_sym->name = l->name; + arr_sym->tok = l->tok; + arr_sym->referent = l; + // XXX: Create multiple indices + if (idx_count == 1 && arr_sym->referent->index_types[0] == pe_unknown) + arr_sym->referent->index_types.pop_back(); + arr_sym->referent->index_types.push_back (pe_string); + // Create an index for the array + struct arrayindex* ai = new arrayindex; + ai->tok = l->tok; + ai->base = arr_sym; + ai->indexes.push_back (idx_sym); + + pf->args.push_back(idx_sym); + pf->args.push_back(ai); + pf->raw_components += "\\n"; + pf->components = print_format::string_to_components(pf->raw_components); + expr_statement* feb = new expr_statement; + feb->value = pf; + fe->base = arr_sym; + fe->block = (statement*)feb; + + // Find the end probe, which is where we will place the foreach loop + int probe_idx = -1; + for (unsigned i=0; probe_idx == -1 && i < s.probes.size(); i++) + { + derived_probe* dp = s.probes[i]; + for (unsigned j=0; probe_idx == -1 && j < dp->locations.size(); j++) + { + for (unsigned k=0; probe_idx == -1 + && k < dp->locations[j]->components.size(); k++) + { + probe_point::component* c = dp->locations[j]->components[k]; + if (c->functor == "end") + probe_idx = i; + } + } + } + + s.probes[probe_idx]->locals.push_back(idx_v); + block *b = (block*)(s.probes[probe_idx]->body); + b->statements.insert(b->statements.begin(), fe); +} + // ------------------------------------------------------------------------ @@ -1740,21 +1827,37 @@ void semantic_pass_opt2 (systemtap_session& s, bool& relaxed_p, unsigned iterati for (unsigned i=0; i::iterator it; + + // Keep unread global variables so we can display the values. if (vut.read.find (l) == vut.read.end() && + vut.written.find (l) != vut.written.end()) + { + add_global_var_display (s, l); + vut.read.insert (l); + i++; + } + else if (vut.read.find (l) == vut.read.end() && vut.written.find (l) == vut.written.end()) { if (l->tok->location.file == s.user_file->name && // !tapset ! s.suppress_warnings) - s.print_warning ("eliding unused variable '" + l->name + "'", l->tok); + { + add_global_var_display (s, l); + vut.read.insert (l); + i++; + s.print_warning ("eliding unused variable '" + l->name + "'", l->tok); + } + else if (s.verbose>2) clog << "Eliding unused global variable " << l->name << endl; if (s.tapset_compile_coverage) { @@ -1838,10 +1942,21 @@ dead_assignment_remover::visit_assignment (assignment* e) // OK if we could replace the array assignment with a // statement-expression containing all the index expressions // and the rvalue... but we can't. + // Another possibility is that we have an unread global variable + // which we keep so we can display the values. + + bool unread_global = false; + vector::iterator it; + for (it = session.globals.begin(); it != session.globals.end(); it++) + if (leftvar->name != (*it)->name) + { + unread_global = true; + break; + } varuse_collecting_visitor vut; e->left->visit (& vut); - if (vut.side_effect_free ()) // XXX: use _wrt() once we track focal_vars + if (vut.side_effect_free () && !unread_global) // XXX: use _wrt() once we track focal_vars { /* PR 1119: NB: This is not necessary here. A write-only variable will also be elided soon at the next _opt2 iteration.