summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorhubicka <hubicka@138bc75d-0d04-0410-961f-82ee72b054a4>2015-12-09 05:07:18 +0000
committerhubicka <hubicka@138bc75d-0d04-0410-961f-82ee72b054a4>2015-12-09 05:07:18 +0000
commitf5d3c0a6c89a46c5bca677767ce129a78e9edafa (patch)
tree605cb507b2dcec62d39dca832e936a5a93ff6a1b
parent8b95d2d220bd184e9394597143bb939d62735fde (diff)
downloadgcc-f5d3c0a6c89a46c5bca677767ce129a78e9edafa.tar.gz
PR ipa/61886
* symtab.c (symtab_node::equal_address_to): New parameter MEMORY_ACCESSED. * cgraph.h (symtab_node::equal_address_to): Update prototype. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@231440 138bc75d-0d04-0410-961f-82ee72b054a4
-rw-r--r--gcc/ChangeLog7
-rw-r--r--gcc/cgraph.h9
-rw-r--r--gcc/symtab.c33
3 files changed, 39 insertions, 10 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index cc95209eba9..5153e2089c7 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,10 @@
+2015-12-08 Jan Hubicka <hubicka@ucw.cz>
+
+ PR ipa/61886
+ * symtab.c (symtab_node::equal_address_to): New parameter
+ MEMORY_ACCESSED.
+ * cgraph.h (symtab_node::equal_address_to): Update prototype.
+
2015-12-08 DJ Delorie <dj@redhat.com>
* config/rx/rx.opt (-mjsr): Add.
diff --git a/gcc/cgraph.h b/gcc/cgraph.h
index 7c643502fff..0a093913be6 100644
--- a/gcc/cgraph.h
+++ b/gcc/cgraph.h
@@ -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. */
diff --git a/gcc/symtab.c b/gcc/symtab.c
index a9a0ab64cf9..581decea5d6 100644
--- a/gcc/symtab.c
+++ b/gcc/symtab.c
@@ -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_node *s2)
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_node *s2)
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_node *s2)
}
/* 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. */