public inbox for gcc-cvs@sourceware.org
help / color / mirror / Atom feed
* [gcc(refs/users/arsenic/heads/vtable_region)] test commit
@ 2021-07-27  9:03 Ankur saini
  0 siblings, 0 replies; only message in thread
From: Ankur saini @ 2021-07-27  9:03 UTC (permalink / raw)
  To: gcc-cvs

https://gcc.gnu.org/g:b1b8a944a8ece15efada192672b6d0b8f710d8bd

commit b1b8a944a8ece15efada192672b6d0b8f710d8bd
Author: Ankur Saini <arsenic@sourceware.org>
Date:   Mon Jul 26 21:57:24 2021 +0530

    test commit

Diff:
---
 gcc/analyzer/engine.cc        | 136 +++++++++++++++++++++++-------------------
 gcc/analyzer/program-point.cc |   4 +-
 gcc/analyzer/region-model.cc  |  15 ++++-
 gcc/analyzer/supergraph.cc    |   5 +-
 4 files changed, 95 insertions(+), 65 deletions(-)

diff --git a/gcc/analyzer/engine.cc b/gcc/analyzer/engine.cc
index d6de8094dde..a15b8917721 100644
--- a/gcc/analyzer/engine.cc
+++ b/gcc/analyzer/engine.cc
@@ -65,6 +65,7 @@ along with GCC; see the file COPYING3.  If not see
 #include <zlib.h>
 #include "plugin.h"
 #include "target.h"
+#include "ipa-utils.h"
 
 /* For an overview, see gcc/doc/analyzer.texi.  */
 
@@ -3263,8 +3264,8 @@ exploded_graph::process_node (exploded_node *node)
 	    program_state next_state (state);
 	    uncertainty_t uncertainty;
 
-	    /* Check if now the analyzer know about the call via 
-               function pointer or not. */
+	    /* Check if now the analyzer know about the calls that don't
+	       have a superedge representing the call or not. */
             if (succ->m_kind == SUPEREDGE_INTRAPROCEDURAL_CALL 
             	&& !(succ->get_any_callgraph_edge ()))
               {    
@@ -3281,35 +3282,49 @@ exploded_graph::process_node (exploded_node *node)
                   this_point->get_stmt());
 
                 region_model *model = this_state->m_region_model;
-                tree fn_decl = model->get_fndecl_for_call(call,&ctxt);
-                function *fun = DECL_STRUCT_FUNCTION(fn_decl);
-                if(fun)
-                {
-                  const supergraph &sg = this->get_supergraph();
-                  supernode * sn_entry = sg.get_node_for_function_entry (fun);
-                  supernode * sn_exit = sg.get_node_for_function_exit (fun);
-
-                  program_point new_point 
-                    = program_point::before_supernode (sn_entry,
-            				               NULL,
-            				               point.get_call_string ());
-
-                  new_point.push_to_call_stack (sn_exit,
-                  				next_point.get_supernode());
-
-                  next_state.push_call(*this, node, call, &uncertainty);
-
-                  // TODO: add some logging here regarding dynamic call
-
-                  if (next_state.m_valid)
+                if (tree fn_decl = model->get_fndecl_for_call(call,&ctxt))
                   {
-                    exploded_node *enode = get_or_create_node (new_point,
-            					               next_state,
-            					               node);
-                    if (enode)
-                      add_edge (node,enode, NULL, new dynamic_call_info_t (call));
+		    function *fun = DECL_STRUCT_FUNCTION(fn_decl)
+                    const supergraph &sg = this->get_supergraph();
+                    supernode * sn_entry = sg.get_node_for_function_entry (fun);
+                    supernode * sn_exit = sg.get_node_for_function_exit (fun);
+
+                    program_point new_point 
+                      = program_point::before_supernode (sn_entry,
+            				                 NULL,
+            				                 point.get_call_string ());
+
+                    new_point.push_to_call_stack (sn_exit,
+                  				  next_point.get_supernode());
+
+                    next_state.push_call(*this, node, call, &uncertainty);
+
+                    // TODO: add some logging here regarding dynamic call
+
+                    if (next_state.m_valid)
+                      {
+                        exploded_node *enode = get_or_create_node (new_point,
+            					                   next_state,
+            					                   node);
+                        if (enode)
+                          add_edge (node,enode, NULL, 
+                          	    new dynamic_call_info_t (call));
+                      }
                   }
-                }
+                /* Is it a polymorphic call ?  */
+                else
+                  {
+		    if (logger)
+	      	       logger->log ("reached here\n");
+                    cgraph_node *n = cgraph_node::get(fn_decl);
+                    vec <cgraph_node *> possible_targets 
+		      = possible_polymorphic_call_targets (n->indirect_calls);
+		    for(cgraph_node *i : possible_targets)
+		    if (logger)
+	      		logger->log ("possible target : %s\n",
+			   	     i->dump_name());
+                  }
+                // don't let this stop the analysis
               }
 
 	    if (!node->on_edge (*this, succ, &next_point, &next_state,
@@ -3327,37 +3342,38 @@ exploded_graph::process_node (exploded_node *node)
 	      add_edge (node, next, succ);
 	  }
 
-    /* Return from the calls which doesn't have a return superedge.
-    	Such case occurs when GCC's middle end didn't knew which function to
-    	call but analyzer did */
-    if((is_an_exit_block && !found_a_superedge)
-       && (!point.get_call_string ().empty_p ()))
-    {
-      const call_string cs = point.get_call_string ();
-      program_point next_point 
-        = program_point::before_supernode (cs.get_caller_node (),
-        				   NULL,
-        				   cs);
-
-      program_state next_state (state);
-      uncertainty_t uncertainty;
-
-      const gcall *call = next_point.get_supernode ()->get_returning_call (); 
-      if(call)
-      {
-        next_state.returning_call(*this, node, call, &uncertainty);
-      }
-
-      if (next_state.m_valid)
-      {
-        next_point.pop_from_call_stack ();
-        exploded_node *enode = get_or_create_node (next_point, 
-        					   next_state, 
-        					   node);
-        if (enode)
-          add_edge (node, enode, NULL, new dynamic_call_info_t (call, true));
-      }
-    }
+      /* Return from the calls which doesn't have a return superedge.
+    	  Such case occurs when GCC's middle end didn't knew which function to
+    	  call but analyzer did */
+      if((is_an_exit_block && !found_a_superedge)
+         && (!point.get_call_string ().empty_p ()))
+        {
+          const call_string cs = point.get_call_string ();
+          program_point next_point 
+            = program_point::before_supernode (cs.get_caller_node (),
+        				       NULL,
+        				       cs);
+
+          program_state next_state (state);
+          uncertainty_t uncertainty;
+
+          const gcall *call = next_point.get_supernode ()->get_returning_call ();
+          if(call)
+            {
+              next_state.returning_call(*this, node, call, &uncertainty);
+    
+              if (next_state.m_valid)
+		{
+                  next_point.pop_from_call_stack ();
+                  exploded_node *enode = get_or_create_node (next_point, 
+        					             next_state, 
+        					             node);
+                  if (enode)
+                    add_edge (node, enode, NULL, 
+                    	      new dynamic_call_info_t (call, true));
+		}
+	    }
+        }
       }
       break;
     }
