sh.c (print_operand_address, [...]): Call mark_constant_pool_use before output_addr_const.

* gcc/config/sh/sh.c (print_operand_address, print_operand): Call
mark_constant_pool_use before output_addr_const.
(struct pool_node): New field wend.
(add_constant): Note a sequence of constants that are referenced
by a given label.
(pool_window_label, pool_window_last): New variables.
(dump_table): Emit a unspec_volatile representing the end of a
sequence of constants.
(mark_constant_pool_use): New function.
* gcc/config/sh/sh.md (UNSPECV_WINDOW_END): New constant.
(consttable_2): Add the second operand which flags whether
this consttable entry was used or not.
(consttable_4, consttable_8, consttable_sf, consttable_df):
Likewise.
(consttable_window_end): New insn.

From-SVN: r42841
This commit is contained in:
Kaz Kojima 2001-06-04 00:20:46 +00:00 committed by Alexandre Oliva
parent 5d9669fd54
commit b91455de3d
3 changed files with 182 additions and 27 deletions

View File

@ -1,3 +1,21 @@
2001-06-03 kaz Kojima <kkojima@rr.iij4u.or.jp>
* gcc/config/sh/sh.c (print_operand_address, print_operand): Call
mark_constant_pool_use before output_addr_const.
(struct pool_node): New field wend.
(add_constant): Note a sequence of constants that are referenced
by a given label.
(pool_window_label, pool_window_last): New variables.
(dump_table): Emit a unspec_volatile representing the end of a
sequence of constants.
(mark_constant_pool_use): New function.
* gcc/config/sh/sh.md (UNSPECV_WINDOW_END): New constant.
(consttable_2): Add the second operand which flags whether
this consttable entry was used or not.
(consttable_4, consttable_8, consttable_sf, consttable_df):
Likewise.
(consttable_window_end): New insn.
2001-06-03 Alexandre Oliva <aoliva@redhat.com>
* insn-addr.h (INSN_ADDRESSES_NEW): Make insn_uid__ unsigned.

View File

