aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJeffrey A Law <law@cygnus.com>1999-03-27 15:18:32 +0000
committerJeff Law <law@gcc.gnu.org>1999-03-27 08:18:32 -0700
commit40b5a77c50dbc2531211bf1c4fa295ad2fc44aa8 (patch)
tree7109b9204485f607af3c8cd91b3218257dea101f
parent26f096f9e545b3f951ab850f06fad454613b0e43 (diff)
downloadgcc-40b5a77c50dbc2531211bf1c4fa295ad2fc44aa8.zip
gcc-40b5a77c50dbc2531211bf1c4fa295ad2fc44aa8.tar.gz
gcc-40b5a77c50dbc2531211bf1c4fa295ad2fc44aa8.tar.bz2
* flow.c (mark_used_regs): Improve handling of ASMs.
From-SVN: r26014
-rw-r--r--gcc/ChangeLog4
-rw-r--r--gcc/flow.c46
2 files changed, 48 insertions, 2 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 0a7843b..a7e32fa 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,7 @@
+Sat Mar 27 16:13:50 1999 Jeffrey A Law (law@cygnus.com)
+
+ * flow.c (mark_used_regs): Improve handling of ASMs.
+
1999-03-26 Zack Weinberg <zack@rabi.columbia.edu>
* Makefile.in (xcpp, cppspec.o): New targets.
diff --git a/gcc/flow.c b/gcc/flow.c
index f60daa4..3c3c090 100644
--- a/gcc/flow.c
+++ b/gcc/flow.c
@@ -242,7 +242,12 @@ static int loop_depth;
static int cc0_live;
/* During propagate_block, this contains a list of all the MEMs we are
- tracking for dead store elimination. */
+ tracking for dead store elimination.
+
+ ?!? Note we leak memory by not free-ing items on this list. We need to
+ write some generic routines to operate on memory lists since cse, gcse,
+ loop, sched, flow and possibly other passes all need to do basically the
+ same operations on these lists. */
static rtx mem_set_list;
@@ -3593,7 +3598,6 @@ mark_used_regs (needed, live, x, final, insn)
case PC:
case ADDR_VEC:
case ADDR_DIFF_VEC:
- case ASM_INPUT:
return;
#ifdef HAVE_cc0
@@ -3908,6 +3912,44 @@ mark_used_regs (needed, live, x, final, insn)
SET_REGNO_REG_SET (live, i);
break;
+ case ASM_OPERANDS:
+ case UNSPEC_VOLATILE:
+ case TRAP_IF:
+ case ASM_INPUT:
+ {
+ /* Traditional and volatile asm instructions must be considered to use
+ and clobber all hard registers, all pseudo-registers and all of
+ memory. So must TRAP_IF and UNSPEC_VOLATILE operations.
+
+ Consider for instance a volatile asm that changes the fpu rounding
+ mode. An insn should not be moved across this even if it only uses
+ pseudo-regs because it might give an incorrectly rounded result.
+
+ ?!? Unfortunately, marking all hard registers as live causes massive
+ problems for the register allocator and marking all pseudos as live
+ creates mountains of uninitialized variable warnings.
+
+ So for now, just clear the memory set list and mark any regs
+ we can find in ASM_OPERANDS as used. */
+ if (code != ASM_OPERANDS || MEM_VOLATILE_P (x))
+ mem_set_list = NULL_RTX;
+
+ /* For all ASM_OPERANDS, we must traverse the vector of input operands.
+ We can not just fall through here since then we would be confused
+ by the ASM_INPUT rtx inside ASM_OPERANDS, which do not indicate
+ traditional asms unlike their normal usage. */
+ if (code == ASM_OPERANDS)
+ {
+ int j;
+
+ for (j = 0; j < ASM_OPERANDS_INPUT_LENGTH (x); j++)
+ mark_used_regs (needed, live, ASM_OPERANDS_INPUT (x, j),
+ final, insn);
+ }
+ break;
+ }
+
+
default:
break;
}