Commit 508e4757 by Jan Hubicka Committed by Jan Hubicka

re PR middle-end/45307 (Stores expanding to no RTL not removed by tree…

re PR middle-end/45307 (Stores expanding to no RTL not removed by tree optimizers, Empty ctors/dtors not eliminated)


	PR c++/45307
	PR c++/17736
	* cgraph.h (cgraph_only_called_directly_p,
	cgraph_can_remove_if_no_direct_calls_and_refs_p): Handle
	static cdtors.
	* cgraphunit.c (cgraph_decide_is_function_needed): Static cdtors
	are not needed.
	(cgraph_finalize_function): Static cdtors are reachable.
	(cgraph_mark_functions_to_output): Use cgraph_only_called_directly_p.

	* gcc.dg/ipa/ctor-empty-1.c: Add testcase.
	* g++.dg/tree-ssa/empty-2.C: Check that constructor got optimized out.

From-SVN: r163439
parent f1395d4a
2010-08-20 Jan Hubicka <jh@suse.cz>
PR c++/45307
PR c++/17736
* cgraph.h (cgraph_only_called_directly_p,
cgraph_can_remove_if_no_direct_calls_and_refs_p): Handle
static cdtors.
* cgraphunit.c (cgraph_decide_is_function_needed): Static cdtors
are not needed.
(cgraph_finalize_function): Static cdtors are reachable.
(cgraph_mark_functions_to_output): Use cgraph_only_called_directly_p.
2010-08-20 Jan Hubicka <jh@suse.cz>
* lto-cgraph.c (lto_output_edge): Use gimple_has_body_p instead of flag_wpa.
* lto-streamer-out.c (lto_output): Likewise.
* passes.c (ipa_write_optimization_summaries): Initialize statement uids.
......
......@@ -2709,6 +2709,33 @@ cgraph_edge_cannot_lead_to_return (struct cgraph_edge *e)
return cgraph_node_cannot_return (e->callee);
}
/* Return true when function NODE can be removed from callgraph
if all direct calls are eliminated. */
bool
cgraph_can_remove_if_no_direct_calls_and_refs_p (struct cgraph_node *node)
{
/* When function is needed, we can not remove it. */
if (node->needed || node->reachable_from_other_partition)
return false;
/* Only COMDAT functions can be removed if externally visible. */
if (node->local.externally_visible
&& (!DECL_COMDAT (node->decl) || node->local.used_from_object_file))
return false;
/* Constructors and destructors are executed by the runtime, however
we can get rid of all pure constructors and destructors. */
if (DECL_STATIC_CONSTRUCTOR (node->decl)
|| DECL_STATIC_DESTRUCTOR (node->decl))
{
int flags = flags_from_decl_or_type (node->decl);
if (!optimize
|| !(flags & (ECF_CONST | ECF_PURE))
|| (flags & ECF_LOOPING_CONST_OR_PURE))
return false;
}
return true;
}
/* Return true when function NODE can be excpected to be removed
from program when direct calls in this compilation unit are removed.
......
......@@ -608,6 +608,10 @@ void cgraph_set_looping_const_or_pure_flag (struct cgraph_node *, bool);
tree clone_function_name (tree decl, const char *);
bool cgraph_node_cannot_return (struct cgraph_node *);
bool cgraph_edge_cannot_lead_to_return (struct cgraph_edge *);
bool cgraph_will_be_removed_from_program_if_no_direct_calls
(struct cgraph_node *node);
bool cgraph_can_remove_if_no_direct_calls_and_refs_p
(struct cgraph_node *node);
/* In cgraphunit.c */
extern FILE *cgraph_dump_file;
......@@ -664,8 +668,6 @@ void cgraph_remove_node_duplication_hook (struct cgraph_2node_hook_list *);
void cgraph_materialize_all_clones (void);
gimple cgraph_redirect_edge_call_stmt_to_callee (struct cgraph_edge *);
bool cgraph_propagate_frequency (struct cgraph_node *node);
bool cgraph_will_be_removed_from_program_if_no_direct_calls
(struct cgraph_node *node);
/* In cgraphbuild.c */
unsigned int rebuild_cgraph_edges (void);
void cgraph_rebuild_references (void);
......@@ -903,17 +905,11 @@ varpool_node_set_nonempty_p (varpool_node_set set)
static inline bool
cgraph_only_called_directly_p (struct cgraph_node *node)
{
return !node->needed && !node->address_taken && !node->local.externally_visible;
}
/* Return true when function NODE can be removed from callgraph
if all direct calls are eliminated. */
static inline bool
cgraph_can_remove_if_no_direct_calls_and_refs_p (struct cgraph_node *node)
{
return (!node->needed && !node->reachable_from_other_partition
&& (DECL_COMDAT (node->decl) || !node->local.externally_visible));
return (!node->needed && !node->address_taken
&& !node->reachable_from_other_partition
&& !DECL_STATIC_CONSTRUCTOR (node->decl)
&& !DECL_STATIC_DESTRUCTOR (node->decl)
&& !node->local.externally_visible);
}
/* Return true when function NODE can be removed from callgraph
......
......@@ -367,11 +367,6 @@ cgraph_decide_is_function_needed (struct cgraph_node *node, tree decl)
&& !DECL_COMDAT (decl) && !DECL_EXTERNAL (decl))
return true;
/* Constructors and destructors are reachable from the runtime by
some mechanism. */
if (DECL_STATIC_CONSTRUCTOR (decl) || DECL_STATIC_DESTRUCTOR (decl))
return true;
return false;
}
......@@ -532,7 +527,9 @@ cgraph_finalize_function (tree decl, bool nested)
/* Since we reclaim unreachable nodes at the end of every language
level unit, we need to be conservative about possible entry points
there. */
if ((TREE_PUBLIC (decl) && !DECL_COMDAT (decl) && !DECL_EXTERNAL (decl)))
if ((TREE_PUBLIC (decl) && !DECL_COMDAT (decl) && !DECL_EXTERNAL (decl))
|| DECL_STATIC_CONSTRUCTOR (decl)
|| DECL_STATIC_DESTRUCTOR (decl))
cgraph_mark_reachable_node (node);
/* If we've not yet emitted decl, tell the debug info about it. */
......@@ -1219,8 +1216,7 @@ cgraph_mark_functions_to_output (void)
outside the current compilation unit. */
if (node->analyzed
&& !node->global.inlined_to
&& (node->needed || node->reachable_from_other_partition
|| node->address_taken
&& (!cgraph_only_called_directly_p (node)
|| (e && node->reachable))
&& !TREE_ASM_WRITTEN (decl)
&& !DECL_EXTERNAL (decl))
......
2010-08-20 Jan Hubicka <jh@suse.cz>
PR c++/45307
PR c++/17736
* gcc.dg/ipa/ctor-empty-1.c: Add testcase.
* g++.dg/tree-ssa/empty-2.C: Check that constructor got optimized out.
2010-08-20 H.J. Lu <hongjiu.lu@intel.com>
PR target/45336
......
// PR c++/45307
// { dg-options -fdump-tree-gimple }
// { dg-options "-fdump-tree-gimple -fdump-tree-optimized" }
struct fallible_t { };
const fallible_t fallible = fallible_t();
// { dg-final { scan-tree-dump-not "fallible" "gimple" } }
// Whole constructor should be optimized away.
// { dg-final { scan-tree-dump-not "int" "optimized" } }
// { dg-final { cleanup-tree-dump "gimple" } }
// { dg-final { cleanup-tree-dump "optimized" } }
/* { dg-do compile } */
/* { dg-options "-O3 -c -fdump-ipa-whole-program" } */
static __attribute__((constructor))
void empty_constructor()
{
}
/* { dg-final { scan-ipa-dump "Reclaiming functions: empty_constructor" "whole-program" } } */
/* { dg-final { cleanup-ipa-dump "whole-program" } } */
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