summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--ChangeLog7
-rw-r--r--coveragedb.cxx30
-rw-r--r--elaborate.cxx206
-rw-r--r--main.cxx10
-rw-r--r--session.h2
-rw-r--r--tapsets.cxx12
-rw-r--r--translate.cxx20
7 files changed, 161 insertions, 126 deletions
diff --git a/ChangeLog b/ChangeLog
index 8ce62fb6..edc84de6 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,10 @@
+2008-09-10 Frank Ch. Eigler <fche@elastic.org>
+
+ PR6876: translator speedup for many $vars
+ * session.h (systemtap_session.functions): vector->map.
+ * coveragedb.cxx, elaborate.cxx, main.cxx, tapsets.cxx, translate.cxx:
+ Adapt all users.
+
2008-09-10 Mark Wielaard <mjw@redhat.com>
* translate.cxx (dump_unwindsyms): Output module_base.
diff --git a/coveragedb.cxx b/coveragedb.cxx
index 63cc4c0f..aafcd545 100644
--- a/coveragedb.cxx
+++ b/coveragedb.cxx
@@ -62,11 +62,12 @@ void print_coverage_info(systemtap_session &s)
}
// print out used functions
clog << "---- used functions----- " << endl;
- for (unsigned i=0; i<s.functions.size(); i++) {
- clog << "function: " << s.functions[i]->tok->location
- << " " << s.functions[i]->name
- << endl;
- }
+ for (map<string,functiondecl*>::iterator it = s.functions.begin(); it != s.functions.end(); it++)
+ {
+ clog << "function: " << it->second->tok->location
+ << " " << it->second->name
+ << endl;
+ }
// print out unused functions
clog << "---- unused functions----- " << endl;
for (unsigned i=0; i<s.unused_functions.size(); i++) {
@@ -262,15 +263,16 @@ void
sql_update_used_functions(sqlite3 *db, systemtap_session &s)
{
// update db used functions
- for (unsigned i=0; i<s.functions.size(); i++) {
- struct source_loc place = s.functions[i]->tok->location;
- coverage_element x(place);
-
- x.type = db_type_function;
- x.name = s.functions[i]->name;
- x.compiled = 1;
- increment_element(db, x);
- }
+ for (map<string,functiondecl*>::iterator it = s.functions.begin(); it != s.functions.end(); it++)
+ {
+ struct source_loc place = it->second->tok->location;
+ coverage_element x(place);
+
+ x.type = db_type_function;
+ x.name = it->second->name;
+ x.compiled = 1;
+ increment_element(db, x);
+ }
}
diff --git a/elaborate.cxx b/elaborate.cxx
index 3dfc7183..552ef338 100644
--- a/elaborate.cxx
+++ b/elaborate.cxx
@@ -912,8 +912,8 @@ semantic_pass_stats (systemtap_session & sess)
{
stat_decl_collector sdc(sess);
- for (unsigned i = 0; i < sess.functions.size(); ++i)
- sess.functions[i]->body->visit (&sdc);
+ for (map<string,functiondecl*>::iterator it = sess.functions.begin(); it != sess.functions.end(); it++)
+ it->second->body->visit (&sdc);
for (unsigned i = 0; i < sess.probes.size(); ++i)
sess.probes[i]->body->visit (&sdc);
@@ -946,9 +946,9 @@ semantic_pass_vars (systemtap_session & sess)
map<functiondecl *, set<vardecl *> *> fmv;
no_var_mutation_during_iteration_check chk(sess, fmv);
- for (unsigned i = 0; i < sess.functions.size(); ++i)
+ for (map<string,functiondecl*>::iterator it = sess.functions.begin(); it != sess.functions.end(); it++)
{
- functiondecl * fn = sess.functions[i];
+ functiondecl * fn = it->second;
if (fn->body)
{
set<vardecl *> * m = new set<vardecl *>();
@@ -958,10 +958,10 @@ semantic_pass_vars (systemtap_session & sess)
}
}
- for (unsigned i = 0; i < sess.functions.size(); ++i)
+ for (map<string,functiondecl*>::iterator it = sess.functions.begin(); it != sess.functions.end(); it++)
{
- if (sess.functions[i]->body)
- sess.functions[i]->body->visit (&chk);
+ functiondecl * fn = it->second;
+ if (fn->body) fn->body->visit (&chk);
}
for (unsigned i = 0; i < sess.probes.size(); ++i)
@@ -1072,7 +1072,7 @@ semantic_pass_symbols (systemtap_session& s)
s.globals.push_back (dome->globals[i]);
for (unsigned i=0; i<dome->functions.size(); i++)
- s.functions.push_back (dome->functions[i]);
+ s.functions[dome->functions[i]->name] = dome->functions[i];
for (unsigned i=0; i<dome->embeds.size(); i++)
s.embeds.push_back (dome->embeds[i]);
@@ -1735,11 +1735,12 @@ symresolution_info::find_var (const string& name, int arity)
functiondecl*
symresolution_info::find_function (const string& name, unsigned arity)
{
- for (unsigned j = 0; j < session.functions.size(); j++)
+ // the common path
+ if (session.functions.find(name) != session.functions.end())
{
- functiondecl* fd = session.functions[j];
- if (fd->name == name &&
- fd->formal_args.size() == arity)
+ functiondecl* fd = session.functions[name];
+ assert (fd->name == name);
+ if (fd->formal_args.size() == arity)
return fd;
}
@@ -1785,25 +1786,30 @@ void semantic_pass_opt1 (systemtap_session& s, bool& relaxed_p)
if (s.probes[i]->sole_location()->condition)
s.probes[i]->sole_location()->condition->visit (& ftv);
}
- for (unsigned i=0; i<s.functions.size(); /* see below */)
+ vector<functiondecl*> new_unused_functions;
+ for (map<string,functiondecl*>::iterator it = s.functions.begin(); it != s.functions.end(); it++)
{
- if (ftv.traversed.find(s.functions[i]) == ftv.traversed.end())
+ functiondecl* fd = it->second;
+ if (ftv.traversed.find(fd) == ftv.traversed.end())
{
- if (s.functions[i]->tok->location.file == s.user_file->name && // !tapset
+ if (fd->tok->location.file == s.user_file->name && // !tapset
! s.suppress_warnings)
- s.print_warning ("eliding unused function '" + s.functions[i]->name + "'", s.functions[i]->tok);
+ s.print_warning ("eliding unused function '" + fd->name + "'", fd->tok);
else if (s.verbose>2)
- clog << "Eliding unused function " << s.functions[i]->name
+ clog << "Eliding unused function " << fd->name
<< endl;
- if (s.tapset_compile_coverage) {
- s.unused_functions.push_back (s.functions[i]);
- }
- s.functions.erase (s.functions.begin() + i);
+ // s.functions.erase (it); // NB: can't, since we're already iterating upon it
+ new_unused_functions.push_back (fd);
relaxed_p = false;
- // NB: don't increment i
}
- else
- i++;
+ }
+ for (unsigned i=0; i<new_unused_functions.size(); i++)
+ {
+ map<string,functiondecl*>::iterator where = s.functions.find (new_unused_functions[i]->name);
+ assert (where != s.functions.end());
+ s.functions.erase (where);
+ if (s.tapset_compile_coverage)
+ s.unused_functions.push_back (new_unused_functions[i]);
}
}
@@ -1877,53 +1883,55 @@ void semantic_pass_opt2 (systemtap_session& s, bool& relaxed_p, unsigned iterati
}
}
- for (unsigned i=0; i<s.functions.size(); i++)
- for (unsigned j=0; j<s.functions[i]->locals.size(); /* see below */)
- {
- vardecl* l = s.functions[i]->locals[j];
- 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);
- else if (s.verbose>2)
- clog << "Eliding unused local variable "
- << l->name << " in function " << s.functions[i]->name
- << endl;
- if (s.tapset_compile_coverage) {
- s.functions[i]->unused_locals.push_back
- (s.functions[i]->locals[j]);
- }
- s.functions[i]->locals.erase(s.functions[i]->locals.begin() + j);
- relaxed_p = false;
- // don't increment j
- }
- else
- {
- if (vut.written.find (l) == vut.written.end())
- if (iterations == 0 && ! s.suppress_warnings)
- {
- stringstream o;
- vector<vardecl*>::iterator it;
- for ( it = s.functions[i]->formal_args.begin() ;
- it != s.functions[i]->formal_args.end(); it++)
- if (l->name != (*it)->name)
- o << " " << (*it)->name;
- for (it = s.functions[i]->locals.begin(); it != s.functions[i]->locals.end(); it++)
- if (l->name != (*it)->name)
- o << " " << (*it)->name;
- for (it = s.globals.begin(); it != s.globals.end(); it++)
- if (l->name != (*it)->name)
- o << " " << (*it)->name;
-
- s.print_warning ("read-only local variable '" + l->name + "' " +
- (o.str() == "" ? "" : ("(alternatives:" + o.str() + ")")), l->tok);
- }
+ for (map<string,functiondecl*>::iterator it = s.functions.begin(); it != s.functions.end(); it++)
+ {
+ functiondecl *fd = it->second;
+ for (unsigned j=0; j<fd->locals.size(); /* see below */)
+ {
+ vardecl* l = fd->locals[j];
+ 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);
+ else if (s.verbose>2)
+ clog << "Eliding unused local variable "
+ << l->name << " in function " << fd->name
+ << endl;
+ if (s.tapset_compile_coverage) {
+ fd->unused_locals.push_back (fd->locals[j]);
+ }
+ fd->locals.erase(fd->locals.begin() + j);
+ relaxed_p = false;
+ // don't increment j
+ }
+ else
+ {
+ if (vut.written.find (l) == vut.written.end())
+ if (iterations == 0 && ! s.suppress_warnings)
+ {
+ stringstream o;
+ vector<vardecl*>::iterator it;
+ for (it = fd->formal_args.begin() ;
+ it != fd->formal_args.end(); it++)
+ if (l->name != (*it)->name)
+ o << " " << (*it)->name;
+ for (it = fd->locals.begin(); it != fd->locals.end(); it++)
+ if (l->name != (*it)->name)
+ o << " " << (*it)->name;
+ for (it = s.globals.begin(); it != s.globals.end(); it++)
+ if (l->name != (*it)->name)
+ o << " " << (*it)->name;
+
+ s.print_warning ("read-only local variable '" + l->name + "' " +
+ (o.str() == "" ? "" : ("(alternatives:" + o.str() + ")")), l->tok);
+ }
- j++;
- }
- }
+ j++;
+ }
+ }
+ }
for (unsigned i=0; i<s.globals.size(); /* see below */)
{
vardecl* l = s.globals[i];
@@ -1932,7 +1940,7 @@ void semantic_pass_opt2 (systemtap_session& s, bool& relaxed_p, unsigned iterati
{
if (l->tok->location.file == s.user_file->name && // !tapset
! s.suppress_warnings)
- s.print_warning ("eliding unused variable '" + l->name + "'", l->tok);
+ s.print_warning ("eliding unused variable '" + l->name + "'", l->tok);
else if (s.verbose>2)
clog << "Eliding unused global variable "
<< l->name << endl;
@@ -2144,8 +2152,8 @@ void semantic_pass_opt3 (systemtap_session& s, bool& relaxed_p)
for (unsigned i=0; i<s.probes.size(); i++)
s.probes[i]->body->visit (& dar);
- for (unsigned i=0; i<s.functions.size(); i++)
- s.functions[i]->body->visit (& dar);
+ for (map<string,functiondecl*>::iterator it = s.functions.begin(); it != s.functions.end(); it++)
+ it->second->body->visit (& dar);
// The rewrite operation is performed within the visitor.
// XXX: we could also zap write-only globals here
@@ -2390,6 +2398,8 @@ void semantic_pass_opt4 (systemtap_session& s, bool& relaxed_p)
for (unsigned i=0; i<s.probes.size(); i++)
{
+ if (pending_interrupts) break;
+
derived_probe* p = s.probes[i];
duv.focal_vars.clear ();
@@ -2411,9 +2421,11 @@ void semantic_pass_opt4 (systemtap_session& s, bool& relaxed_p)
// XXX: possible duplicate warnings; see below
}
}
- for (unsigned i=0; i<s.functions.size(); i++)
+ for (map<string,functiondecl*>::iterator it = s.functions.begin(); it != s.functions.end(); it++)
{
- functiondecl* fn = s.functions[i];
+ if (pending_interrupts) break;
+
+ functiondecl* fn = it->second;
duv.focal_vars.clear ();
duv.focal_vars.insert (fn->locals.begin(),
fn->locals.end());
@@ -2788,9 +2800,9 @@ void semantic_pass_opt5 (systemtap_session& s, bool& relaxed_p)
vuv.current_stmt = & p->body;
p->body->visit (& vuv);
}
- for (unsigned i=0; i<s.functions.size(); i++)
+ for (map<string,functiondecl*>::iterator it = s.functions.begin(); it != s.functions.end(); it++)
{
- functiondecl* fn = s.functions[i];
+ functiondecl* fn = it->second;
vuv.current_stmt = & fn->body;
fn->body->visit (& vuv);
}
@@ -2854,30 +2866,34 @@ void semantic_pass_opt6 (systemtap_session& s, bool& relaxed_p)
// Walk through all the functions, looking for duplicates.
map<string, functiondecl*> functionsig_map;
map<functiondecl*, functiondecl*> duplicate_function_map;
- for (unsigned i=0; i < s.functions.size(); /* see below */)
+
+
+ vector<functiondecl*> newly_zapped_functions;
+ for (map<string,functiondecl*>::iterator it = s.functions.begin(); it != s.functions.end(); it++)
{
- string functionsig = get_functionsig(s.functions[i]);
+ functiondecl *fd = it->second;
+ string functionsig = get_functionsig(fd);
if (functionsig_map.count(functionsig) == 0)
{
// This function is unique. Remember it.
- functionsig_map[functionsig] = s.functions[i];
- i++;
+ functionsig_map[functionsig] = fd;
}
else
{
// This function is a duplicate.
- duplicate_function_map[s.functions[i]]
- = functionsig_map[functionsig];
-
- // Remove the duplicate function (since we don't need it
- // anymore).
- s.functions.erase (s.functions.begin() + i);
-
+ duplicate_function_map[fd] = functionsig_map[functionsig];
+ newly_zapped_functions.push_back (fd);
relaxed_p = false;
- // NB: don't increment i
}
}
+ for (unsigned i=0; i<newly_zapped_functions.size(); i++)
+ {
+ map<string,functiondecl*>::iterator where = s.functions.find (newly_zapped_functions[i]->name);
+ assert (where != s.functions.end());
+ s.functions.erase (where);
+ }
+
// If we have duplicate functions, traverse down the tree, replacing
// the appropriate function calls.
@@ -2971,21 +2987,21 @@ semantic_pass_types (systemtap_session& s)
ti.num_newly_resolved = 0;
ti.num_still_unresolved = 0;
- for (unsigned j=0; j<s.functions.size(); j++)
+ for (map<string,functiondecl*>::iterator it = s.functions.begin(); it != s.functions.end(); it++)
{
if (pending_interrupts) break;
- functiondecl* fn = s.functions[j];
+ functiondecl* fd = it->second;
ti.current_probe = 0;
- ti.current_function = fn;
+ ti.current_function = fd;
ti.t = pe_unknown;
- fn->body->visit (& ti);
+ fd->body->visit (& ti);
// NB: we don't have to assert a known type for
// functions here, to permit a "void" function.
// The translator phase will omit the "retvalue".
//
- // if (fn->type == pe_unknown)
- // ti.unresolved (fn->tok);
+ // if (fd->type == pe_unknown)
+ // ti.unresolved (fd->tok);
}
for (unsigned j=0; j<s.probes.size(); j++)
diff --git a/main.cxx b/main.cxx
index 5d0739eb..634feb03 100644
--- a/main.cxx
+++ b/main.cxx
@@ -147,6 +147,8 @@ printscript(systemtap_session& s, ostream& o)
for (unsigned i=0; i<s.probes.size(); i++)
{
+ if (pending_interrupts) return;
+
derived_probe* p = s.probes[i];
// NB: p->basest() is not so interesting;
// p->almost_basest() doesn't quite work, so ...
@@ -198,6 +200,7 @@ printscript(systemtap_session& s, ostream& o)
o << "# global embedded code" << endl;
for (unsigned i=0; i<s.embeds.size(); i++)
{
+ if (pending_interrupts) return;
embeddedcode* ec = s.embeds[i];
ec->print (o);
o << endl;
@@ -207,6 +210,7 @@ printscript(systemtap_session& s, ostream& o)
o << "# globals" << endl;
for (unsigned i=0; i<s.globals.size(); i++)
{
+ if (pending_interrupts) return;
vardecl* v = s.globals[i];
v->printsig (o);
if (s.verbose && v->init)
@@ -219,9 +223,10 @@ printscript(systemtap_session& s, ostream& o)
if (s.functions.size() > 0)
o << "# functions" << endl;
- for (unsigned i=0; i<s.functions.size(); i++)
+ for (map<string,functiondecl*>::iterator it = s.functions.begin(); it != s.functions.end(); it++)
{
- functiondecl* f = s.functions[i];
+ if (pending_interrupts) return;
+ functiondecl* f = it->second;
f->printsig (o);
o << endl;
if (f->locals.size() > 0)
@@ -244,6 +249,7 @@ printscript(systemtap_session& s, ostream& o)
o << "# probes" << endl;
for (unsigned i=0; i<s.probes.size(); i++)
{
+ if (pending_interrupts) return;
derived_probe* p = s.probes[i];
p->printsig (o);
o << endl;
diff --git a/session.h b/session.h
index e8100cf5..22575e8d 100644
--- a/session.h
+++ b/session.h
@@ -131,7 +131,7 @@ struct systemtap_session
// resolved globals/functions/probes for the run as a whole
std::vector<stapfile*> files;
std::vector<vardecl*> globals;
- std::vector<functiondecl*> functions;
+ std::map<std::string,functiondecl*> functions;
std::vector<derived_probe*> probes; // see also *_probes groups below
std::vector<embeddedcode*> embeds;
std::map<std::string, statistic_decl> stat_decls;
diff --git a/tapsets.cxx b/tapsets.cxx
index 28f945fe..308cef1f 100644
--- a/tapsets.cxx
+++ b/tapsets.cxx
@@ -1090,6 +1090,7 @@ struct dwflpp
for (unsigned i=0; i<v->size(); i++)
{
+ if (pending_interrupts) return;
Dwarf_Die die = v->at(i);
int rc = (*callback)(& die, data);
if (rc != DWARF_CB_OK) break;
@@ -2659,6 +2660,7 @@ dwflpp::iterate_over_functions (int (* callback)(Dwarf_Die * func, void * arg),
{
for (cu_function_cache_t::iterator it = v->begin(); it != v->end(); it++)
{
+ if (pending_interrupts) return DWARF_CB_ABORT;
string func_name = it->first;
Dwarf_Die die = it->second;
if (function_name_matches_pattern (func_name, subkey))
@@ -4428,6 +4430,8 @@ dwarf_var_expanding_copy_visitor::visit_target_symbol (target_symbol *e)
}
const char *diename = dwarf_diename (&result);
+ if (! diename) continue;
+
tsym->tok = e->tok;
tsym->base_name = "$";
tsym->base_name += diename;
@@ -4526,7 +4530,7 @@ dwarf_var_expanding_copy_visitor::visit_target_symbol (target_symbol *e)
v->tok = e->tok;
fdecl->formal_args.push_back(v);
}
- q.sess.functions.push_back(fdecl);
+ q.sess.functions[fdecl->name]=fdecl;
// Synthesize a functioncall.
functioncall* n = new functioncall;
@@ -7684,7 +7688,7 @@ procfs_var_expanding_copy_visitor::visit_target_symbol (target_symbol* e)
v->tok = e->tok;
fdecl->formal_args.push_back(v);
}
- sess.functions.push_back(fdecl);
+ sess.functions[fdecl->name]=fdecl;
// Synthesize a functioncall.
functioncall* n = new functioncall;
@@ -7930,7 +7934,7 @@ mark_var_expanding_copy_visitor::visit_target_symbol_arg (target_symbol* e)
fdecl->name = fname;
fdecl->body = ec;
fdecl->type = mark_args[argnum-1]->stp_type;
- sess.functions.push_back(fdecl);
+ sess.functions[fdecl->name]=fdecl;
// Synthesize a functioncall.
functioncall* n = new functioncall;
@@ -8838,7 +8842,7 @@ perfmon_var_expanding_copy_visitor::visit_target_symbol (target_symbol *e)
fdecl->name = fname;
fdecl->body = ec;
fdecl->type = pe_long;
- sess.functions.push_back(fdecl);
+ sess.functions[fdecl->name]=fdecl;
// Synthesize a functioncall.
functioncall* n = new functioncall;
diff --git a/translate.cxx b/translate.cxx
index 7c1469df..c1e56dcf 100644
--- a/translate.cxx
+++ b/translate.cxx
@@ -948,9 +948,9 @@ c_unparser::emit_common_header ()
}
}
- for (unsigned i=0; i<session->functions.size(); i++)
+ for (map<string,functiondecl*>::iterator it = session->functions.begin(); it != session->functions.end(); it++)
{
- functiondecl* fd = session->functions[i];
+ functiondecl* fd = it->second;
o->newline()
<< "struct function_" << c_varname (fd->name) << "_locals {";
o->indent(1);
@@ -1778,8 +1778,8 @@ c_unparser::emit_map_type_instantiations ()
for (unsigned i = 0; i < session->probes.size(); ++i)
collect_map_index_types(session->probes[i]->locals, types);
- for (unsigned i = 0; i < session->functions.size(); ++i)
- collect_map_index_types(session->functions[i]->locals, types);
+ for (map<string,functiondecl*>::iterator it = session->functions.begin(); it != session->functions.end(); it++)
+ collect_map_index_types(it->second->locals, types);
if (!types.empty())
o->newline() << "#include \"alloc.c\"";
@@ -4350,7 +4350,7 @@ static void *get_unwind_data (Dwfl_Module *m, size_t *l)
GElf_Shdr *shdr, shdr_mem;
Elf_Scn *scn = NULL;
Elf_Data *data = NULL;
-
+
dw = dwfl_module_getdwarf(m, &bias);
if (dw != NULL)
{
@@ -4468,7 +4468,7 @@ dump_unwindsyms (Dwfl_Module *m,
else if (n > 0)
{
assert (secname != NULL);
- // secname adequately set
+ // secname adequately set
// NB: it may be an empty string for ET_DYN objects
// like shared libraries, as their relocation base
@@ -4807,19 +4807,19 @@ translate_pass (systemtap_session& s)
s.op->newline(-1) << "};";
s.op->assert_0_indent();
- for (unsigned i=0; i<s.functions.size(); i++)
+ for (map<string,functiondecl*>::iterator it = s.functions.begin(); it != s.functions.end(); it++)
{
if (pending_interrupts) return 1;
s.op->newline();
- s.up->emit_functionsig (s.functions[i]);
+ s.up->emit_functionsig (it->second);
}
s.op->assert_0_indent();
- for (unsigned i=0; i<s.functions.size(); i++)
+ for (map<string,functiondecl*>::iterator it = s.functions.begin(); it != s.functions.end(); it++)
{
if (pending_interrupts) return 1;
s.op->newline();
- s.up->emit_function (s.functions[i]);
+ s.up->emit_function (it->second);
}
s.op->assert_0_indent();