This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[PATCH][RFC] PR78035


The following tries to address the inconsistency with folding
two addresses based on two decls vs. one pointer vs a decl address
caused by the latter not honoring interposition.

Honza, is

+      /* If obj1 is interposable give up.  */
+      if (VAR_P (obj1)
+         && (TREE_STATIC (obj1) || DECL_EXTERNAL (obj1)))
+       {
+         varpool_node *node = varpool_node::get (obj1);
+         if (! node
+             || ! node->analyzed
+             || ! decl_binds_to_current_def_p (obj1))
+           return false;
+       }

conservatively correct?  I tried to learn from
symtab_node::equal_address_to but I'm not 100% sure.  Esp.
in what cases can I expect a NULL node from varpool_node::get?

Basically I am using the above to decide whether I can use
the ultimate alias target of two decls to decide whether they
are not equal (points-to uses the DECL_UID of the ultimate alias
target in the bitmaps).

Maybe you can factor out a symtab helper for me?  I think I
want to catch all cases where symtab_node::equal_address_to
would return -1 (thus with respect to aliases the above doesn't
look conservative?)

Thanks,
Richard.

2016-10-19  Richard Biener  <rguenther@suse.de>

	PR tree-optimization/78035
	* tree-ssa-alias.h (struct pt_solution): Add vars_contains_interposable
	flag.
	* tree-ssa-structalias.c: Include varasm.h.
	(set_uids_in_ptset): Set vars_contains_interposable for
	interposable variables.
	(ipa_escaped_pt): Adjust.
	* tree-ssa-alias.c: Include varasm.h.
	(ptrs_compare_unequal): If pt->vars_contains_interposable or
	a decl is interposable then do not conclude anything about
	address equality.
	(dump_points_to_solution): Handle vars_contains_interposable.
	* gimple-pretty-print.c (pp_points_to_solution): Likewise.

	* gcc.target/i386/pr78035.c: New testcase.


Index: gcc/testsuite/gcc.target/i386/pr78035.c
===================================================================
--- gcc/testsuite/gcc.target/i386/pr78035.c	(revision 0)
+++ gcc/testsuite/gcc.target/i386/pr78035.c	(revision 0)
@@ -0,0 +1,24 @@
+/* { dg-do compile } */
+/* { dg-options "-O2" } */
+
+extern int a;
+extern int b;
+extern int c;
+
+int foo(int choose_a)
+{
+  int *p;
+  if (choose_a)
+    p = &a;
+  else
+    p = &b;
+  return p != &c;
+}
+
+int bar ()
+{
+  return &a != &c;
+}
+
+/* We should not optimize away either comparison.  */
+/* { dg-final { scan-assembler-times "cmp" 2 } } */
Index: gcc/tree-ssa-alias.c
===================================================================
--- gcc/tree-ssa-alias.c	(revision 241362)
+++ gcc/tree-ssa-alias.c	(working copy)
@@ -32,12 +32,12 @@ along with GCC; see the file COPYING3.
 #include "tree-pretty-print.h"
 #include "alias.h"
 #include "fold-const.h"
-
 #include "langhooks.h"
 #include "dumpfile.h"
 #include "tree-eh.h"
 #include "tree-dfa.h"
 #include "ipa-reference.h"
+#include "varasm.h"
 
 /* Broad overview of how alias analysis on gimple works:
 
@@ -366,15 +366,39 @@ ptrs_compare_unequal (tree ptr1, tree pt
       /* We may not use restrict to optimize pointer comparisons.
          See PR71062.  So we have to assume that restrict-pointed-to
 	 may be in fact obj1.  */
-      if (!pi || pi->pt.vars_contains_restrict)
+      if (! pi
+	  || pi->pt.vars_contains_restrict
+	  || pi->pt.vars_contains_interposable)
 	return false;
