Commit cf94b0fc by Paolo Bonzini Committed by Paolo Bonzini

rtlanal.c (non_rtx_starting_operands, [...]): New.

2005-01-24  Paolo Bonzini  <bonzini@gnu.org>

	* rtlanal.c (non_rtx_starting_operands, for_each_rtx_1,
	init_rtlanal): New.
	(for_each_rtx): Call for_each_rtx_1.
	* rtl.h (init_rtlanal): Declare.
	* toplev.c (backend_init): Call init_rtlanal.

From-SVN: r94146
parent b77302be
2005-01-24 Paolo Bonzini <bonzini@gnu.org>
* rtlanal.c (non_rtx_starting_operands, for_each_rtx_1,
init_rtlanal): New.
(for_each_rtx): Call for_each_rtx_1.
* rtl.h (init_rtlanal): Declare.
* toplev.c (backend_init): Call init_rtlanal.
2005-01-24 Jakub Jelinek <jakub@redhat.com>
* flow.c (propagate_one_insn): Formatting.
......
......@@ -966,6 +966,7 @@ enum label_kind
not to use an rtx with this cost under any circumstances. */
#define MAX_COST INT_MAX
extern void init_rtlanal (void);
extern int rtx_cost (rtx, enum rtx_code);
extern int address_cost (rtx, enum machine_mode);
extern unsigned int subreg_lsb (rtx);
......
......@@ -58,6 +58,10 @@ static unsigned int cached_num_sign_bit_copies (rtx, enum machine_mode, rtx,
static unsigned int num_sign_bit_copies1 (rtx, enum machine_mode, rtx,
enum machine_mode, unsigned int);
/* Offset of the first 'e', 'E' or 'V' operand for each rtx code, or
-1 if a code has no such operand. */
static int non_rtx_starting_operands[NUM_RTX_CODE];
/* Bit flags that specify the machine subtype we are compiling for.
Bits are tested using macros TARGET_... defined in the tm.h file
and set by `-m...' switches. Must be defined in rtlanal.c. */
......@@ -2624,61 +2628,67 @@ computed_jump_p (rtx insn)
return 0;
}
/* Traverse X via depth-first search, calling F for each
sub-expression (including X itself). F is also passed the DATA.
If F returns -1, do not traverse sub-expressions, but continue
traversing the rest of the tree. If F ever returns any other
nonzero value, stop the traversal, and return the value returned
by F. Otherwise, return 0. This function does not traverse inside
tree structure that contains RTX_EXPRs, or into sub-expressions
whose format code is `0' since it is not known whether or not those
codes are actually RTL.
This routine is very general, and could (should?) be used to
implement many of the other routines in this file. */
int
for_each_rtx (rtx *x, rtx_function f, void *data)
/* Optimized loop of for_each_rtx, trying to avoid useless recursive
calls. Processes the subexpressions of EXP and passes them to F. */
static int
for_each_rtx_1 (rtx exp, int n, rtx_function f, void *data)
{
int result;
int length;
const char *format;
int i;
int result, i, j;
const char *format = GET_RTX_FORMAT (GET_CODE (exp));
rtx *x;
for (; format[n] != '\0'; n++)
{
switch (format[n])
{
case 'e':
/* Call F on X. */
x = &XEXP (exp, n);
result = (*f) (x, data);
if (result == -1)
/* Do not traverse sub-expressions. */
return 0;
continue;
else if (result != 0)
/* Stop the traversal. */
return result;
if (*x == NULL_RTX)
/* There are no sub-expressions. */
return 0;
length = GET_RTX_LENGTH (GET_CODE (*x));
format = GET_RTX_FORMAT (GET_CODE (*x));
continue;
for (i = 0; i < length; ++i)
{
switch (format[i])
i = non_rtx_starting_operands[GET_CODE (*x)];
if (i >= 0)
{
case 'e':
result = for_each_rtx (&XEXP (*x, i), f, data);
result = for_each_rtx_1 (*x, i, f, data);
if (result != 0)
return result;
}
break;
case 'V':
case 'E':
if (XVEC (*x, i) != 0)
if (XVEC (exp, n) == 0)
continue;
for (j = 0; j < XVECLEN (exp, n); ++j)
{
int j;
for (j = 0; j < XVECLEN (*x, i); ++j)
/* Call F on X. */
x = &XVECEXP (exp, n, j);
result = (*f) (x, data);
if (result == -1)
/* Do not traverse sub-expressions. */
continue;
else if (result != 0)
/* Stop the traversal. */
return result;
if (*x == NULL_RTX)
/* There are no sub-expressions. */
continue;
i = non_rtx_starting_operands[GET_CODE (*x)];
if (i >= 0)
{
result = for_each_rtx (&XVECEXP (*x, i, j), f, data);
result = for_each_rtx_1 (*x, i, f, data);
if (result != 0)
return result;
}
......@@ -2689,12 +2699,51 @@ for_each_rtx (rtx *x, rtx_function f, void *data)
/* Nothing to do. */
break;
}
}
return 0;
}
/* Traverse X via depth-first search, calling F for each
sub-expression (including X itself). F is also passed the DATA.
If F returns -1, do not traverse sub-expressions, but continue
traversing the rest of the tree. If F ever returns any other
nonzero value, stop the traversal, and return the value returned
by F. Otherwise, return 0. This function does not traverse inside
tree structure that contains RTX_EXPRs, or into sub-expressions
whose format code is `0' since it is not known whether or not those
codes are actually RTL.
This routine is very general, and could (should?) be used to
implement many of the other routines in this file. */
int
for_each_rtx (rtx *x, rtx_function f, void *data)
{
int result;
int i;
/* Call F on X. */
result = (*f) (x, data);
if (result == -1)
/* Do not traverse sub-expressions. */
return 0;
else if (result != 0)
/* Stop the traversal. */
return result;
if (*x == NULL_RTX)
/* There are no sub-expressions. */
return 0;
i = non_rtx_starting_operands[GET_CODE (*x)];
if (i < 0)
return 0;
return for_each_rtx_1 (*x, i, f, data);
}
/* Searches X for any reference to REGNO, returning the rtx of the
reference found if any. Otherwise, returns NULL_RTX. */
......@@ -4612,3 +4661,17 @@ get_condition (rtx jump, rtx *earliest, int allow_cc_mode, int valid_at_insn_p)
allow_cc_mode, valid_at_insn_p);
}
/* Initialize non_rtx_starting_operands, which is used to speed up
for_each_rtx. */
void
init_rtlanal (void)
{
int i;
for (i = 0; i < NUM_RTX_CODE; i++)
{
const char *format = GET_RTX_FORMAT (i);
const char *first = strpbrk (format, "eEV");
non_rtx_starting_operands[i] = first ? first - format : -1;
}
}
......@@ -1951,6 +1951,7 @@ backend_init (void)
#endif
|| flag_test_coverage);
init_rtlanal ();
init_regs ();
init_fake_stack_mems ();
init_alias_once ();
......
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