[multiple changes]
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. From-SVN: r135053
This commit is contained in:
parent
d320458418
commit
becfd6e57b
|
@ -1,3 +1,89 @@
|
||||||
|
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.
|
||||||
|
|
||||||
|
|
||||||
2008-05-08 Uros Bizjak <ubizjak@gmail.com>
|
2008-05-08 Uros Bizjak <ubizjak@gmail.com>
|
||||||
|
|
||||||
PR target/35714
|
PR target/35714
|
||||||
|
|
|
@ -6098,7 +6098,7 @@ expand_builtin (tree exp, rtx target, rtx subtarget, enum machine_mode mode,
|
||||||
none of its arguments are volatile, we can avoid expanding the
|
none of its arguments are volatile, we can avoid expanding the
|
||||||
built-in call and just evaluate the arguments for side-effects. */
|
built-in call and just evaluate the arguments for side-effects. */
|
||||||
if (target == const0_rtx
|
if (target == const0_rtx
|
||||||
&& (DECL_IS_PURE (fndecl) || TREE_READONLY (fndecl)))
|
&& (DECL_PURE_P (fndecl) || TREE_READONLY (fndecl)))
|
||||||
{
|
{
|
||||||
bool volatilep = false;
|
bool volatilep = false;
|
||||||
tree arg;
|
tree arg;
|
||||||
|
|
|
@ -6019,7 +6019,7 @@ handle_pure_attribute (tree *node, tree name, tree ARG_UNUSED (args),
|
||||||
int ARG_UNUSED (flags), bool *no_add_attrs)
|
int ARG_UNUSED (flags), bool *no_add_attrs)
|
||||||
{
|
{
|
||||||
if (TREE_CODE (*node) == FUNCTION_DECL)
|
if (TREE_CODE (*node) == FUNCTION_DECL)
|
||||||
DECL_IS_PURE (*node) = 1;
|
DECL_PURE_P (*node) = 1;
|
||||||
/* ??? TODO: Support types. */
|
/* ??? TODO: Support types. */
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
|
|
@ -1729,10 +1729,10 @@ merge_decls (tree newdecl, tree olddecl, tree newtype, tree oldtype)
|
||||||
DECL_NO_INSTRUMENT_FUNCTION_ENTRY_EXIT (newdecl)
|
DECL_NO_INSTRUMENT_FUNCTION_ENTRY_EXIT (newdecl)
|
||||||
|= DECL_NO_INSTRUMENT_FUNCTION_ENTRY_EXIT (olddecl);
|
|= DECL_NO_INSTRUMENT_FUNCTION_ENTRY_EXIT (olddecl);
|
||||||
TREE_THIS_VOLATILE (newdecl) |= TREE_THIS_VOLATILE (olddecl);
|
TREE_THIS_VOLATILE (newdecl) |= TREE_THIS_VOLATILE (olddecl);
|
||||||
TREE_READONLY (newdecl) |= TREE_READONLY (olddecl);
|
|
||||||
DECL_IS_MALLOC (newdecl) |= DECL_IS_MALLOC (olddecl);
|
DECL_IS_MALLOC (newdecl) |= DECL_IS_MALLOC (olddecl);
|
||||||
DECL_IS_OPERATOR_NEW (newdecl) |= DECL_IS_OPERATOR_NEW (olddecl);
|
DECL_IS_OPERATOR_NEW (newdecl) |= DECL_IS_OPERATOR_NEW (olddecl);
|
||||||
DECL_IS_PURE (newdecl) |= DECL_IS_PURE (olddecl);
|
TREE_READONLY (newdecl) |= TREE_READONLY (olddecl);
|
||||||
|
DECL_PURE_P (newdecl) |= DECL_PURE_P (olddecl);
|
||||||
DECL_IS_NOVOPS (newdecl) |= DECL_IS_NOVOPS (olddecl);
|
DECL_IS_NOVOPS (newdecl) |= DECL_IS_NOVOPS (olddecl);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
87
gcc/calls.c
87
gcc/calls.c
|
@ -359,21 +359,20 @@ emit_call_1 (rtx funexp, tree fntree, tree fndecl ATTRIBUTE_UNUSED,
|
||||||
/* Find the call we just emitted. */
|
/* Find the call we just emitted. */
|
||||||
call_insn = last_call_insn ();
|
call_insn = last_call_insn ();
|
||||||
|
|
||||||
/* Mark memory as used for "pure" function call. */
|
|
||||||
if (ecf_flags & ECF_PURE)
|
|
||||||
call_fusage
|
|
||||||
= gen_rtx_EXPR_LIST
|
|
||||||
(VOIDmode,
|
|
||||||
gen_rtx_USE (VOIDmode,
|
|
||||||
gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (VOIDmode))),
|
|
||||||
call_fusage);
|
|
||||||
|
|
||||||
/* Put the register usage information there. */
|
/* Put the register usage information there. */
|
||||||
add_function_usage_to (call_insn, call_fusage);
|
add_function_usage_to (call_insn, call_fusage);
|
||||||
|
|
||||||
/* If this is a const call, then set the insn's unchanging bit. */
|
/* If this is a const call, then set the insn's unchanging bit. */
|
||||||
if (ecf_flags & (ECF_CONST | ECF_PURE))
|
if (ecf_flags & ECF_CONST)
|
||||||
CONST_OR_PURE_CALL_P (call_insn) = 1;
|
RTL_CONST_CALL_P (call_insn) = 1;
|
||||||
|
|
||||||
|
/* If this is a pure call, then set the insn's unchanging bit. */
|
||||||
|
if (ecf_flags & ECF_PURE)
|
||||||
|
RTL_PURE_CALL_P (call_insn) = 1;
|
||||||
|
|
||||||
|
/* If this is a const call, then set the insn's unchanging bit. */
|
||||||
|
if (ecf_flags & ECF_LOOPING_CONST_OR_PURE)
|
||||||
|
RTL_LOOPING_CONST_OR_PURE_CALL_P (call_insn) = 1;
|
||||||
|
|
||||||
/* If this call can't throw, attach a REG_EH_REGION reg note to that
|
/* If this call can't throw, attach a REG_EH_REGION reg note to that
|
||||||
effect. */
|
effect. */
|
||||||
|
@ -580,9 +579,13 @@ flags_from_decl_or_type (const_tree exp)
|
||||||
if (DECL_IS_RETURNS_TWICE (exp))
|
if (DECL_IS_RETURNS_TWICE (exp))
|
||||||
flags |= ECF_RETURNS_TWICE;
|
flags |= ECF_RETURNS_TWICE;
|
||||||
|
|
||||||
/* The function exp may have the `pure' attribute. */
|
/* Process the pure and const attributes. */
|
||||||
if (DECL_IS_PURE (exp))
|
if (TREE_READONLY (exp) && ! TREE_THIS_VOLATILE (exp))
|
||||||
|
flags |= ECF_CONST;
|
||||||
|
if (DECL_PURE_P (exp))
|
||||||
flags |= ECF_PURE;
|
flags |= ECF_PURE;
|
||||||
|
if (DECL_LOOPING_CONST_OR_PURE_P (exp))
|
||||||
|
flags |= ECF_LOOPING_CONST_OR_PURE;
|
||||||
|
|
||||||
if (DECL_IS_NOVOPS (exp))
|
if (DECL_IS_NOVOPS (exp))
|
||||||
flags |= ECF_NOVOPS;
|
flags |= ECF_NOVOPS;
|
||||||
|
@ -590,9 +593,6 @@ flags_from_decl_or_type (const_tree exp)
|
||||||
if (TREE_NOTHROW (exp))
|
if (TREE_NOTHROW (exp))
|
||||||
flags |= ECF_NOTHROW;
|
flags |= ECF_NOTHROW;
|
||||||
|
|
||||||
if (TREE_READONLY (exp) && ! TREE_THIS_VOLATILE (exp))
|
|
||||||
flags |= ECF_CONST;
|
|
||||||
|
|
||||||
flags = special_function_p (exp, flags);
|
flags = special_function_p (exp, flags);
|
||||||
}
|
}
|
||||||
else if (TYPE_P (exp) && TYPE_READONLY (exp) && ! TREE_THIS_VOLATILE (exp))
|
else if (TYPE_P (exp) && TYPE_READONLY (exp) && ! TREE_THIS_VOLATILE (exp))
|
||||||
|
@ -1038,7 +1038,9 @@ initialize_argument_information (int num_actuals ATTRIBUTE_UNUSED,
|
||||||
args[i].tree_value = build_fold_addr_expr (args[i].tree_value);
|
args[i].tree_value = build_fold_addr_expr (args[i].tree_value);
|
||||||
type = TREE_TYPE (args[i].tree_value);
|
type = TREE_TYPE (args[i].tree_value);
|
||||||
|
|
||||||
*ecf_flags &= ~(ECF_CONST | ECF_LIBCALL_BLOCK);
|
if (*ecf_flags & ECF_CONST)
|
||||||
|
*ecf_flags &= ~(ECF_CONST | ECF_LOOPING_CONST_OR_PURE);
|
||||||
|
*ecf_flags &= ~ECF_LIBCALL_BLOCK;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -1073,10 +1075,19 @@ initialize_argument_information (int num_actuals ATTRIBUTE_UNUSED,
|
||||||
|
|
||||||
store_expr (args[i].tree_value, copy, 0, false);
|
store_expr (args[i].tree_value, copy, 0, false);
|
||||||
|
|
||||||
if (callee_copies)
|
*ecf_flags &= ~(ECF_LIBCALL_BLOCK);
|
||||||
*ecf_flags &= ~(ECF_CONST | ECF_LIBCALL_BLOCK);
|
|
||||||
else
|
/* Just change the const function to pure and then let
|
||||||
*ecf_flags &= ~(ECF_CONST | ECF_PURE | ECF_LIBCALL_BLOCK);
|
the next test clear the pure based on
|
||||||
|
callee_copies. */
|
||||||
|
if (*ecf_flags & ECF_CONST)
|
||||||
|
{
|
||||||
|
*ecf_flags &= ~ECF_CONST;
|
||||||
|
*ecf_flags |= ECF_PURE;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!callee_copies && *ecf_flags & ECF_PURE)
|
||||||
|
*ecf_flags &= ~(ECF_PURE | ECF_LOOPING_CONST_OR_PURE);
|
||||||
|
|
||||||
args[i].tree_value
|
args[i].tree_value
|
||||||
= build_fold_addr_expr (make_tree (type, copy));
|
= build_fold_addr_expr (make_tree (type, copy));
|
||||||
|
@ -2022,10 +2033,12 @@ expand_call (tree exp, rtx target, int ignore)
|
||||||
if (AGGREGATE_TYPE_P (TREE_TYPE (exp)))
|
if (AGGREGATE_TYPE_P (TREE_TYPE (exp)))
|
||||||
warning (OPT_Waggregate_return, "function call has aggregate value");
|
warning (OPT_Waggregate_return, "function call has aggregate value");
|
||||||
|
|
||||||
/* If the result of a pure or const function call is ignored (or void),
|
/* If the result of a non looping pure or const function call is
|
||||||
and none of its arguments are volatile, we can avoid expanding the
|
ignored (or void), and none of its arguments are volatile, we can
|
||||||
call and just evaluate the arguments for side-effects. */
|
avoid expanding the call and just evaluate the arguments for
|
||||||
|
side-effects. */
|
||||||
if ((flags & (ECF_CONST | ECF_PURE))
|
if ((flags & (ECF_CONST | ECF_PURE))
|
||||||
|
&& (!(flags & ECF_LOOPING_CONST_OR_PURE))
|
||||||
&& (ignore || target == const0_rtx
|
&& (ignore || target == const0_rtx
|
||||||
|| TYPE_MODE (TREE_TYPE (exp)) == VOIDmode))
|
|| TYPE_MODE (TREE_TYPE (exp)) == VOIDmode))
|
||||||
{
|
{
|
||||||
|
@ -2061,7 +2074,8 @@ expand_call (tree exp, rtx target, int ignore)
|
||||||
if (aggregate_value_p (exp, fndecl))
|
if (aggregate_value_p (exp, fndecl))
|
||||||
{
|
{
|
||||||
/* This call returns a big structure. */
|
/* This call returns a big structure. */
|
||||||
flags &= ~(ECF_CONST | ECF_PURE | ECF_LIBCALL_BLOCK);
|
flags &= ~(ECF_CONST | ECF_PURE | ECF_LOOPING_CONST_OR_PURE
|
||||||
|
| ECF_LIBCALL_BLOCK);
|
||||||
|
|
||||||
#ifdef PCC_STATIC_STRUCT_RETURN
|
#ifdef PCC_STATIC_STRUCT_RETURN
|
||||||
{
|
{
|
||||||
|
@ -2852,13 +2866,6 @@ expand_call (tree exp, rtx target, int ignore)
|
||||||
note = gen_rtx_EXPR_LIST (VOIDmode,
|
note = gen_rtx_EXPR_LIST (VOIDmode,
|
||||||
args[i].initial_value, note);
|
args[i].initial_value, note);
|
||||||
note = gen_rtx_EXPR_LIST (VOIDmode, funexp, note);
|
note = gen_rtx_EXPR_LIST (VOIDmode, funexp, note);
|
||||||
|
|
||||||
if (flags & ECF_PURE)
|
|
||||||
note = gen_rtx_EXPR_LIST (VOIDmode,
|
|
||||||
gen_rtx_USE (VOIDmode,
|
|
||||||
gen_rtx_MEM (BLKmode,
|
|
||||||
gen_rtx_SCRATCH (VOIDmode))),
|
|
||||||
note);
|
|
||||||
}
|
}
|
||||||
emit_libcall_block (insns, temp, valreg, note);
|
emit_libcall_block (insns, temp, valreg, note);
|
||||||
|
|
||||||
|
@ -3369,7 +3376,8 @@ emit_library_call_value_1 (int retval, rtx orgfun, rtx value,
|
||||||
mem_value = assign_temp (tfom, 0, 1, 1);
|
mem_value = assign_temp (tfom, 0, 1, 1);
|
||||||
#endif
|
#endif
|
||||||
/* This call returns a big structure. */
|
/* This call returns a big structure. */
|
||||||
flags &= ~(ECF_CONST | ECF_PURE | ECF_LIBCALL_BLOCK);
|
flags &= ~(ECF_CONST | ECF_PURE | ECF_LOOPING_CONST_OR_PURE
|
||||||
|
| ECF_LIBCALL_BLOCK);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
@ -3472,10 +3480,9 @@ emit_library_call_value_1 (int retval, rtx orgfun, rtx value,
|
||||||
end_sequence ();
|
end_sequence ();
|
||||||
emit_insn (insns);
|
emit_insn (insns);
|
||||||
}
|
}
|
||||||
flags &= ~(ECF_CONST | ECF_PURE | ECF_LIBCALL_BLOCK);
|
|
||||||
|
|
||||||
/* If this was a CONST function, it is now PURE since
|
/* If this was a CONST function, it is now PURE since it now
|
||||||
it now reads memory. */
|
reads memory. */
|
||||||
if (flags & ECF_CONST)
|
if (flags & ECF_CONST)
|
||||||
{
|
{
|
||||||
flags &= ~ECF_CONST;
|
flags &= ~ECF_CONST;
|
||||||
|
@ -3901,14 +3908,6 @@ emit_library_call_value_1 (int retval, rtx orgfun, rtx value,
|
||||||
|
|
||||||
insns = get_insns ();
|
insns = get_insns ();
|
||||||
end_sequence ();
|
end_sequence ();
|
||||||
|
|
||||||
if (flags & ECF_PURE)
|
|
||||||
note = gen_rtx_EXPR_LIST (VOIDmode,
|
|
||||||
gen_rtx_USE (VOIDmode,
|
|
||||||
gen_rtx_MEM (BLKmode,
|
|
||||||
gen_rtx_SCRATCH (VOIDmode))),
|
|
||||||
note);
|
|
||||||
|
|
||||||
emit_libcall_block (insns, temp, valreg, note);
|
emit_libcall_block (insns, temp, valreg, note);
|
||||||
|
|
||||||
valreg = temp;
|
valreg = temp;
|
||||||
|
|
|
@ -2745,7 +2745,7 @@ need_fake_edge_p (const_rtx insn)
|
||||||
if ((CALL_P (insn)
|
if ((CALL_P (insn)
|
||||||
&& !SIBLING_CALL_P (insn)
|
&& !SIBLING_CALL_P (insn)
|
||||||
&& !find_reg_note (insn, REG_NORETURN, NULL)
|
&& !find_reg_note (insn, REG_NORETURN, NULL)
|
||||||
&& !CONST_OR_PURE_CALL_P (insn)))
|
&& !(RTL_CONST_OR_PURE_CALL_P (insn))))
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
return ((GET_CODE (PATTERN (insn)) == ASM_OPERANDS
|
return ((GET_CODE (PATTERN (insn)) == ASM_OPERANDS
|
||||||
|
|
|
@ -986,7 +986,7 @@ alpha_legitimize_address (rtx x, rtx scratch,
|
||||||
emit_insn (gen_movdi_er_tlsgd (r16, pic_offset_table_rtx, x, seq));
|
emit_insn (gen_movdi_er_tlsgd (r16, pic_offset_table_rtx, x, seq));
|
||||||
insn = gen_call_value_osf_tlsgd (r0, tga, seq);
|
insn = gen_call_value_osf_tlsgd (r0, tga, seq);
|
||||||
insn = emit_call_insn (insn);
|
insn = emit_call_insn (insn);
|
||||||
CONST_OR_PURE_CALL_P (insn) = 1;
|
RTL_CONST_CALL_P (insn) = 1;
|
||||||
use_reg (&CALL_INSN_FUNCTION_USAGE (insn), r16);
|
use_reg (&CALL_INSN_FUNCTION_USAGE (insn), r16);
|
||||||
|
|
||||||
insn = get_insns ();
|
insn = get_insns ();
|
||||||
|
@ -1007,7 +1007,7 @@ alpha_legitimize_address (rtx x, rtx scratch,
|
||||||
emit_insn (gen_movdi_er_tlsldm (r16, pic_offset_table_rtx, seq));
|
emit_insn (gen_movdi_er_tlsldm (r16, pic_offset_table_rtx, seq));
|
||||||
insn = gen_call_value_osf_tlsldm (r0, tga, seq);
|
insn = gen_call_value_osf_tlsldm (r0, tga, seq);
|
||||||
insn = emit_call_insn (insn);
|
insn = emit_call_insn (insn);
|
||||||
CONST_OR_PURE_CALL_P (insn) = 1;
|
RTL_CONST_CALL_P (insn) = 1;
|
||||||
use_reg (&CALL_INSN_FUNCTION_USAGE (insn), r16);
|
use_reg (&CALL_INSN_FUNCTION_USAGE (insn), r16);
|
||||||
|
|
||||||
insn = get_insns ();
|
insn = get_insns ();
|
||||||
|
@ -3013,7 +3013,7 @@ alpha_emit_xfloating_libcall (rtx func, rtx target, rtx operands[],
|
||||||
tmp = emit_call_insn (GEN_CALL_VALUE (reg, tmp, const0_rtx,
|
tmp = emit_call_insn (GEN_CALL_VALUE (reg, tmp, const0_rtx,
|
||||||
const0_rtx, const0_rtx));
|
const0_rtx, const0_rtx));
|
||||||
CALL_INSN_FUNCTION_USAGE (tmp) = usage;
|
CALL_INSN_FUNCTION_USAGE (tmp) = usage;
|
||||||
CONST_OR_PURE_CALL_P (tmp) = 1;
|
RTL_CONST_CALL_P (tmp) = 1;
|
||||||
|
|
||||||
tmp = get_insns ();
|
tmp = get_insns ();
|
||||||
end_sequence ();
|
end_sequence ();
|
||||||
|
|
|
@ -7859,7 +7859,7 @@ legitimize_tls_address (rtx x, enum tls_model model, int for_mov)
|
||||||
insns = get_insns ();
|
insns = get_insns ();
|
||||||
end_sequence ();
|
end_sequence ();
|
||||||
|
|
||||||
CONST_OR_PURE_CALL_P (insns) = 1;
|
RTL_CONST_CALL_P (insns) = 1;
|
||||||
emit_libcall_block (insns, dest, rax, x);
|
emit_libcall_block (insns, dest, rax, x);
|
||||||
}
|
}
|
||||||
else if (TARGET_64BIT && TARGET_GNU2_TLS)
|
else if (TARGET_64BIT && TARGET_GNU2_TLS)
|
||||||
|
@ -7890,7 +7890,7 @@ legitimize_tls_address (rtx x, enum tls_model model, int for_mov)
|
||||||
|
|
||||||
note = gen_rtx_EXPR_LIST (VOIDmode, const0_rtx, NULL);
|
note = gen_rtx_EXPR_LIST (VOIDmode, const0_rtx, NULL);
|
||||||
note = gen_rtx_EXPR_LIST (VOIDmode, ix86_tls_get_addr (), note);
|
note = gen_rtx_EXPR_LIST (VOIDmode, ix86_tls_get_addr (), note);
|
||||||
CONST_OR_PURE_CALL_P (insns) = 1;
|
RTL_CONST_CALL_P (insns) = 1;
|
||||||
emit_libcall_block (insns, base, rax, note);
|
emit_libcall_block (insns, base, rax, note);
|
||||||
}
|
}
|
||||||
else if (TARGET_64BIT && TARGET_GNU2_TLS)
|
else if (TARGET_64BIT && TARGET_GNU2_TLS)
|
||||||
|
|
|
@ -2371,7 +2371,7 @@ mips_call_tls_get_addr (rtx sym, enum mips_symbol_type type, rtx v0)
|
||||||
emit_insn (gen_rtx_SET (Pmode, a0,
|
emit_insn (gen_rtx_SET (Pmode, a0,
|
||||||
gen_rtx_LO_SUM (Pmode, pic_offset_table_rtx, loc)));
|
gen_rtx_LO_SUM (Pmode, pic_offset_table_rtx, loc)));
|
||||||
insn = mips_expand_call (v0, mips_tls_symbol, const0_rtx, const0_rtx, false);
|
insn = mips_expand_call (v0, mips_tls_symbol, const0_rtx, const0_rtx, false);
|
||||||
CONST_OR_PURE_CALL_P (insn) = 1;
|
RTL_CONST_CALL_P (insn) = 1;
|
||||||
use_reg (&CALL_INSN_FUNCTION_USAGE (insn), a0);
|
use_reg (&CALL_INSN_FUNCTION_USAGE (insn), a0);
|
||||||
insn = get_insns ();
|
insn = get_insns ();
|
||||||
|
|
||||||
|
|
|
@ -3902,7 +3902,7 @@ rs6000_legitimize_tls_address (rtx addr, enum tls_model model)
|
||||||
tga = gen_rtx_MEM (Pmode, rs6000_tls_get_addr ());
|
tga = gen_rtx_MEM (Pmode, rs6000_tls_get_addr ());
|
||||||
insn = gen_call_value (r3, tga, const0_rtx, const0_rtx);
|
insn = gen_call_value (r3, tga, const0_rtx, const0_rtx);
|
||||||
insn = emit_call_insn (insn);
|
insn = emit_call_insn (insn);
|
||||||
CONST_OR_PURE_CALL_P (insn) = 1;
|
RTL_CONST_CALL_P (insn) = 1;
|
||||||
use_reg (&CALL_INSN_FUNCTION_USAGE (insn), r3);
|
use_reg (&CALL_INSN_FUNCTION_USAGE (insn), r3);
|
||||||
insn = get_insns ();
|
insn = get_insns ();
|
||||||
end_sequence ();
|
end_sequence ();
|
||||||
|
@ -3920,7 +3920,7 @@ rs6000_legitimize_tls_address (rtx addr, enum tls_model model)
|
||||||
tga = gen_rtx_MEM (Pmode, rs6000_tls_get_addr ());
|
tga = gen_rtx_MEM (Pmode, rs6000_tls_get_addr ());
|
||||||
insn = gen_call_value (r3, tga, const0_rtx, const0_rtx);
|
insn = gen_call_value (r3, tga, const0_rtx, const0_rtx);
|
||||||
insn = emit_call_insn (insn);
|
insn = emit_call_insn (insn);
|
||||||
CONST_OR_PURE_CALL_P (insn) = 1;
|
RTL_CONST_CALL_P (insn) = 1;
|
||||||
use_reg (&CALL_INSN_FUNCTION_USAGE (insn), r3);
|
use_reg (&CALL_INSN_FUNCTION_USAGE (insn), r3);
|
||||||
insn = get_insns ();
|
insn = get_insns ();
|
||||||
end_sequence ();
|
end_sequence ();
|
||||||
|
|
|
@ -3178,7 +3178,7 @@ s390_emit_tls_call_insn (rtx result_reg, rtx tls_call)
|
||||||
gen_rtx_REG (Pmode, RETURN_REGNUM));
|
gen_rtx_REG (Pmode, RETURN_REGNUM));
|
||||||
|
|
||||||
use_reg (&CALL_INSN_FUNCTION_USAGE (insn), result_reg);
|
use_reg (&CALL_INSN_FUNCTION_USAGE (insn), result_reg);
|
||||||
CONST_OR_PURE_CALL_P (insn) = 1;
|
RTL_CONST_CALL_P (insn) = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ADDR contains a thread-local SYMBOL_REF. Generate code to compute
|
/* ADDR contains a thread-local SYMBOL_REF. Generate code to compute
|
||||||
|
|
|
@ -1,3 +1,11 @@
|
||||||
|
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.
|
||||||
|
|
||||||
|
|
||||||
2008-05-02 Simon Baldwin <simonb@google.com>
|
2008-05-02 Simon Baldwin <simonb@google.com>
|
||||||
|
|
||||||
PR bootstrap/36108
|
PR bootstrap/36108
|
||||||
|
|
|
@ -1802,11 +1802,13 @@ duplicate_decls (tree newdecl, tree olddecl, bool newdecl_is_friend)
|
||||||
|= DECL_NO_INSTRUMENT_FUNCTION_ENTRY_EXIT (olddecl);
|
|= DECL_NO_INSTRUMENT_FUNCTION_ENTRY_EXIT (olddecl);
|
||||||
DECL_NO_LIMIT_STACK (newdecl) |= DECL_NO_LIMIT_STACK (olddecl);
|
DECL_NO_LIMIT_STACK (newdecl) |= DECL_NO_LIMIT_STACK (olddecl);
|
||||||
TREE_THIS_VOLATILE (newdecl) |= TREE_THIS_VOLATILE (olddecl);
|
TREE_THIS_VOLATILE (newdecl) |= TREE_THIS_VOLATILE (olddecl);
|
||||||
TREE_READONLY (newdecl) |= TREE_READONLY (olddecl);
|
|
||||||
TREE_NOTHROW (newdecl) |= TREE_NOTHROW (olddecl);
|
TREE_NOTHROW (newdecl) |= TREE_NOTHROW (olddecl);
|
||||||
DECL_IS_MALLOC (newdecl) |= DECL_IS_MALLOC (olddecl);
|
DECL_IS_MALLOC (newdecl) |= DECL_IS_MALLOC (olddecl);
|
||||||
DECL_IS_OPERATOR_NEW (newdecl) |= DECL_IS_OPERATOR_NEW (olddecl);
|
DECL_IS_OPERATOR_NEW (newdecl) |= DECL_IS_OPERATOR_NEW (olddecl);
|
||||||
DECL_IS_PURE (newdecl) |= DECL_IS_PURE (olddecl);
|
DECL_PURE_P (newdecl) |= DECL_PURE_P (olddecl);
|
||||||
|
TREE_READONLY (newdecl) |= TREE_READONLY (olddecl);
|
||||||
|
DECL_LOOPING_CONST_OR_PURE_P (newdecl)
|
||||||
|
|= DECL_LOOPING_CONST_OR_PURE_P (olddecl);
|
||||||
/* Keep the old RTL. */
|
/* Keep the old RTL. */
|
||||||
COPY_DECL_RTL (olddecl, newdecl);
|
COPY_DECL_RTL (olddecl, newdecl);
|
||||||
}
|
}
|
||||||
|
|
|
@ -707,7 +707,7 @@ build_dynamic_cast_1 (tree type, tree expr, tsubst_flags_t complain)
|
||||||
(NULL_TREE, ptrdiff_type_node, void_list_node))));
|
(NULL_TREE, ptrdiff_type_node, void_list_node))));
|
||||||
tmp = build_function_type (ptr_type_node, tmp);
|
tmp = build_function_type (ptr_type_node, tmp);
|
||||||
dcast_fn = build_library_fn_ptr (name, tmp);
|
dcast_fn = build_library_fn_ptr (name, tmp);
|
||||||
DECL_IS_PURE (dcast_fn) = 1;
|
DECL_PURE_P (dcast_fn) = 1;
|
||||||
pop_abi_namespace ();
|
pop_abi_namespace ();
|
||||||
dynamic_cast_node = dcast_fn;
|
dynamic_cast_node = dcast_fn;
|
||||||
}
|
}
|
||||||
|
|
|
@ -5249,7 +5249,7 @@ cse_insn (rtx insn, rtx libcall_insn)
|
||||||
|
|
||||||
if (CALL_P (insn))
|
if (CALL_P (insn))
|
||||||
{
|
{
|
||||||
if (! CONST_OR_PURE_CALL_P (insn))
|
if (!(RTL_CONST_OR_PURE_CALL_P (insn)))
|
||||||
invalidate_memory ();
|
invalidate_memory ();
|
||||||
invalidate_for_call ();
|
invalidate_for_call ();
|
||||||
}
|
}
|
||||||
|
|
|
@ -1693,7 +1693,11 @@ cselib_process_insn (rtx insn)
|
||||||
GET_MODE (REG_VALUES (i)->elt->val_rtx))))
|
GET_MODE (REG_VALUES (i)->elt->val_rtx))))
|
||||||
cselib_invalidate_regno (i, reg_raw_mode[i]);
|
cselib_invalidate_regno (i, reg_raw_mode[i]);
|
||||||
|
|
||||||
if (! CONST_OR_PURE_CALL_P (insn))
|
/* Since it is not clear how cselib is going to be used, be
|
||||||
|
conservative here and treat looping pure or const functions
|
||||||
|
as if they were regular functions. */
|
||||||
|
if (RTL_LOOPING_CONST_OR_PURE_CALL_P (insn)
|
||||||
|
|| !(RTL_CONST_OR_PURE_CALL_P (insn)))
|
||||||
cselib_invalidate_mem (callmem);
|
cselib_invalidate_mem (callmem);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -99,6 +99,15 @@ deletable_insn_p (rtx insn, bool fast)
|
||||||
rtx body, x;
|
rtx body, x;
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
|
/* We can delete dead const or pure calls as long as they do not
|
||||||
|
infinite loop and are not sibling calls. The problem with
|
||||||
|
sibling calls is that it is hard to see the result. */
|
||||||
|
if (CALL_P (insn)
|
||||||
|
&& (!SIBLING_CALL_P (insn))
|
||||||
|
&& (RTL_CONST_OR_PURE_CALL_P (insn)
|
||||||
|
&& !RTL_LOOPING_CONST_OR_PURE_CALL_P (insn)))
|
||||||
|
return true;
|
||||||
|
|
||||||
if (!NONJUMP_INSN_P (insn))
|
if (!NONJUMP_INSN_P (insn))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
|
|
|
@ -1967,7 +1967,7 @@ scan_insn (bb_info_t bb_info, rtx insn)
|
||||||
/* Const functions cannot do anything bad i.e. read memory,
|
/* Const functions cannot do anything bad i.e. read memory,
|
||||||
however, they can read their parameters which may have
|
however, they can read their parameters which may have
|
||||||
been pushed onto the stack. */
|
been pushed onto the stack. */
|
||||||
if (CONST_OR_PURE_CALL_P (insn) && !pure_call_p (insn))
|
if (RTL_CONST_CALL_P (insn))
|
||||||
{
|
{
|
||||||
insn_info_t i_ptr = active_local_stores;
|
insn_info_t i_ptr = active_local_stores;
|
||||||
insn_info_t last = NULL;
|
insn_info_t last = NULL;
|
||||||
|
|
|
@ -5464,7 +5464,10 @@ emit_copy_of_insn_after (rtx insn, rtx after)
|
||||||
CALL_INSN_FUNCTION_USAGE (new)
|
CALL_INSN_FUNCTION_USAGE (new)
|
||||||
= copy_insn (CALL_INSN_FUNCTION_USAGE (insn));
|
= copy_insn (CALL_INSN_FUNCTION_USAGE (insn));
|
||||||
SIBLING_CALL_P (new) = SIBLING_CALL_P (insn);
|
SIBLING_CALL_P (new) = SIBLING_CALL_P (insn);
|
||||||
CONST_OR_PURE_CALL_P (new) = CONST_OR_PURE_CALL_P (insn);
|
RTL_CONST_CALL_P (new) = RTL_CONST_CALL_P (insn);
|
||||||
|
RTL_PURE_CALL_P (new) = RTL_PURE_CALL_P (insn);
|
||||||
|
RTL_LOOPING_CONST_OR_PURE_CALL_P (new)
|
||||||
|
= RTL_LOOPING_CONST_OR_PURE_CALL_P (insn);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
|
|
|
@ -1,3 +1,8 @@
|
||||||
|
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.
|
||||||
|
|
||||||
2008-05-06 Francois-Xavier Coudert <fxcoudert@gcc.gnu.org>
|
2008-05-06 Francois-Xavier Coudert <fxcoudert@gcc.gnu.org>
|
||||||
|
|
||||||
* arith.c: (gfc_arith_concat, gfc_compare_string,
|
* arith.c: (gfc_arith_concat, gfc_compare_string,
|
||||||
|
|
|
@ -1197,7 +1197,7 @@ gfc_get_extern_function_decl (gfc_symbol * sym)
|
||||||
if (sym->attr.pure || sym->attr.elemental)
|
if (sym->attr.pure || sym->attr.elemental)
|
||||||
{
|
{
|
||||||
if (sym->attr.function && !gfc_return_by_reference (sym))
|
if (sym->attr.function && !gfc_return_by_reference (sym))
|
||||||
DECL_IS_PURE (fndecl) = 1;
|
DECL_PURE_P (fndecl) = 1;
|
||||||
/* TODO: check if pure SUBROUTINEs don't have INTENT(OUT)
|
/* TODO: check if pure SUBROUTINEs don't have INTENT(OUT)
|
||||||
parameters and don't use alternate returns (is this
|
parameters and don't use alternate returns (is this
|
||||||
allowed?). In that case, calls to them are meaningless, and
|
allowed?). In that case, calls to them are meaningless, and
|
||||||
|
@ -1324,7 +1324,7 @@ build_function_decl (gfc_symbol * sym)
|
||||||
including an alternate return. In that case it can also be
|
including an alternate return. In that case it can also be
|
||||||
marked as PURE. See also in gfc_get_extern_function_decl(). */
|
marked as PURE. See also in gfc_get_extern_function_decl(). */
|
||||||
if (attr.function && !gfc_return_by_reference (sym))
|
if (attr.function && !gfc_return_by_reference (sym))
|
||||||
DECL_IS_PURE (fndecl) = 1;
|
DECL_PURE_P (fndecl) = 1;
|
||||||
TREE_SIDE_EFFECTS (fndecl) = 0;
|
TREE_SIDE_EFFECTS (fndecl) = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -2309,7 +2309,7 @@ oprs_not_set_p (const_rtx x, const_rtx insn)
|
||||||
static void
|
static void
|
||||||
mark_call (rtx insn)
|
mark_call (rtx insn)
|
||||||
{
|
{
|
||||||
if (! CONST_OR_PURE_CALL_P (insn))
|
if (! RTL_CONST_OR_PURE_CALL_P (insn))
|
||||||
record_last_mem_set_info (insn);
|
record_last_mem_set_info (insn);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -5987,7 +5987,7 @@ store_killed_in_insn (const_rtx x, const_rtx x_regs, const_rtx insn, int after)
|
||||||
{
|
{
|
||||||
/* A normal or pure call might read from pattern,
|
/* A normal or pure call might read from pattern,
|
||||||
but a const call will not. */
|
but a const call will not. */
|
||||||
if (! CONST_OR_PURE_CALL_P (insn) || pure_call_p (insn))
|
if (RTL_CONST_CALL_P (insn))
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
/* But even a const call reads its parameters. Check whether the
|
/* But even a const call reads its parameters. Check whether the
|
||||||
|
|
|
@ -2274,10 +2274,14 @@ gimplify_call_expr (tree *expr_p, tree *pre_p, bool want_value)
|
||||||
/* If the function is "const" or "pure", then clear TREE_SIDE_EFFECTS on its
|
/* If the function is "const" or "pure", then clear TREE_SIDE_EFFECTS on its
|
||||||
decl. This allows us to eliminate redundant or useless
|
decl. This allows us to eliminate redundant or useless
|
||||||
calls to "const" functions. */
|
calls to "const" functions. */
|
||||||
if (TREE_CODE (*expr_p) == CALL_EXPR
|
if (TREE_CODE (*expr_p) == CALL_EXPR)
|
||||||
&& (call_expr_flags (*expr_p) & (ECF_CONST | ECF_PURE)))
|
{
|
||||||
TREE_SIDE_EFFECTS (*expr_p) = 0;
|
int flags = call_expr_flags (*expr_p);
|
||||||
|
if (flags & (ECF_CONST | ECF_PURE)
|
||||||
|
/* An infinite loop is considered a side effect. */
|
||||||
|
&& !(flags & (ECF_LOOPING_CONST_OR_PURE)))
|
||||||
|
TREE_SIDE_EFFECTS (*expr_p) = 0;
|
||||||
|
}
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -2168,9 +2168,7 @@ noce_can_store_speculate_p (basic_block top_bb, const_rtx mem)
|
||||||
unconditionally before the barrier. */
|
unconditionally before the barrier. */
|
||||||
if (INSN_P (insn)
|
if (INSN_P (insn)
|
||||||
&& (volatile_insn_p (PATTERN (insn))
|
&& (volatile_insn_p (PATTERN (insn))
|
||||||
|| (CALL_P (insn)
|
|| (CALL_P (insn) && (!RTL_CONST_CALL_P (insn)))))
|
||||||
&& (!CONST_OR_PURE_CALL_P (insn)
|
|
||||||
|| pure_call_p (insn)))))
|
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
if (memory_modified_in_insn_p (mem, insn))
|
if (memory_modified_in_insn_p (mem, insn))
|
||||||
|
|
|
@ -19,7 +19,8 @@ along with GCC; see the file COPYING3. If not see
|
||||||
<http://www.gnu.org/licenses/>. */
|
<http://www.gnu.org/licenses/>. */
|
||||||
|
|
||||||
/* This file mark functions as being either const (TREE_READONLY) or
|
/* 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
|
This must be run after inlining decisions have been made since
|
||||||
otherwise, the local sets will not contain information that is
|
otherwise, the local sets will not contain information that is
|
||||||
|
@ -69,6 +70,7 @@ enum pure_const_state_e
|
||||||
struct funct_state_d
|
struct funct_state_d
|
||||||
{
|
{
|
||||||
enum pure_const_state_e pure_const_state;
|
enum pure_const_state_e pure_const_state;
|
||||||
|
bool looping;
|
||||||
bool state_set_in_source;
|
bool state_set_in_source;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -95,6 +97,7 @@ check_decl (funct_state local,
|
||||||
if (lookup_attribute ("used", DECL_ATTRIBUTES (t)))
|
if (lookup_attribute ("used", DECL_ATTRIBUTES (t)))
|
||||||
{
|
{
|
||||||
local->pure_const_state = IPA_NEITHER;
|
local->pure_const_state = IPA_NEITHER;
|
||||||
|
local->looping = false;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -103,6 +106,7 @@ check_decl (funct_state local,
|
||||||
if (TREE_THIS_VOLATILE (t))
|
if (TREE_THIS_VOLATILE (t))
|
||||||
{
|
{
|
||||||
local->pure_const_state = IPA_NEITHER;
|
local->pure_const_state = IPA_NEITHER;
|
||||||
|
local->looping = false;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -116,6 +120,7 @@ check_decl (funct_state local,
|
||||||
if (checking_write)
|
if (checking_write)
|
||||||
{
|
{
|
||||||
local->pure_const_state = IPA_NEITHER;
|
local->pure_const_state = IPA_NEITHER;
|
||||||
|
local->looping = false;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -174,6 +179,7 @@ check_tree (funct_state local, tree t, bool checking_write)
|
||||||
if (TREE_THIS_VOLATILE (t))
|
if (TREE_THIS_VOLATILE (t))
|
||||||
{
|
{
|
||||||
local->pure_const_state = IPA_NEITHER;
|
local->pure_const_state = IPA_NEITHER;
|
||||||
|
local->looping = false;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -199,6 +205,7 @@ check_tree (funct_state local, tree t, bool checking_write)
|
||||||
if (checking_write)
|
if (checking_write)
|
||||||
{
|
{
|
||||||
local->pure_const_state = IPA_NEITHER;
|
local->pure_const_state = IPA_NEITHER;
|
||||||
|
local->looping = false;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
else if (local->pure_const_state == IPA_CONST)
|
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
|
/* When bad things happen to bad functions, they cannot be const
|
||||||
or pure. */
|
or pure. */
|
||||||
if (setjmp_call_p (callee_t))
|
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)
|
if (DECL_BUILT_IN_CLASS (callee_t) == BUILT_IN_NORMAL)
|
||||||
switch (DECL_FUNCTION_CODE (callee_t))
|
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_LONGJMP:
|
||||||
case BUILT_IN_NONLOCAL_GOTO:
|
case BUILT_IN_NONLOCAL_GOTO:
|
||||||
local->pure_const_state = IPA_NEITHER;
|
local->pure_const_state = IPA_NEITHER;
|
||||||
|
local->looping = false;
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
|
@ -480,7 +491,10 @@ scan_function (tree *tp,
|
||||||
case LABEL_EXPR:
|
case LABEL_EXPR:
|
||||||
if (DECL_NONLOCAL (TREE_OPERAND (t, 0)))
|
if (DECL_NONLOCAL (TREE_OPERAND (t, 0)))
|
||||||
/* Target of long jump. */
|
/* Target of long jump. */
|
||||||
local->pure_const_state = IPA_NEITHER;
|
{
|
||||||
|
local->pure_const_state = IPA_NEITHER;
|
||||||
|
local->looping = false;
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case CALL_EXPR:
|
case CALL_EXPR:
|
||||||
|
@ -513,6 +527,10 @@ analyze_function (struct cgraph_node *fn)
|
||||||
|
|
||||||
l->pure_const_state = IPA_CONST;
|
l->pure_const_state = IPA_CONST;
|
||||||
l->state_set_in_source = false;
|
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,
|
/* 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
|
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->pure_const_state = IPA_CONST;
|
||||||
l->state_set_in_source = true;
|
l->state_set_in_source = true;
|
||||||
}
|
}
|
||||||
if (DECL_IS_PURE (decl))
|
if (DECL_PURE_P (decl))
|
||||||
{
|
{
|
||||||
l->pure_const_state = IPA_PURE;
|
l->pure_const_state = IPA_PURE;
|
||||||
l->state_set_in_source = true;
|
l->state_set_in_source = true;
|
||||||
|
@ -644,6 +662,7 @@ static_execute (void)
|
||||||
for (i = 0; i < order_pos; i++ )
|
for (i = 0; i < order_pos; i++ )
|
||||||
{
|
{
|
||||||
enum pure_const_state_e pure_const_state = IPA_CONST;
|
enum pure_const_state_e pure_const_state = IPA_CONST;
|
||||||
|
bool looping = false;
|
||||||
int count = 0;
|
int count = 0;
|
||||||
node = order[i];
|
node = order[i];
|
||||||
|
|
||||||
|
@ -655,6 +674,9 @@ static_execute (void)
|
||||||
if (pure_const_state < w_l->pure_const_state)
|
if (pure_const_state < w_l->pure_const_state)
|
||||||
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)
|
if (pure_const_state == IPA_NEITHER)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
@ -663,24 +685,8 @@ static_execute (void)
|
||||||
struct cgraph_edge *e;
|
struct cgraph_edge *e;
|
||||||
count++;
|
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)
|
if (count > 1)
|
||||||
{
|
looping = true;
|
||||||
pure_const_state = IPA_NEITHER;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
for (e = w->callees; e; e = e->next_callee)
|
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. */
|
/* Only look at the master nodes and skip external nodes. */
|
||||||
y = cgraph_master_clone (y);
|
y = cgraph_master_clone (y);
|
||||||
|
|
||||||
/* Check for immediate recursive functions. See the
|
|
||||||
FIXME above. */
|
|
||||||
if (w == y)
|
if (w == y)
|
||||||
{
|
looping = true;
|
||||||
pure_const_state = IPA_NEITHER;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
if (y)
|
if (y)
|
||||||
{
|
{
|
||||||
funct_state y_l = get_function_state (y);
|
funct_state y_l = get_function_state (y);
|
||||||
|
@ -702,6 +703,8 @@ static_execute (void)
|
||||||
pure_const_state = y_l->pure_const_state;
|
pure_const_state = y_l->pure_const_state;
|
||||||
if (pure_const_state == IPA_NEITHER)
|
if (pure_const_state == IPA_NEITHER)
|
||||||
break;
|
break;
|
||||||
|
if (y_l->looping)
|
||||||
|
looping = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -724,15 +727,19 @@ static_execute (void)
|
||||||
{
|
{
|
||||||
case IPA_CONST:
|
case IPA_CONST:
|
||||||
TREE_READONLY (w->decl) = 1;
|
TREE_READONLY (w->decl) = 1;
|
||||||
|
DECL_LOOPING_CONST_OR_PURE_P (w->decl) = looping;
|
||||||
if (dump_file)
|
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));
|
lang_hooks.decl_printable_name(w->decl, 2));
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case IPA_PURE:
|
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)
|
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));
|
lang_hooks.decl_printable_name(w->decl, 2));
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
|
|
@ -1,3 +1,8 @@
|
||||||
|
2008-05-07 Kenneth Zadeck <zadeck@naturalbridge.com>
|
||||||
|
|
||||||
|
* decl.c (java_init_decl_processing): Change DECL_IS_PURE to
|
||||||
|
DECL_PURE_P.
|
||||||
|
|
||||||
2008-04-23 Paolo Bonzini <bonzini@gnu.org>
|
2008-04-23 Paolo Bonzini <bonzini@gnu.org>
|
||||||
|
|
||||||
* class.c (build_utf8_ref): Don't set TREE_INVARIANT.
|
* class.c (build_utf8_ref): Don't set TREE_INVARIANT.
|
||||||
|
|
|
@ -906,7 +906,7 @@ java_init_decl_processing (void)
|
||||||
= add_builtin_function ("_Jv_ResolvePoolEntry",
|
= add_builtin_function ("_Jv_ResolvePoolEntry",
|
||||||
build_function_type (ptr_type_node, t),
|
build_function_type (ptr_type_node, t),
|
||||||
0,NOT_BUILT_IN, NULL, NULL_TREE);
|
0,NOT_BUILT_IN, NULL, NULL_TREE);
|
||||||
DECL_IS_PURE (soft_resolvepoolentry_node) = 1;
|
DECL_PURE_P (soft_resolvepoolentry_node) = 1;
|
||||||
throw_node = add_builtin_function ("_Jv_Throw",
|
throw_node = add_builtin_function ("_Jv_Throw",
|
||||||
build_function_type (void_type_node, t),
|
build_function_type (void_type_node, t),
|
||||||
0, NOT_BUILT_IN, NULL, NULL_TREE);
|
0, NOT_BUILT_IN, NULL, NULL_TREE);
|
||||||
|
@ -1000,7 +1000,7 @@ java_init_decl_processing (void)
|
||||||
= add_builtin_function ("_Jv_IsInstanceOf",
|
= add_builtin_function ("_Jv_IsInstanceOf",
|
||||||
build_function_type (boolean_type_node, t),
|
build_function_type (boolean_type_node, t),
|
||||||
0, NOT_BUILT_IN, NULL, NULL_TREE);
|
0, NOT_BUILT_IN, NULL, NULL_TREE);
|
||||||
DECL_IS_PURE (soft_instanceof_node) = 1;
|
DECL_PURE_P (soft_instanceof_node) = 1;
|
||||||
t = tree_cons (NULL_TREE, object_ptr_type_node,
|
t = tree_cons (NULL_TREE, object_ptr_type_node,
|
||||||
tree_cons (NULL_TREE, object_ptr_type_node, endlink));
|
tree_cons (NULL_TREE, object_ptr_type_node, endlink));
|
||||||
soft_checkarraystore_node
|
soft_checkarraystore_node
|
||||||
|
@ -1014,7 +1014,7 @@ java_init_decl_processing (void)
|
||||||
= add_builtin_function ("_Jv_LookupInterfaceMethodIdx",
|
= add_builtin_function ("_Jv_LookupInterfaceMethodIdx",
|
||||||
build_function_type (ptr_type_node, t),
|
build_function_type (ptr_type_node, t),
|
||||||
0, NOT_BUILT_IN, NULL, NULL_TREE);
|
0, NOT_BUILT_IN, NULL, NULL_TREE);
|
||||||
DECL_IS_PURE (soft_lookupinterfacemethod_node) = 1;
|
DECL_PURE_P (soft_lookupinterfacemethod_node) = 1;
|
||||||
t = tree_cons (NULL_TREE, ptr_type_node,
|
t = tree_cons (NULL_TREE, ptr_type_node,
|
||||||
tree_cons (NULL_TREE, ptr_type_node,
|
tree_cons (NULL_TREE, ptr_type_node,
|
||||||
tree_cons (NULL_TREE, ptr_type_node, endlink)));
|
tree_cons (NULL_TREE, ptr_type_node, endlink)));
|
||||||
|
|
|
@ -505,7 +505,7 @@ validate_equiv_mem (rtx start, rtx reg, rtx memref)
|
||||||
return 1;
|
return 1;
|
||||||
|
|
||||||
if (CALL_P (insn) && ! MEM_READONLY_P (memref)
|
if (CALL_P (insn) && ! MEM_READONLY_P (memref)
|
||||||
&& ! CONST_OR_PURE_CALL_P (insn))
|
&& ! RTL_CONST_OR_PURE_CALL_P (insn))
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
note_stores (PATTERN (insn), validate_equiv_mem_from_store, NULL);
|
note_stores (PATTERN (insn), validate_equiv_mem_from_store, NULL);
|
||||||
|
@ -781,9 +781,7 @@ memref_used_between_p (rtx memref, rtx start, rtx end)
|
||||||
return 1;
|
return 1;
|
||||||
|
|
||||||
/* Nonconst functions may access memory. */
|
/* Nonconst functions may access memory. */
|
||||||
if (CALL_P (insn)
|
if (CALL_P (insn) && (! RTL_CONST_CALL_P (insn)))
|
||||||
&& (! CONST_OR_PURE_CALL_P (insn)
|
|
||||||
|| pure_call_p (insn)))
|
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -563,7 +563,8 @@ find_exits (struct loop *loop, basic_block *body,
|
||||||
FOR_BB_INSNS (body[i], insn)
|
FOR_BB_INSNS (body[i], insn)
|
||||||
{
|
{
|
||||||
if (CALL_P (insn)
|
if (CALL_P (insn)
|
||||||
&& !CONST_OR_PURE_CALL_P (insn))
|
&& (RTL_LOOPING_CONST_OR_PURE_CALL_P (insn)
|
||||||
|
|| !RTL_CONST_OR_PURE_CALL_P (insn)))
|
||||||
{
|
{
|
||||||
has_call = true;
|
has_call = true;
|
||||||
bitmap_set_bit (may_exit, i);
|
bitmap_set_bit (may_exit, i);
|
||||||
|
@ -904,7 +905,8 @@ find_invariants_bb (basic_block bb, bool always_reached, bool always_executed)
|
||||||
|
|
||||||
if (always_reached
|
if (always_reached
|
||||||
&& CALL_P (insn)
|
&& CALL_P (insn)
|
||||||
&& !CONST_OR_PURE_CALL_P (insn))
|
&& (RTL_LOOPING_CONST_OR_PURE_CALL_P (insn)
|
||||||
|
|| ! RTL_CONST_OR_PURE_CALL_P (insn)))
|
||||||
always_reached = false;
|
always_reached = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -758,7 +758,7 @@ record_opr_changes (rtx insn)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (! CONST_OR_PURE_CALL_P (insn))
|
if (! RTL_CONST_OR_PURE_CALL_P (insn))
|
||||||
record_last_mem_set_info (insn);
|
record_last_mem_set_info (insn);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -3155,7 +3155,7 @@ delete_prior_computation (rtx note, rtx insn)
|
||||||
/* If we reach a CALL which is not calling a const function
|
/* If we reach a CALL which is not calling a const function
|
||||||
or the callee pops the arguments, then give up. */
|
or the callee pops the arguments, then give up. */
|
||||||
if (CALL_P (our_prev)
|
if (CALL_P (our_prev)
|
||||||
&& (! CONST_OR_PURE_CALL_P (our_prev)
|
&& (! RTL_CONST_CALL_P (our_prev)
|
||||||
|| GET_CODE (pat) != SET || GET_CODE (SET_SRC (pat)) != CALL))
|
|| GET_CODE (pat) != SET || GET_CODE (SET_SRC (pat)) != CALL))
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
|
31
gcc/rtl.h
31
gcc/rtl.h
|
@ -253,14 +253,17 @@ struct rtx_def GTY((chain_next ("RTX_NEXT (&%h)"),
|
||||||
In a CODE_LABEL, part of the two-bit alternate entry field. */
|
In a CODE_LABEL, part of the two-bit alternate entry field. */
|
||||||
unsigned int jump : 1;
|
unsigned int jump : 1;
|
||||||
/* In a CODE_LABEL, part of the two-bit alternate entry field.
|
/* In a CODE_LABEL, part of the two-bit alternate entry field.
|
||||||
1 in a MEM if it cannot trap. */
|
1 in a MEM if it cannot trap.
|
||||||
|
1 in a CALL_INSN logically equivalent to
|
||||||
|
ECF_LOOPING_CONST_OR_PURE and DECL_LOOPING_CONST_OR_PURE_P. */
|
||||||
unsigned int call : 1;
|
unsigned int call : 1;
|
||||||
/* 1 in a REG, MEM, or CONCAT if the value is set at most once, anywhere.
|
/* 1 in a REG, MEM, or CONCAT if the value is set at most once, anywhere.
|
||||||
1 in a SUBREG if it references an unsigned object whose mode has been
|
1 in a SUBREG if it references an unsigned object whose mode has been
|
||||||
from a promoted to a wider mode.
|
from a promoted to a wider mode.
|
||||||
1 in a SYMBOL_REF if it addresses something in the per-function
|
1 in a SYMBOL_REF if it addresses something in the per-function
|
||||||
constants pool.
|
constants pool.
|
||||||
1 in a CALL_INSN, NOTE, or EXPR_LIST for a const or pure call.
|
1 in a CALL_INSN logically equivalent to ECF_CONST and TREE_READONLY.
|
||||||
|
1 in a NOTE, or EXPR_LIST for a const call.
|
||||||
1 in a JUMP_INSN, CALL_INSN, or INSN of an annulling branch. */
|
1 in a JUMP_INSN, CALL_INSN, or INSN of an annulling branch. */
|
||||||
unsigned int unchanging : 1;
|
unsigned int unchanging : 1;
|
||||||
/* 1 in a MEM or ASM_OPERANDS expression if the memory reference is volatile.
|
/* 1 in a MEM or ASM_OPERANDS expression if the memory reference is volatile.
|
||||||
|
@ -303,7 +306,8 @@ struct rtx_def GTY((chain_next ("RTX_NEXT (&%h)"),
|
||||||
unsigned frame_related : 1;
|
unsigned frame_related : 1;
|
||||||
/* 1 in a REG or PARALLEL that is the current function's return value.
|
/* 1 in a REG or PARALLEL that is the current function's return value.
|
||||||
1 in a MEM if it refers to a scalar.
|
1 in a MEM if it refers to a scalar.
|
||||||
1 in a SYMBOL_REF for a weak symbol. */
|
1 in a SYMBOL_REF for a weak symbol.
|
||||||
|
1 in a CALL_INSN logically equivalent to ECF_PURE and DECL_PURE_P. */
|
||||||
unsigned return_val : 1;
|
unsigned return_val : 1;
|
||||||
|
|
||||||
/* The first element of the operands of this rtx.
|
/* The first element of the operands of this rtx.
|
||||||
|
@ -765,10 +769,24 @@ extern void rtl_check_failed_flag (const char *, const_rtx, const char *,
|
||||||
(RTL_FLAG_CHECK6("INSN_DELETED_P", (RTX), INSN, CALL_INSN, JUMP_INSN, \
|
(RTL_FLAG_CHECK6("INSN_DELETED_P", (RTX), INSN, CALL_INSN, JUMP_INSN, \
|
||||||
CODE_LABEL, BARRIER, NOTE)->volatil)
|
CODE_LABEL, BARRIER, NOTE)->volatil)
|
||||||
|
|
||||||
|
/* 1 if RTX is a call to a const function. Built from ECF_CONST and
|
||||||
|
TREE_READONLY. */
|
||||||
|
#define RTL_CONST_CALL_P(RTX) \
|
||||||
|
(RTL_FLAG_CHECK1("RTL_CONST_CALL_P", (RTX), CALL_INSN)->unchanging)
|
||||||
|
|
||||||
|
/* 1 if RTX is a call to a pure function. Built from ECF_PURE and
|
||||||
|
DECL_PURE_P. */
|
||||||
|
#define RTL_PURE_CALL_P(RTX) \
|
||||||
|
(RTL_FLAG_CHECK1("RTL_PURE_CALL_P", (RTX), CALL_INSN)->return_val)
|
||||||
|
|
||||||
/* 1 if RTX is a call to a const or pure function. */
|
/* 1 if RTX is a call to a const or pure function. */
|
||||||
#define CONST_OR_PURE_CALL_P(RTX) \
|
#define RTL_CONST_OR_PURE_CALL_P(RTX) \
|
||||||
(RTL_FLAG_CHECK3("CONST_OR_PURE_CALL_P", (RTX), CALL_INSN, NOTE, \
|
(RTL_CONST_CALL_P(RTX) || RTL_PURE_CALL_P(RTX))
|
||||||
EXPR_LIST)->unchanging)
|
|
||||||
|
/* 1 if RTX is a call to a looping const or pure function. Built from
|
||||||
|
ECF_LOOPING_CONST_OR_PURE and DECL_LOOPING_CONST_OR_PURE_P. */
|
||||||
|
#define RTL_LOOPING_CONST_OR_PURE_CALL_P(RTX) \
|
||||||
|
(RTL_FLAG_CHECK1("CONST_OR_PURE_CALL_P", (RTX), CALL_INSN)->call)
|
||||||
|
|
||||||
/* 1 if RTX is a call_insn for a sibling call. */
|
/* 1 if RTX is a call_insn for a sibling call. */
|
||||||
#define SIBLING_CALL_P(RTX) \
|
#define SIBLING_CALL_P(RTX) \
|
||||||
|
@ -1733,7 +1751,6 @@ extern rtx find_reg_equal_equiv_note (const_rtx);
|
||||||
extern rtx find_constant_src (const_rtx);
|
extern rtx find_constant_src (const_rtx);
|
||||||
extern int find_reg_fusage (const_rtx, enum rtx_code, const_rtx);
|
extern int find_reg_fusage (const_rtx, enum rtx_code, const_rtx);
|
||||||
extern int find_regno_fusage (const_rtx, enum rtx_code, unsigned int);
|
extern int find_regno_fusage (const_rtx, enum rtx_code, unsigned int);
|
||||||
extern int pure_call_p (const_rtx);
|
|
||||||
extern void remove_note (rtx, const_rtx);
|
extern void remove_note (rtx, const_rtx);
|
||||||
extern void remove_reg_equal_equiv_notes (rtx);
|
extern void remove_reg_equal_equiv_notes (rtx);
|
||||||
extern int side_effects_p (const_rtx);
|
extern int side_effects_p (const_rtx);
|
||||||
|
|
|
@ -1846,29 +1846,6 @@ find_regno_fusage (const_rtx insn, enum rtx_code code, unsigned int regno)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Return true if INSN is a call to a pure function. */
|
|
||||||
|
|
||||||
int
|
|
||||||
pure_call_p (const_rtx insn)
|
|
||||||
{
|
|
||||||
const_rtx link;
|
|
||||||
|
|
||||||
if (!CALL_P (insn) || ! CONST_OR_PURE_CALL_P (insn))
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
/* Look for the note that differentiates const and pure functions. */
|
|
||||||
for (link = CALL_INSN_FUNCTION_USAGE (insn); link; link = XEXP (link, 1))
|
|
||||||
{
|
|
||||||
rtx u, m;
|
|
||||||
|
|
||||||
if (GET_CODE (u = XEXP (link, 0)) == USE
|
|
||||||
&& MEM_P (m = XEXP (u, 0)) && GET_MODE (m) == BLKmode
|
|
||||||
&& GET_CODE (XEXP (m, 0)) == SCRATCH)
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Remove register note NOTE from the REG_NOTES of INSN. */
|
/* Remove register note NOTE from the REG_NOTES of INSN. */
|
||||||
|
|
||||||
|
|
|
@ -2304,7 +2304,8 @@ sched_analyze (struct deps *deps, rtx head, rtx tail)
|
||||||
all pending reads and writes, and start new dependencies starting
|
all pending reads and writes, and start new dependencies starting
|
||||||
from here. But only flush writes for constant calls (which may
|
from here. But only flush writes for constant calls (which may
|
||||||
be passed a pointer to something we haven't written yet). */
|
be passed a pointer to something we haven't written yet). */
|
||||||
flush_pending_lists (deps, insn, true, !CONST_OR_PURE_CALL_P (insn));
|
flush_pending_lists (deps, insn, true,
|
||||||
|
! RTL_CONST_OR_PURE_CALL_P (insn));
|
||||||
|
|
||||||
/* Remember the last function call for limiting lifetimes. */
|
/* Remember the last function call for limiting lifetimes. */
|
||||||
free_INSN_LIST_list (&deps->last_function_call);
|
free_INSN_LIST_list (&deps->last_function_call);
|
||||||
|
|
|
@ -2430,7 +2430,10 @@ see_copy_insn (rtx insn)
|
||||||
CALL_INSN_FUNCTION_USAGE (ret)
|
CALL_INSN_FUNCTION_USAGE (ret)
|
||||||
= copy_rtx (CALL_INSN_FUNCTION_USAGE (insn));
|
= copy_rtx (CALL_INSN_FUNCTION_USAGE (insn));
|
||||||
SIBLING_CALL_P (ret) = SIBLING_CALL_P (insn);
|
SIBLING_CALL_P (ret) = SIBLING_CALL_P (insn);
|
||||||
CONST_OR_PURE_CALL_P (ret) = CONST_OR_PURE_CALL_P (insn);
|
RTL_CONST_CALL_P (ret) = RTL_CONST_CALL_P (insn);
|
||||||
|
RTL_PURE_CALL_P (ret) = RTL_PURE_CALL_P (insn);
|
||||||
|
RTL_LOOPING_CONST_OR_PURE_CALL_P (ret)
|
||||||
|
= RTL_LOOPING_CONST_OR_PURE_CALL_P (insn);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
gcc_unreachable ();
|
gcc_unreachable ();
|
||||||
|
|
|
@ -1792,9 +1792,11 @@ static void
|
||||||
update_call_expr_flags (tree call)
|
update_call_expr_flags (tree call)
|
||||||
{
|
{
|
||||||
tree decl = get_callee_fndecl (call);
|
tree decl = get_callee_fndecl (call);
|
||||||
|
int flags;
|
||||||
if (!decl)
|
if (!decl)
|
||||||
return;
|
return;
|
||||||
if (call_expr_flags (call) & (ECF_CONST | ECF_PURE))
|
flags = call_expr_flags (call);
|
||||||
|
if (flags & (ECF_CONST | ECF_PURE) && !(flags & ECF_LOOPING_CONST_OR_PURE))
|
||||||
TREE_SIDE_EFFECTS (call) = 0;
|
TREE_SIDE_EFFECTS (call) = 0;
|
||||||
if (TREE_NOTHROW (decl))
|
if (TREE_NOTHROW (decl))
|
||||||
TREE_NOTHROW (call) = 1;
|
TREE_NOTHROW (call) = 1;
|
||||||
|
@ -3906,7 +3908,19 @@ verify_gimple_expr (tree expr)
|
||||||
case CALL_EXPR:
|
case CALL_EXPR:
|
||||||
/* FIXME. The C frontend passes unpromoted arguments in case it
|
/* FIXME. The C frontend passes unpromoted arguments in case it
|
||||||
didn't see a function declaration before the call. */
|
didn't see a function declaration before the call. */
|
||||||
return false;
|
{
|
||||||
|
tree decl = CALL_EXPR_FN (expr);
|
||||||
|
|
||||||
|
if (TREE_CODE (decl) == FUNCTION_DECL
|
||||||
|
&& DECL_LOOPING_CONST_OR_PURE_P (decl)
|
||||||
|
&& (!DECL_PURE_P (decl))
|
||||||
|
&& (!TREE_READONLY (decl)))
|
||||||
|
{
|
||||||
|
error ("invalid pure const state for function");
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
case OBJ_TYPE_REF:
|
case OBJ_TYPE_REF:
|
||||||
/* FIXME. */
|
/* FIXME. */
|
||||||
|
|
|
@ -671,7 +671,7 @@ copy_body_r (tree *tp, int *walk_subtrees, void *data)
|
||||||
{
|
{
|
||||||
value = *n;
|
value = *n;
|
||||||
STRIP_TYPE_NOPS (value);
|
STRIP_TYPE_NOPS (value);
|
||||||
if (TREE_CONSTANT (value) || TREE_READONLY_DECL_P (value))
|
if (TREE_CONSTANT (value) || TREE_READONLY (value))
|
||||||
{
|
{
|
||||||
*tp = build_empty_stmt ();
|
*tp = build_empty_stmt ();
|
||||||
return copy_body_r (tp, walk_subtrees, data);
|
return copy_body_r (tp, walk_subtrees, data);
|
||||||
|
|
|
@ -299,7 +299,8 @@ execute_fixup_cfg (void)
|
||||||
tree call = get_call_expr_in (stmt);
|
tree call = get_call_expr_in (stmt);
|
||||||
tree decl = call ? get_callee_fndecl (call) : NULL;
|
tree decl = call ? get_callee_fndecl (call) : NULL;
|
||||||
|
|
||||||
if (decl && call_expr_flags (call) & (ECF_CONST | ECF_PURE)
|
if (decl && call_expr_flags (call) & (ECF_CONST | ECF_PURE
|
||||||
|
| ECF_LOOPING_CONST_OR_PURE)
|
||||||
&& TREE_SIDE_EFFECTS (call))
|
&& TREE_SIDE_EFFECTS (call))
|
||||||
{
|
{
|
||||||
if (gimple_in_ssa_p (cfun))
|
if (gimple_in_ssa_p (cfun))
|
||||||
|
|
|
@ -2077,7 +2077,7 @@ can_value_number_call (tree stmt)
|
||||||
{
|
{
|
||||||
tree call = get_call_expr_in (stmt);
|
tree call = get_call_expr_in (stmt);
|
||||||
|
|
||||||
if (call_expr_flags (call) & (ECF_PURE | ECF_CONST))
|
if (call_expr_flags (call) & (ECF_PURE | ECF_CONST))
|
||||||
return true;
|
return true;
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
|
@ -7373,7 +7373,9 @@ local_define_builtin (const char *name, tree type, enum built_in_function code,
|
||||||
if (ecf_flags & ECF_CONST)
|
if (ecf_flags & ECF_CONST)
|
||||||
TREE_READONLY (decl) = 1;
|
TREE_READONLY (decl) = 1;
|
||||||
if (ecf_flags & ECF_PURE)
|
if (ecf_flags & ECF_PURE)
|
||||||
DECL_IS_PURE (decl) = 1;
|
DECL_PURE_P (decl) = 1;
|
||||||
|
if (ecf_flags & ECF_LOOPING_CONST_OR_PURE)
|
||||||
|
DECL_LOOPING_CONST_OR_PURE_P (decl) = 1;
|
||||||
if (ecf_flags & ECF_NORETURN)
|
if (ecf_flags & ECF_NORETURN)
|
||||||
TREE_THIS_VOLATILE (decl) = 1;
|
TREE_THIS_VOLATILE (decl) = 1;
|
||||||
if (ecf_flags & ECF_NOTHROW)
|
if (ecf_flags & ECF_NOTHROW)
|
||||||
|
@ -7766,7 +7768,7 @@ process_call_operands (tree t)
|
||||||
/* Calls have side-effects, except those to const or
|
/* Calls have side-effects, except those to const or
|
||||||
pure functions. */
|
pure functions. */
|
||||||
i = call_expr_flags (t);
|
i = call_expr_flags (t);
|
||||||
if (!(i & (ECF_CONST | ECF_PURE)))
|
if ((i & ECF_LOOPING_CONST_OR_PURE) || !(i & (ECF_CONST | ECF_PURE)))
|
||||||
side_effects = 1;
|
side_effects = 1;
|
||||||
}
|
}
|
||||||
TREE_SIDE_EFFECTS (t) = side_effects;
|
TREE_SIDE_EFFECTS (t) = side_effects;
|
||||||
|
|
69
gcc/tree.h
69
gcc/tree.h
|
@ -788,7 +788,7 @@ enum tree_node_structure_enum {
|
||||||
&__t->phi.a[__i]; }))
|
&__t->phi.a[__i]; }))
|
||||||
|
|
||||||
#define OMP_CLAUSE_ELT_CHECK(T, I) __extension__ \
|
#define OMP_CLAUSE_ELT_CHECK(T, I) __extension__ \
|
||||||
(*({__typeof (T) const __t = (T); \
|
(*({__typeof (T) const __t = (T); \
|
||||||
const int __i = (I); \
|
const int __i = (I); \
|
||||||
if (TREE_CODE (__t) != OMP_CLAUSE) \
|
if (TREE_CODE (__t) != OMP_CLAUSE) \
|
||||||
tree_check_failed (__t, __FILE__, __LINE__, __FUNCTION__, \
|
tree_check_failed (__t, __FILE__, __LINE__, __FUNCTION__, \
|
||||||
|
@ -1281,13 +1281,11 @@ extern void omp_clause_range_check_failed (const_tree, const char *, int,
|
||||||
#define TREE_THIS_NOTRAP(NODE) ((NODE)->base.nothrow_flag)
|
#define TREE_THIS_NOTRAP(NODE) ((NODE)->base.nothrow_flag)
|
||||||
|
|
||||||
/* In a VAR_DECL, PARM_DECL or FIELD_DECL, or any kind of ..._REF node,
|
/* In a VAR_DECL, PARM_DECL or FIELD_DECL, or any kind of ..._REF node,
|
||||||
nonzero means it may not be the lhs of an assignment. */
|
nonzero means it may not be the lhs of an assignment.
|
||||||
|
Nonzero in a FUNCTION_DECL means this function should be treated
|
||||||
|
as "const" function (can only read its arguments). */
|
||||||
#define TREE_READONLY(NODE) (NON_TYPE_CHECK (NODE)->base.readonly_flag)
|
#define TREE_READONLY(NODE) (NON_TYPE_CHECK (NODE)->base.readonly_flag)
|
||||||
|
|
||||||
/* Nonzero if NODE is a _DECL with TREE_READONLY set. */
|
|
||||||
#define TREE_READONLY_DECL_P(NODE)\
|
|
||||||
(DECL_P (NODE) && TREE_READONLY (NODE))
|
|
||||||
|
|
||||||
/* Value of expression is constant. Always on in all ..._CST nodes. May
|
/* Value of expression is constant. Always on in all ..._CST nodes. May
|
||||||
also appear in an expression or decl where the value is constant. */
|
also appear in an expression or decl where the value is constant. */
|
||||||
#define TREE_CONSTANT(NODE) (NON_TYPE_CHECK (NODE)->base.constant_flag)
|
#define TREE_CONSTANT(NODE) (NON_TYPE_CHECK (NODE)->base.constant_flag)
|
||||||
|
@ -3256,7 +3254,16 @@ struct tree_decl_non_common GTY(())
|
||||||
|
|
||||||
/* Nonzero in a FUNCTION_DECL means this function should be treated
|
/* Nonzero in a FUNCTION_DECL means this function should be treated
|
||||||
as "pure" function (like const function, but may read global memory). */
|
as "pure" function (like const function, but may read global memory). */
|
||||||
#define DECL_IS_PURE(NODE) (FUNCTION_DECL_CHECK (NODE)->function_decl.pure_flag)
|
#define DECL_PURE_P(NODE) (FUNCTION_DECL_CHECK (NODE)->function_decl.pure_flag)
|
||||||
|
|
||||||
|
/* Nonzero only if one of TREE_READONLY or DECL_PURE_P is nonzero AND
|
||||||
|
the const or pure function may not terminate. When this is nonzero
|
||||||
|
for a const or pure function, it can be dealt with by cse passes
|
||||||
|
but cannot be removed by dce passes since you are not allowed to
|
||||||
|
change an infinite looping program into one that terminates without
|
||||||
|
error. */
|
||||||
|
#define DECL_LOOPING_CONST_OR_PURE_P(NODE) \
|
||||||
|
(FUNCTION_DECL_CHECK (NODE)->function_decl.looping_const_or_pure_flag)
|
||||||
|
|
||||||
/* Nonzero in a FUNCTION_DECL means this function should be treated
|
/* Nonzero in a FUNCTION_DECL means this function should be treated
|
||||||
as "novops" function (function that does not read global memory,
|
as "novops" function (function that does not read global memory,
|
||||||
|
@ -3354,7 +3361,6 @@ struct tree_function_decl GTY(())
|
||||||
unsigned returns_twice_flag : 1;
|
unsigned returns_twice_flag : 1;
|
||||||
unsigned malloc_flag : 1;
|
unsigned malloc_flag : 1;
|
||||||
unsigned operator_new_flag : 1;
|
unsigned operator_new_flag : 1;
|
||||||
unsigned pure_flag : 1;
|
|
||||||
unsigned declared_inline_flag : 1;
|
unsigned declared_inline_flag : 1;
|
||||||
unsigned regdecl_flag : 1;
|
unsigned regdecl_flag : 1;
|
||||||
|
|
||||||
|
@ -3362,8 +3368,11 @@ struct tree_function_decl GTY(())
|
||||||
unsigned no_instrument_function_entry_exit : 1;
|
unsigned no_instrument_function_entry_exit : 1;
|
||||||
unsigned no_limit_stack : 1;
|
unsigned no_limit_stack : 1;
|
||||||
unsigned disregard_inline_limits : 1;
|
unsigned disregard_inline_limits : 1;
|
||||||
|
unsigned pure_flag : 1;
|
||||||
|
unsigned looping_const_or_pure_flag : 1;
|
||||||
|
|
||||||
/* 4 bits left */
|
|
||||||
|
/* 3 bits left */
|
||||||
};
|
};
|
||||||
|
|
||||||
/* For a TYPE_DECL, holds the "original" type. (TREE_TYPE has the copy.) */
|
/* For a TYPE_DECL, holds the "original" type. (TREE_TYPE has the copy.) */
|
||||||
|
@ -4987,28 +4996,34 @@ extern tree build_duplicate_type (tree);
|
||||||
|
|
||||||
/* Nonzero if this is a call to a function whose return value depends
|
/* Nonzero if this is a call to a function whose return value depends
|
||||||
solely on its arguments, has no side effects, and does not read
|
solely on its arguments, has no side effects, and does not read
|
||||||
global memory. */
|
global memory. This corresponds to TREE_READONLY for function
|
||||||
#define ECF_CONST 1
|
decls. */
|
||||||
/* Nonzero if this call will never return. */
|
#define ECF_CONST (1 << 0)
|
||||||
#define ECF_NORETURN 2
|
|
||||||
/* Nonzero if this is a call to malloc or a related function. */
|
|
||||||
#define ECF_MALLOC 4
|
|
||||||
/* Nonzero if it is plausible that this is a call to alloca. */
|
|
||||||
#define ECF_MAY_BE_ALLOCA 8
|
|
||||||
/* Nonzero if this is a call to a function that won't throw an exception. */
|
|
||||||
#define ECF_NOTHROW 16
|
|
||||||
/* Nonzero if this is a call to setjmp or a related function. */
|
|
||||||
#define ECF_RETURNS_TWICE 32
|
|
||||||
/* Nonzero if this call replaces the current stack frame. */
|
|
||||||
#define ECF_SIBCALL 64
|
|
||||||
/* Nonzero if this is a call to "pure" function (like const function,
|
/* Nonzero if this is a call to "pure" function (like const function,
|
||||||
but may read memory. */
|
but may read memory. This corresponds to DECL_PURE_P for function
|
||||||
#define ECF_PURE 128
|
decls. */
|
||||||
|
#define ECF_PURE (1 << 1)
|
||||||
|
/* Nonzero if this is ECF_CONST or ECF_PURE but cannot be proven to no
|
||||||
|
infinite loop. This corresponds to DECL_LOOPING_CONST_OR_PURE_P
|
||||||
|
for function decls.*/
|
||||||
|
#define ECF_LOOPING_CONST_OR_PURE (1 << 2)
|
||||||
|
/* Nonzero if this call will never return. */
|
||||||
|
#define ECF_NORETURN (1 << 3)
|
||||||
|
/* Nonzero if this is a call to malloc or a related function. */
|
||||||
|
#define ECF_MALLOC (1 << 4)
|
||||||
|
/* Nonzero if it is plausible that this is a call to alloca. */
|
||||||
|
#define ECF_MAY_BE_ALLOCA (1 << 5)
|
||||||
|
/* Nonzero if this is a call to a function that won't throw an exception. */
|
||||||
|
#define ECF_NOTHROW (1 << 6)
|
||||||
|
/* Nonzero if this is a call to setjmp or a related function. */
|
||||||
|
#define ECF_RETURNS_TWICE (1 << 7)
|
||||||
|
/* Nonzero if this call replaces the current stack frame. */
|
||||||
|
#define ECF_SIBCALL (1 << 8)
|
||||||
/* Create libcall block around the call. */
|
/* Create libcall block around the call. */
|
||||||
#define ECF_LIBCALL_BLOCK 256
|
#define ECF_LIBCALL_BLOCK (1 << 9)
|
||||||
/* Function does not read or write memory (but may have side effects, so
|
/* Function does not read or write memory (but may have side effects, so
|
||||||
it does not necessarily fit ECF_CONST). */
|
it does not necessarily fit ECF_CONST). */
|
||||||
#define ECF_NOVOPS 512
|
#define ECF_NOVOPS (1 << 10)
|
||||||
|
|
||||||
extern int flags_from_decl_or_type (const_tree);
|
extern int flags_from_decl_or_type (const_tree);
|
||||||
extern int call_expr_flags (const_tree);
|
extern int call_expr_flags (const_tree);
|
||||||
|
|
Loading…
Reference in New Issue