Commit 89330618 by Jan Hubicka Committed by Jan Hubicka

cgraph.h (symtab_node): Add nonzero_address.


	* cgraph.h (symtab_node): Add nonzero_address.
	(decl_in_symtab_p): Break out from ...
	(symtab_get_node): ... here.
	* fold-const.c: Include cgraph.h
	(tree_single_nonzero_warnv_p): Use symtab to determine
	if symbol is non-zero.
	* symtab.c (symtab_node::nonzero_address): New method.

	* gcc.dg/pr36901.h: Simplify because non-zero symbol folding no
	longer happens during parsing.
	* gcc.dg/pr44024.c: Update template.
	* g++.dg/tree-ssa/nonzero-2.C: New testcase.
	* g++.dg/tree-ssa/nonzero-1.C: New testcase.
	* gcc.dg/tree-ssa/nonzero-1.c: New testcase.

From-SVN: r212499
parent 69dc8208
2014-07-13 Jan Hubicka <hubicka@ucw.cz>
* cgraph.h (symtab_node): Add nonzero_address.
(decl_in_symtab_p): Break out from ...
(symtab_get_node): ... here.
* fold-const.c: Include cgraph.h
(tree_single_nonzero_warnv_p): Use symtab to determine
if symbol is non-zero.
* symtab.c (symtab_node::nonzero_address): New method.
2014-07-12 Jan Hubicka <hubicka@ucw.cz>
* ipa-devirt.c (odr_subtypes_equivalent_p): Disable temporary hack
......
......@@ -314,6 +314,7 @@ create_cilk_helper_decl (struct wrapper_data *wd)
tree block = make_node (BLOCK);
DECL_INITIAL (fndecl) = block;
TREE_USED (block) = 1;
BLOCK_SUPERCONTEXT (block) = fndecl;
gcc_assert (!DECL_SAVED_TREE (fndecl));
/* Inlining would defeat the purpose of this wrapper.
......
......@@ -282,6 +282,9 @@ public:
void set_init_priority (priority_type priority);
priority_type get_init_priority ();
/* Return true if symbol is known to be nonzero. */
bool nonzero_address ();
};
/* Walk all aliases for NODE. */
......@@ -1148,6 +1151,17 @@ tree varpool_get_constructor (struct varpool_node *node);
/* In cgraph.c */
extern void change_decl_assembler_name (tree, tree);
/* Return true if DECL should have entry in symbol table if used.
Those are functions and static & external veriables*/
static bool
decl_in_symtab_p (const_tree decl)
{
return (TREE_CODE (decl) == FUNCTION_DECL
|| (TREE_CODE (decl) == VAR_DECL
&& (TREE_STATIC (decl) || DECL_EXTERNAL (decl))));
}
/* Return symbol table node associated with DECL, if any,
and NULL otherwise. */
......@@ -1155,12 +1169,7 @@ static inline symtab_node *
symtab_get_node (const_tree decl)
{
#ifdef ENABLE_CHECKING
/* Check that we are called for sane type of object - functions
and static or external variables. */
gcc_checking_assert (TREE_CODE (decl) == FUNCTION_DECL
|| (TREE_CODE (decl) == VAR_DECL
&& (TREE_STATIC (decl) || DECL_EXTERNAL (decl)
|| in_lto_p)));
gcc_checking_assert (decl_in_symtab_p (decl));
/* Check that the mapping is sane - perhaps this check can go away,
but at the moment frontends tends to corrupt the mapping by calling
memcpy/memset on the tree nodes. */
......
......@@ -69,6 +69,7 @@ along with GCC; see the file COPYING3. If not see
#include "tree-dfa.h"
#include "hash-table.h" /* Required for ENABLE_FOLD_CHECKING. */
#include "builtins.h"
#include "cgraph.h"
/* Nonzero if we are folding constants inside an initializer; zero
otherwise. */
......@@ -16020,21 +16021,33 @@ tree_single_nonzero_warnv_p (tree t, bool *strict_overflow_p)
case ADDR_EXPR:
{
tree base = TREE_OPERAND (t, 0);
if (!DECL_P (base))
base = get_base_address (base);
if (!base)
return false;
/* Weak declarations may link to NULL. Other things may also be NULL
so protect with -fdelete-null-pointer-checks; but not variables
allocated on the stack. */
/* For objects in symbol table check if we know they are non-zero.
Don't do anything for variables and functions before symtab is built;
it is quite possible that they will be declared weak later. */
if (DECL_P (base) && decl_in_symtab_p (base))
{
struct symtab_node *symbol;
symbol = symtab_get_node (base);
if (symbol)
return symbol->nonzero_address ();
else
return false;
}
/* Function local objects are never NULL. */
if (DECL_P (base)
&& (flag_delete_null_pointer_checks
|| (DECL_CONTEXT (base)
&& TREE_CODE (DECL_CONTEXT (base)) == FUNCTION_DECL
&& auto_var_in_fn_p (base, DECL_CONTEXT (base)))))
return !VAR_OR_FUNCTION_DECL_P (base) || !DECL_WEAK (base);
&& (DECL_CONTEXT (base)
&& TREE_CODE (DECL_CONTEXT (base)) == FUNCTION_DECL
&& auto_var_in_fn_p (base, DECL_CONTEXT (base))))
return true;
/* Constants are never weak. */
if (CONSTANT_CLASS_P (base))
......
......@@ -1890,4 +1890,67 @@ symtab_get_symbol_partitioning_class (symtab_node *node)
return SYMBOL_PARTITION;
}
/* Return true when symbol is known to be non-zero. */
bool
symtab_node::nonzero_address ()
{
/* Weakrefs may be NULL when their target is not defined. */
if (this->alias && this->weakref)
{
if (this->analyzed)
{
symtab_node *target = symtab_alias_ultimate_target (this);
if (target->alias && target->weakref)
return false;
/* We can not recurse to target::nonzero. It is possible that the
target is used only via the alias.
We may walk references and look for strong use, but we do not know
if this strong use will survive to final binary, so be
conservative here.
??? Maybe we could do the lookup during late optimization that
could be useful to eliminate the NULL pointer checks in LTO
programs. */
if (target->definition && !DECL_EXTERNAL (target->decl))
return true;
if (target->resolution != LDPR_UNKNOWN
&& target->resolution != LDPR_UNDEF
&& flag_delete_null_pointer_checks)
return true;
return false;
}
else
return false;
}
/* With !flag_delete_null_pointer_checks we assume that symbols may
bind to NULL. This is on by default on embedded targets only.
Otherwise all non-WEAK symbols must be defined and thus non-NULL or
linking fails. Important case of WEAK we want to do well are comdats.
Those are handled by later check for definition.
When parsing, beware the cases when WEAK attribute is added later. */
if (!DECL_WEAK (this->decl)
&& flag_delete_null_pointer_checks
&& cgraph_state > CGRAPH_STATE_PARSING)
return true;
/* If target is defined and not extern, we know it will be output and thus
it will bind to non-NULL.
Play safe for flag_delete_null_pointer_checks where weak definition maye
be re-defined by NULL. */
if (this->definition && !DECL_EXTERNAL (this->decl)
&& (flag_delete_null_pointer_checks || !DECL_WEAK (this->decl)))
return true;
/* As the last resort, check the resolution info. */
if (this->resolution != LDPR_UNKNOWN
&& this->resolution != LDPR_UNDEF
&& flag_delete_null_pointer_checks)
return true;
return false;
}
#include "gt-symtab.h"
2014-07-13 Jan Hubicka <hubicka@ucw.cz>
* gcc.dg/pr36901.h: Simplify because non-zero symbol folding no
longer happens during parsing.
* gcc.dg/pr44024.c: Update template.
* g++.dg/tree-ssa/nonzero-2.C: New testcase.
* g++.dg/tree-ssa/nonzero-1.C: New testcase.
* gcc.dg/tree-ssa/nonzero-1.c: New testcase.
2014-07-13 Tom de Vries <tom@codesourcery.com>
* gcc.target/i386/fuse-caller-save-xmm-run.c: New test.
......
/* { dg-do compile } */
/* { dg-options "-O2 -fdump-tree-ccp1" } */
inline void t()
{
}
int m()
{
void *q = (void *)&t;
return q != 0;
}
/* { dg-final { scan-tree-dump "return 1" "ccp1"} } */
/* { dg-final { cleanup-tree-dump "ccp1" } } */
/* { dg-do compile } */
/* { dg-options "-O2 -fdump-tree-ccp1 -fdelete-null-pointer-checks" } */
struct t
{
static inline void tt()
{
}
virtual void q();
};
int m()
{
void *q = (void *)&t::tt;
return q != 0;
}
/* { dg-final { scan-tree-dump "return 1" "ccp1"} } */
/* { dg-final { cleanup-tree-dump "ccp1" } } */
#if defined(AVR) /* flag_delete_null_pointer_checks = 0 */
int sc = (&sc >= 0);
#else
int sc = (&sc > 0);
#endif
/* { dg-do link } */
/* { dg-options "-fdelete-null-pointer-checks -fdump-tree-original" } */
/* { dg-options "-fdelete-null-pointer-checks -fdump-tree-ccp1" } */
void foo();
......@@ -10,5 +10,5 @@ int main()
return 0;
}
/* { dg-final { scan-tree-dump-not "foo" "original" { target { ! avr*-*-* } } } } */
/* { dg-final { cleanup-tree-dump "original" } } */
/* { dg-final { scan-tree-dump-not "foo" "ccp1" { target { ! avr*-*-* } } } } */
/* { dg-final { cleanup-tree-dump "ccp1" } } */
/* { dg-do compile } */
/* { dg-options "-O2 -fdump-tree-optimized" } */
extern int a;
t()
{
return &a!=0;
}
extern int a __attribute__ ((weak));
/* { dg-final { scan-tree-dump-not "return 1" "optimized"} } */
/* { dg-final { cleanup-tree-dump "optimized" } } */
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment