summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--gcc/ChangeLog7
-rw-r--r--gcc/flow.c16
-rw-r--r--gcc/rtl.texi17
-rw-r--r--gcc/rtlanal.c42
-rw-r--r--gcc/sched-deps.c15
-rw-r--r--gcc/sched-rgn.c24
6 files changed, 53 insertions, 68 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 6b5271f5195..10023e080b6 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,5 +1,12 @@
Fri Jan 19 13:02:56 2001 Richard Kenner <kenner@vlsi1.ultra.nyu.edu>
+ * rtl.texi (SET, CLOBBER): Document PARALLEL as SET_DEST possibility.
+ * flow.c (mark_set_1, case PARALLEL): Don't require BLKmode, allow
+ element to be null, and always expect an EXPR_LIST.
+ * rtlanal.c (reg_overlap_mentioned_p, note_stores): Likewise.
+ * sched-deps.c (sched_analyze_1): Likewise.
+ * sched-rgn.c (check_live_1, update_live_1): Likewise.
+
* regclass.c (max_set_parallel): New variable.
(reg_scan): Take it into account in computation of max_parallel.
(reg_scan_mark_refs, case SET): Compute it.
diff --git a/gcc/flow.c b/gcc/flow.c
index aa37d05de56..2e76e3d398f 100644
--- a/gcc/flow.c
+++ b/gcc/flow.c
@@ -4660,19 +4660,11 @@ mark_set_1 (pbi, code, reg, cond, insn, flags)
case PARALLEL:
/* Some targets place small structures in registers for return values of
functions. We have to detect this case specially here to get correct
- flow information. Note that each element might be either a REG
- or an EXPR_LIST whose first operand is a REG. */
- if (GET_MODE (reg) != BLKmode)
- abort ();
-
+ flow information. */
for (i = XVECLEN (reg, 0) - 1; i >= 0; i--)
- {
- rtx elmt = XVECEXP (reg, 0, i);
-
- mark_set_1 (pbi, code,
- GET_CODE (elmt) == EXPR_LIST ? XEXP (elmt, 0) : elmt,
- cond, insn, flags);
- }
+ if (XEXP (XVECEXP (reg, 0, i), 0) != 0)
+ mark_set_1 (pbi, code, XEXP (XVECEXP (reg, 0, i), 0), cond, insn,
+ flags);
return;
case ZERO_EXTRACT:
diff --git a/gcc/rtl.texi b/gcc/rtl.texi
index 0e9d8c48652..4cb0eb7014b 100644
--- a/gcc/rtl.texi
+++ b/gcc/rtl.texi
@@ -1923,8 +1923,8 @@ the operands of these.
@item (set @var{lval} @var{x})
Represents the action of storing the value of @var{x} into the place
represented by @var{lval}. @var{lval} must be an expression
-representing a place that can be stored in: @code{reg} (or
-@code{subreg} or @code{strict_low_part}), @code{mem}, @code{pc} or
+representing a place that can be stored in: @code{reg} (or @code{subreg}
+or @code{strict_low_part}), @code{mem}, @code{pc}, @code{parallel}, or
@code{cc0}.@refill
If @var{lval} is a @code{reg}, @code{subreg} or @code{mem}, it has a
@@ -1950,6 +1950,14 @@ The latter case represents a ``test'' instruction. The expression
@code{(set (cc0) (compare (reg:@var{m} @var{n}) (const_int 0)))}.
Use the former expression to save space during the compilation.
+If @var{lval} is a @code{parallel}, it is used to represent the case of
+a function returning a structure in multiple registers. Each element
+of the @code{paralllel} is an @code{expr_list} whose first operand is a
+@code{reg} and whose second operand is a @code{const_int} representing the
+offset (in bytes) into the structure at which the data in that register
+corresponds. The first element may be null to indicate that the structure
+is also passed partly in memory.
+
@cindex jump instructions and @code{set}
@cindex @code{if_then_else} usage
If @var{lval} is @code{(pc)}, we have a jump instruction, and the
@@ -2006,7 +2014,7 @@ addressed.
@item (clobber @var{x})
Represents the storing or possible storing of an unpredictable,
undescribed value into @var{x}, which must be a @code{reg},
-@code{scratch} or @code{mem} expression.
+@code{scratch}, @code{parallel} or @code{mem} expression.
One place this is used is in string instructions that store standard
values into particular hard registers. It may not be worth the
@@ -2015,7 +2023,8 @@ 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
-locations must be presumed clobbered.
+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.
Note that the machine description classifies certain hard registers as
``call-clobbered''. All function call instructions are assumed by
diff --git a/gcc/rtlanal.c b/gcc/rtlanal.c
index a869bb7565f..ff75d5c5832 100644
--- a/gcc/rtlanal.c
+++ b/gcc/rtlanal.c
@@ -1185,18 +1185,11 @@ reg_overlap_mentioned_p (x, in)
int i;
/* If any register in here refers to it we return true. */
- for (i = XVECLEN (x, 0); i >= 0; i--)
- {
- rtx reg = XVECEXP (x, 0, i);
-
- if (GET_CODE (reg) == EXPR_LIST)
- reg = XEXP (reg, 0);
-
- if (reg_overlap_mentioned_p (reg, in))
+ for (i = XVECLEN (x, 0) - 1; i >= 0; i--)
+ if (XEXP (XVECEXP (x, 0, i), 0) != 0
+ && reg_overlap_mentioned_p (XEXP (XVECEXP (x, 0, i), 0), in))
return 1;
- return 0;
-
- }
+ return 0;
}
default:
@@ -1288,20 +1281,19 @@ note_stores (x, fun, data)
|| GET_CODE (dest) == STRICT_LOW_PART)
dest = XEXP (dest, 0);
- /* If we have a PARALLEL, SET_DEST is a list of registers or
- EXPR_LIST expressions, each of whose first operand is a register.
- We can't know what precisely is being set in these cases, so
- make up a CLOBBER to pass to the function. */
- if (GET_CODE (dest) == PARALLEL && GET_MODE (dest) == BLKmode)
- for (i = XVECLEN (dest, 0) - 1; i >= 0; i--)
- {
- rtx reg = XVECEXP (dest, 0, i);
-
- if (GET_CODE (reg) == EXPR_LIST)
- reg = XEXP (reg, 0);
-
- (*fun) (reg, gen_rtx_CLOBBER (VOIDmode, reg), data);
- }
+ /* If we have a PARALLEL, SET_DEST is a list of EXPR_LIST expressions,
+ each of whose first operand is a register. We can't know what
+ precisely is being set in these cases, so make up a CLOBBER to pass
+ to the function. */
+ if (GET_CODE (dest) == PARALLEL)
+ {
+ for (i = XVECLEN (dest, 0) - 1; i >= 0; i--)
+ if (XEXP (XVECEXP (dest, 0, i), 0) != 0)
+ (*fun) (XEXP (XVECEXP (dest, 0, i), 0),
+ gen_rtx_CLOBBER (VOIDmode,
+ XEXP (XVECEXP (dest, 0, i), 0)),
+ data);
+ }
else
(*fun) (dest, x, data);
}
diff --git a/gcc/sched-deps.c b/gcc/sched-deps.c
index 9b566a0ec26..904b37e1d4c 100644
--- a/gcc/sched-deps.c
+++ b/gcc/sched-deps.c
@@ -551,19 +551,16 @@ sched_analyze_1 (deps, x, insn)
if (dest == 0)
return;
- if (GET_CODE (dest) == PARALLEL && GET_MODE (dest) == BLKmode)
+ if (GET_CODE (dest) == PARALLEL)
{
register int i;
for (i = XVECLEN (dest, 0) - 1; i >= 0; i--)
- {
- rtx reg = XVECEXP (dest, 0, i);
-
- if (GET_CODE (reg) == EXPR_LIST)
- reg = XEXP (reg, 0);
-
- sched_analyze_1 (deps, reg, insn);
- }
+ if (XEXP (XVECEXP (dest, 0, i), 0) != 0)
+ sched_analyze_1 (deps,
+ gen_rtx_CLOBBER (VOIDmode,
+ XEXP (XVECEXP (dest, 0, i), 0)),
+ insn);
if (GET_CODE (x) == SET)
sched_analyze_2 (deps, SET_SRC (x), insn);
diff --git a/gcc/sched-rgn.c b/gcc/sched-rgn.c
index 71c4018bb1c..41989cc0cd6 100644
--- a/gcc/sched-rgn.c
+++ b/gcc/sched-rgn.c
@@ -1396,20 +1396,14 @@ check_live_1 (src, x)
|| GET_CODE (reg) == STRICT_LOW_PART)
reg = XEXP (reg, 0);
- if (GET_CODE (reg) == PARALLEL && GET_MODE (reg) == BLKmode)
+ if (GET_CODE (reg) == PARALLEL)
{
register int i;
for (i = XVECLEN (reg, 0) - 1; i >= 0; i--)
- {
- rtx dest = XVECEXP (reg, 0, i);
-
- if (GET_CODE (dest) == EXPR_LIST)
- dest = XEXP (dest, 0);
-
- if (check_live_1 (src, dest))
+ if (XEXP (XVECEXP (reg, 0, i), 0) != 0)
+ if (check_live_1 (src, XEXP (XVECEXP (reg, 0, i), 0)))
return 1;
- }
return 0;
}
@@ -1482,19 +1476,13 @@ update_live_1 (src, x)
|| GET_CODE (reg) == STRICT_LOW_PART)
reg = XEXP (reg, 0);
- if (GET_CODE (reg) == PARALLEL && GET_MODE (reg) == BLKmode)
+ if (GET_CODE (reg) == PARALLEL)
{
register int i;
for (i = XVECLEN (reg, 0) - 1; i >= 0; i--)
- {
- rtx dest = XVECEXP (reg, 0, i);
-
- if (GET_CODE (dest) == EXPR_LIST)
- dest = XEXP (dest, 0);
-
- update_live_1 (src, dest);
- }
+ if (XEXP (XVECEXP (reg, 0, i), 0) != 0)
+ update_live_1 (src, XEXP (XVECEXP (reg, 0, i), 0));
return;
}