public inbox for gcc-cvs@sourceware.org
help / color / mirror / Atom feed
* [gcc(refs/users/arsenic/heads/vtable_region)] prototype polymorphic call changes for testing
@ 2021-07-28 13:51 Ankur saini
  0 siblings, 0 replies; 3+ messages in thread
From: Ankur saini @ 2021-07-28 13:51 UTC (permalink / raw)
  To: gcc-cvs

https://gcc.gnu.org/g:775a569cee42dfa845a556f09714d41e82100599

commit 775a569cee42dfa845a556f09714d41e82100599
Author: Ankur Saini <arsenic@sourceware.org>
Date:   Tue Jul 27 15:15:20 2021 +0530

    prototype polymorphic call changes for testing

Diff:
---
 gcc/analyzer/engine.cc        | 118 ++++++++++++++++++++++++++++++++----------
 gcc/analyzer/program-state.cc |   5 +-
 gcc/analyzer/program-state.h  |   3 +-
 gcc/analyzer/region-model.cc  |  13 +++--
 gcc/analyzer/region-model.h   |   3 +-
 5 files changed, 105 insertions(+), 37 deletions(-)

diff --git a/gcc/analyzer/engine.cc b/gcc/analyzer/engine.cc
index d6de8094dde..97261a4549f 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.  */
 
@@ -1242,6 +1243,17 @@ exploded_node::on_stmt (exploded_graph &eg,
 	unknown_side_effects = false;
     }
 
+    /* If the statmement is a polymorphic call then assume 
+       there are no side effects.  */
+    gimple *call_stmt = const_cast<gimple *>(stmt);
+    if (gcall *call = dyn_cast<gcall *> (call_stmt))
+    {
+      function *fun = this->get_function();
+      cgraph_edge *e = cgraph_node::get (fun->decl)->get_edge (call);
+      if (e && e->indirect_info->polymorphic)
+        unknown_side_effects = false;
+    }
+
   on_stmt_post (stmt, state, unknown_side_effects, &ctxt);
 
   return on_stmt_flags ();
@@ -3263,8 +3275,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 call withough a 
+	       superedge or not.  */
             if (succ->m_kind == SUPEREDGE_INTRAPROCEDURAL_CALL 
             	&& !(succ->get_any_callgraph_edge ()))
               {    
@@ -3272,6 +3284,7 @@ exploded_graph::process_node (exploded_node *node)
                 const program_state *this_state = &node->get_state ();
                 const gcall *call 
                   = this_point->get_supernode ()->get_final_call ();
+                /* Check if it is a plymorphic call or not.  */
 
                 impl_region_model_context ctxt (*this,
                   node, 
@@ -3281,35 +3294,84 @@ 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 (tree fn_decl = model->get_fndecl_for_call(call,&ctxt))
+                  {
+                    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, NULL);
+  
+                    // 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));
+                      }
+                  }
 
-                  if (next_state.m_valid)
+                /* Is it a polymorphic call ?  */
+                else
                   {
-                    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 = node->get_function();
+	      	    // cgraph_node *n = cgraph_node::get (fun->decl);
+	      	    gcall *stmt  = const_cast<gcall *>(call);
+	      	    cgraph_edge *e = cgraph_node::get (fun->decl)->get_edge (stmt);
+	      	    if (e->indirect_info->polymorphic)
+	      	    {
+	      	    	// struct cgraph_node *likely_target = NULL;
+	    		void *cache_token;
+	    		bool final;
+	    		vec <cgraph_node *>targets
+	       		   = possible_polymorphic_call_targets (e, &final, &cache_token, true);
+	       		// create enodes and eedges representing the call
+	       		for (cgraph_node *x : targets)
+	       		{
+	       		  // maybe make a function to create eenodes for such calls
+	       		  function *fun = DECL_STRUCT_FUNCTION(x->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, x->decl);
+        
+                          // 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));
+                            }
+	       		}
+	      	    }
                   }