@ -147,6 +147,7 @@ static void push_regs PARAMS ((int, int));
static int calc_live_regs PARAMS ((int *, int *));
static void mark_use PARAMS ((rtx, rtx *));
static HOST_WIDE_INT rounded_frame_size PARAMS ((int));
static rtx mark_constant_pool_use PARAMS ((rtx));
/* Print the operand address in x to the stream. */
@ -201,6 +202,7 @@ print_operand_address (stream, x)
break;
default:
x = mark_constant_pool_use (x);
output_addr_const (stream, x);
break;
}
@ -261,6 +263,7 @@ print_operand (stream, x, code)
fprintf (stream, "\n\tnop");
break;
case 'O':
x = mark_constant_pool_use (x);
output_addr_const (stream, x);
break;
case 'R':
@ -1932,6 +1935,7 @@ typedef struct
{
rtx value; /* Value in table. */
rtx label; /* Label of value. */
rtx wend; /* End of window. */
enum machine_mode mode; /* Mode of value. */
} pool_node;
@ -1942,6 +1946,8 @@ typedef struct
#define MAX_POOL_SIZE (1020/4)
static pool_node pool_vector[MAX_POOL_SIZE];
static int pool_size;
static rtx pool_window_label;
static int pool_window_last;
/* ??? If we need a constant in HImode which is the truncated value of a
constant we need in SImode, we could combine the two entries thus saving
@ -1962,7 +1968,7 @@ add_constant (x, mode, last_value)
rtx last_value;
{
int i;
rtx lab;
rtx lab, new, ref, newref;
/* First see if we've already got it. */
for (i = 0; i < pool_size; i++)
@ -1977,15 +1983,25 @@ add_constant (x, mode, last_value)
}
if (rtx_equal_p (x, pool_vector[i].value))
{
lab = 0;
lab = new = 0;
if (! last_value
|| ! i
|| ! rtx_equal_p (last_value, pool_vector[i-1].value))
{
lab = pool_vector[i].label;
if (! lab)
pool_vector[i].label = lab = gen_label_rtx ();
new = gen_label_rtx ();
LABEL_REFS (new) = pool_vector[i].label;
pool_vector[i].label = lab = new;
}
if (lab && pool_window_label)
{
newref = gen_rtx_LABEL_REF (VOIDmode, pool_window_label);
ref = pool_vector[pool_window_last].wend;
LABEL_NEXTREF (newref) = ref;
pool_vector[pool_window_last].wend = newref;
}
if (new)
pool_window_label = new;
pool_window_last = i;
return lab;
}
}
@ -1999,6 +2015,17 @@ add_constant (x, mode, last_value)
lab = gen_label_rtx ();
pool_vector[pool_size].mode = mode;
pool_vector[pool_size].label = lab;
pool_vector[pool_size].wend = NULL_RTX;
if (lab && pool_window_label)
{
newref = gen_rtx_LABEL_REF (VOIDmode, pool_window_label);
ref = pool_vector[pool_window_last].wend;
LABEL_NEXTREF (newref) = ref;
pool_vector[pool_window_last].wend = newref;
}
if (lab)
pool_window_label = lab;
pool_window_last = pool_size;
pool_size++;
return lab;
}
@ -2011,6 +2038,7 @@ dump_table (scan)
{
int i;
int need_align = 1;
rtx lab, ref;
/* Do two passes, first time dump out the HI sized constants. */
@ -2025,8 +2053,15 @@ dump_table (scan)
scan = emit_insn_after (gen_align_2 (), scan);
need_align = 0;
}
scan = emit_label_after (p->label, scan);
scan = emit_insn_after (gen_consttable_2 (p->value), scan);
for (lab = p->label; lab; lab = LABEL_REFS (lab))
scan = emit_label_after (lab, scan);
scan = emit_insn_after (gen_consttable_2 (p->value, const0_rtx),
scan);
for (ref = p->wend; ref; ref = LABEL_NEXTREF (ref))
{
lab = XEXP (ref, 0);
scan = emit_insn_after (gen_consttable_window_end (lab), scan);
}
}
}
@ -2048,9 +2083,10 @@ dump_table (scan)
scan = emit_label_after (gen_label_rtx (), scan);
scan = emit_insn_after (gen_align_4 (), scan);
}
if (p->label)
scan = emit_label_after (p->label, scan);
scan = emit_insn_after (gen_consttable_4 (p->value), scan);
for (lab = p->label; lab; lab = LABEL_REFS (lab))
scan = emit_label_after (lab, scan);
scan = emit_insn_after (gen_consttable_4 (p->value, const0_rtx),
scan);
break;
case DFmode:
case DImode:
@ -2060,19 +2096,31 @@ dump_table (scan)
scan = emit_label_after (gen_label_rtx (), scan);
scan = emit_insn_after (gen_align_4 (), scan);
}
if (p->label)
scan = emit_label_after (p->label, scan);
scan = emit_insn_after (gen_consttable_8 (p->value), scan);
for (lab = p->label; lab; lab = LABEL_REFS (lab))
scan = emit_label_after (lab, scan);
scan = emit_insn_after (gen_consttable_8 (p->value, const0_rtx),
scan);
break;
default:
abort ();
break;
}
if (p->mode != HImode)
{
for (ref = p->wend; ref; ref = LABEL_NEXTREF (ref))
{
lab = XEXP (ref, 0);
scan = emit_insn_after (gen_consttable_window_end (lab), scan);
}
}
}
scan = emit_insn_after (gen_consttable_end (), scan);
scan = emit_barrier_after (scan);
pool_size = 0;
pool_window_label = NULL_RTX;
pool_window_last = 0;
}
/* Return non-zero if constant would be an ok source for a
@ -5386,3 +5434,68 @@ legitimize_pic_address (orig, mode, reg)
}
return orig;
}
/* Mark the use of a constant in the literal table. If the constant
has multiple labels, make it unique. */
static rtx mark_constant_pool_use (x)
rtx x;
{
rtx insn, lab, pattern;
if (x == NULL)
return x;
switch (GET_CODE (x))
{
case LABEL_REF:
x = XEXP (x, 0);
case CODE_LABEL:
break;
default:
return x;
}
/* Get the first label in the list of labels for the same constant
and delete another labels in the list. */
lab = x;
for (insn = PREV_INSN (x); insn; insn = PREV_INSN (insn))
{
if (GET_CODE (insn) != CODE_LABEL
|| LABEL_REFS (insn) != NEXT_INSN (insn))
break;
lab = insn;
}
for (insn = LABEL_REFS (lab); insn; insn = LABEL_REFS (insn))
INSN_DELETED_P (insn) = 1;
/* Mark constants in a window. */
for (insn = NEXT_INSN (x); insn; insn = NEXT_INSN (insn))
{
if (GET_CODE (insn) != INSN)
continue;
pattern = PATTERN (insn);
if (GET_CODE (pattern) != UNSPEC_VOLATILE)
continue;
switch (XINT (pattern, 1))
{
case UNSPECV_CONST2:
case UNSPECV_CONST4:
case UNSPECV_CONST8:
XVECEXP (pattern, 0, 1) = const1_rtx;
break;
case UNSPECV_WINDOW_END:
if (XVECEXP (pattern, 0, 0) == x)
return lab;
break;
case UNSPECV_CONST_END:
return lab;
default:
break;
}
}
return lab;
}

