diff mbox

Transparent alias suport part 8 (equal_address_to support)

Message ID 20151209051137.GA39879@kam.mff.cuni.cz
State New
Headers show

Commit Message

Jan Hubicka Dec. 9, 2015, 5:11 a.m. UTC
Hi,
this patch makes symtab_node::equal_address_to to understand transparent
aliases and always return true for symbol and its transparent alias. In
addition I introduced new parameter MEMORY_ACCESSED which makes the function
useful for base/ofset alias oracle implementation.

We are bit schisofrenic about assumptions when aliases can happen. i.e.

  &global_var == &globa_var2

will not fold to false, because we think that the variables may be aliases,
but

  global_var = 1;
  global_var2 = 2;
  return global_var

will return 1 becuase the alias oracle assumes aliases to not exist.
I think we could have optimization flag controling this and switch
to the assumption that there are no invisible aliases next stage1. For
now I am preserving current schisofreny - see the end of the patch
so we won't lose too many of alias oracle hits.

Bootstrapped/regtested x86_64-linux, comitted. 

	* symtab.c (symtab_node::equal_address_to): New parameter
	MEMORY_ACCESSED.
	* cgraph.h (symtab_node::equal_address_to): Update prototype.
diff mbox

Patch

Index: symtab.c
===================================================================
--- symtab.c	(revision 231439)
+++ symtab.c	(working copy)
@@ -1878,9 +1878,14 @@  symtab_node::nonzero_address ()
 
 /* Return 0 if symbol is known to have different address than S2,
    Return 1 if symbol is known to have same address as S2,
-   return 2 otherwise.   */
+   return 2 otherwise.  
+
+   If MEMORY_ACCESSED is true, assume that both memory pointer to THIS
+   and S2 is going to be accessed.  This eliminates the situations when
+   either THIS or S2 is NULL and is seful for comparing bases when deciding
+   about memory aliasing.  */
 int
-symtab_node::equal_address_to (symtab_node *s2)
+symtab_node::equal_address_to (symtab_node *s2, bool memory_accessed)
 {
   enum availability avail1, avail2;
 
@@ -1888,6 +1893,16 @@  symtab_node::equal_address_to (symtab_no
   if (this == s2)
     return 1;
 
+  /* Unwind transparent aliases first; those are always equal to their
+     target.  */
+  if (this->transparent_alias && this->analyzed)
+    return this->get_alias_target ()->equal_address_to (s2);
+  while (s2->transparent_alias && s2->analyzed)
+    s2 = s2->get_alias_target();
+
+  if (this == s2)
+    return 1;
+
   /* For non-interposable aliases, lookup and compare their actual definitions.
      Also check if the symbol needs to bind to given definition.  */
   symtab_node *rs1 = ultimate_alias_target (&avail1);
@@ -1924,8 +1939,9 @@  symtab_node::equal_address_to (symtab_no
       return 1;
     }
 
-  /* If both symbols may resolve to NULL, we can not really prove them different.  */
-  if (!nonzero_address () && !s2->nonzero_address ())
+  /* If both symbols may resolve to NULL, we can not really prove them
+     different.  */
+  if (!memory_accessed && !nonzero_address () && !s2->nonzero_address ())
     return 2;
 
   /* Except for NULL, functions and variables never overlap.  */
@@ -1956,11 +1972,12 @@  symtab_node::equal_address_to (symtab_no
     }
 
   /* TODO: Alias oracle basically assume that addresses of global variables
-     are different unless they are declared as alias of one to another.
-     We probably should be consistent and use this fact here, too, and update
-     alias oracle to use this predicate.  */
+     are different unless they are declared as alias of one to another while
+     the code folding comparsions doesn't.
+     We probably should be consistent and use this fact here, too, but for
+     the moment return false only when we are called from the alias oracle.  */
 
-  return 2;
+  return memory_accessed && rs1 != rs2 ? 0 : 2;
 }
 
 /* Worker for call_for_symbol_and_aliases.  */
Index: cgraph.h
===================================================================
--- cgraph.h	(revision 231439)
+++ cgraph.h	(working copy)
@@ -355,8 +355,13 @@  public:
 
   /* Return 0 if symbol is known to have different address than S2,
      Return 1 if symbol is known to have same address as S2,
-     return 2 otherwise.   */
-  int equal_address_to (symtab_node *s2);
+     return 2 otherwise. 
+
+     If MEMORY_ACCESSED is true, assume that both memory pointer to THIS
+     and S2 is going to be accessed.  This eliminates the situations when
+     either THIS or S2 is NULL and is seful for comparing bases when deciding
+     about memory aliasing.  */
+  int equal_address_to (symtab_node *s2, bool memory_accessed = false);
 
   /* Return true if symbol's address may possibly be compared to other
      symbol's address.  */