]> sourceware.org Git - systemtap.git/commitdiff
some function overloading optimizations
authorFelix Lu <flu@redhat.com>
Mon, 8 Aug 2016 18:48:37 +0000 (14:48 -0400)
committerFelix Lu <flu@redhat.com>
Tue, 9 Aug 2016 13:32:22 +0000 (09:32 -0400)
This removes some unnecessary code in the generated module.

* elaborate.cxx: Store next flag in functiondecl instead of in a set.
* staptree.h: struct functiondecl:: new has_next flag.
* translate.cxx: c_unparser::visit_functioncall - Don't generate
  redundant functioncall code for overloaded functions.

elaborate.cxx
staptree.cxx
staptree.h
translate.cxx

index 6e639a832a6e9f93d849b149d5a5bd1d8991d5dd..c6d7c4880da019415f74fa5a7b8040d409fa1454 100644 (file)
@@ -4670,20 +4670,19 @@ static void semantic_pass_dead_control (systemtap_session& s, bool& relaxed_p)
 struct function_next_check : public traversing_visitor
 {
   functiondecl* current_function;
-  set<functiondecl*>& function_next;
 
-  function_next_check(set<functiondecl*>& fn)
-    : current_function(0), function_next(fn) { }
+  function_next_check()
+    : current_function(0) { }
 
   void visit_next_statement(next_statement*)
   {
-    function_next.insert(current_function);
+    current_function->has_next = true;
   }
 
   void visit_embeddedcode(embeddedcode* s)
   {
     if (s->code.find("STAP_NEXT;") != string::npos)
-      function_next.insert(current_function);
+      current_function->has_next = true;
   }
 };
 
@@ -4691,12 +4690,10 @@ struct dead_overload_remover : public traversing_visitor
 {
   systemtap_session& s;
   bool& relaxed_p;
-  const set<functiondecl*>& function_next;
 
   dead_overload_remover(systemtap_session& sess,
-                        bool& r,
-                        const set<functiondecl*>& fn)
-    : s(sess), relaxed_p(r), function_next(fn) { }
+                        bool& r)
+    : s(sess), relaxed_p(r) { }
 
   void visit_functioncall(functioncall* e);
 };
@@ -4711,10 +4708,12 @@ void dead_overload_remover::visit_functioncall(functioncall *e)
       functiondecl* r = e->referents[fd];
 
       // Note that this is not a sound inference but it suffices for most
-      // cases. We simply use the presence of a 'next' statement as an indicator
+      // cases. It may be the case that there is a 'next' statement in the
+      // function that will never be executed by the control flow.
+      // We simply use the presence of a 'next' statement as an indicator
       // of a potential fall through. Once a function can't be 'nexted' the
       // remaining functions are unreachable.
-      if (chained && function_next.find(r) != function_next.end())
+      if (chained && r->has_next)
         reachable++;
       else
         chained = false;
@@ -4736,7 +4735,7 @@ void dead_overload_remover::visit_functioncall(functioncall *e)
 static void semantic_pass_overload(systemtap_session& s, bool& relaxed_p)
 {
   set<functiondecl*> function_next;
-  function_next_check fnc(function_next);
+  function_next_check fnc;
 
   for (auto it = s.functions.begin(); it != s.functions.end(); ++it)
     {
@@ -4747,13 +4746,13 @@ static void semantic_pass_overload(systemtap_session& s, bool& relaxed_p)
 
   for (auto it = s.probes.begin(); it != s.probes.end(); ++it)
     {
-      dead_overload_remover ovr(s, relaxed_p, function_next);
+      dead_overload_remover ovr(s, relaxed_p);
       (*it)->body->visit(&ovr);
     }
 
   for (auto it = s.functions.begin(); it != s.functions.end(); ++it)
     {
-      dead_overload_remover ovr(s, relaxed_p, function_next);
+      dead_overload_remover ovr(s, relaxed_p);
       it->second->body->visit(&ovr);
     }
 }
index b691a69710f57efbc3854a587ae5b7d443953b11..4b12e3b9ab03b712e1a9cbd2575d02863b2a086f 100644 (file)
@@ -212,7 +212,8 @@ vardecl::compatible_arity (int a)
 
 
 functiondecl::functiondecl ():
-  body (0), synthetic (false), mangle_oldstyle (false), priority(1)
+  body (0), synthetic (false), mangle_oldstyle (false), has_next(false),
+  priority(1)
 {
 }
 
index 8a1705eb19ff04c9e26d3a2148083ed9fe02b91b..1dfb43ebc0b4e708c9e47783f39ad138b15bc0d2 100644 (file)
@@ -618,6 +618,7 @@ struct functiondecl: public symboldecl
   statement* body;
   bool synthetic;
   bool mangle_oldstyle;
+  bool has_next;
   int64_t priority;
   functiondecl ();
   void print (std::ostream& o) const;
index 58205f10eb969c1b2d53056ab91d0f9f3145ed35..73efcb95e28f018070402415d772b970f0cc453b 100644 (file)
@@ -5550,7 +5550,7 @@ c_unparser::visit_functioncall (functioncall* e)
           yield = true;
         }
 
-      if (e->referents.size() > 1)
+      if (e->referents.size() > 1 && r != e->referents.back())
         // branch to end of the enclosing statement-expression if one of the
         // function alternatives is selected
         o->newline() << "if (!c->next) goto fc_end_" << fc_counter << ";";
@@ -5562,8 +5562,9 @@ c_unparser::visit_functioncall (functioncall* e)
       o->newline() << "fc_end_" << fc_counter++ << ":";
     }
 
-  // check for aborted return from function; this could happen from non-overloaded ones too
-  o->newline() << "if (unlikely(c->next)) { c->last_error = \"all functions exhausted\"; goto out; }";
+  if (e->referents.back()->has_next)
+    // check for aborted return from function; this could happen from non-overloaded ones too
+    o->newline() << "if (unlikely(c->next)) { c->last_error = \"all functions exhausted\"; goto out; }";
 
   // return result from retvalue slot NB: this must be last, for the
   // enclosing statement-expression ({ ... }) to carry this value.
This page took 0.039385 seconds and 5 git commands to generate.