rtl.texi (SET, CLOBBER): Document PARALLEL as SET_DEST possibility.
* 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
This commit is contained in:
parent
79b9ec0ddb
commit
7193d1dc3d
@ -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.
|
||||
|
16
gcc/flow.c
16
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:
|
||||
|
17
gcc/rtl.texi
17
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
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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);
|
||||
|
@ -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;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user