jump.c (jmp_uses_reg_or_mem): Deleted unused function.
* jump.c (jmp_uses_reg_or_mem): Deleted unused function. (find_basic_blocks): Use computed_jump_p to determine if a particular JUMP_INSN is a computed jump. * reg-stack.c (find_blocks): Use computed_jump_p to determine if a particular JUMP_INSN is a computed jump. * rtlanal.c (jmp_uses_reg_or_mem): New function. (computed_jump_p): Likewise. * rtl.h (computed_jump_p): Declare. * genattrtab.c (pc_rtx): Define and initialize. * loop.c (loop_optimize): Always determine if the current function has a computed jump. (indirect_jump_in_function_p): Use computed_jump_p to determine if a particular JUMP_INSN is a computed jump. General (and haifa) cleanups. From-SVN: r15615
This commit is contained in:
parent
37842442c3
commit
2a1777af22
@ -1,5 +1,19 @@
|
|||||||
Sun Sep 21 17:45:45 1997 Jeffrey A Law (law@cygnus.com)
|
Sun Sep 21 17:45:45 1997 Jeffrey A Law (law@cygnus.com)
|
||||||
|
|
||||||
|
* jump.c (jmp_uses_reg_or_mem): Deleted unused function.
|
||||||
|
(find_basic_blocks): Use computed_jump_p to determine if a
|
||||||
|
particular JUMP_INSN is a computed jump.
|
||||||
|
* reg-stack.c (find_blocks): Use computed_jump_p to determine
|
||||||
|
if a particular JUMP_INSN is a computed jump.
|
||||||
|
* rtlanal.c (jmp_uses_reg_or_mem): New function.
|
||||||
|
(computed_jump_p): Likewise.
|
||||||
|
* rtl.h (computed_jump_p): Declare.
|
||||||
|
* genattrtab.c (pc_rtx): Define and initialize.
|
||||||
|
* loop.c (loop_optimize): Always determine if the current
|
||||||
|
function has a computed jump.
|
||||||
|
(indirect_jump_in_function_p): Use computed_jump_p to determine
|
||||||
|
if a particular JUMP_INSN is a computed jump.
|
||||||
|
|
||||||
* loop.c (fix_bct_param): Delete unused function.
|
* loop.c (fix_bct_param): Delete unused function.
|
||||||
(check_bct_param): Likewise.
|
(check_bct_param): Likewise.
|
||||||
|
|
||||||
|
@ -483,6 +483,8 @@ struct attr_hash *attr_hash_table[RTL_HASH_SIZE];
|
|||||||
codes are made. */
|
codes are made. */
|
||||||
#define RTL_HASH(RTL) ((HOST_WIDE_INT) (RTL) & 0777777)
|
#define RTL_HASH(RTL) ((HOST_WIDE_INT) (RTL) & 0777777)
|
||||||
|
|
||||||
|
rtx pc_rtx;
|
||||||
|
|
||||||
/* Add an entry to the hash table for RTL with hash code HASHCODE. */
|
/* Add an entry to the hash table for RTL with hash code HASHCODE. */
|
||||||
|
|
||||||
static void
|
static void
|
||||||
@ -5573,6 +5575,11 @@ main (argc, argv)
|
|||||||
|
|
||||||
init_rtl ();
|
init_rtl ();
|
||||||
|
|
||||||
|
/* We don't use this, but it is referenced in rtlanal.c.
|
||||||
|
Set it up correctly just in case someone tries to use it someday. */
|
||||||
|
pc_rtx = rtx_alloc (PC);
|
||||||
|
PUT_MODE (pc_rtx, VOIDmode);
|
||||||
|
|
||||||
/* Set up true and false rtx's */
|
/* Set up true and false rtx's */
|
||||||
true_rtx = rtx_alloc (CONST_INT);
|
true_rtx = rtx_alloc (CONST_INT);
|
||||||
XWINT (true_rtx, 0) = 1;
|
XWINT (true_rtx, 0) = 1;
|
||||||
|
42
gcc/loop.c
42
gcc/loop.c
@ -330,13 +330,14 @@ static void insert_bct ();
|
|||||||
/* Auxiliary function that inserts the bct pattern into the loop */
|
/* Auxiliary function that inserts the bct pattern into the loop */
|
||||||
static void instrument_loop_bct ();
|
static void instrument_loop_bct ();
|
||||||
|
|
||||||
/* Indirect_jump_in_function is computed once per function. */
|
|
||||||
int indirect_jump_in_function = 0;
|
|
||||||
static int indirect_jump_in_function_p ();
|
|
||||||
|
|
||||||
int loop_number ();
|
int loop_number ();
|
||||||
#endif /* HAIFA */
|
#endif /* HAIFA */
|
||||||
|
|
||||||
|
/* Indirect_jump_in_function is computed once per function. */
|
||||||
|
int indirect_jump_in_function = 0;
|
||||||
|
static int indirect_jump_in_function_p ();
|
||||||
|
|
||||||
|
|
||||||
/* Relative gain of eliminating various kinds of operations. */
|
/* Relative gain of eliminating various kinds of operations. */
|
||||||
int add_cost;
|
int add_cost;
|
||||||
@ -507,11 +508,9 @@ loop_optimize (f, dumpfile)
|
|||||||
if (flag_unroll_loops && write_symbols != NO_DEBUG)
|
if (flag_unroll_loops && write_symbols != NO_DEBUG)
|
||||||
find_loop_tree_blocks ();
|
find_loop_tree_blocks ();
|
||||||
|
|
||||||
#ifdef HAIFA
|
/* Determine if the function has indirect jump. On some systems
|
||||||
/* determine if the function has indirect jump. If it does,
|
this prevents low overhead loop instructions from being used. */
|
||||||
we cannot instrument loops in this function with bct */
|
|
||||||
indirect_jump_in_function = indirect_jump_in_function_p (f);
|
indirect_jump_in_function = indirect_jump_in_function_p (f);
|
||||||
#endif /* HAIFA */
|
|
||||||
|
|
||||||
/* Now scan the loops, last ones first, since this means inner ones are done
|
/* Now scan the loops, last ones first, since this means inner ones are done
|
||||||
before outer ones. */
|
before outer ones. */
|
||||||
@ -7592,8 +7591,12 @@ loop_number (loop_start, loop_end)
|
|||||||
|
|
||||||
return loop_num;
|
return loop_num;
|
||||||
}
|
}
|
||||||
|
#endif /* HAIFA */
|
||||||
|
|
||||||
/* scan the function and determine whether it has indirect (computed) jump */
|
/* Scan the function and determine whether it has indirect (computed) jumps.
|
||||||
|
|
||||||
|
This is taken mostly from flow.c; similar code exists elsewhere
|
||||||
|
in the compiler. It may be useful to put this into rtlanal.c. */
|
||||||
static int
|
static int
|
||||||
indirect_jump_in_function_p (start)
|
indirect_jump_in_function_p (start)
|
||||||
rtx start;
|
rtx start;
|
||||||
@ -7601,25 +7604,8 @@ indirect_jump_in_function_p (start)
|
|||||||
rtx insn;
|
rtx insn;
|
||||||
int is_indirect_jump = 0;
|
int is_indirect_jump = 0;
|
||||||
|
|
||||||
for (insn = start; insn; insn = NEXT_INSN (insn)) {
|
for (insn = start; insn; insn = NEXT_INSN (insn))
|
||||||
if (GET_CODE (insn) == JUMP_INSN) {
|
if (computed_jump_p (insn))
|
||||||
if (GET_CODE (PATTERN (insn)) == SET) {
|
return 1;
|
||||||
rtx insn_work_code = XEXP (PATTERN (insn), 1);
|
|
||||||
|
|
||||||
if (GET_CODE (insn_work_code) == LABEL_REF)
|
|
||||||
continue;
|
|
||||||
if (GET_CODE (insn_work_code) == IF_THEN_ELSE) {
|
|
||||||
rtx jump_target = XEXP (insn_work_code, 1);
|
|
||||||
|
|
||||||
if (jump_target == pc_rtx
|
|
||||||
|| (GET_CODE (jump_target) == (enum rtx_code)LABEL_REF))
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
is_indirect_jump = 1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return is_indirect_jump;
|
|
||||||
}
|
}
|
||||||
#endif /* HAIFA */
|
|
||||||
/* END CYGNUS LOCAL haifa */
|
/* END CYGNUS LOCAL haifa */
|
||||||
|
@ -1351,34 +1351,8 @@ find_blocks (first)
|
|||||||
|
|
||||||
if (GET_CODE (insn) == JUMP_INSN)
|
if (GET_CODE (insn) == JUMP_INSN)
|
||||||
{
|
{
|
||||||
rtx pat = PATTERN (insn);
|
|
||||||
int computed_jump = 0;
|
|
||||||
rtx x;
|
|
||||||
|
|
||||||
if (GET_CODE (pat) == PARALLEL)
|
if (computed_jump_p (insn))
|
||||||
{
|
|
||||||
int len = XVECLEN (pat, 0);
|
|
||||||
int has_use_labelref = 0;
|
|
||||||
int i;
|
|
||||||
|
|
||||||
for (i = len - 1; i >= 0; i--)
|
|
||||||
if (GET_CODE (XVECEXP (pat, 0, i)) == USE
|
|
||||||
&& GET_CODE (XEXP (XVECEXP (pat, 0, i), 0)) == LABEL_REF)
|
|
||||||
has_use_labelref = 1;
|
|
||||||
|
|
||||||
if (! has_use_labelref)
|
|
||||||
for (i = len - 1; i >= 0; i--)
|
|
||||||
if (GET_CODE (XVECEXP (pat, 0, i)) == SET
|
|
||||||
&& SET_DEST (XVECEXP (pat, 0, i)) == pc_rtx
|
|
||||||
&& uses_reg_or_mem (SET_SRC (XVECEXP (pat, 0, i))))
|
|
||||||
computed_jump = 1;
|
|
||||||
}
|
|
||||||
else if (GET_CODE (pat) == SET
|
|
||||||
&& SET_DEST (pat) == pc_rtx
|
|
||||||
&& uses_reg_or_mem (SET_SRC (pat)))
|
|
||||||
computed_jump = 1;
|
|
||||||
|
|
||||||
if (computed_jump)
|
|
||||||
{
|
{
|
||||||
for (x = label_value_list; x; x = XEXP (x, 1))
|
for (x = label_value_list; x; x = XEXP (x, 1))
|
||||||
record_label_references (insn,
|
record_label_references (insn,
|
||||||
|
@ -978,3 +978,4 @@ extern void init_alias_analysis PROTO((void));
|
|||||||
extern void end_alias_analysis PROTO((void));
|
extern void end_alias_analysis PROTO((void));
|
||||||
extern void mark_user_reg PROTO((rtx));
|
extern void mark_user_reg PROTO((rtx));
|
||||||
extern void mark_reg_pointer PROTO((rtx, int));
|
extern void mark_reg_pointer PROTO((rtx, int));
|
||||||
|
extern int computed_jump_p PROTO((rtx));
|
||||||
|
@ -25,6 +25,10 @@ Boston, MA 02111-1307, USA. */
|
|||||||
void note_stores ();
|
void note_stores ();
|
||||||
int reg_set_p ();
|
int reg_set_p ();
|
||||||
|
|
||||||
|
|
||||||
|
/* Forward declarations */
|
||||||
|
static int jmp_uses_reg_or_mem PROTO((rtx));
|
||||||
|
|
||||||
/* Bit flags that specify the machine subtype we are compiling for.
|
/* Bit flags that specify the machine subtype we are compiling for.
|
||||||
Bits are tested using macros TARGET_... defined in the tm.h file
|
Bits are tested using macros TARGET_... defined in the tm.h file
|
||||||
and set by `-m...' switches. Must be defined in rtlanal.c. */
|
and set by `-m...' switches. Must be defined in rtlanal.c. */
|
||||||
@ -1847,3 +1851,95 @@ replace_regs (x, reg_map, nregs, replace_dest)
|
|||||||
}
|
}
|
||||||
return x;
|
return x;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* Return 1 if X, the SRC_SRC of SET of (pc) contain a REG or MEM that is
|
||||||
|
not in the constant pool and not in the condition of an IF_THEN_ELSE. */
|
||||||
|
|
||||||
|
static int
|
||||||
|
jmp_uses_reg_or_mem (x)
|
||||||
|
rtx x;
|
||||||
|
{
|
||||||
|
enum rtx_code code = GET_CODE (x);
|
||||||
|
int i, j;
|
||||||
|
char *fmt;
|
||||||
|
|
||||||
|
switch (code)
|
||||||
|
{
|
||||||
|
case CONST:
|
||||||
|
case LABEL_REF:
|
||||||
|
case PC:
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
case REG:
|
||||||
|
return 1;
|
||||||
|
|
||||||
|
case MEM:
|
||||||
|
return ! (GET_CODE (XEXP (x, 0)) == SYMBOL_REF
|
||||||
|
&& CONSTANT_POOL_ADDRESS_P (XEXP (x, 0)));
|
||||||
|
|
||||||
|
case IF_THEN_ELSE:
|
||||||
|
return (jmp_uses_reg_or_mem (XEXP (x, 1))
|
||||||
|
|| jmp_uses_reg_or_mem (XEXP (x, 2)));
|
||||||
|
|
||||||
|
case PLUS: case MINUS: case MULT:
|
||||||
|
return (jmp_uses_reg_or_mem (XEXP (x, 0))
|
||||||
|
|| jmp_uses_reg_or_mem (XEXP (x, 1)));
|
||||||
|
}
|
||||||
|
|
||||||
|
fmt = GET_RTX_FORMAT (code);
|
||||||
|
for (i = GET_RTX_LENGTH (code) - 1; i >= 0; i--)
|
||||||
|
{
|
||||||
|
if (fmt[i] == 'e'
|
||||||
|
&& jmp_uses_reg_or_mem (XEXP (x, i)))
|
||||||
|
return 1;
|
||||||
|
|
||||||
|
if (fmt[i] == 'E')
|
||||||
|
for (j = 0; j < XVECLEN (x, i); j++)
|
||||||
|
if (jmp_uses_reg_or_mem (XVECEXP (x, i, j)))
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Return nonzero if INSN is an indirect jump (aka computed jump).
|
||||||
|
|
||||||
|
Tablejumps and casesi insns are not considered indirect jumps;
|
||||||
|
we can recognize them by a (use (lael_ref)). */
|
||||||
|
|
||||||
|
int
|
||||||
|
computed_jump_p (insn)
|
||||||
|
rtx insn;
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
if (GET_CODE (insn) == JUMP_INSN)
|
||||||
|
{
|
||||||
|
rtx pat = PATTERN (insn);
|
||||||
|
int computed_jump = 0;
|
||||||
|
|
||||||
|
if (GET_CODE (pat) == PARALLEL)
|
||||||
|
{
|
||||||
|
int len = XVECLEN (pat, 0);
|
||||||
|
int has_use_labelref = 0;
|
||||||
|
|
||||||
|
for (i = len - 1; i >= 0; i--)
|
||||||
|
if (GET_CODE (XVECEXP (pat, 0, i)) == USE
|
||||||
|
&& (GET_CODE (XEXP (XVECEXP (pat, 0, i), 0))
|
||||||
|
== LABEL_REF))
|
||||||
|
has_use_labelref = 1;
|
||||||
|
|
||||||
|
if (! has_use_labelref)
|
||||||
|
for (i = len - 1; i >= 0; i--)
|
||||||
|
if (GET_CODE (XVECEXP (pat, 0, i)) == SET
|
||||||
|
&& SET_DEST (XVECEXP (pat, 0, i)) == pc_rtx
|
||||||
|
&& jmp_uses_reg_or_mem (SET_SRC (XVECEXP (pat, 0, 1))))
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
else if (GET_CODE (pat) == SET
|
||||||
|
&& SET_DEST (pat) == pc_rtx
|
||||||
|
&& jmp_uses_reg_or_mem (SET_SRC (pat)))
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user