* cgraph.h (const_value_known_p): Declare.
(varpool_decide_const_value_known): Remove.
* tree-ssa-ccp.c (get_base_constructor): Use it.
* lto-cgraph.c (compute_ltrans_boundary): Likewise.
* expr.c (string_constant): Likewise.
* tree-ssa-loop-ivcanon.c (constant_after_peeling): Likewise.
* ipa.c (ipa_discover_readonly_nonaddressable_var,
function_and_variable_visibility): Likewise.
* gimplify.c (gimplify_call_expr): Likewise.
* gimple-fold.c (get_symbol_constant_value): Likewise.
* varpool.c (varpool_decide_const_value_known): Replace by...
(const_value_known_p): ... this one; handle other kinds of DECLs
too and work for automatic vars.
(varpool_finalize_decl): Use const_value_known_p.
* lto.c (lto_promote_cross_file_statics): Use const_value_known_p.
* g++.dg/tree-ssa/pr45605.C: New testcase.
git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@164438
138bc75d-0d04-0410-961f-
82ee72b054a4
+2010-09-20 Jan Hubicka <jh@suse.cz>
+
+ PR tree-optimize/45605
+ * cgraph.h (const_value_known_p): Declare.
+ (varpool_decide_const_value_known): Remove.
+ * tree-ssa-ccp.c (get_base_constructor): Use it.
+ * lto-cgraph.c (compute_ltrans_boundary): Likewise.
+ * expr.c (string_constant): Likewise.
+ * tree-ssa-loop-ivcanon.c (constant_after_peeling): Likewise.
+ * ipa.c (ipa_discover_readonly_nonaddressable_var,
+ function_and_variable_visibility): Likewise.
+ * gimplify.c (gimplify_call_expr): Likewise.
+ * gimple-fold.c (get_symbol_constant_value): Likewise.
+ * varpool.c (varpool_decide_const_value_known): Replace by...
+ (const_value_known_p): ... this one; handle other kinds of DECLs
+ too and work for automatic vars.
+ (varpool_finalize_decl): Use const_value_known_p.
+
2010-09-20 Rafael Carre <rafael.carre@gmail.com>
PR target/45726
bool varpool_extra_name_alias (tree, tree);
const char * varpool_node_name (struct varpool_node *node);
void varpool_reset_queue (void);
-bool varpool_decide_const_value_known (struct varpool_node *node);
+bool const_value_known_p (tree);
/* Walk all reachable static variables. */
#define FOR_EACH_STATIC_VARIABLE(node) \
int length;
/* Variables initialized to string literals can be handled too. */
- if (DECL_INITIAL (array) == NULL_TREE
+ if (!const_value_known_p (array)
|| TREE_CODE (DECL_INITIAL (array)) != STRING_CST)
return 0;
- /* If they are read-only, non-volatile and bind locally. */
- if (! TREE_READONLY (array)
- || TREE_SIDE_EFFECTS (array)
- || ! targetm.binds_local_p (array))
- return 0;
-
/* Avoid const char foo[4] = "abcde"; */
if (DECL_SIZE_UNIT (array) == NULL_TREE
|| TREE_CODE (DECL_SIZE_UNIT (array)) != INTEGER_CST
tree
get_symbol_constant_value (tree sym)
{
- if ((TREE_STATIC (sym) || DECL_EXTERNAL (sym))
- && (TREE_CODE (sym) == CONST_DECL
- || varpool_get_node (sym)->const_value_known))
+ if (const_value_known_p (sym))
{
tree val = DECL_INITIAL (sym);
if (val)
{
/* The CALL_EXPR in *EXPR_P is already in GIMPLE form, so all we
have to do is replicate it as a GIMPLE_CALL tuple. */
+ gimple_stmt_iterator gsi;
call = gimple_build_call_from_tree (*expr_p);
gimplify_seq_add_stmt (pre_p, call);
+ gsi = gsi_last (*pre_p);
+ fold_stmt (&gsi);
*expr_p = NULL_TREE;
}
if (dump_file)
fprintf (dump_file, " %s (read-only)", varpool_node_name (vnode));
TREE_READONLY (vnode->decl) = 1;
- vnode->const_value_known |= varpool_decide_const_value_known (vnode);
+ vnode->const_value_known |= const_value_known_p (vnode->decl);
}
}
if (dump_file)
DECL_COMMON (vnode->decl) = 0;
/* Even extern variables might have initializers known.
See, for example testsuite/g++.dg/opt/static3.C */
- vnode->const_value_known |= varpool_decide_const_value_known (vnode);
+ vnode->const_value_known |= const_value_known_p (vnode->decl);
}
for (vnode = varpool_nodes_queue; vnode; vnode = vnode->next_needed)
{
gcc_assert (in_lto_p || whole_program || !TREE_PUBLIC (vnode->decl));
cgraph_make_decl_local (vnode->decl);
}
- vnode->const_value_known |= varpool_decide_const_value_known (vnode);
+ vnode->const_value_known |= const_value_known_p (vnode->decl);
gcc_assert (TREE_STATIC (vnode->decl));
}
pointer_set_destroy (aliased_nodes);
if (DECL_INITIAL (vnode->decl)
&& !lto_varpool_encoder_encode_initializer_p (varpool_encoder,
vnode)
- && (DECL_IN_CONSTANT_POOL (vnode->decl)
- || vnode->const_value_known))
+ && const_value_known_p (vnode->decl))
{
lto_set_varpool_encoder_encode_initializer (varpool_encoder, vnode);
add_references (encoder, varpool_encoder, &vnode->ref_list);
+2010-09-20 Jan Hubicka <jh@suse.cz>
+
+ PR tree-optimize/45605
+ * lto.c (lto_promote_cross_file_statics): Use const_value_known_p.
+
2010-09-18 Gerald Pfeifer <gerald@pfeifer.com>
* lto-elf.c (lto_obj_file_open): Also provide filename when
from this partition that are not in this partition.
This needs to be done recursively. */
for (vnode = varpool_nodes; vnode; vnode = vnode->next)
- if ((vnode->const_value_known || DECL_IN_CONSTANT_POOL (vnode->decl))
+ if (const_value_known_p (vnode->decl)
&& DECL_INITIAL (vnode->decl)
&& !varpool_node_in_set_p (vnode, vset)
&& referenced_from_this_partition_p (&vnode->ref_list, set, vset)
+2010-09-20 Jan Hubicka <jh@suse.cz>
+
+ PR tree-optimize/45605
+ * g++.dg/tree-ssa/pr45605.C: New testcase.
+
2010-09-20 Michael Matz <matz@suse.de>
PR testsuite/45706
--- /dev/null
+/* { dg-do compile } */
+/* { dg-options "-O1 -fdump-tree-ssa" } */
+extern "C" void abort();
+bool destructor_called = false;
+
+struct B {
+ virtual void Run(){};
+};
+
+struct D : public B {
+ virtual void Run()
+ {
+ struct O {
+ ~O() { destructor_called = true; };
+ } o;
+
+ struct Raiser {
+ Raiser() throw( int ) {throw 1;};
+ } raiser;
+ };
+};
+
+int main() {
+ try {
+ D d;
+ static_cast<B&>(d).Run();
+ } catch (...) {}
+
+ if (!destructor_called)
+ abort ();
+}
+
+
+
+/* We should devirtualize call to D::Run */
+/* { dg-final { scan-tree-dump-times "D::Run (" 1 "ssa"} } */
+/* { dg-final { cleanup-tree-dump "ssa" } } */
switch (TREE_CODE (base))
{
case VAR_DECL:
- if (!TREE_READONLY (base)
- || ((TREE_STATIC (base) || DECL_EXTERNAL (base))
- && !varpool_get_node (base)->const_value_known))
+ if (!const_value_known_p (base))
return NULL_TREE;
/* Fallthru. */
/* First make fast look if we see constant array inside. */
while (handled_component_p (base))
base = TREE_OPERAND (base, 0);
- if ((DECL_P (base)
- && TREE_STATIC (base)
- && TREE_READONLY (base)
- && varpool_get_node (base)->const_value_known)
+ if ((DECL_P (base) == VAR_DECL
+ && const_value_known_p (base))
|| CONSTANT_CLASS_P (base))
{
/* If so, see if we understand all the indices. */
return true;
}
-/* Return if NODE is constant and its initial value is known (so we can do
- constant folding). The decision depends on whole program decisions
- and can not be recomputed at ltrans stage for variables from other
- partitions. For this reason the new value should be always combined
- with the previous knowledge. */
+/* Return if DECL is constant and its initial value is known (so we can do
+ constant folding using DECL_INITIAL (decl)). */
bool
-varpool_decide_const_value_known (struct varpool_node *node)
+const_value_known_p (tree decl)
{
- tree decl = node->decl;
+ struct varpool_node *vnode;
+
+ if (TREE_CODE (decl) == PARM_DECL
+ || TREE_CODE (decl) == RESULT_DECL)
+ return false;
+
+ if (TREE_CODE (decl) == CONST_DECL
+ || DECL_IN_CONSTANT_POOL (decl))
+ return true;
- gcc_assert (TREE_STATIC (decl) || DECL_EXTERNAL (decl));
gcc_assert (TREE_CODE (decl) == VAR_DECL);
+
if (!TREE_READONLY (decl))
return false;
+
+ /* Gimplifier takes away constructors of local vars */
+ if (!TREE_STATIC (decl) && !DECL_EXTERNAL (decl))
+ return DECL_INITIAL (decl) != NULL;
+
+ gcc_assert (TREE_STATIC (decl) || DECL_EXTERNAL (decl));
+
+ /* In WHOPR mode we can put variable into one partition
+ and make it external in the other partition. In this
+ case we still know the value, but it can't be determined
+ from DECL flags. For this reason we keep const_value_known
+ flag in varpool nodes. */
+ if ((vnode = varpool_get_node (decl))
+ && vnode->const_value_known)
+ return true;
+
/* Variables declared 'const' without an initializer
have zero as the initializer if they may not be
overridden at link or run time. */
there. */
else if (TREE_PUBLIC (decl) && !DECL_COMDAT (decl) && !DECL_EXTERNAL (decl))
varpool_mark_needed_node (node);
- node->const_value_known |= varpool_decide_const_value_known (node);
+ node->const_value_known |= const_value_known_p (node->decl);
if (cgraph_global_info_ready)
varpool_assemble_pending_decls ();
}