summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authoramodra <amodra@138bc75d-0d04-0410-961f-82ee72b054a4>2002-04-10 03:50:39 +0000
committeramodra <amodra@138bc75d-0d04-0410-961f-82ee72b054a4>2002-04-10 03:50:39 +0000
commitef15379a9f713ff182ad985f5b8dd173c6e3a7fb (patch)
tree8f57737d03a2fc651bab26e059ff589511d75dfa
parenta87d8cb5071e60e984ed60e995fd0f025ca996a5 (diff)
downloadgcc-ef15379a9f713ff182ad985f5b8dd173c6e3a7fb.tar.gz
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. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@52110 138bc75d-0d04-0410-961f-82ee72b054a4
-rw-r--r--gcc/ChangeLog8
-rw-r--r--gcc/gcse.c16
-rw-r--r--gcc/loop.c2
-rw-r--r--gcc/rtl.h1
-rw-r--r--gcc/rtlanal.c25
5 files changed, 37 insertions, 15 deletions
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 <amodra@bigpond.net.au>
+
+ 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 <echristo@redhat.com>
* 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. */