summaryrefslogtreecommitdiffstats
path: root/gcc
diff options
context:
space:
mode:
authorrth <rth@138bc75d-0d04-0410-961f-82ee72b054a4>2004-09-24 19:47:05 +0000
committerrth <rth@138bc75d-0d04-0410-961f-82ee72b054a4>2004-09-24 19:47:05 +0000
commit3dc77328bc12b3fda1709cb5a6da381b6144fc2c (patch)
tree8f489fcd2a7911641c9c974bdfda7d1ab77702cc /gcc
parentab5a7d5536558eec88d4f6c8096381c8cb1efbbc (diff)
downloadppe42-gcc-3dc77328bc12b3fda1709cb5a6da381b6144fc2c.tar.gz
ppe42-gcc-3dc77328bc12b3fda1709cb5a6da381b6144fc2c.zip
PR rtl-opt/17503
* regclass.c (subregs_of_mode): Turn into an htab. Make static. (som_hash, som_eq): New. (init_subregs_of_mode, record_subregs_of_mode): New. (cannot_change_mode_set_regs): Rewrite for htab implementation. (invalid_mode_change_p): Likewise. * combine.c (gen_lowpart_for_combine): Use record_subregs_of_mode. * flow.c (mark_used_regs): Likewise. (life_analysis): Use init_subregs_of_mode. * regs.h (subregs_of_mode): Remove. * rtl.h (init_subregs_of_mode, record_subregs_of_mode): Declare. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@88067 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'gcc')
-rw-r--r--gcc/ChangeLog14
-rw-r--r--gcc/combine.c9
-rw-r--r--gcc/flow.c19
-rw-r--r--gcc/regclass.c127
-rw-r--r--gcc/regs.h2
-rw-r--r--gcc/rtl.h2
6 files changed, 120 insertions, 53 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 74b4a425f54..070d85c8254 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,17 @@
+2004-09-24 Richard Henderson <rth@redhat.com>
+
+ PR rtl-opt/17503
+ * regclass.c (subregs_of_mode): Turn into an htab. Make static.
+ (som_hash, som_eq): New.
+ (init_subregs_of_mode, record_subregs_of_mode): New.
+ (cannot_change_mode_set_regs): Rewrite for htab implementation.
+ (invalid_mode_change_p): Likewise.
+ * combine.c (gen_lowpart_for_combine): Use record_subregs_of_mode.
+ * flow.c (mark_used_regs): Likewise.
+ (life_analysis): Use init_subregs_of_mode.
+ * regs.h (subregs_of_mode): Remove.
+ * rtl.h (init_subregs_of_mode, record_subregs_of_mode): Declare.
+
2004-09-24 Andrew Pinski <pinskia@physics.uc.edu>
* tree-ssa-phiopt.c (conditional_replacement): Use the correct
diff --git a/gcc/combine.c b/gcc/combine.c
index 24ebbc97147..f0b5b0698dd 100644
--- a/gcc/combine.c
+++ b/gcc/combine.c
@@ -9327,13 +9327,8 @@ gen_lowpart_for_combine (enum machine_mode mode, rtx x)
result = gen_lowpart_common (mode, x);
#ifdef CANNOT_CHANGE_MODE_CLASS
- if (result != 0
- && GET_CODE (result) == SUBREG
- && REG_P (SUBREG_REG (result))
- && REGNO (SUBREG_REG (result)) >= FIRST_PSEUDO_REGISTER)
- bitmap_set_bit (&subregs_of_mode, REGNO (SUBREG_REG (result))
- * MAX_MACHINE_MODE
- + GET_MODE (result));
+ if (result != 0 && GET_CODE (result) == SUBREG)
+ record_subregs_of_mode (result);
#endif
if (result)
diff --git a/gcc/flow.c b/gcc/flow.c
index d1e7e2d61c4..02f7ff21505 100644
--- a/gcc/flow.c
+++ b/gcc/flow.c
@@ -377,7 +377,7 @@ life_analysis (FILE *file, int flags)
#ifdef CANNOT_CHANGE_MODE_CLASS
if (flags & PROP_REG_INFO)
- bitmap_initialize (&subregs_of_mode, 1);
+ init_subregs_of_mode ();
#endif
if (! optimize)
@@ -3773,12 +3773,8 @@ mark_used_regs (struct propagate_block_info *pbi, rtx x, rtx cond, rtx insn)
case SUBREG:
#ifdef CANNOT_CHANGE_MODE_CLASS
- if ((flags & PROP_REG_INFO)
- && REG_P (SUBREG_REG (x))
- && REGNO (SUBREG_REG (x)) >= FIRST_PSEUDO_REGISTER)
- bitmap_set_bit (&subregs_of_mode, REGNO (SUBREG_REG (x))
- * MAX_MACHINE_MODE
- + GET_MODE (x));
+ if (flags & PROP_REG_INFO)
+ record_subregs_of_mode (x);
#endif
/* While we're here, optimize this case. */
@@ -3823,13 +3819,8 @@ mark_used_regs (struct propagate_block_info *pbi, rtx x, rtx cond, rtx insn)
|| GET_CODE (testreg) == SUBREG)
{
#ifdef CANNOT_CHANGE_MODE_CLASS
- if ((flags & PROP_REG_INFO)
- && GET_CODE (testreg) == SUBREG
- && REG_P (SUBREG_REG (testreg))
- && REGNO (SUBREG_REG (testreg)) >= FIRST_PSEUDO_REGISTER)
- bitmap_set_bit (&subregs_of_mode, REGNO (SUBREG_REG (testreg))
- * MAX_MACHINE_MODE
- + GET_MODE (testreg));
+ if ((flags & PROP_REG_INFO) && GET_CODE (testreg) == SUBREG)
+ record_subregs_of_mode (testreg);
#endif
/* Modifying a single register in an alternate mode
diff --git a/gcc/regclass.c b/gcc/regclass.c
index 1d33a0977b2..6d1d975f093 100644
--- a/gcc/regclass.c
+++ b/gcc/regclass.c
@@ -45,6 +45,7 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
#include "output.h"
#include "ggc.h"
#include "timevar.h"
+#include "hashtab.h"
static void init_reg_sets_1 (void);
static void init_reg_autoinc (void);
@@ -235,12 +236,6 @@ static char *in_inc_dec;
#endif /* FORBIDDEN_INC_DEC_CLASSES */
-#ifdef CANNOT_CHANGE_MODE_CLASS
-/* All registers that have been subreged. Indexed by regno * MAX_MACHINE_MODE
- + mode. */
-bitmap_head subregs_of_mode;
-#endif
-
/* Sample MEM values for use by memory_move_secondary_cost. */
static GTY(()) rtx top_of_stack[MAX_MACHINE_MODE];
@@ -2594,6 +2589,70 @@ regset_release_memory (void)
}
#ifdef CANNOT_CHANGE_MODE_CLASS
+
+struct subregs_of_mode_node
+{
+ unsigned int block;
+ unsigned char modes[MAX_MACHINE_MODE];
+};
+
+static htab_t subregs_of_mode;
+
+static hashval_t
+som_hash (const void *x)
+{
+ const struct subregs_of_mode_node *a = x;
+ return a->block;
+}
+
+static int
+som_eq (const void *x, const void *y)
+{
+ const struct subregs_of_mode_node *a = x;
+ const struct subregs_of_mode_node *b = y;
+ return a->block == b->block;
+}
+
+void
+init_subregs_of_mode (void)
+{
+ if (subregs_of_mode)
+ htab_empty (subregs_of_mode);
+ else
+ subregs_of_mode = htab_create (100, som_hash, som_eq, free);
+}
+
+void
+record_subregs_of_mode (rtx subreg)
+{
+ struct subregs_of_mode_node dummy, *node;
+ enum machine_mode mode;
+ unsigned int regno;
+ void **slot;
+
+ if (!REG_P (SUBREG_REG (subreg)))
+ return;
+
+ regno = REGNO (SUBREG_REG (subreg));
+ mode = GET_MODE (subreg);
+
+ if (regno < FIRST_PSEUDO_REGISTER)
+ return;
+
+ dummy.block = regno & -8;
+ slot = htab_find_slot_with_hash (subregs_of_mode, &dummy,
+ dummy.block, INSERT);
+ node = *slot;
+ if (node == NULL)
+ {
+ node = xcalloc (1, sizeof (*node));
+ node->block = regno & -8;
+ *slot = node;
+ }
+
+ node->modes[mode] |= 1 << (regno & 7);
+}
+
/* Set bits in *USED which correspond to registers which can't change
their mode from FROM to any mode in which REGNO was encountered. */
@@ -2601,19 +2660,23 @@ void
cannot_change_mode_set_regs (HARD_REG_SET *used, enum machine_mode from,
unsigned int regno)
{
+ struct subregs_of_mode_node dummy, *node;
enum machine_mode to;
- int n, i;
- int start = regno * MAX_MACHINE_MODE;
+ unsigned char mask;
+ unsigned int i;
- EXECUTE_IF_SET_IN_BITMAP (&subregs_of_mode, start, n,
- if (n >= MAX_MACHINE_MODE + start)
- return;
- to = n - start;
- for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
- if (! TEST_HARD_REG_BIT (*used, i)
- && REG_CANNOT_CHANGE_MODE_P (i, from, to))
- SET_HARD_REG_BIT (*used, i);
- );
+ dummy.block = regno & -8;
+ node = htab_find_with_hash (subregs_of_mode, &dummy, dummy.block);
+ if (node == NULL)
+ return;
+
+ mask = 1 << (regno & 7);
+ for (to = VOIDmode; to < NUM_MACHINE_MODES; to++)
+ if (node->modes[to] & mask)
+ for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
+ if (!TEST_HARD_REG_BIT (*used, i)
+ && REG_CANNOT_CHANGE_MODE_P (i, from, to))
+ SET_HARD_REG_BIT (*used, i);
}
/* Return 1 if REGNO has had an invalid mode change in CLASS from FROM
@@ -2621,20 +2684,24 @@ cannot_change_mode_set_regs (HARD_REG_SET *used, enum machine_mode from,
bool
invalid_mode_change_p (unsigned int regno, enum reg_class class,
- enum machine_mode from_mode)
+ enum machine_mode from)
{
- enum machine_mode to_mode;
- int n;
- int start = regno * MAX_MACHINE_MODE;
-
- EXECUTE_IF_SET_IN_BITMAP (&subregs_of_mode, start, n,
- if (n >= MAX_MACHINE_MODE + start)
- return 0;
- to_mode = n - start;
- if (CANNOT_CHANGE_MODE_CLASS (from_mode, to_mode, class))
- return 1;
- );
- return 0;
+ struct subregs_of_mode_node dummy, *node;
+ enum machine_mode to;
+ unsigned char mask;
+
+ dummy.block = regno & -8;
+ node = htab_find_with_hash (subregs_of_mode, &dummy, dummy.block);
+ if (node == NULL)
+ return false;
+
+ mask = 1 << (regno & 7);
+ for (to = VOIDmode; to < NUM_MACHINE_MODES; to++)
+ if (node->modes[to] & mask)
+ if (CANNOT_CHANGE_MODE_CLASS (from, to, class))
+ return true;
+
+ return false;
}
#endif /* CANNOT_CHANGE_MODE_CLASS */
diff --git a/gcc/regs.h b/gcc/regs.h
index 027b0e33c67..848c306a3ff 100644
--- a/gcc/regs.h
+++ b/gcc/regs.h
@@ -68,8 +68,6 @@ typedef struct reg_info_def
extern varray_type reg_n_info;
-extern bitmap_head subregs_of_mode;
-
/* Indexed by n, gives number of times (REG n) is used or set. */
#define REG_N_REFS(N) (VARRAY_REG (reg_n_info, N)->refs)
diff --git a/gcc/rtl.h b/gcc/rtl.h
index d96b3d4c433..8f7274a3c1b 100644
--- a/gcc/rtl.h
+++ b/gcc/rtl.h
@@ -2092,6 +2092,8 @@ extern void regclass (rtx, int, FILE *);
extern void reg_scan (rtx, unsigned int, int);
extern void reg_scan_update (rtx, rtx, unsigned int);
extern void fix_register (const char *, int, int);
+extern void init_subregs_of_mode (void);
+extern void record_subregs_of_mode (rtx);
#ifdef HARD_CONST
extern void cannot_change_mode_set_regs (HARD_REG_SET *,
enum machine_mode, unsigned int);
OpenPOWER on IntegriCloud