View File

@ -117,6 +117,7 @@
(UNSPECV_CONST2 2)
(UNSPECV_CONST4 4)
(UNSPECV_CONST8 6)
(UNSPECV_WINDOW_END 10)
(UNSPECV_CONST_END 11)
])
@ -4120,12 +4121,14 @@
; 2 byte integer in line
(define_insn "consttable_2"
[(unspec_volatile [(match_operand:SI 0 "general_operand" "=g")]
[(unspec_volatile [(match_operand:SI 0 "general_operand" "=g")
(match_operand 1 "" "")]
UNSPECV_CONST2)]
""
"*
{
assemble_integer (operands[0], 2, 1);
if (operands[1] != const0_rtx)
assemble_integer (operands[0], 2, 1);
return \"\";
}"
[(set_attr "length" "2")
@ -4134,12 +4137,14 @@
; 4 byte integer in line
(define_insn "consttable_4"
[(unspec_volatile [(match_operand:SI 0 "general_operand" "=g")]
[(unspec_volatile [(match_operand:SI 0 "general_operand" "=g")
(match_operand 1 "" "")]
UNSPECV_CONST4)]
""
"*
{
assemble_integer (operands[0], 4, 1);
if (operands[1] != const0_rtx)
assemble_integer (operands[0], 4, 1);
return \"\";
}"
[(set_attr "length" "4")
@ -4148,12 +4153,14 @@
; 8 byte integer in line
(define_insn "consttable_8"
[(unspec_volatile [(match_operand:SI 0 "general_operand" "=g")]
[(unspec_volatile [(match_operand:SI 0 "general_operand" "=g")
(match_operand 1 "" "")]
UNSPECV_CONST8)]
""
"*
{
assemble_integer (operands[0], 8, 1);
if (operands[1] != const0_rtx)
assemble_integer (operands[0], 8, 1);
return \"\";
}"
[(set_attr "length" "8")
@ -4162,14 +4169,18 @@
; 4 byte floating point
(define_insn "consttable_sf"
[(unspec_volatile [(match_operand:SF 0 "general_operand" "=g")]
[(unspec_volatile [(match_operand:SF 0 "general_operand" "=g")
(match_operand 1 "" "")]
UNSPECV_CONST4)]
""
"*
{
union real_extract u;
memcpy (&u, &CONST_DOUBLE_LOW (operands[0]), sizeof u);
assemble_real (u.d, SFmode);
if (operands[1] != const0_rtx)
{
union real_extract u;
memcpy (&u, &CONST_DOUBLE_LOW (operands[0]), sizeof u);
assemble_real (u.d, SFmode);
}
return \"\";
}"
[(set_attr "length" "4")
@ -4178,14 +4189,18 @@
; 8 byte floating point
(define_insn "consttable_df"
[(unspec_volatile [(match_operand:DF 0 "general_operand" "=g")]
[(unspec_volatile [(match_operand:DF 0 "general_operand" "=g")
(match_operand 1 "" "")]
UNSPECV_CONST8)]
""
"*
{
union real_extract u;
memcpy (&u, &CONST_DOUBLE_LOW (operands[0]), sizeof u);
assemble_real (u.d, DFmode);
if (operands[1] != const0_rtx)
{
union real_extract u;
memcpy (&u, &CONST_DOUBLE_LOW (operands[0]), sizeof u);
assemble_real (u.d, DFmode);
}
return \"\";
}"
[(set_attr "length" "8")
@ -4231,6 +4246,15 @@
"* return output_jump_label_table ();"
[(set_attr "in_delay_slot" "no")])
; emitted at the end of the window in the literal table.
(define_insn "consttable_window_end"
[(unspec_volatile [(match_operand 0 "" "")] UNSPECV_WINDOW_END)]
""
""
[(set_attr "length" "0")
(set_attr "in_delay_slot" "no")])
;; -------------------------------------------------------------------------
;; Misc
;; -------------------------------------------------------------------------