-                }
               }
 
 	    if (!node->on_edge (*this, succ, &next_point, &next_state,
diff --git a/gcc/analyzer/program-state.cc b/gcc/analyzer/program-state.cc
index f7ccf96b2b6..a22c26be866 100644
--- a/gcc/analyzer/program-state.cc
+++ b/gcc/analyzer/program-state.cc
@@ -1042,7 +1042,8 @@ void
 program_state::push_call(exploded_graph &eg,
       			 exploded_node *enode,
       			 const gcall *call_stmt,
-      			 uncertainty_t *uncertainty)
+      			 uncertainty_t *uncertainty,
+      			 tree fn_decl = NULL)
 {
   /* Update state.  */
   const program_point &point = enode->get_point ();
@@ -1053,7 +1054,7 @@ program_state::push_call(exploded_graph &eg,
           			  this,
           			  uncertainty,
           			  last_stmt);
-  m_region_model->update_for_gcall(call_stmt, &ctxt);
+  m_region_model->update_for_gcall(call_stmt, &ctxt, fn_decl);
 }
 
 /* Update this program_state to reflect a return from function
diff --git a/gcc/analyzer/program-state.h b/gcc/analyzer/program-state.h
index 658dbb69075..a94a3637a09 100644
--- a/gcc/analyzer/program-state.h
+++ b/gcc/analyzer/program-state.h
@@ -221,7 +221,8 @@ public:
   void push_call (exploded_graph &eg,
       		  exploded_node *enode,
       		  const gcall *call_stmt,
-      		  uncertainty_t *uncertainty);
+      		  uncertainty_t *uncertainty,
+      		  tree fn_decl);
 
   void returning_call (exploded_graph &eg,
       		       exploded_node *enode,
diff --git a/gcc/analyzer/region-model.cc b/gcc/analyzer/region-model.cc
index 5dfe7a0f487..403f5b44905 100644
--- a/gcc/analyzer/region-model.cc
+++ b/gcc/analyzer/region-model.cc
@@ -3140,7 +3140,8 @@ region_model::maybe_update_for_edge (const superedge &edge,
 
 void
 region_model::update_for_gcall (const gcall *call_stmt,
-				region_model_context *ctxt)
+				region_model_context *ctxt,
+				tree fn_decl = NULL)
 {
   /* Build a vec of argument svalues, using the current top
      frame for resolving tree expressions.  */
@@ -3151,10 +3152,12 @@ region_model::update_for_gcall (const gcall *call_stmt,
       tree arg = gimple_call_arg (call_stmt, i);
       arg_svals.quick_push (get_rvalue (arg, ctxt));
     }
-
-  /* get the function * from the call */
-  tree fn_decl = get_fndecl_for_call(call_stmt,ctxt);
-  function *fun = DECL_STRUCT_FUNCTION(fn_decl);
+  
+  /* Get the fn_decl from the call if not provided as argument.  */
+  if (!fn_decl)
+    fn_decl = get_fndecl_for_call (call_stmt,ctxt);
+ 
+  function *fun = DECL_STRUCT_FUNCTION (fn_decl);
   push_frame (fun, &arg_svals, ctxt);
 }
 
diff --git a/gcc/analyzer/region-model.h b/gcc/analyzer/region-model.h
index a15bc9e2f6d..3279f313feb 100644
--- a/gcc/analyzer/region-model.h
+++ b/gcc/analyzer/region-model.h
@@ -590,7 +590,8 @@ class region_model
 			      rejected_constraint **out);
 
   void update_for_gcall (const gcall *call_stmt,
-			 region_model_context *ctxt);
+			 region_model_context *ctxt,
+			 tree fn_decl);
   
   void update_for_return_gcall (const gcall *call_stmt,
 				region_model_context *ctxt);


^ permalink raw reply	[flat|nested] 3+ messages in thread

* [gcc(refs/users/arsenic/heads/vtable_region)] prototype polymorphic call changes for testing
@ 2021-07-28  7:21 Ankur saini
  0 siblings, 0 replies; 3+ messages in thread
From: Ankur saini @ 2021-07-28  7:21 UTC (permalink / raw)
  To: gcc-cvs

https://gcc.gnu.org/g:3f3a5c7162741a331d2b13171d7bbf9462f32dde

commit 3f3a5c7162741a331d2b13171d7bbf9462f32dde
Author: Ankur Saini <arsenic@sourceware.org>
Date:   Tue Jul 27 15:15:20 2021 +0530

    prototype polymorphic call changes for testing

