diff options
author | Frank Ch. Eigler <fche@elastic.org> | 2008-09-10 17:21:44 -0400 |
---|---|---|
committer | Frank Ch. Eigler <fche@elastic.org> | 2008-09-10 17:21:44 -0400 |
commit | f76427a2bf80e4451e5e8d0c26b06aca65e4e2c4 (patch) | |
tree | 0c90ae0cf7b3c2758226feab577d6273528b2ef1 | |
parent | e0c72583f8fb7a61d052c58b8e9c6df0925bc234 (diff) | |
download | systemtap-steved-f76427a2bf80e4451e5e8d0c26b06aca65e4e2c4.tar.gz systemtap-steved-f76427a2bf80e4451e5e8d0c26b06aca65e4e2c4.tar.xz systemtap-steved-f76427a2bf80e4451e5e8d0c26b06aca65e4e2c4.zip |
PR6876: translator speedup for many $vars
-rw-r--r-- | ChangeLog | 7 | ||||
-rw-r--r-- | coveragedb.cxx | 30 | ||||
-rw-r--r-- | elaborate.cxx | 206 | ||||
-rw-r--r-- | main.cxx | 10 | ||||
-rw-r--r-- | session.h | 2 | ||||
-rw-r--r-- | tapsets.cxx | 12 | ||||
-rw-r--r-- | translate.cxx | 20 |
7 files changed, 161 insertions, 126 deletions
@@ -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++) @@ -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; @@ -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(); |