diff --git a/gcc/analyzer/program-point.cc b/gcc/analyzer/program-point.cc
index f3b332774a2..ad9bc17313b 100644
--- a/gcc/analyzer/program-point.cc
+++ b/gcc/analyzer/program-point.cc
@@ -449,8 +449,8 @@ program_point::on_edge (exploded_graph &eg,
 	    return false;
 	  }
 	const call_string::element_t top_of_stack = m_call_string.pop ();
-	call_string::element_t current_call_string_element (succ->m_src, 
-							    succ->m_dest);
+	call_string::element_t current_call_string_element (succ->m_dest, 
+							    succ->m_src);
 	if (top_of_stack != current_call_string_element)
 	  {
 	    if (logger)
diff --git a/gcc/analyzer/region-model.cc b/gcc/analyzer/region-model.cc
index 5dfe7a0f487..db5402582b9 100644
--- a/gcc/analyzer/region-model.cc
+++ b/gcc/analyzer/region-model.cc
@@ -3200,8 +3200,21 @@ void
 region_model::update_for_return_superedge (const return_superedge &return_edge,
 					   region_model_context *ctxt)
 {
+  /* Get the region for the result of the call, within the caller frame.  */
+  const region *result_dst_reg = NULL;
   const gcall *call_stmt = return_edge.get_call_stmt ();
-  update_for_return_gcall (call_stmt, ctxt);
+  tree lhs = gimple_call_lhs (call_stmt);
+  if (lhs)
+    {
+      /* Normally we access the top-level frame, which is:
+	   path_var (expr, get_stack_depth () - 1)
+	 whereas here we need the caller frame, hence "- 2" here.  */
+      gcc_assert (get_stack_depth () >= 2);
+      result_dst_reg = get_lvalue (path_var (lhs, get_stack_depth () - 2),
+				   ctxt);
+    }
+
+  pop_frame (result_dst_reg, NULL, ctxt);
 }
 
 /* Update this region_model with a summary of the effect of calling
diff --git a/gcc/analyzer/supergraph.cc b/gcc/analyzer/supergraph.cc
index 598965dd7fc..31bf5a3238f 100644
--- a/gcc/analyzer/supergraph.cc
+++ b/gcc/analyzer/supergraph.cc
@@ -189,9 +189,10 @@ supergraph::supergraph (logger *logger)
     		   			     NULL);
     		  m_cgraph_edge_to_caller_next_node.put (edge, node_for_stmts);
     		}
-	       else
+	      else
 	        {
-	          // maybe call is via a function pointer
+	          /* Still split the call, and let ananlyzer figure out the
+	             callee in later stages.  */
 	          if (gcall *call = dyn_cast<gcall *> (stmt))
 	          {
 	            cgraph_edge *edge


^ permalink raw reply	[flat|nested] only message in thread

only message in thread, other threads:[~2021-07-27  9:03 UTC | newest]

Thread overview: (only message) (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2021-07-27  9:03 [gcc(refs/users/arsenic/heads/vtable_region)] test commit Ankur saini

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).