Diff:
---
 gcc/analyzer/engine.cc | 108 ++++++++++++++++++++++++++++++++++++-------------
 1 file changed, 80 insertions(+), 28 deletions(-)

diff --git a/gcc/analyzer/engine.cc b/gcc/analyzer/engine.cc
index d6de8094dde..67d7f95b4a9 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 call withough a 
+	       superedge or not.  */
             if (succ->m_kind == SUPEREDGE_INTRAPROCEDURAL_CALL 
             	&& !(succ->get_any_callgraph_edge ()))
               {    
@@ -3272,6 +3273,7 @@ exploded_graph::process_node (exploded_node *node)
                 const program_state *this_state = &node->get_state ();
                 const gcall *call 
                   = this_point->get_supernode ()->get_final_call ();
+                /* Check if it is a plymorphic call or not.  */
 
                 impl_region_model_context ctxt (*this,
                   node, 
@@ -3281,35 +3283,85 @@ 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 (tree fn_decl = model->get_fndecl_for_call(call,&ctxt))
+                  {
+                    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));
+                      }
+                  }
 
-                  if (next_state.m_valid)
+                /* Is it a polymorphic call ?  */
+                else
                   {
-                    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 = node->get_function();
+	      	    cgraph_node *n = cgraph_node::get (fun->decl);
+	      	    gcall *stmt  = const_cast<gcall *>(call);
+	      	    cgraph_edge *e = cgraph_node::get (fun->decl)->get_edge (stmt);
+	      	    if (e->indirect_info->polymorphic)
+	      	    {
+	      	    	struct cgraph_node *likely_target = NULL;
+	    		void *cache_token;
+	    		bool final;
+	    		vec <cgraph_node *>targets
+	       		   = possible_polymorphic_call_targets (e, &final, &cache_token, true);
+	       		// create enodes and eedges representing the call
+	       		for (cgraph_node *x : targets)
+	       		{
+	       		  // maybe branch this out in a function 
+	       		  function *fun = DECL_STRUCT_FUNCTION(x->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));
+                            }
+	       		  // if (logger)
+	      		   //  logger->log ("found targets: %s\n",x->dump_name ());
+	       		}
+	      	    }
                   }
-                }
               }
 
 	    if (!node->on_edge (*this, succ, &next_point, &next_state,


^ permalink raw reply	[flat|nested] 3+ messages in thread

* [gcc(refs/users/arsenic/heads/vtable_region)] prototype polymorphic call changes for testing
@ 2021-07-27  9:47 Ankur saini
  0 siblings, 0 replies; 3+ messages in thread
From: Ankur saini @ 2021-07-27  9:47 UTC (permalink / raw)
  To: gcc-cvs

https://gcc.gnu.org/g:8713b6b19fe0a608207d39b0230b5d0b03a70c7f

commit 8713b6b19fe0a608207d39b0230b5d0b03a70c7f
Author: Ankur Saini <arsenic@sourceware.org>
Date:   Tue Jul 27 15:15:20 2021 +0530

    prototype polymorphic call changes for testing

Diff:
---
 gcc/analyzer/engine.cc | 63 +++++++++++++++++++++++++++++++-------------------
 1 file changed, 39 insertions(+), 24 deletions(-)

diff --git a/gcc/analyzer/engine.cc b/gcc/analyzer/engine.cc
index d6de8094dde..9488c6889e0 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.  */
 
@@ -3284,32 +3285,46 @@ exploded_graph::process_node (exploded_node *node)
                 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)
                   {
-                    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));
+                    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());
                   }
-                }
               }
 
 	    if (!node->on_edge (*this, succ, &next_point, &next_state,


^ permalink raw reply	[flat|nested] 3+ messages in thread

end of thread, other threads:[~2021-07-28 13:51 UTC | newest]

Thread overview: 3+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2021-07-28 13:51 [gcc(refs/users/arsenic/heads/vtable_region)] prototype polymorphic call changes for testing Ankur saini
  -- strict thread matches above, loose matches on Subject: below --
2021-07-28  7:21 Ankur saini
2021-07-27  9:47 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).