re PR middle-end/17503 (quadratic behaviour in invalid_mode_change_p)
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. From-SVN: r88067
This commit is contained in:
parent
84f7a28c9b
commit
41bf2a8b17
6 changed files with 119 additions and 52 deletions
|
@ -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
|
||||
|
|
|
@ -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)
|
||||
|
|
19
gcc/flow.c
19
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
|
||||
|
|
125
gcc/regclass.c
125
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;
|
||||
struct subregs_of_mode_node dummy, *node;
|
||||
enum machine_mode to;
|
||||
unsigned char mask;
|
||||
|
||||
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;
|
||||
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 */
|
||||
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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);
|
||||
|
|
Loading…
Add table
Reference in a new issue