+      /* If obj1 is interposable give up.  */
+      if (VAR_P (obj1)
+	  && (TREE_STATIC (obj1) || DECL_EXTERNAL (obj1)))
+	{
+	  varpool_node *node = varpool_node::get (obj1);
+	  if (! node
+	      || ! node->analyzed
+	      || ! decl_binds_to_current_def_p (obj1))
+	    return false;
+	}
       return !pt_solution_includes (&pi->pt, obj1);
     }
   else if (TREE_CODE (ptr1) == SSA_NAME && obj2)
     {
       struct ptr_info_def *pi = SSA_NAME_PTR_INFO (ptr1);
-      if (!pi || pi->pt.vars_contains_restrict)
+      if (! pi
+	  || pi->pt.vars_contains_restrict
+	  || pi->pt.vars_contains_interposable)
 	return false;
+      /* If obj2 is interposable give up.  */
+      if (VAR_P (obj2)
+	  && (TREE_STATIC (obj2) || DECL_EXTERNAL (obj2)))
+	{
+	  varpool_node *node = varpool_node::get (obj2);
+	  if (! node
+	      || ! node->analyzed
+	      || ! decl_binds_to_current_def_p (obj2))
+	    return false;
+	}
       return !pt_solution_includes (&pi->pt, obj2);
     }
 
@@ -545,7 +569,12 @@ dump_points_to_solution (FILE *file, str
 	      comma = ", ";
 	    }
 	  if (pt->vars_contains_restrict)
-	    fprintf (file, "%srestrict", comma);
+	    {
+	      fprintf (file, "%srestrict", comma);
+	      comma = ", ";
+	    }
+	  if (pt->vars_contains_interposable)
+	    fprintf (file, "%sinterposable", comma);
 	  fprintf (file, ")");
 	}
     }
Index: gcc/tree-ssa-alias.h
===================================================================
--- gcc/tree-ssa-alias.h	(revision 241362)
+++ gcc/tree-ssa-alias.h	(working copy)
@@ -57,6 +57,8 @@ struct GTY(()) pt_solution
   /* Nonzero if the vars bitmap includes a anonymous variable used to
      represent storage pointed to by a restrict qualified pointer.  */
   unsigned int vars_contains_restrict : 1;
+  /* Nonzero if the vars bitmap includes an interposable variable.  */
+  unsigned int vars_contains_interposable : 1;
 
   /* Set of variables that this pointer may point to.  */
   bitmap vars;
Index: gcc/gimple-pretty-print.c
===================================================================
--- gcc/gimple-pretty-print.c	(revision 241362)
+++ gcc/gimple-pretty-print.c	(working copy)
@@ -728,6 +728,12 @@ pp_points_to_solution (pretty_printer *b
 	    {
 	      pp_string (buffer, comma);
 	      pp_string (buffer, "restrict");
+	      comma = ", ";
+	    }
+	  if (pt->vars_contains_interposable)
+	    {
+	      pp_string (buffer, comma);
+	      pp_string (buffer, "interposable");
 	    }
 	  pp_string (buffer, ")");
 	}
Index: gcc/tree-ssa-structalias.c
===================================================================
--- gcc/tree-ssa-structalias.c	(revision 241362)
+++ gcc/tree-ssa-structalias.c	(working copy)
@@ -39,6 +39,8 @@
 #include "tree-dfa.h"
 #include "params.h"
 #include "gimple-walk.h"
+#include "varasm.h"
+
 
 /* The idea behind this analyzer is to generate set constraints from the
    program, then solve the resulting constraints in order to generate the
@@ -6344,6 +6346,18 @@ set_uids_in_ptset (bitmap into, bitmap f
 		  && fndecl
 		  && ! auto_var_in_fn_p (vi->decl, fndecl)))
 	    pt->vars_contains_nonlocal = true;
+
+	  /* If we have a variable that is interposable record that fact
+	     for pointer comparison simplification.  */
+	  if (VAR_P (vi->decl)
+	      && (DECL_EXTERNAL (vi->decl) || TREE_PUBLIC (vi->decl)))
+	    {
+	      varpool_node *node = varpool_node::get (vi->decl);
+	      if (! node
+		  || ! node->analyzed
+		  || ! decl_binds_to_current_def_p (node->decl))
+		pt->vars_contains_interposable = true;
+	    }
 	}
 
       else if (TREE_CODE (vi->decl) == FUNCTION_DECL
@@ -7576,7 +7590,8 @@ make_pass_build_ealias (gcc::context *ct
 
 /* IPA PTA solutions for ESCAPED.  */
 struct pt_solution ipa_escaped_pt
-  = { true, false, false, false, false, false, false, false, false, NULL };
+  = { true, false, false, false, false,
+      false, false, false, false, false, NULL };
 
 /* Associate node with varinfo DATA. Worker for
    cgraph_for_symbol_thunks_and_aliases.  */


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]