Commit 070a7956 by J"orn Rennecke Committed by Joern Rennecke

re PR rtl-optimization/23898 (basic block reordering excessively increases code…

re PR rtl-optimization/23898 (basic block reordering excessively increases code size; get_uncond_jump_length pessimistic)

	PR rtl-optimization/23898
	* output.h (get_attr_min_length): Declare.
	* final.c (get_attr_length_1): New function, broken out of:
	(get_attr_length).
	(get_attr_min_length): New function.
	* bb-reorder.c (copy_bb_p, get_uncond_jump_length): Use it.
	(duplicate_computed_gotos): Likewise.
	* genattr.c (insn_min_length): Generate declaration.
	* genattrtab.c (min_fn, min_attr_value): New functions.
	(make_length_attrs): Generate insn_min_length.

From-SVN: r104468
parent 9972f30d
2005-09-20 J"orn Rennecke <joern.rennecke@st.com>
PR rtl-optimization/23898
* output.h (get_attr_min_length): Declare.
* final.c (get_attr_length_1): New function, broken out of:
(get_attr_length).
(get_attr_min_length): New function.
* bb-reorder.c (copy_bb_p, get_uncond_jump_length): Use it.
(duplicate_computed_gotos): Likewise.
* genattr.c (insn_min_length): Generate declaration.
* genattrtab.c (min_fn, min_attr_value): New functions.
(make_length_attrs): Generate insn_min_length.
2005-09-20 Steve Ellcey <sje@cup.hp.com> 2005-09-20 Steve Ellcey <sje@cup.hp.com>
* config/pa/pa.c (output_cbranch): Check for zero in operands[2]. * config/pa/pa.c (output_cbranch): Check for zero in operands[2].
......
...@@ -1178,7 +1178,7 @@ copy_bb_p (basic_block bb, int code_may_grow) ...@@ -1178,7 +1178,7 @@ copy_bb_p (basic_block bb, int code_may_grow)
FOR_BB_INSNS (bb, insn) FOR_BB_INSNS (bb, insn)
{ {
if (INSN_P (insn)) if (INSN_P (insn))
size += get_attr_length (insn); size += get_attr_min_length (insn);
} }
if (size <= max_size) if (size <= max_size)
...@@ -1205,7 +1205,7 @@ get_uncond_jump_length (void) ...@@ -1205,7 +1205,7 @@ get_uncond_jump_length (void)
label = emit_label_before (gen_label_rtx (), get_insns ()); label = emit_label_before (gen_label_rtx (), get_insns ());
jump = emit_jump_insn (gen_jump (label)); jump = emit_jump_insn (gen_jump (label));
length = get_attr_length (jump); length = get_attr_min_length (jump);
delete_insn (jump); delete_insn (jump);
delete_insn (label); delete_insn (label);
...@@ -2030,7 +2030,7 @@ duplicate_computed_gotos (void) ...@@ -2030,7 +2030,7 @@ duplicate_computed_gotos (void)
FOR_BB_INSNS (bb, insn) FOR_BB_INSNS (bb, insn)
if (INSN_P (insn)) if (INSN_P (insn))
{ {
size += get_attr_length (insn); size += get_attr_min_length (insn);
if (size > max_size) if (size > max_size)
break; break;
} }
......
...@@ -383,10 +383,11 @@ init_insn_lengths (void) ...@@ -383,10 +383,11 @@ init_insn_lengths (void)
} }
/* Obtain the current length of an insn. If branch shortening has been done, /* Obtain the current length of an insn. If branch shortening has been done,
get its actual length. Otherwise, get its maximum length. */ get its actual length. Otherwise, use FALLBACK_FN to calcualte the
length. */
int static inline int
get_attr_length (rtx insn ATTRIBUTE_UNUSED) get_attr_length_1 (rtx insn ATTRIBUTE_UNUSED,
int (*fallback_fn) (rtx) ATTRIBUTE_UNUSED)
{ {
#ifdef HAVE_ATTR_length #ifdef HAVE_ATTR_length
rtx body; rtx body;
...@@ -404,7 +405,7 @@ get_attr_length (rtx insn ATTRIBUTE_UNUSED) ...@@ -404,7 +405,7 @@ get_attr_length (rtx insn ATTRIBUTE_UNUSED)
return 0; return 0;
case CALL_INSN: case CALL_INSN:
length = insn_default_length (insn); length = fallback_fn (insn);
break; break;
case JUMP_INSN: case JUMP_INSN:
...@@ -415,7 +416,7 @@ get_attr_length (rtx insn ATTRIBUTE_UNUSED) ...@@ -415,7 +416,7 @@ get_attr_length (rtx insn ATTRIBUTE_UNUSED)
ADDR_VEC_ALIGN. */ ADDR_VEC_ALIGN. */
} }
else else
length = insn_default_length (insn); length = fallback_fn (insn);
break; break;
case INSN: case INSN:
...@@ -424,12 +425,12 @@ get_attr_length (rtx insn ATTRIBUTE_UNUSED) ...@@ -424,12 +425,12 @@ get_attr_length (rtx insn ATTRIBUTE_UNUSED)
return 0; return 0;
else if (GET_CODE (body) == ASM_INPUT || asm_noperands (body) >= 0) else if (GET_CODE (body) == ASM_INPUT || asm_noperands (body) >= 0)
length = asm_insn_count (body) * insn_default_length (insn); length = asm_insn_count (body) * fallback_fn (insn);
else if (GET_CODE (body) == SEQUENCE) else if (GET_CODE (body) == SEQUENCE)
for (i = 0; i < XVECLEN (body, 0); i++) for (i = 0; i < XVECLEN (body, 0); i++)
length += get_attr_length (XVECEXP (body, 0, i)); length += get_attr_length (XVECEXP (body, 0, i));
else else
length = insn_default_length (insn); length = fallback_fn (insn);
break; break;
default: default:
...@@ -444,6 +445,22 @@ get_attr_length (rtx insn ATTRIBUTE_UNUSED) ...@@ -444,6 +445,22 @@ get_attr_length (rtx insn ATTRIBUTE_UNUSED)
return 0; return 0;
#endif /* not HAVE_ATTR_length */ #endif /* not HAVE_ATTR_length */
} }
/* Obtain the current length of an insn. If branch shortening has been done,
get its actual length. Otherwise, get its maximum length. */
int
get_attr_length (rtx insn)
{
return get_attr_length_1 (insn, insn_default_length);
}
/* Obtain the current length of an insn. If branch shortening has been done,
get its actual length. Otherwise, get its minimum length. */
int
get_attr_min_length (rtx insn)
{
return get_attr_length_1 (insn, insn_min_length);
}
/* Code to handle alignment inside shorten_branches. */ /* Code to handle alignment inside shorten_branches. */
......
...@@ -79,6 +79,7 @@ gen_attr (rtx attr) ...@@ -79,6 +79,7 @@ gen_attr (rtx attr)
puts ("\ puts ("\
extern void shorten_branches (rtx);\n\ extern void shorten_branches (rtx);\n\
extern int insn_default_length (rtx);\n\ extern int insn_default_length (rtx);\n\
extern int insn_min_length (rtx);\n\
extern int insn_variable_length_p (rtx);\n\ extern int insn_variable_length_p (rtx);\n\
extern int insn_current_length (rtx);\n\n\ extern int insn_current_length (rtx);\n\n\
#include \"insn-addr.h\"\n"); #include \"insn-addr.h\"\n");
......
...@@ -285,6 +285,7 @@ static rtx identity_fn (rtx); ...@@ -285,6 +285,7 @@ static rtx identity_fn (rtx);
static rtx zero_fn (rtx); static rtx zero_fn (rtx);
static rtx one_fn (rtx); static rtx one_fn (rtx);
static rtx max_fn (rtx); static rtx max_fn (rtx);
static rtx min_fn (rtx);
static void write_length_unit_log (void); static void write_length_unit_log (void);
static rtx simplify_cond (rtx, int, int); static rtx simplify_cond (rtx, int, int);
static void clear_struct_flag (rtx); static void clear_struct_flag (rtx);
...@@ -307,6 +308,7 @@ static void gen_insn (rtx, int); ...@@ -307,6 +308,7 @@ static void gen_insn (rtx, int);
static void gen_delay (rtx, int); static void gen_delay (rtx, int);
static void write_test_expr (rtx, int); static void write_test_expr (rtx, int);
static int max_attr_value (rtx, int*); static int max_attr_value (rtx, int*);
static int min_attr_value (rtx, int*);
static int or_attr_value (rtx, int*); static int or_attr_value (rtx, int*);
static void walk_attr_value (rtx); static void walk_attr_value (rtx);
static void write_attr_get (struct attr_desc *); static void write_attr_get (struct attr_desc *);
...@@ -1583,11 +1585,14 @@ make_length_attrs (void) ...@@ -1583,11 +1585,14 @@ make_length_attrs (void)
static const char *new_names[] = static const char *new_names[] =
{ {
"*insn_default_length", "*insn_default_length",
"*insn_min_length",
"*insn_variable_length_p", "*insn_variable_length_p",
"*insn_current_length" "*insn_current_length"
}; };
static rtx (*const no_address_fn[]) (rtx) = {identity_fn, zero_fn, zero_fn}; static rtx (*const no_address_fn[]) (rtx)
static rtx (*const address_fn[]) (rtx) = {max_fn, one_fn, identity_fn}; = {identity_fn,identity_fn, zero_fn, zero_fn};
static rtx (*const address_fn[]) (rtx)
= {max_fn, min_fn, one_fn, identity_fn};
size_t i; size_t i;
struct attr_desc *length_attr, *new_attr; struct attr_desc *length_attr, *new_attr;
struct attr_value *av, *new_av; struct attr_value *av, *new_av;
...@@ -1654,6 +1659,13 @@ max_fn (rtx exp) ...@@ -1654,6 +1659,13 @@ max_fn (rtx exp)
return make_numeric_value (max_attr_value (exp, &unknown)); return make_numeric_value (max_attr_value (exp, &unknown));
} }
static rtx
min_fn (rtx exp)
{
int unknown;
return make_numeric_value (min_attr_value (exp, &unknown));
}
static void static void
write_length_unit_log (void) write_length_unit_log (void)
{ {
...@@ -3531,6 +3543,47 @@ max_attr_value (rtx exp, int *unknownp) ...@@ -3531,6 +3543,47 @@ max_attr_value (rtx exp, int *unknownp)
return current_max; return current_max;
} }
/* Given an attribute value, return the minimum CONST_STRING argument
encountered. Set *UNKNOWNP and return 0 if the value is unknown. */
static int
min_attr_value (rtx exp, int *unknownp)
{
int current_min;
int i, n;
switch (GET_CODE (exp))
{
case CONST_STRING:
current_min = atoi (XSTR (exp, 0));
break;
case COND:
current_min = min_attr_value (XEXP (exp, 1), unknownp);
for (i = 0; i < XVECLEN (exp, 0); i += 2)
{
n = min_attr_value (XVECEXP (exp, 0, i + 1), unknownp);
if (n < current_min)
current_min = n;
}
break;
case IF_THEN_ELSE:
current_min = min_attr_value (XEXP (exp, 1), unknownp);
n = min_attr_value (XEXP (exp, 2), unknownp);
if (n < current_min)
current_min = n;
break;
default:
*unknownp = 1;
current_min = INT_MAX;
break;
}
return current_min;
}
/* Given an attribute value, return the result of ORing together all /* Given an attribute value, return the result of ORing together all
CONST_STRING arguments encountered. Set *UNKNOWNP and return -1 CONST_STRING arguments encountered. Set *UNKNOWNP and return -1
if the numeric value is not known. */ if the numeric value is not known. */
......
...@@ -49,6 +49,10 @@ extern void init_insn_lengths (void); ...@@ -49,6 +49,10 @@ extern void init_insn_lengths (void);
get its actual length. Otherwise, get its maximum length. */ get its actual length. Otherwise, get its maximum length. */
extern int get_attr_length (rtx); extern int get_attr_length (rtx);
/* Obtain the current length of an insn. If branch shortening has been done,
get its actual length. Otherwise, get its minimum length. */
extern int get_attr_min_length (rtx);
/* Make a pass over all insns and compute their actual lengths by shortening /* Make a pass over all insns and compute their actual lengths by shortening
any branches of variable length if possible. */ any branches of variable length if possible. */
extern void shorten_branches (rtx); extern void shorten_branches (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