Commit 2c07f13b by Jan Hubicka Committed by Jan Hubicka

emit-rtl.c (set_used_flags): New.


	* emit-rtl.c (set_used_flags): New.
	(verify_rtx_sharing, verify_rtl_sharing): New.
	(unshare_all_rtl_1): Rename to....
	(unshare_all_rtl_in_chain): ... this one; make static.
	(copy_rtx_if_shared): LABEL_REF chan be shared.
	* ifcvt.c (unshare_ifcvt_sequence): New.
	(noce_try_move, noce_try_store_flag, noce_try_store_flag_constants,
	noce_try_addcc, noce_try_addcc, noce_try_store_flag_mask,
	noce_try_cmove, noce_try_store_flag_mask, noce_try_minmax,
	noce_try_abs, noce_process_if_block, find_cond_trap
	* rtl.h (verify_rtl_sharing, set_used_flags, unshare_all_rtl_in_chain):
	Declare.

From-SVN: r74030
parent 58c5975b
2003-11-28 Jan Hubicka <jh@suse.cz>
* emit-rtl.c (set_used_flags): New.
(verify_rtx_sharing, verify_rtl_sharing): New.
(unshare_all_rtl_1): Rename to....
(unshare_all_rtl_in_chain): ... this one; make static.
(copy_rtx_if_shared): LABEL_REF chan be shared.
* ifcvt.c (unshare_ifcvt_sequence): New.
(noce_try_move, noce_try_store_flag, noce_try_store_flag_constants,
noce_try_addcc, noce_try_addcc, noce_try_store_flag_mask,
noce_try_cmove, noce_try_store_flag_mask, noce_try_minmax,
noce_try_abs, noce_process_if_block, find_cond_trap
* rtl.h (verify_rtl_sharing, set_used_flags, unshare_all_rtl_in_chain):
Declare.
2003-11-28 Kazu Hirata <kazu@cs.umass.edu>
* config/h8300/h8300.md: Fix a comment typo.
......@@ -204,8 +219,8 @@
2003-11-24 Jan Hubicka <jh@suse.cz>
* fold-const.c (fold): Do not return early when optimizing COMPONENT_REF
and constant.
* fold-const.c (fold): Do not return early when optimizing
COMPONENT_REF and constant.
2003-11-24 Kazu Hirata <kazu@cs.umass.edu>
......
......@@ -180,7 +180,6 @@ static rtx make_jump_insn_raw (rtx);
static rtx make_call_insn_raw (rtx);
static rtx find_line_note (rtx);
static rtx change_address_1 (rtx, enum machine_mode, rtx, int);
static void unshare_all_rtl_1 (rtx);
static void unshare_all_decls (tree);
static void reset_used_decls (tree);
static void mark_label_nuses (rtx);
......@@ -2450,7 +2449,7 @@ unshare_all_rtl (tree fndecl, rtx insn)
unshare_all_decls (DECL_INITIAL (fndecl));
/* Unshare just about everything else. */
unshare_all_rtl_1 (insn);
unshare_all_rtl_in_chain (insn);
/* Make sure the addresses of stack slots found outside the insn chain
(such as, in DECL_RTL of a variable) are not shared
......@@ -2492,11 +2491,138 @@ unshare_all_rtl_again (rtx insn)
unshare_all_rtl (cfun->decl, insn);
}
/* Check that ORIG is not marked when it should not be and mark ORIG as in use,
Recursively does the same for subexpressions. */
static void
verify_rtx_sharing (rtx orig, rtx insn)
{
rtx x = orig;
int i;
enum rtx_code code;
const char *format_ptr;
if (x == 0)
return;
code = GET_CODE (x);
/* These types may be freely shared. */
switch (code)
{
case REG:
case QUEUED:
case CONST_INT:
case CONST_DOUBLE:
case CONST_VECTOR:
case SYMBOL_REF:
case LABEL_REF:
case CODE_LABEL:
case PC:
case CC0:
case SCRATCH:
/* SCRATCH must be shared because they represent distinct values. */
return;
case CONST:
/* CONST can be shared if it contains a SYMBOL_REF. If it contains
a LABEL_REF, it isn't sharable. */
if (GET_CODE (XEXP (x, 0)) == PLUS
&& GET_CODE (XEXP (XEXP (x, 0), 0)) == SYMBOL_REF
&& GET_CODE (XEXP (XEXP (x, 0), 1)) == CONST_INT)
return;
break;
case MEM:
/* A MEM is allowed to be shared if its address is constant. */
if (CONSTANT_ADDRESS_P (XEXP (x, 0))
|| reload_completed || reload_in_progress)
return;
break;
default:
break;
}
/* This rtx may not be shared. If it has already been seen,
replace it with a copy of itself. */
if (RTX_FLAG (x, used))
{
error ("Invalid rtl sharing found in the insn");
debug_rtx (insn);
error ("Shared rtx");
debug_rtx (x);
abort ();
}
RTX_FLAG (x, used) = 1;
/* Now scan the subexpressions recursively. */
format_ptr = GET_RTX_FORMAT (code);
for (i = 0; i < GET_RTX_LENGTH (code); i++)
{
switch (*format_ptr++)
{
case 'e':
verify_rtx_sharing (XEXP (x, i), insn);
break;
case 'E':
if (XVEC (x, i) != NULL)
{
int j;
int len = XVECLEN (x, i);
for (j = 0; j < len; j++)
{
/* We allow sharing of ASM_OPERANDS inside single instruction. */
if (j && GET_CODE (XVECEXP (x, i, j)) == SET
&& GET_CODE (SET_SRC (XVECEXP (x, i, j))) == ASM_OPERANDS)
verify_rtx_sharing (SET_DEST (XVECEXP (x, i, j)), insn);
else
verify_rtx_sharing (XVECEXP (x, i, j), insn);
}
}
break;
}
}
return;
}
/* Go through all the RTL insn bodies and chec that there is no inexpected
sharing in between the subexpressions. */
void
verify_rtl_sharing (void)
{
rtx p;
for (p = get_insns (); p; p = NEXT_INSN (p))
if (INSN_P (p))
{
reset_used_flags (PATTERN (p));
reset_used_flags (REG_NOTES (p));
reset_used_flags (LOG_LINKS (p));
}
for (p = get_insns (); p; p = NEXT_INSN (p))
if (INSN_P (p))
{
verify_rtx_sharing (PATTERN (p), p);
verify_rtx_sharing (REG_NOTES (p), p);
verify_rtx_sharing (LOG_LINKS (p), p);
}
}
/* Go through all the RTL insn bodies and copy any invalid shared structure.
Assumes the mark bits are cleared at entry. */
static void
unshare_all_rtl_1 (rtx insn)
void
unshare_all_rtl_in_chain (rtx insn)
{
for (; insn; insn = NEXT_INSN (insn))
if (INSN_P (insn))
......@@ -2668,6 +2794,7 @@ copy_rtx_if_shared (rtx orig)
case CONST_DOUBLE:
case CONST_VECTOR:
case SYMBOL_REF:
case LABEL_REF:
case CODE_LABEL:
case PC:
case CC0:
......@@ -2804,6 +2931,69 @@ reset_used_flags (rtx x)
}
}
}
/* Set all the USED bits in X to allow copy_rtx_if_shared to be used
to look for shared sub-parts. */
void
set_used_flags (rtx x)
{
int i, j;
enum rtx_code code;
const char *format_ptr;
if (x == 0)
return;
code = GET_CODE (x);
/* These types may be freely shared so we needn't do any resetting
for them. */
switch (code)
{
case REG:
case QUEUED:
case CONST_INT:
case CONST_DOUBLE:
case CONST_VECTOR:
case SYMBOL_REF:
case CODE_LABEL:
case PC:
case CC0:
return;
case INSN:
case JUMP_INSN:
case CALL_INSN:
case NOTE:
case LABEL_REF:
case BARRIER:
/* The chain of insns is not being copied. */
return;
default:
break;
}
RTX_FLAG (x, used) = 1;
format_ptr = GET_RTX_FORMAT (code);
for (i = 0; i < GET_RTX_LENGTH (code); i++)
{
switch (*format_ptr++)
{
case 'e':
set_used_flags (XEXP (x, i));
break;
case 'E':
for (j = 0; j < XVECLEN (x, i); j++)
set_used_flags (XVECEXP (x, i, j));
break;
}
}
}
/* Copy X if necessary so that it won't be altered by changes in OTHER.
Return X or the rtx for the pseudo reg the value of X was copied into.
......
......@@ -700,6 +700,16 @@ noce_emit_move_insn (rtx x, rtx y)
GET_MODE_BITSIZE (inmode));
}
/* Unshare sequence SEQ produced by if conversion. We care to mark
all arguments that may be shared with outer instruction stream. */
static void
unshare_ifcvt_sequence (struct noce_if_info *if_info, rtx seq)
{
set_used_flags (if_info->x);
set_used_flags (if_info->cond);
unshare_all_rtl_in_chain (seq);
}
/* Convert "if (a != b) x = a; else x = b" into "x = a" and
"if (a == b) x = a; else x = b" into "x = b". */
......@@ -734,6 +744,7 @@ noce_try_move (struct noce_if_info *if_info)
start_sequence ();
noce_emit_move_insn (if_info->x, y);
seq = get_insns ();
unshare_ifcvt_sequence (if_info, seq);
end_sequence ();
emit_insn_before_setloc (seq, if_info->jump,
INSN_LOCATOR (if_info->insn_a));
......@@ -777,6 +788,7 @@ noce_try_store_flag (struct noce_if_info *if_info)
noce_emit_move_insn (if_info->x, target);
seq = get_insns ();
unshare_ifcvt_sequence (if_info, seq);
end_sequence ();
emit_insn_before_setloc (seq, if_info->jump, INSN_LOCATOR (if_info->insn_a));
......@@ -907,6 +919,7 @@ noce_try_store_flag_constants (struct noce_if_info *if_info)
noce_emit_move_insn (if_info->x, target);
seq = get_insns ();
unshare_ifcvt_sequence (if_info, seq);
end_sequence ();
if (seq_contains_jump (seq))
......@@ -944,9 +957,11 @@ noce_try_addcc (struct noce_if_info *if_info)
{
start_sequence ();
target = emit_conditional_add (if_info->x, code,
XEXP (cond, 0), XEXP (cond, 1),
XEXP (cond, 0),
XEXP (cond, 1),
VOIDmode,
if_info->b, XEXP (if_info->a, 1),
if_info->b,
XEXP (if_info->a, 1),
GET_MODE (if_info->x),
(code == LTU || code == GEU
|| code == LEU || code == GTU));
......@@ -956,6 +971,7 @@ noce_try_addcc (struct noce_if_info *if_info)
noce_emit_move_insn (if_info->x, target);
seq = get_insns ();
unshare_ifcvt_sequence (if_info, seq);
end_sequence ();
emit_insn_before_setloc (seq, if_info->jump,
INSN_LOCATOR (if_info->insn_a));
......@@ -994,6 +1010,7 @@ noce_try_addcc (struct noce_if_info *if_info)
noce_emit_move_insn (if_info->x, target);
seq = get_insns ();
unshare_ifcvt_sequence (if_info, seq);
end_sequence ();
if (seq_contains_jump (seq))
......@@ -1037,7 +1054,8 @@ noce_try_store_flag_mask (struct noce_if_info *if_info)
reversep, -1);
if (target)
target = expand_simple_binop (GET_MODE (if_info->x), AND,
if_info->x, target, if_info->x, 0,
if_info->x,
target, if_info->x, 0,
OPTAB_WIDEN);
if (target)
......@@ -1046,6 +1064,7 @@ noce_try_store_flag_mask (struct noce_if_info *if_info)
noce_emit_move_insn (if_info->x, target);
seq = get_insns ();
unshare_ifcvt_sequence (if_info, seq);
end_sequence ();
if (seq_contains_jump (seq))
......@@ -1143,6 +1162,7 @@ noce_try_cmove (struct noce_if_info *if_info)
noce_emit_move_insn (if_info->x, target);
seq = get_insns ();
unshare_ifcvt_sequence (if_info, seq);
end_sequence ();
emit_insn_before_setloc (seq, if_info->jump,
INSN_LOCATOR (if_info->insn_a));
......@@ -1260,7 +1280,9 @@ noce_try_cmove_arith (struct noce_if_info *if_info)
if (is_mem)
{
tmp = gen_reg_rtx (GET_MODE (b));
tmp = emit_insn (gen_rtx_SET (VOIDmode, tmp, b));
tmp = emit_insn (gen_rtx_SET (VOIDmode,
tmp,
b));
}
else if (! insn_b)
goto end_seq_and_fail;
......@@ -1305,6 +1327,7 @@ noce_try_cmove_arith (struct noce_if_info *if_info)
noce_emit_move_insn (x, target);
tmp = get_insns ();
unshare_ifcvt_sequence (if_info, tmp);
end_sequence ();
emit_insn_before_setloc (tmp, if_info->jump, INSN_LOCATOR (if_info->insn_a));
return TRUE;
......@@ -1550,6 +1573,7 @@ noce_try_minmax (struct noce_if_info *if_info)
noce_emit_move_insn (if_info->x, target);
seq = get_insns ();
unshare_ifcvt_sequence (if_info, seq);
end_sequence ();
if (seq_contains_jump (seq))
......@@ -1667,6 +1691,7 @@ noce_try_abs (struct noce_if_info *if_info)
noce_emit_move_insn (if_info->x, target);
seq = get_insns ();
unshare_ifcvt_sequence (if_info, seq);
end_sequence ();
if (seq_contains_jump (seq))
......@@ -1988,8 +2013,10 @@ noce_process_if_block (struct ce_if_block * ce_info)
if (orig_x != x)
{
start_sequence ();
noce_emit_move_insn (copy_rtx (orig_x), x);
noce_emit_move_insn (orig_x, x);
insn_b = get_insns ();
set_used_flags (orig_x);
unshare_all_rtl_in_chain (insn_b);
end_sequence ();
emit_insn_after_setloc (insn_b, test_bb->end, INSN_LOCATOR (insn_a));
......@@ -2585,7 +2612,8 @@ find_cond_trap (basic_block test_bb, edge then_edge, edge else_edge)
}
/* Attempt to generate the conditional trap. */
seq = gen_cond_trap (code, XEXP (cond, 0), XEXP (cond, 1),
seq = gen_cond_trap (code, XEXP (cond, 0),
XEXP (cond, 1),
TRAP_CODE (PATTERN (trap)));
if (seq == NULL)
return FALSE;
......
......@@ -2036,6 +2036,7 @@ extern void delete_insns_since (rtx);
extern void mark_reg_pointer (rtx, int);
extern void mark_user_reg (rtx);
extern void reset_used_flags (rtx);
extern void set_used_flags (rtx);
extern void reorder_insns (rtx, rtx, rtx);
extern void reorder_insns_nobb (rtx, rtx, rtx);
extern int get_max_uid (void);
......@@ -2051,6 +2052,8 @@ extern void set_new_first_and_last_insn (rtx, rtx);
extern void set_new_first_and_last_label_num (int, int);
extern void set_new_last_label_num (int);
extern void unshare_all_rtl_again (rtx);
extern void unshare_all_rtl_in_chain (rtx);
extern void verify_rtl_sharing (void);
extern void set_first_insn (rtx);
extern void set_last_insn (rtx);
extern void link_cc0_insns (rtx);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment