diff --git a/gcc/ChangeLog b/gcc/ChangeLog index fb618b47dfb..1def463bd49 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,11 @@ +2002-04-10 Alan Modra + + PR optimization/6233 + * rtlanal.c (pure_call_p): New function. + * rtl.h (pure_call_p): Declare. + * loop.c (prescan_loop): Use it to set has_nonconst_call. + * gcse.c (store_killed_in_insn): Use pure_call_p here too. + 2002-04-09 Eric Christopher * config/mips/mips.h (ASM_OUTPUT_ALIGNED_DECL_COMMON): Add additional diff --git a/gcc/gcse.c b/gcc/gcse.c index 7a49ffc8955..ba83712e249 100644 --- a/gcc/gcse.c +++ b/gcc/gcse.c @@ -6528,21 +6528,7 @@ store_killed_in_insn (x, insn) { /* A normal or pure call might read from pattern, but a const call will not. */ - if (CONST_OR_PURE_CALL_P (insn)) - { - rtx link; - - for (link = CALL_INSN_FUNCTION_USAGE (insn); - link; - link = XEXP (link, 1)) - if (GET_CODE (XEXP (link, 0)) == USE - && GET_CODE (XEXP (XEXP (link, 0), 0)) == MEM - && GET_CODE (XEXP (XEXP (XEXP (link, 0), 0), 0)) == SCRATCH) - return 1; - return 0; - } - else - return 1; + return ! CONST_OR_PURE_CALL_P (insn) || pure_call_p (insn); } if (GET_CODE (PATTERN (insn)) == SET) diff --git a/gcc/loop.c b/gcc/loop.c index 53b9caa3aa0..468dc20951d 100644 --- a/gcc/loop.c +++ b/gcc/loop.c @@ -2494,6 +2494,8 @@ prescan_loop (loop) loop_info->unknown_address_altered = 1; loop_info->has_nonconst_call = 1; } + else if (pure_call_p (insn)) + loop_info->has_nonconst_call = 1; loop_info->has_call = 1; if (can_throw_internal (insn)) loop_info->has_multiple_exit_targets = 1; diff --git a/gcc/rtl.h b/gcc/rtl.h index d795a4a64b9..7f62b91ef69 100644 --- a/gcc/rtl.h +++ b/gcc/rtl.h @@ -1502,6 +1502,7 @@ extern rtx find_reg_equal_equiv_note PARAMS ((rtx)); extern int find_reg_fusage PARAMS ((rtx, enum rtx_code, rtx)); extern int find_regno_fusage PARAMS ((rtx, enum rtx_code, unsigned int)); +extern int pure_call_p PARAMS ((rtx)); extern void remove_note PARAMS ((rtx, rtx)); extern int side_effects_p PARAMS ((rtx)); extern int volatile_refs_p PARAMS ((rtx)); diff --git a/gcc/rtlanal.c b/gcc/rtlanal.c index 9348fd01d11..07cb6d8d6a7 100644 --- a/gcc/rtlanal.c +++ b/gcc/rtlanal.c @@ -2011,6 +2011,31 @@ find_regno_fusage (insn, code, regno) return 0; } + +/* Return true if INSN is a call to a pure function. */ + +int +pure_call_p (insn) + rtx insn; +{ + rtx link; + + if (GET_CODE (insn) != CALL_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 + && GET_CODE (m = XEXP (u, 0)) == MEM && GET_MODE (m) == BLKmode + && GET_CODE (XEXP (m, 0)) == SCRATCH) + return 1; + } + + return 0; +} /* Remove register note NOTE from the REG_NOTES of INSN. */