diff options
author | hubicka <hubicka@138bc75d-0d04-0410-961f-82ee72b054a4> | 2015-12-09 05:07:18 +0000 |
---|---|---|
committer | hubicka <hubicka@138bc75d-0d04-0410-961f-82ee72b054a4> | 2015-12-09 05:07:18 +0000 |
commit | f5d3c0a6c89a46c5bca677767ce129a78e9edafa (patch) | |
tree | 605cb507b2dcec62d39dca832e936a5a93ff6a1b | |
parent | 8b95d2d220bd184e9394597143bb939d62735fde (diff) | |
download | gcc-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/ChangeLog | 7 | ||||
-rw-r--r-- | gcc/cgraph.h | 9 | ||||
-rw-r--r-- | gcc/symtab.c | 33 |
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. */ |