mirror of
git://gcc.gnu.org/git/gcc.git
synced 2025-02-20 15:09:45 +08:00
calls.c (emit_library_call_value_1): Add USEs and CLOBBERs to function usage for arguments passed by reference.
* calls.c (emit_library_call_value_1): Add USEs and CLOBBERs to function usage for arguments passed by reference. Optimize callee-copied arguments. * regmove.c (find_related_toplev): Find uses in function usage. (replace_in_call_usage): New function. (fixup_match_1): Call it. * cse.c (cse_insn): Canonicalize registers in function usage. * reload1.c (replace_pseudos_in_call_usage): New function. (reload): Call it. From-SVN: r38964
This commit is contained in:
parent
7dd232a882
commit
f474c6f8f9
@ -1,5 +1,15 @@
|
||||
2001-01-12 Alexandre Oliva <aoliva@redhat.com>
|
||||
|
||||
* calls.c (emit_library_call_value_1): Add USEs and CLOBBERs
|
||||
to function usage for arguments passed by reference. Optimize
|
||||
callee-copied arguments.
|
||||
* regmove.c (find_related_toplev): Find uses in function usage.
|
||||
(replace_in_call_usage): New function.
|
||||
(fixup_match_1): Call it.
|
||||
* cse.c (cse_insn): Canonicalize registers in function usage.
|
||||
* reload1.c (replace_pseudos_in_call_usage): New function.
|
||||
(reload): Call it.
|
||||
|
||||
* Makefile.in: Reverted yesterday's wrong patch. Installed the
|
||||
right version.
|
||||
|
||||
|
38
gcc/calls.c
38
gcc/calls.c
@ -3676,16 +3676,44 @@ emit_library_call_value_1 (retval, orgfun, value, fn_type, outmode, nargs, p)
|
||||
#ifdef FUNCTION_ARG_PASS_BY_REFERENCE
|
||||
if (FUNCTION_ARG_PASS_BY_REFERENCE (args_so_far, mode, NULL_TREE, 1))
|
||||
{
|
||||
/* We do not support FUNCTION_ARG_CALLEE_COPIES here since it can
|
||||
be viewed as just an efficiency improvement. */
|
||||
rtx slot = assign_temp (type_for_mode (mode, 0), 0, 1, 1);
|
||||
rtx slot;
|
||||
int must_copy = 1
|
||||
#ifdef FUNCTION_ARG_CALLEE_COPIES
|
||||
&& ! FUNCTION_ARG_CALLEE_COPIES (args_so_far, mode,
|
||||
NULL_TREE, 1)
|
||||
#endif
|
||||
;
|
||||
|
||||
if (GET_MODE (val) == MEM && ! must_copy)
|
||||
slot = val;
|
||||
else if (must_copy)
|
||||
{
|
||||
slot = assign_temp (type_for_mode (mode, 0), 0, 1, 1);
|
||||
emit_move_insn (slot, val);
|
||||
}
|
||||
else
|
||||
{
|
||||
tree type = type_for_mode (mode, 0);
|
||||
|
||||
slot = gen_rtx_MEM (Pmode,
|
||||
expand_expr (build1 (ADDR_EXPR,
|
||||
build_pointer_type
|
||||
(type),
|
||||
make_tree (type, val)),
|
||||
NULL_RTX, VOIDmode, 0));
|
||||
}
|
||||
|
||||
call_fusage = gen_rtx_EXPR_LIST (VOIDmode,
|
||||
gen_rtx_USE (VOIDmode, slot),
|
||||
call_fusage);
|
||||
emit_move_insn (slot, val);
|
||||
val = force_operand (XEXP (slot, 0), NULL_RTX);
|
||||
if (must_copy)
|
||||
call_fusage = gen_rtx_EXPR_LIST (VOIDmode,
|
||||
gen_rtx_CLOBBER (VOIDmode,
|
||||
slot),
|
||||
call_fusage);
|
||||
|
||||
mode = Pmode;
|
||||
val = force_operand (XEXP (slot, 0), NULL_RTX);
|
||||
}
|
||||
#endif
|
||||
|
||||
|
@ -1,6 +1,6 @@
|
||||
/* Common subexpression elimination for GNU compiler.
|
||||
Copyright (C) 1987, 1988, 1989, 1992, 1993, 1994, 1995, 1996, 1997, 1998
|
||||
1999, 2000 Free Software Foundation, Inc.
|
||||
1999, 2000, 2001 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of GNU CC.
|
||||
|
||||
@ -4754,8 +4754,11 @@ cse_insn (insn, libcall_insn)
|
||||
if (GET_CODE (insn) == CALL_INSN)
|
||||
{
|
||||
for (tem = CALL_INSN_FUNCTION_USAGE (insn); tem; tem = XEXP (tem, 1))
|
||||
if (GET_CODE (XEXP (tem, 0)) == CLOBBER)
|
||||
invalidate (SET_DEST (XEXP (tem, 0)), VOIDmode);
|
||||
{
|
||||
if (GET_CODE (XEXP (tem, 0)) == CLOBBER)
|
||||
invalidate (SET_DEST (XEXP (tem, 0)), VOIDmode);
|
||||
XEXP (tem, 0) = canon_reg (XEXP (tem, 0), insn);
|
||||
}
|
||||
}
|
||||
|
||||
if (GET_CODE (x) == SET)
|
||||
|
@ -1,6 +1,6 @@
|
||||
/* Move registers around to reduce number of move instructions needed.
|
||||
Copyright (C) 1987, 1988, 1989, 1992, 1993, 1994, 1995, 1996, 1997, 1998,
|
||||
1999, 2000 Free Software Foundation, Inc.
|
||||
1999, 2000, 2001 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of GNU CC.
|
||||
|
||||
@ -1505,6 +1505,17 @@ find_matches (insn, matchp)
|
||||
int op_no;
|
||||
int any_matches = 0;
|
||||
|
||||
if (GET_CODE (insn) == CALL_INSN
|
||||
&& CALL_INSN_FUNCTION_USAGE (insn))
|
||||
{
|
||||
rtx usage;
|
||||
|
||||
for (usage = CALL_INSN_FUNCTION_USAGE (insn);
|
||||
usage;
|
||||
usage = XEXP (usage, 1))
|
||||
find_related (&XEXP (usage, 0), insn, luid, call_tally);
|
||||
}
|
||||
|
||||
extract_insn (insn);
|
||||
if (! constrain_operands (0))
|
||||
return 0;
|
||||
@ -1571,6 +1582,45 @@ find_matches (insn, matchp)
|
||||
return any_matches;
|
||||
}
|
||||
|
||||
/* Try to replace all occurrences of DST_REG with SRC in LOC, that is
|
||||
assumed to be in INSN. */
|
||||
|
||||
static void
|
||||
replace_in_call_usage (loc, dst_reg, src, insn)
|
||||
rtx *loc;
|
||||
int dst_reg;
|
||||
rtx src;
|
||||
rtx insn;
|
||||
{
|
||||
rtx x = *loc;
|
||||
enum rtx_code code;
|
||||
const char *fmt;
|
||||
int i, j;
|
||||
|
||||
if (! x)
|
||||
return;
|
||||
|
||||
code = GET_CODE (x);
|
||||
if (code == REG)
|
||||
{
|
||||
if (REGNO (x) != dst_reg)
|
||||
return;
|
||||
|
||||
validate_change (insn, loc, src, 1);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
/* Process each of our operands recursively. */
|
||||
fmt = GET_RTX_FORMAT (code);
|
||||
for (i = 0; i < GET_RTX_LENGTH (code); i++, fmt++)
|
||||
if (*fmt == 'e')
|
||||
replace_in_call_usage (&XEXP (x, i), dst_reg, src, insn);
|
||||
else if (*fmt == 'E')
|
||||
for (j = 0; j < XVECLEN (x, i); j++)
|
||||
replace_in_call_usage (& XVECEXP (x, i, j), dst_reg, src, insn);
|
||||
}
|
||||
|
||||
/* Try to replace output operand DST in SET, with input operand SRC. SET is
|
||||
the only set in INSN. INSN has just been recognized and constrained.
|
||||
SRC is operand number OPERAND_NUMBER in INSN.
|
||||
@ -1643,6 +1693,10 @@ fixup_match_1 (insn, set, src, src_subreg, dst, backward, operand_number,
|
||||
|
||||
for (length = s_length = 0, p = NEXT_INSN (insn); p; p = NEXT_INSN (p))
|
||||
{
|
||||
if (GET_CODE (p) == CALL_INSN)
|
||||
replace_in_call_usage (& CALL_INSN_FUNCTION_USAGE (p),
|
||||
REGNO (dst), src, p);
|
||||
|
||||
/* ??? We can't scan past the end of a basic block without updating
|
||||
the register lifetime info (REG_DEAD/basic_block_live_at_start). */
|
||||
if (perhaps_ends_bb_p (p))
|
||||
|
@ -577,6 +577,63 @@ compute_use_by_pseudos (to, from)
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/* Replace all pseudos found in LOC with their corresponding
|
||||
equivalences. */
|
||||
|
||||
static void
|
||||
replace_pseudos_in_call_usage (loc, mem_mode, usage)
|
||||
rtx *loc;
|
||||
enum machine_mode mem_mode;
|
||||
rtx usage;
|
||||
{
|
||||
rtx x = *loc;
|
||||
enum rtx_code code;
|
||||
const char *fmt;
|
||||
int i, j;
|
||||
|
||||
if (! x)
|
||||
return;
|
||||
|
||||
code = GET_CODE (x);
|
||||
if (code == REG)
|
||||
{
|
||||
if (REGNO (x) < FIRST_PSEUDO_REGISTER)
|
||||
return;
|
||||
|
||||
x = eliminate_regs (x, mem_mode, usage);
|
||||
if (x != *loc)
|
||||
{
|
||||
*loc = x;
|
||||
replace_pseudos_in_call_usage (loc, mem_mode, usage);
|
||||
return;
|
||||
}
|
||||
|
||||
if (reg_renumber [REGNO (x)] < 0)
|
||||
*loc = regno_reg_rtx[REGNO (x)];
|
||||
else if (reg_equiv_mem[REGNO (x)])
|
||||
*loc = reg_equiv_mem[REGNO (x)];
|
||||
else
|
||||
abort ();
|
||||
|
||||
return;
|
||||
}
|
||||
else if (code == MEM)
|
||||
{
|
||||
replace_pseudos_in_call_usage (& XEXP (x, 0), GET_MODE (x), usage);
|
||||
return;
|
||||
}
|
||||
|
||||
/* Process each of our operands recursively. */
|
||||
fmt = GET_RTX_FORMAT (code);
|
||||
for (i = 0; i < GET_RTX_LENGTH (code); i++, fmt++)
|
||||
if (*fmt == 'e')
|
||||
replace_pseudos_in_call_usage (&XEXP (x, i), mem_mode, usage);
|
||||
else if (*fmt == 'E')
|
||||
for (j = 0; j < XVECLEN (x, i); j++)
|
||||
replace_pseudos_in_call_usage (& XVECEXP (x, i, j), mem_mode, usage);
|
||||
}
|
||||
|
||||
|
||||
/* Global variables used by reload and its subroutines. */
|
||||
|
||||
@ -1114,6 +1171,11 @@ reload (first, global)
|
||||
{
|
||||
rtx *pnote;
|
||||
|
||||
if (GET_CODE (insn) == CALL_INSN)
|
||||
replace_pseudos_in_call_usage (& CALL_INSN_FUNCTION_USAGE (insn),
|
||||
VOIDmode,
|
||||
CALL_INSN_FUNCTION_USAGE (insn));
|
||||
|
||||
if ((GET_CODE (PATTERN (insn)) == USE
|
||||
&& find_reg_note (insn, REG_EQUAL, NULL_RTX))
|
||||
|| (GET_CODE (PATTERN (insn)) == CLOBBER
|
||||
|
Loading…
Reference in New Issue
Block a user