* 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.
From-SVN: r39141
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.
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:
@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
@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
@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
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
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:
|| 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);
}
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);
|| 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;
}
|| 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;
}