summaryrefslogtreecommitdiffstats
path: root/elaborate.cxx
diff options
context:
space:
mode:
authordsmith <dsmith>2006-08-10 19:19:05 +0000
committerdsmith <dsmith>2006-08-10 19:19:05 +0000
commit88bbd60de43030f300649cd049ad87393c54a933 (patch)
treed866e76a2c0c12b75c1f1e64e168ce351b016ebf /elaborate.cxx
parent408acea1833e4cdc2d303edf4295f9d04c21e2d2 (diff)
downloadsystemtap-steved-88bbd60de43030f300649cd049ad87393c54a933.tar.gz
systemtap-steved-88bbd60de43030f300649cd049ad87393c54a933.tar.xz
systemtap-steved-88bbd60de43030f300649cd049ad87393c54a933.zip
2006-08-10 David Smith <dsmith@redhat.com>
* elaborate.cxx (duplicate_function_remover): Added class. (get_functionsig): Added function. (semantic_pass_opt5): New function merges duplicate identical functions into one function. (semantic_pass_optimize): Calls semantic_pass_opt5. * translate.cxx (c_unparser::emit_probe): Changed to merge duplicate probes bodies by making the duplicate probe just call the original probe (BZ# 2421).
Diffstat (limited to 'elaborate.cxx')
-rw-r--r--elaborate.cxx89
1 files changed, 89 insertions, 0 deletions
diff --git a/elaborate.cxx b/elaborate.cxx
index b6d0f226..00a3a7c2 100644
--- a/elaborate.cxx
+++ b/elaborate.cxx
@@ -1550,6 +1550,94 @@ void semantic_pass_opt4 (systemtap_session& s, bool& relaxed_p)
}
}
+struct duplicate_function_remover: public functioncall_traversing_visitor
+{
+ systemtap_session& s;
+ bool& relaxed_p;
+ map<functiondecl*, functiondecl*>& duplicate_function_map;
+
+ duplicate_function_remover(systemtap_session& sess, bool& r,
+ map<functiondecl*, functiondecl*>&dfm):
+ s(sess), relaxed_p(r), duplicate_function_map(dfm) {};
+
+ void visit_functioncall (functioncall* e);
+};
+
+void
+duplicate_function_remover::visit_functioncall (functioncall *e)
+{
+ functioncall_traversing_visitor::visit_functioncall (e);
+
+ // If the current function call reference points to a function that
+ // is a duplicate, replace it.
+ if (duplicate_function_map.count(e->referent) != 0)
+ {
+ if (s.verbose>2)
+ clog << "Changing " << e->referent->name
+ << " reference to "
+ << duplicate_function_map[e->referent]->name
+ << " reference\n";
+ e->tok = duplicate_function_map[e->referent]->tok;
+ e->function = duplicate_function_map[e->referent]->name;
+ e->referent = duplicate_function_map[e->referent];
+
+ relaxed_p = false;
+ }
+}
+
+static string
+get_functionsig (functiondecl* f)
+{
+ ostringstream s;
+
+ // Get the "name:args body" of the function in s. We have to
+ // include the args since the function 'x1(a, b)' is different than
+ // the function 'x2(b, a)' even if the bodies of the two functions
+ // are exactly the same.
+ f->printsig(s);
+ f->body->print(s);
+
+ // printsig puts f->name + ':' on the front. Remove this
+ // (otherwise, functions would never compare equal).
+ string str = s.str().erase(0, f->name.size() + 1);
+
+ // Return the function signature.
+ return str;
+}
+
+void semantic_pass_opt5 (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(); i++)
+ {
+ string functionsig = get_functionsig(s.functions[i]);
+
+ if (functionsig_map.count(functionsig) == 0)
+ // This function is unique. Remember it.
+ functionsig_map[functionsig] = s.functions[i];
+ else
+ // This function is a duplicate.
+ duplicate_function_map[s.functions[i]]
+ = functionsig_map[functionsig];
+ }
+
+ // If we have duplicate functions, traverse down the tree, replacing
+ // the appropriate function calls.
+ // duplicate_function_remover::visit_functioncall() handles the
+ // details of replacing the function calls. Note that we don't
+ // delete the duplicate functiondecl itself, we'll let pass 1 do
+ // that.
+ if (duplicate_function_map.size() != 0)
+ {
+ duplicate_function_remover dfr (s, relaxed_p, duplicate_function_map);
+
+ for (unsigned i=0; i < s.probes.size(); i++)
+ s.probes[i]->body->visit(&dfr);
+ }
+}
+
static int
semantic_pass_optimize (systemtap_session& s)
@@ -1571,6 +1659,7 @@ semantic_pass_optimize (systemtap_session& s)
semantic_pass_opt2 (s, relaxed_p);
semantic_pass_opt3 (s, relaxed_p);
semantic_pass_opt4 (s, relaxed_p);
+ semantic_pass_opt5 (s, relaxed_p);
}
if (s.probes.size() == 0)