aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorDale Johannesen <dalej@apple.com>2002-08-14 17:41:52 +0000
committerDale Johannesen <dalej@gcc.gnu.org>2002-08-14 17:41:52 +0000
commit260f91c2927c3850919f8ebdcbc294cfbd04daa9 (patch)
treeb89a47d1833a43c5e6808e162a723c626e81adbb /gcc
parent615d009f6d673f288348c4394d36da2fb0dbbcc8 (diff)
downloadgcc-260f91c2927c3850919f8ebdcbc294cfbd04daa9.zip
gcc-260f91c2927c3850919f8ebdcbc294cfbd04daa9.tar.gz
gcc-260f91c2927c3850919f8ebdcbc294cfbd04daa9.tar.bz2
Insert memory clobbers before the code that pops variable arrays.
This prevents the scheduler from moving references to the arrays below the stack pop. From-SVN: r56328
Diffstat (limited to 'gcc')
-rw-r--r--gcc/ChangeLog8
-rw-r--r--gcc/doc/rtl.texi3
-rw-r--r--gcc/explow.c12
-rw-r--r--gcc/reload1.c10
4 files changed, 28 insertions, 5 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 270fc37..bb6158e 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,11 @@
+2002-08-14 Dale Johannesen <dalej@apple.com>
+
+ * explow.c (emit_stack_restore): Emit memory clobbers
+ preceding the stack pop, to prevent the scheduler from
+ moving refs to variable arrays below this pop.
+ * reload1.c (reload): Preserve these clobbers for sched2.
+ * doc/rtl.texi: Document clobber (mem:BLK (scratch)).
+
2002-08-14 Neil Booth <neil@daikokuya.co.uk>
* c-opts.c (c_common_post_options): Correct test.
diff --git a/gcc/doc/rtl.texi b/gcc/doc/rtl.texi
index 4276374..8db2e9c 100644
--- a/gcc/doc/rtl.texi
+++ b/gcc/doc/rtl.texi
@@ -2294,7 +2294,8 @@ trouble to describe the values that are stored, but it is essential to
inform the compiler that the registers will be altered, lest it
attempt to keep data in them across the string instruction.
-If @var{x} is @code{(mem:BLK (const_int 0))}, it means that all memory
+If @var{x} is @code{(mem:BLK (const_int 0))} or
+@code{(mem:BLK (scratch))}, it means that all memory
locations must be presumed clobbered. If @var{x} is a @code{parallel},
it has the same meaning as a @code{parallel} in a @code{set} expression.
diff --git a/gcc/explow.c b/gcc/explow.c
index 1d27640..f61d009 100644
--- a/gcc/explow.c
+++ b/gcc/explow.c
@@ -1079,7 +1079,17 @@ emit_stack_restore (save_level, sa, after)
}
if (sa != 0)
- sa = validize_mem (sa);
+ {
+ sa = validize_mem (sa);
+ /* These clobbers prevent the scheduler from moving
+ references to variable arrays below the code
+ that deletes (pops) the arrays. */
+ emit_insn (gen_rtx_CLOBBER (VOIDmode,
+ gen_rtx_MEM (BLKmode,
+ gen_rtx_SCRATCH (VOIDmode))));
+ emit_insn (gen_rtx_CLOBBER (VOIDmode,
+ gen_rtx_MEM (BLKmode, stack_pointer_rtx)));
+ }
if (after)
{
diff --git a/gcc/reload1.c b/gcc/reload1.c
index 58b0bd04..c00426c 100644
--- a/gcc/reload1.c
+++ b/gcc/reload1.c
@@ -1181,9 +1181,11 @@ reload (first, global)
/* Make a pass over all the insns and delete all USEs which we inserted
only to tag a REG_EQUAL note on them. Remove all REG_DEAD and REG_UNUSED
notes. Delete all CLOBBER insns that don't refer to the return value
- and simplify (subreg (reg)) operands. Also remove all REG_RETVAL and
- REG_LIBCALL notes since they are no longer useful or accurate. Strip
- and regenerate REG_INC notes that may have been moved around. */
+ or to memory (mem:BLK CLOBBERs must be retained to prevent the scheduler
+ from misarranging variable-array code) and simplify (subreg (reg))
+ operands. Also remove all REG_RETVAL and REG_LIBCALL notes since they
+ are no longer useful or accurate. Strip and regenerate REG_INC notes
+ that may have been moved around. */
for (insn = first; insn; insn = NEXT_INSN (insn))
if (INSN_P (insn))
@@ -1200,6 +1202,8 @@ reload (first, global)
&& (GET_MODE (insn) == QImode
|| find_reg_note (insn, REG_EQUAL, NULL_RTX)))
|| (GET_CODE (PATTERN (insn)) == CLOBBER
+ && (GET_CODE (XEXP (PATTERN (insn), 0)) != MEM
+ || GET_MODE (XEXP (PATTERN (insn), 0)) != BLKmode)
&& (GET_CODE (XEXP (PATTERN (insn), 0)) != REG
|| ! REG_FUNCTION_VALUE_P (XEXP (PATTERN (insn), 0)))))
{