summaryrefslogtreecommitdiffstats
path: root/gcc/ipa-pure-const.c
diff options
context:
space:
mode:
authorzadeck <zadeck@138bc75d-0d04-0410-961f-82ee72b054a4>2008-05-07 20:48:07 +0000
committerzadeck <zadeck@138bc75d-0d04-0410-961f-82ee72b054a4>2008-05-07 20:48:07 +0000
commit9c2a0c05b3929cb733f49c3e4f125a961bf9b07a (patch)
treeb1aaf0884496e7223907dc2c04ecd0cf5ded732f /gcc/ipa-pure-const.c
parent582b1949ea35078bbe368033b69067fdb9d5f4f5 (diff)
downloadppe42-gcc-9c2a0c05b3929cb733f49c3e4f125a961bf9b07a.tar.gz
ppe42-gcc-9c2a0c05b3929cb733f49c3e4f125a961bf9b07a.zip
2008-05-07 Kenneth Zadeck <zadeck@naturalbridge.com>
PATCH rtl/7335 PATCH rtl/33826 * see.c (see_copy_insn): Copy new pure const attributes for new call. * c-decl.c (merge_decls): Ditto. * postreload.c (record_opr_changes): Change CONST_OR_PURE_CALL_P to RTL_CONST_OR_PURE_CALL_P. * tree.c (define_local_buitin): Rename DECL_IS_PURE to DECL_PURE_P. Initialized DECL_LOOPING_CONST_PURE. (process_call_operands): Set tree_side_effects properly. * tree.h (TREE_READONLY_DECL_P): Removed. (DECL_IS_PURE): Renamed to DECL_PURE_P. (DECL_LOOPING_OR_CONST_P): New macro. (struct tree_function_decl): Added looping_const_or_pure_p. (ECF_*) Renumbered. (ECF_LOOPING_OR_CONST_P): New macro, * rtlanal.c (pure_const_p): Removed. * builtins.c (expand_builtin): Rename DECL_IS_PURE to DECL_PURE_P. * reorg.c (delete_prior_computation) Changed CONST_OR_PURE_CALL_P to RTL_CONST_CALL_P. * ipa-pure-const.c (pure_const_state_e): Added looping field. (check_decl, check_tree, check_call, scan_function): Initialize looping. (analyze_function): Rename DECL_IS_PURE to DECL_PURE_P. (static_execute): Set looping true for recursive functions. Undo setting state to IPA_NEITHER for recursive functions. * cse.c (cse_insn): * ifcvt.c (noce_can_store_speculate_p): Changed CONST_OR_PURE_CALL_P and pure_call_p to RTL_CONST_CALL_P or RTL_CONST_OR_PURE_CALL_P. * dse.c (scan_insn): Ditto. * local-alloc.c (validate_equiv_mem, memref_used_between_p): Ditto. * gcse.c (oprs_not_seen_p) Changed CONST_OR_PURE_CALL_P to RTL_CONST_OR_PURE_CALL_P. (store_killed_in_insn): Changed CONST_OR_PURE_CALL_P and pure_call_p to RTL_CONST_CALL_P. * gimplify.c (gimplify_call_expr): Clear side effects for non-looping pure and constant calls. * calls.c (emit_call_1): Set rtl flags from ecf flags. (flags_from_decl_or_type): Set ecf flags from decl flags. (initialize_argument_information): Turn off ECF_LOOPING_CONST_OR_PURE when turning off ECF_CONST. Change const to pure if callee_copies is true rather than just turning off const. (expand_call): Turn off ECF_LOOPING_PURE_CONST_CALL and remove old way of marking pure calls. (emit_library_call_value_1): Turn off ECF_LOOPING_PURE_CONST_CALL. Remove hack that was supposed to fix pr7335 and remove old way of marking pure calls. * emit-rtl.c (emit_copy_of_insn_after): Copy RTL_CONST_CALL_P, RTL_PURE_CALL_P, RTL_LOOPING_CONST_OR_PURE_CALL_P. * cselib.c (cselib_process_insn): Changed CONST_OR_PURE_CALL_P to RTL_CONST_OR_PURE_CALL_P. * tree-ssa-pre.c (can_value_number_call): Fixed spacing. * loop-invariant.c (find_exits, find_invariant_bb): Changed CONST_OR_PURE_CALL_P to RTL_CONST_OR_PURE_CALL_P. * sched-deps.c (schedule_analyze): Ditto. * rtl.h (struct rtx_def): Use call field, unchanging field, and return_val field of calls to represent pure and const function info. (CONST_OR_PURE_CALL_P): Deleted macro. (RTL_CONST_CALL_P, RTL_PURE_CALL_P, RTL_LOOPING_CONST_OR_PURE_CALL_P, RTL_CONST_OR_PURE_P): New macros. * tree-inline.c (copy_body_r): Changed TREE_READONLY_DECL_P to TREE_READONLY. * tree-optimize.c (execute_fixup_cfg): Added test for ECF_LOOPING_CONST_OR_PURE. * c-common.c (handle_pure_attribute): Changed DECL_IS_PURE to DECL_PURE_P. * tree-cfg.c (update_call_expr_flags): Do not clear tree side effects for looping pure or const calls. (verify_gimple_expr): Added verification code. * config/alpha/alpha.c (alpha_legitimize_address, alpha_emit_xfloating_libcall): Changed CONST_OR_PURE_CALL_P to RTL_CONST_CALL_P. * config/s390/s390.c (s390_emit_tls_call_insn): Ditto. * config/rs6000/rs6000.c (rs6000_legitimize_tls_address): Ditto. * config/mips/mips.c (mips_call_tls_get_addr): Ditto. * cfgrtl.c (need_fake_edge_p): Changed CONST_OR_PURE_CALL_P to RTL_CONST_OR_PURE_CALL_P. * dce.c (deletable_insn_p): Allow non looping, non sibling, pure and const calls to be deleted. java: 2008-05-07 Kenneth Zadeck <zadeck@naturalbridge.com> * decl.c (java_init_decl_processing): Change DECL_IS_PURE to DECL_PURE_P. cp: 2008-05-07 Kenneth Zadeck <zadeck@naturalbridge.com> * decl.c (duplicate_decls): Merge in DECL_PURE_P, TREE_READONLY, DECL_LOOPING_CONST_OR_PURE_P attributes. * rtti.c (build_dynamic_cast_1): Rename DECL_IS_PURE to DECL_PURE_P. gfortran: 2008-05-07 Kenneth Zadeck <zadeck@naturalbridge.com> * trans-decl.c (gfc_get_extern_function_decl, build_function_decl): Rename DECL_IS_PURE to DECL_PURE_P. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@135053 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'gcc/ipa-pure-const.c')
-rw-r--r--gcc/ipa-pure-const.c67
1 files changed, 37 insertions, 30 deletions
diff --git a/gcc/ipa-pure-const.c b/gcc/ipa-pure-const.c
index c180e35d6c1..a2c920601ac 100644
--- a/gcc/ipa-pure-const.c
+++ b/gcc/ipa-pure-const.c
@@ -19,7 +19,8 @@ along with GCC; see the file COPYING3. If not see
<http://www.gnu.org/licenses/>. */
/* This file mark functions as being either const (TREE_READONLY) or
- pure (DECL_IS_PURE).
+ pure (DECL_PURE_P). It can also set the a variant of these that
+ are allowed to infinite loop (DECL_LOOPING_CONST_PURE_P).
This must be run after inlining decisions have been made since
otherwise, the local sets will not contain information that is
@@ -69,6 +70,7 @@ enum pure_const_state_e
struct funct_state_d
{
enum pure_const_state_e pure_const_state;
+ bool looping;
bool state_set_in_source;
};
@@ -95,6 +97,7 @@ check_decl (funct_state local,
if (lookup_attribute ("used", DECL_ATTRIBUTES (t)))
{
local->pure_const_state = IPA_NEITHER;
+ local->looping = false;
return;
}
@@ -103,6 +106,7 @@ check_decl (funct_state local,
if (TREE_THIS_VOLATILE (t))
{
local->pure_const_state = IPA_NEITHER;
+ local->looping = false;
return;
}
@@ -116,6 +120,7 @@ check_decl (funct_state local,
if (checking_write)
{
local->pure_const_state = IPA_NEITHER;
+ local->looping = false;
return;
}
@@ -174,6 +179,7 @@ check_tree (funct_state local, tree t, bool checking_write)
if (TREE_THIS_VOLATILE (t))
{
local->pure_const_state = IPA_NEITHER;
+ local->looping = false;
return;
}
@@ -199,6 +205,7 @@ check_tree (funct_state local, tree t, bool checking_write)
if (checking_write)
{
local->pure_const_state = IPA_NEITHER;
+ local->looping = false;
return;
}
else if (local->pure_const_state == IPA_CONST)
@@ -346,7 +353,10 @@ check_call (funct_state local, tree call_expr)
/* When bad things happen to bad functions, they cannot be const
or pure. */
if (setjmp_call_p (callee_t))
- local->pure_const_state = IPA_NEITHER;
+ {
+ local->pure_const_state = IPA_NEITHER;
+ local->looping = false;
+ }
if (DECL_BUILT_IN_CLASS (callee_t) == BUILT_IN_NORMAL)
switch (DECL_FUNCTION_CODE (callee_t))
@@ -354,6 +364,7 @@ check_call (funct_state local, tree call_expr)
case BUILT_IN_LONGJMP:
case BUILT_IN_NONLOCAL_GOTO:
local->pure_const_state = IPA_NEITHER;
+ local->looping = false;
break;
default:
break;
@@ -480,7 +491,10 @@ scan_function (tree *tp,
case LABEL_EXPR:
if (DECL_NONLOCAL (TREE_OPERAND (t, 0)))
/* Target of long jump. */
- local->pure_const_state = IPA_NEITHER;
+ {
+ local->pure_const_state = IPA_NEITHER;
+ local->looping = false;
+ }
break;
case CALL_EXPR:
@@ -513,6 +527,10 @@ analyze_function (struct cgraph_node *fn)
l->pure_const_state = IPA_CONST;
l->state_set_in_source = false;
+ if (DECL_LOOPING_CONST_OR_PURE_P (decl))
+ l->looping = true;
+ else
+ l->looping = false;
/* If this function does not return normally or does not bind local,
do not touch this unless it has been marked as const or pure by the
@@ -529,7 +547,7 @@ analyze_function (struct cgraph_node *fn)
l->pure_const_state = IPA_CONST;
l->state_set_in_source = true;
}
- if (DECL_IS_PURE (decl))
+ if (DECL_PURE_P (decl))
{
l->pure_const_state = IPA_PURE;
l->state_set_in_source = true;
@@ -644,6 +662,7 @@ static_execute (void)
for (i = 0; i < order_pos; i++ )
{
enum pure_const_state_e pure_const_state = IPA_CONST;
+ bool looping = false;
int count = 0;
node = order[i];
@@ -655,6 +674,9 @@ static_execute (void)
if (pure_const_state < w_l->pure_const_state)
pure_const_state = w_l->pure_const_state;
+ if (w_l->looping)
+ looping = true;
+
if (pure_const_state == IPA_NEITHER)
break;
@@ -663,24 +685,8 @@ static_execute (void)
struct cgraph_edge *e;
count++;
- /* FIXME!!! Because of pr33826, we cannot have either
- immediate or transitive recursive functions marked as
- pure or const because dce can delete a function that
- is in reality an infinite loop. A better solution
- than just outlawing them is to add another bit the
- functions to distinguish recursive from non recursive
- pure and const function. This would allow the
- recursive ones to be cse'd but not dce'd. In this
- same vein, we could allow functions with loops to
- also be cse'd but not dce'd.
-
- Unfortunately we are late in stage 3, and the fix
- described above is is not appropriate. */
if (count > 1)
- {
- pure_const_state = IPA_NEITHER;
- break;
- }
+ looping = true;
for (e = w->callees; e; e = e->next_callee)
{
@@ -688,13 +694,8 @@ static_execute (void)
/* Only look at the master nodes and skip external nodes. */
y = cgraph_master_clone (y);
- /* Check for immediate recursive functions. See the
- FIXME above. */
if (w == y)
- {
- pure_const_state = IPA_NEITHER;
- break;
- }
+ looping = true;
if (y)
{
funct_state y_l = get_function_state (y);
@@ -702,6 +703,8 @@ static_execute (void)
pure_const_state = y_l->pure_const_state;
if (pure_const_state == IPA_NEITHER)
break;
+ if (y_l->looping)
+ looping = true;
}
}
}
@@ -724,15 +727,19 @@ static_execute (void)
{
case IPA_CONST:
TREE_READONLY (w->decl) = 1;
+ DECL_LOOPING_CONST_OR_PURE_P (w->decl) = looping;
if (dump_file)
- fprintf (dump_file, "Function found to be const: %s\n",
+ fprintf (dump_file, "Function found to be %sconst: %s\n",
+ looping ? "looping " : "",
lang_hooks.decl_printable_name(w->decl, 2));
break;
case IPA_PURE:
- DECL_IS_PURE (w->decl) = 1;
+ DECL_PURE_P (w->decl) = 1;
+ DECL_LOOPING_CONST_OR_PURE_P (w->decl) = looping;
if (dump_file)
- fprintf (dump_file, "Function found to be pure: %s\n",
+ fprintf (dump_file, "Function found to be %spure: %s\n",
+ looping ? "looping " : "",
lang_hooks.decl_printable_name(w->decl, 2));
break;
OpenPOWER on IntegriCloud