aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorJeffrey A Law <law@cygnus.com>1997-09-22 00:49:32 +0000
committerJeff Law <law@gcc.gnu.org>1997-09-21 18:49:32 -0600
commit2a1777af229bc5e9e738fd5bb8285ac0c1e24a7d (patch)
tree18e02cdfa9330785934ec403168033e5f85505e6 /gcc
parent37842442c3a0fc8e10d227cd7af112fdd4ef14e7 (diff)
downloadgcc-2a1777af229bc5e9e738fd5bb8285ac0c1e24a7d.zip
gcc-2a1777af229bc5e9e738fd5bb8285ac0c1e24a7d.tar.gz
gcc-2a1777af229bc5e9e738fd5bb8285ac0c1e24a7d.tar.bz2
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
Diffstat (limited to 'gcc')
-rw-r--r--gcc/ChangeLog14
-rw-r--r--gcc/genattrtab.c7
-rw-r--r--gcc/loop.c42
-rw-r--r--gcc/reg-stack.c28
-rw-r--r--gcc/rtl.h1
-rw-r--r--gcc/rtlanal.c96
6 files changed, 133 insertions, 55 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 89de397..d081529 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,5 +1,19 @@
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.
(check_bct_param): Likewise.
diff --git a/gcc/genattrtab.c b/gcc/genattrtab.c
index bde3f51..8e4f423 100644
--- a/gcc/genattrtab.c
+++ b/gcc/genattrtab.c
@@ -483,6 +483,8 @@ struct attr_hash *attr_hash_table[RTL_HASH_SIZE];
codes are made. */
#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. */
static void
@@ -5573,6 +5575,11 @@ main (argc, argv)
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 */
true_rtx = rtx_alloc (CONST_INT);
XWINT (true_rtx, 0) = 1;
diff --git a/gcc/loop.c b/gcc/loop.c
index d73d339..3bbe741 100644
--- a/gcc/loop.c
+++ b/gcc/loop.c
@@ -330,13 +330,14 @@ static void insert_bct ();
/* Auxiliary function that inserts the bct pattern into the loop */
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 ();
#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. */
int add_cost;
@@ -507,11 +508,9 @@ loop_optimize (f, dumpfile)
if (flag_unroll_loops && write_symbols != NO_DEBUG)
find_loop_tree_blocks ();
-#ifdef HAIFA
- /* determine if the function has indirect jump. If it does,
- we cannot instrument loops in this function with bct */
+ /* Determine if the function has indirect jump. On some systems
+ this prevents low overhead loop instructions from being used. */
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
before outer ones. */
@@ -7592,8 +7591,12 @@ loop_number (loop_start, loop_end)
return loop_num;
}
+#endif /* HAIFA */
+
+/* Scan the function and determine whether it has indirect (computed) jumps.
-/* scan the function and determine whether it has indirect (computed) jump */
+ 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
indirect_jump_in_function_p (start)
rtx start;
@@ -7601,25 +7604,8 @@ indirect_jump_in_function_p (start)
rtx insn;
int is_indirect_jump = 0;
- for (insn = start; insn; insn = NEXT_INSN (insn)) {
- if (GET_CODE (insn) == JUMP_INSN) {
- if (GET_CODE (PATTERN (insn)) == SET) {
- 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;
+ for (insn = start; insn; insn = NEXT_INSN (insn))
+ if (computed_jump_p (insn))
+ return 1;
}
-#endif /* HAIFA */
/* END CYGNUS LOCAL haifa */
diff --git a/gcc/reg-stack.c b/gcc/reg-stack.c
index 881d94f..5b0c8ab 100644
--- a/gcc/reg-stack.c
+++ b/gcc/reg-stack.c
@@ -1351,34 +1351,8 @@ find_blocks (first)
if (GET_CODE (insn) == JUMP_INSN)
{
- rtx pat = PATTERN (insn);
- int computed_jump = 0;
- rtx x;
- if (GET_CODE (pat) == PARALLEL)
- {
- 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)
+ if (computed_jump_p (insn))
{
for (x = label_value_list; x; x = XEXP (x, 1))
record_label_references (insn,
diff --git a/gcc/rtl.h b/gcc/rtl.h
index 4b8d510..f4d1db9 100644
--- a/gcc/rtl.h
+++ b/gcc/rtl.h
@@ -978,3 +978,4 @@ extern void init_alias_analysis PROTO((void));
extern void end_alias_analysis PROTO((void));
extern void mark_user_reg PROTO((rtx));
extern void mark_reg_pointer PROTO((rtx, int));
+extern int computed_jump_p PROTO((rtx));
diff --git a/gcc/rtlanal.c b/gcc/rtlanal.c
index 3e6b4ae..069c5e8 100644
--- a/gcc/rtlanal.c
+++ b/gcc/rtlanal.c
@@ -25,6 +25,10 @@ Boston, MA 02111-1307, USA. */
void note_stores ();
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.
Bits are tested using macros TARGET_... defined in the tm.h file
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 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;
+}