Commit 56b138ae by Richard Sandiford Committed by Richard Sandiford

hard-reg-set.h (GO_IF_HARD_REG_SUBSET, [...]): Delete in favor of...

gcc/
	* hard-reg-set.h (GO_IF_HARD_REG_SUBSET, GO_IF_HARD_REG_EQUAL): Delete
	in favor of...
	(hard_reg_subset_p, hard_reg_sets_equal_p, hard_reg_sets_intersect_p)
	(hard_reg_set_empty_p): ...these new functions.
	* bt-load.c (choose_btr): Use hard_reg_subset_p instead of
	GO_IF_HARD_REG_SUBSET.
	* cfgcleanup.c (old_insns_match_p): Use hard_reg_sets_equal_p
	instead of GO_IF_HARD_REG_EQUAL.
	* df-problems.c (df_urec_local_compute): Use hard_reg_set_empty_p
	instead of GO_IF_HARD_REG_EQUAL.
	* global.c (find_reg): Use hard_reg_set_empty_p instead of
	GO_IF_HARD_REG_SUBSET.
	(modify_reg_pav): Use hard_reg_set_empty_p instead of
	GO_IF_HARD_REG_EQUAL.
	* local-alloc.c (find_free_reg): Use hard_reg_subset_p instead
	of GO_IF_HARD_REG_SUBSET.
	* reg-stack.c (change_stack, convert_regs_1): Use hard_reg_sets_equal_p
	instead of GO_IF_HARD_REG_EQUAL.
	* regclass.c (init_reg_sets_1, reg_scan_mark_refs): Use
	hard_reg_subset_p instead of GO_IF_HARD_REG_SUBSET.
	(reg_classes_intersect_p): Use hard_reg_sets_intersect_p instead
	of GO_IF_HARD_REG_SUBSET,
	* reload1.c (finish_spills): Use hard_reg_subset_p instead of
	GO_IF_HARD_REG_SUBSET.
	* struct-equiv.c (death_notes_match_p): Use hard_reg_sets_equal_p
	instead of GO_IF_HARD_REG_EQUAL.
	* config/sh/sh.c (push_regs, calc_live_regs): Use
	hard_reg_sets_intersect_p instead of hard_regs_intersect_p.
	(hard_regs_intersect_p): Delete.

From-SVN: r124954
parent 965ff670
2007-05-22 Richard Sandiford <richard@codesourcery.com>
* hard-reg-set.h (GO_IF_HARD_REG_SUBSET, GO_IF_HARD_REG_EQUAL): Delete
in favor of...
(hard_reg_subset_p, hard_reg_sets_equal_p, hard_reg_sets_intersect_p)
(hard_reg_set_empty_p): ...these new functions.
* bt-load.c (choose_btr): Use hard_reg_subset_p instead of
GO_IF_HARD_REG_SUBSET.
* cfgcleanup.c (old_insns_match_p): Use hard_reg_sets_equal_p
instead of GO_IF_HARD_REG_EQUAL.
* df-problems.c (df_urec_local_compute): Use hard_reg_set_empty_p
instead of GO_IF_HARD_REG_EQUAL.
* global.c (find_reg): Use hard_reg_set_empty_p instead of
GO_IF_HARD_REG_SUBSET.
(modify_reg_pav): Use hard_reg_set_empty_p instead of
GO_IF_HARD_REG_EQUAL.
* local-alloc.c (find_free_reg): Use hard_reg_subset_p instead
of GO_IF_HARD_REG_SUBSET.
* reg-stack.c (change_stack, convert_regs_1): Use hard_reg_sets_equal_p
instead of GO_IF_HARD_REG_EQUAL.
* regclass.c (init_reg_sets_1, reg_scan_mark_refs): Use
hard_reg_subset_p instead of GO_IF_HARD_REG_SUBSET.
(reg_classes_intersect_p): Use hard_reg_sets_intersect_p instead
of GO_IF_HARD_REG_SUBSET,
* reload1.c (finish_spills): Use hard_reg_subset_p instead of
GO_IF_HARD_REG_SUBSET.
* struct-equiv.c (death_notes_match_p): Use hard_reg_sets_equal_p
instead of GO_IF_HARD_REG_EQUAL.
* config/sh/sh.c (push_regs, calc_live_regs): Use
hard_reg_sets_intersect_p instead of hard_regs_intersect_p.
(hard_regs_intersect_p): Delete.
2007-05-22 Janis Johnson <janis187@us.ibm.com> 2007-05-22 Janis Johnson <janis187@us.ibm.com>
* doc/sourcebuild.texi (Test Directives) Add dg-message. * doc/sourcebuild.texi (Test Directives) Add dg-message.
......
...@@ -988,20 +988,19 @@ static int ...@@ -988,20 +988,19 @@ static int
choose_btr (HARD_REG_SET used_btrs) choose_btr (HARD_REG_SET used_btrs)
{ {
int i; int i;
GO_IF_HARD_REG_SUBSET (all_btrs, used_btrs, give_up);
for (i = 0; i < FIRST_PSEUDO_REGISTER; i++) if (!hard_reg_set_subset_p (all_btrs, used_btrs))
{ for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
{
#ifdef REG_ALLOC_ORDER #ifdef REG_ALLOC_ORDER
int regno = reg_alloc_order[i]; int regno = reg_alloc_order[i];
#else #else
int regno = i; int regno = i;
#endif #endif
if (TEST_HARD_REG_BIT (all_btrs, regno) if (TEST_HARD_REG_BIT (all_btrs, regno)
&& !TEST_HARD_REG_BIT (used_btrs, regno)) && !TEST_HARD_REG_BIT (used_btrs, regno))
return regno; return regno;
} }
give_up:
return -1; return -1;
} }
......
...@@ -974,12 +974,8 @@ old_insns_match_p (int mode ATTRIBUTE_UNUSED, rtx i1, rtx i2) ...@@ -974,12 +974,8 @@ old_insns_match_p (int mode ATTRIBUTE_UNUSED, rtx i1, rtx i2)
if (REG_NOTE_KIND (note) == REG_DEAD && STACK_REG_P (XEXP (note, 0))) if (REG_NOTE_KIND (note) == REG_DEAD && STACK_REG_P (XEXP (note, 0)))
SET_HARD_REG_BIT (i2_regset, REGNO (XEXP (note, 0))); SET_HARD_REG_BIT (i2_regset, REGNO (XEXP (note, 0)));
GO_IF_HARD_REG_EQUAL (i1_regset, i2_regset, done); if (!hard_reg_set_equal_p (i1_regset, i2_regset))
return false;
return false;
done:
;
} }
#endif #endif
......
...@@ -267,7 +267,6 @@ static bool sh_callee_copies (CUMULATIVE_ARGS *, enum machine_mode, ...@@ -267,7 +267,6 @@ static bool sh_callee_copies (CUMULATIVE_ARGS *, enum machine_mode,
static int sh_arg_partial_bytes (CUMULATIVE_ARGS *, enum machine_mode, static int sh_arg_partial_bytes (CUMULATIVE_ARGS *, enum machine_mode,
tree, bool); tree, bool);
static int sh_dwarf_calling_convention (tree); static int sh_dwarf_calling_convention (tree);
static int hard_regs_intersect_p (HARD_REG_SET *, HARD_REG_SET *);
/* Initialize the GCC target structure. */ /* Initialize the GCC target structure. */
...@@ -5777,7 +5776,7 @@ push_regs (HARD_REG_SET *mask, int interrupt_handler) ...@@ -5777,7 +5776,7 @@ push_regs (HARD_REG_SET *mask, int interrupt_handler)
and we have to push any floating point register, we need and we have to push any floating point register, we need
to switch to the correct precision first. */ to switch to the correct precision first. */
if (i == FIRST_FP_REG && interrupt_handler && TARGET_FMOVD if (i == FIRST_FP_REG && interrupt_handler && TARGET_FMOVD
&& hard_regs_intersect_p (mask, &reg_class_contents[DF_REGS])) && hard_reg_set_intersect_p (*mask, reg_class_contents[DF_REGS]))
{ {
HARD_REG_SET unsaved; HARD_REG_SET unsaved;
...@@ -5987,10 +5986,10 @@ calc_live_regs (HARD_REG_SET *live_regs_mask) ...@@ -5987,10 +5986,10 @@ calc_live_regs (HARD_REG_SET *live_regs_mask)
Make sure we save at least one general purpose register when we need Make sure we save at least one general purpose register when we need
to save target registers. */ to save target registers. */
if (interrupt_handler if (interrupt_handler
&& hard_regs_intersect_p (live_regs_mask, && hard_reg_set_intersect_p (*live_regs_mask,
&reg_class_contents[TARGET_REGS]) reg_class_contents[TARGET_REGS])
&& ! hard_regs_intersect_p (live_regs_mask, && ! hard_reg_set_intersect_p (*live_regs_mask,
&reg_class_contents[GENERAL_REGS])) reg_class_contents[GENERAL_REGS]))
{ {
SET_HARD_REG_BIT (*live_regs_mask, R0_REG); SET_HARD_REG_BIT (*live_regs_mask, R0_REG);
count += GET_MODE_SIZE (REGISTER_NATURAL_MODE (R0_REG)); count += GET_MODE_SIZE (REGISTER_NATURAL_MODE (R0_REG));
...@@ -6766,8 +6765,8 @@ sh_expand_epilogue (bool sibcall_p) ...@@ -6766,8 +6765,8 @@ sh_expand_epilogue (bool sibcall_p)
int j = (FIRST_PSEUDO_REGISTER - 1) - i; int j = (FIRST_PSEUDO_REGISTER - 1) - i;
if (j == FPSCR_REG && current_function_interrupt && TARGET_FMOVD if (j == FPSCR_REG && current_function_interrupt && TARGET_FMOVD
&& hard_regs_intersect_p (&live_regs_mask, && hard_reg_set_intersect_p (live_regs_mask,
&reg_class_contents[DF_REGS])) reg_class_contents[DF_REGS]))
fpscr_deferred = 1; fpscr_deferred = 1;
else if (j != PR_REG && TEST_HARD_REG_BIT (live_regs_mask, j)) else if (j != PR_REG && TEST_HARD_REG_BIT (live_regs_mask, j))
pop (j); pop (j);
...@@ -10643,21 +10642,6 @@ sh_init_cumulative_args (CUMULATIVE_ARGS * pcum, ...@@ -10643,21 +10642,6 @@ sh_init_cumulative_args (CUMULATIVE_ARGS * pcum,
} }
} }
/* Determine if two hard register sets intersect.
Return 1 if they do. */
static int
hard_regs_intersect_p (HARD_REG_SET *a, HARD_REG_SET *b)
{
HARD_REG_SET c;
COPY_HARD_REG_SET (c, *a);
AND_HARD_REG_SET (c, *b);
GO_IF_HARD_REG_SUBSET (c, reg_class_contents[(int) NO_REGS], lose);
return 1;
lose:
return 0;
}
/* Replace any occurrence of FROM(n) in X with TO(n). The function does /* Replace any occurrence of FROM(n) in X with TO(n). The function does
not enter into CONST_DOUBLE for the replace. not enter into CONST_DOUBLE for the replace.
......
...@@ -2487,7 +2487,7 @@ df_urec_local_compute (struct dataflow *dflow, ...@@ -2487,7 +2487,7 @@ df_urec_local_compute (struct dataflow *dflow,
bitmap_iterator bi; bitmap_iterator bi;
#ifdef STACK_REGS #ifdef STACK_REGS
int i; int i;
HARD_REG_SET zero, stack_hard_regs, used; HARD_REG_SET stack_hard_regs, used;
struct df_urec_problem_data *problem_data struct df_urec_problem_data *problem_data
= (struct df_urec_problem_data *) dflow->problem_data; = (struct df_urec_problem_data *) dflow->problem_data;
...@@ -2498,7 +2498,6 @@ df_urec_local_compute (struct dataflow *dflow, ...@@ -2498,7 +2498,6 @@ df_urec_local_compute (struct dataflow *dflow,
FIXME: This seems like an incredibly poor idea. */ FIXME: This seems like an incredibly poor idea. */
CLEAR_HARD_REG_SET (zero);
CLEAR_HARD_REG_SET (stack_hard_regs); CLEAR_HARD_REG_SET (stack_hard_regs);
for (i = FIRST_STACK_REG; i <= LAST_STACK_REG; i++) for (i = FIRST_STACK_REG; i <= LAST_STACK_REG; i++)
SET_HARD_REG_BIT (stack_hard_regs, i); SET_HARD_REG_BIT (stack_hard_regs, i);
...@@ -2508,10 +2507,8 @@ df_urec_local_compute (struct dataflow *dflow, ...@@ -2508,10 +2507,8 @@ df_urec_local_compute (struct dataflow *dflow,
COPY_HARD_REG_SET (used, reg_class_contents[reg_preferred_class (i)]); COPY_HARD_REG_SET (used, reg_class_contents[reg_preferred_class (i)]);
IOR_HARD_REG_SET (used, reg_class_contents[reg_alternate_class (i)]); IOR_HARD_REG_SET (used, reg_class_contents[reg_alternate_class (i)]);
AND_HARD_REG_SET (used, stack_hard_regs); AND_HARD_REG_SET (used, stack_hard_regs);
GO_IF_HARD_REG_EQUAL (used, zero, skip); if (!hard_reg_set_empty_p (used))
bitmap_set_bit (problem_data->stack_regs, i); bitmap_set_bit (problem_data->stack_regs, i);
skip:
;
} }
#endif #endif
......
...@@ -1161,10 +1161,8 @@ find_reg (int num, HARD_REG_SET losers, int alt_regs_p, int accept_call_clobbere ...@@ -1161,10 +1161,8 @@ find_reg (int num, HARD_REG_SET losers, int alt_regs_p, int accept_call_clobbere
preferred registers. */ preferred registers. */
AND_COMPL_HARD_REG_SET (allocno[num].hard_reg_copy_preferences, used); AND_COMPL_HARD_REG_SET (allocno[num].hard_reg_copy_preferences, used);
GO_IF_HARD_REG_SUBSET (allocno[num].hard_reg_copy_preferences, if (!hard_reg_set_empty_p (allocno[num].hard_reg_copy_preferences)
reg_class_contents[(int) NO_REGS], no_copy_prefs); && best_reg >= 0)
if (best_reg >= 0)
{ {
for (i = 0; i < FIRST_PSEUDO_REGISTER; i++) for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
if (TEST_HARD_REG_BIT (allocno[num].hard_reg_copy_preferences, i) if (TEST_HARD_REG_BIT (allocno[num].hard_reg_copy_preferences, i)
...@@ -1197,13 +1195,10 @@ find_reg (int num, HARD_REG_SET losers, int alt_regs_p, int accept_call_clobbere ...@@ -1197,13 +1195,10 @@ find_reg (int num, HARD_REG_SET losers, int alt_regs_p, int accept_call_clobbere
} }
} }
} }
no_copy_prefs:
AND_COMPL_HARD_REG_SET (allocno[num].hard_reg_preferences, used); AND_COMPL_HARD_REG_SET (allocno[num].hard_reg_preferences, used);
GO_IF_HARD_REG_SUBSET (allocno[num].hard_reg_preferences, if (!hard_reg_set_empty_p (allocno[num].hard_reg_preferences)
reg_class_contents[(int) NO_REGS], no_prefs); && best_reg >= 0)
if (best_reg >= 0)
{ {
for (i = 0; i < FIRST_PSEUDO_REGISTER; i++) for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
if (TEST_HARD_REG_BIT (allocno[num].hard_reg_preferences, i) if (TEST_HARD_REG_BIT (allocno[num].hard_reg_preferences, i)
...@@ -2437,10 +2432,9 @@ modify_reg_pav (void) ...@@ -2437,10 +2432,9 @@ modify_reg_pav (void)
struct bb_info *bb_info; struct bb_info *bb_info;
#ifdef STACK_REGS #ifdef STACK_REGS
int i; int i;
HARD_REG_SET zero, stack_hard_regs, used; HARD_REG_SET stack_hard_regs, used;
bitmap stack_regs; bitmap stack_regs;
CLEAR_HARD_REG_SET (zero);
CLEAR_HARD_REG_SET (stack_hard_regs); CLEAR_HARD_REG_SET (stack_hard_regs);
for (i = FIRST_STACK_REG; i <= LAST_STACK_REG; i++) for (i = FIRST_STACK_REG; i <= LAST_STACK_REG; i++)
SET_HARD_REG_BIT(stack_hard_regs, i); SET_HARD_REG_BIT(stack_hard_regs, i);
...@@ -2450,10 +2444,8 @@ modify_reg_pav (void) ...@@ -2450,10 +2444,8 @@ modify_reg_pav (void)
COPY_HARD_REG_SET (used, reg_class_contents[reg_preferred_class (i)]); COPY_HARD_REG_SET (used, reg_class_contents[reg_preferred_class (i)]);
IOR_HARD_REG_SET (used, reg_class_contents[reg_alternate_class (i)]); IOR_HARD_REG_SET (used, reg_class_contents[reg_alternate_class (i)]);
AND_HARD_REG_SET (used, stack_hard_regs); AND_HARD_REG_SET (used, stack_hard_regs);
GO_IF_HARD_REG_EQUAL(used, zero, skip); if (!hard_reg_set_empty_p (used))
bitmap_set_bit (stack_regs, i); bitmap_set_bit (stack_regs, i);
skip:
;
} }
#endif #endif
FOR_EACH_BB (bb) FOR_EACH_BB (bb)
......
...@@ -83,9 +83,12 @@ typedef HARD_REG_ELT_TYPE HARD_REG_SET[HARD_REG_SET_LONGS]; ...@@ -83,9 +83,12 @@ typedef HARD_REG_ELT_TYPE HARD_REG_SET[HARD_REG_SET_LONGS];
IOR_COMPL_HARD_REG_SET and AND_COMPL_HARD_REG_SET IOR_COMPL_HARD_REG_SET and AND_COMPL_HARD_REG_SET
which use the complement of the set FROM. which use the complement of the set FROM.
Also define GO_IF_HARD_REG_SUBSET (X, Y, TO): Also define:
if X is a subset of Y, go to TO.
*/ hard_reg_set_subset_p (X, Y), which returns true if X is a subset of Y.
hard_reg_set_equal_p (X, Y), which returns true if X and Y are equal.
hard_reg_set_intersect_p (X, Y), which returns true if X and Y intersect.
hard_reg_set_empty_p (X), which returns true if X is empty. */
#ifdef HARD_REG_SET #ifdef HARD_REG_SET
...@@ -107,9 +110,29 @@ typedef HARD_REG_ELT_TYPE HARD_REG_SET[HARD_REG_SET_LONGS]; ...@@ -107,9 +110,29 @@ typedef HARD_REG_ELT_TYPE HARD_REG_SET[HARD_REG_SET_LONGS];
#define AND_HARD_REG_SET(TO, FROM) ((TO) &= (FROM)) #define AND_HARD_REG_SET(TO, FROM) ((TO) &= (FROM))
#define AND_COMPL_HARD_REG_SET(TO, FROM) ((TO) &= ~ (FROM)) #define AND_COMPL_HARD_REG_SET(TO, FROM) ((TO) &= ~ (FROM))
#define GO_IF_HARD_REG_SUBSET(X,Y,TO) if (HARD_CONST (0) == ((X) & ~(Y))) goto TO static inline bool
hard_reg_set_subset_p (const HARD_REG_SET x, const HARD_REG_SET y)
#define GO_IF_HARD_REG_EQUAL(X,Y,TO) if ((X) == (Y)) goto TO {
return (x & ~y) == HARD_CONST (0);
}
static inline bool
hard_reg_set_equal_p (const HARD_REG_SET x, const HARD_REG_SET y)
{
return x == y;
}
static inline bool
hard_reg_set_intersect_p (const HARD_REG_SET x, const HARD_REG_SET y)
{
return (x & y) != HARD_CONST (0);
}
static inline bool
hard_reg_set_empty_p (const HARD_REG_SET x)
{
return x == HARD_CONST (0);
}
#else #else
...@@ -168,17 +191,29 @@ do { HARD_REG_ELT_TYPE *scan_tp_ = (TO), *scan_fp_ = (FROM); \ ...@@ -168,17 +191,29 @@ do { HARD_REG_ELT_TYPE *scan_tp_ = (TO), *scan_fp_ = (FROM); \
scan_tp_[0] |= ~ scan_fp_[0]; \ scan_tp_[0] |= ~ scan_fp_[0]; \
scan_tp_[1] |= ~ scan_fp_[1]; } while (0) scan_tp_[1] |= ~ scan_fp_[1]; } while (0)
#define GO_IF_HARD_REG_SUBSET(X,Y,TO) \ static inline bool
do { HARD_REG_ELT_TYPE *scan_xp_ = (X), *scan_yp_ = (Y); \ hard_reg_set_subset_p (const HARD_REG_SET x, const HARD_REG_SET y)
if ((0 == (scan_xp_[0] & ~ scan_yp_[0])) \ {
&& (0 == (scan_xp_[1] & ~ scan_yp_[1]))) \ return (x[0] & ~y[0]) == 0 && (x[1] & ~y[1]) == 0;
goto TO; } while (0) }
#define GO_IF_HARD_REG_EQUAL(X,Y,TO) \ static inline bool
do { HARD_REG_ELT_TYPE *scan_xp_ = (X), *scan_yp_ = (Y); \ hard_reg_set_equal_p (const HARD_REG_SET x, const HARD_REG_SET y)
if ((scan_xp_[0] == scan_yp_[0]) \ {
&& (scan_xp_[1] == scan_yp_[1])) \ return x[0] == y[0] && x[1] == y[1];
goto TO; } while (0) }
static inline bool
hard_reg_set_intersect_p (const HARD_REG_SET x, const HARD_REG_SET y)
{
return (x[0] & y[0]) != 0 || (x[1] & y[1]) != 0;
}
static inline bool
hard_reg_set_empty_p (const HARD_REG_SET x)
{
return x[0] == 0 && x[1] == 0;
}
#else #else
#if FIRST_PSEUDO_REGISTER <= 3*HOST_BITS_PER_WIDEST_FAST_INT #if FIRST_PSEUDO_REGISTER <= 3*HOST_BITS_PER_WIDEST_FAST_INT
...@@ -230,19 +265,33 @@ do { HARD_REG_ELT_TYPE *scan_tp_ = (TO), *scan_fp_ = (FROM); \ ...@@ -230,19 +265,33 @@ do { HARD_REG_ELT_TYPE *scan_tp_ = (TO), *scan_fp_ = (FROM); \
scan_tp_[1] |= ~ scan_fp_[1]; \ scan_tp_[1] |= ~ scan_fp_[1]; \
scan_tp_[2] |= ~ scan_fp_[2]; } while (0) scan_tp_[2] |= ~ scan_fp_[2]; } while (0)
#define GO_IF_HARD_REG_SUBSET(X,Y,TO) \ static inline bool
do { HARD_REG_ELT_TYPE *scan_xp_ = (X), *scan_yp_ = (Y); \ hard_reg_set_subset_p (const HARD_REG_SET x, const HARD_REG_SET y)
if ((0 == (scan_xp_[0] & ~ scan_yp_[0])) \ {
&& (0 == (scan_xp_[1] & ~ scan_yp_[1])) \ return ((x[0] & ~y[0]) == 0
&& (0 == (scan_xp_[2] & ~ scan_yp_[2]))) \ && (x[1] & ~y[1]) == 0
goto TO; } while (0) && (x[2] & ~y[2]) == 0);
}
#define GO_IF_HARD_REG_EQUAL(X,Y,TO) \
do { HARD_REG_ELT_TYPE *scan_xp_ = (X), *scan_yp_ = (Y); \ static inline bool
if ((scan_xp_[0] == scan_yp_[0]) \ hard_reg_set_equal_p (const HARD_REG_SET x, const HARD_REG_SET y)
&& (scan_xp_[1] == scan_yp_[1]) \ {
&& (scan_xp_[2] == scan_yp_[2])) \ return x[0] == y[0] && x[1] == y[1] && x[2] == y[2];
goto TO; } while (0) }
static inline bool
hard_reg_set_intersect_p (const HARD_REG_SET x, const HARD_REG_SET y)
{
return ((x[0] & y[0]) != 0
|| (x[1] & y[1]) != 0
|| (x[2] & y[2]) != 0);
}
static inline bool
hard_reg_set_empty_p (const HARD_REG_SET x)
{
return x[0] == 0 && x[1] == 0 && x[2] == 0;
}
#else #else
#if FIRST_PSEUDO_REGISTER <= 4*HOST_BITS_PER_WIDEST_FAST_INT #if FIRST_PSEUDO_REGISTER <= 4*HOST_BITS_PER_WIDEST_FAST_INT
...@@ -302,21 +351,35 @@ do { HARD_REG_ELT_TYPE *scan_tp_ = (TO), *scan_fp_ = (FROM); \ ...@@ -302,21 +351,35 @@ do { HARD_REG_ELT_TYPE *scan_tp_ = (TO), *scan_fp_ = (FROM); \
scan_tp_[2] |= ~ scan_fp_[2]; \ scan_tp_[2] |= ~ scan_fp_[2]; \
scan_tp_[3] |= ~ scan_fp_[3]; } while (0) scan_tp_[3] |= ~ scan_fp_[3]; } while (0)
#define GO_IF_HARD_REG_SUBSET(X,Y,TO) \ static inline bool
do { HARD_REG_ELT_TYPE *scan_xp_ = (X), *scan_yp_ = (Y); \ hard_reg_set_subset_p (const HARD_REG_SET x, const HARD_REG_SET y)
if ((0 == (scan_xp_[0] & ~ scan_yp_[0])) \ {
&& (0 == (scan_xp_[1] & ~ scan_yp_[1])) \ return ((x[0] & ~y[0]) == 0
&& (0 == (scan_xp_[2] & ~ scan_yp_[2])) \ && (x[1] & ~y[1]) == 0
&& (0 == (scan_xp_[3] & ~ scan_yp_[3]))) \ && (x[2] & ~y[2]) == 0
goto TO; } while (0) && (x[3] & ~y[3]) == 0);
}
#define GO_IF_HARD_REG_EQUAL(X,Y,TO) \
do { HARD_REG_ELT_TYPE *scan_xp_ = (X), *scan_yp_ = (Y); \ static inline bool
if ((scan_xp_[0] == scan_yp_[0]) \ hard_reg_set_equal_p (const HARD_REG_SET x, const HARD_REG_SET y)
&& (scan_xp_[1] == scan_yp_[1]) \ {
&& (scan_xp_[2] == scan_yp_[2]) \ return x[0] == y[0] && x[1] == y[1] && x[2] == y[2] && x[3] == y[3];
&& (scan_xp_[3] == scan_yp_[3])) \ }
goto TO; } while (0)
static inline bool
hard_reg_set_intersect_p (const HARD_REG_SET x, const HARD_REG_SET y)
{
return ((x[0] & y[0]) != 0
|| (x[1] & y[1]) != 0
|| (x[2] & y[2]) != 0
|| (x[3] & y[3]) != 0);
}
static inline bool
hard_reg_set_empty_p (const HARD_REG_SET x)
{
return x[0] == 0 && x[1] == 0 && x[2] == 0 && x[3] == 0;
}
#else /* FIRST_PSEUDO_REGISTER > 3*HOST_BITS_PER_WIDEST_FAST_INT */ #else /* FIRST_PSEUDO_REGISTER > 3*HOST_BITS_PER_WIDEST_FAST_INT */
...@@ -368,19 +431,49 @@ do { HARD_REG_ELT_TYPE *scan_tp_ = (TO), *scan_fp_ = (FROM); \ ...@@ -368,19 +431,49 @@ do { HARD_REG_ELT_TYPE *scan_tp_ = (TO), *scan_fp_ = (FROM); \
for (i = 0; i < HARD_REG_SET_LONGS; i++) \ for (i = 0; i < HARD_REG_SET_LONGS; i++) \
*scan_tp_++ |= ~ *scan_fp_++; } while (0) *scan_tp_++ |= ~ *scan_fp_++; } while (0)
#define GO_IF_HARD_REG_SUBSET(X,Y,TO) \ static inline bool
do { HARD_REG_ELT_TYPE *scan_xp_ = (X), *scan_yp_ = (Y); \ hard_reg_set_subset_p (const HARD_REG_SET x, const HARD_REG_SET y)
int i; \ {
for (i = 0; i < HARD_REG_SET_LONGS; i++) \ int i;
if (0 != (*scan_xp_++ & ~ *scan_yp_++)) break; \
if (i == HARD_REG_SET_LONGS) goto TO; } while (0) for (i = 0; i < HARD_REG_SET_LONGS; i++)
if ((x[i] & ~y[i]) != 0)
#define GO_IF_HARD_REG_EQUAL(X,Y,TO) \ return false;
do { HARD_REG_ELT_TYPE *scan_xp_ = (X), *scan_yp_ = (Y); \ return true;
int i; \ }
for (i = 0; i < HARD_REG_SET_LONGS; i++) \
if (*scan_xp_++ != *scan_yp_++) break; \ static inline bool
if (i == HARD_REG_SET_LONGS) goto TO; } while (0) hard_reg_set_equal_p (const HARD_REG_SET x, const HARD_REG_SET y)
{
int i;
for (i = 0; i < HARD_REG_SET_LONGS; i++)
if (x[i] != y[i])
return false;
return true;
}
static inline bool
hard_reg_set_intersect_p (const HARD_REG_SET x, const HARD_REG_SET y)
{
int i;
for (i = 0; i < HARD_REG_SET_LONGS; i++)
if ((x[i] & y[i]) != 0)
return true;
return false;
}
static inline bool
hard_reg_set_empty_p (const HARD_REG_SET x)
{
int i;
for (i = 0; i < HARD_REG_SET_LONGS; i++)
if (x[i] != 0)
return false;
return true;
}
#endif #endif
#endif #endif
......
...@@ -2286,42 +2286,40 @@ find_free_reg (enum reg_class class, enum machine_mode mode, int qtyno, ...@@ -2286,42 +2286,40 @@ find_free_reg (enum reg_class class, enum machine_mode mode, int qtyno,
IOR_COMPL_HARD_REG_SET (first_used, qty_phys_sugg[qtyno]); IOR_COMPL_HARD_REG_SET (first_used, qty_phys_sugg[qtyno]);
} }
/* If all registers are excluded, we can't do anything. */
GO_IF_HARD_REG_SUBSET (reg_class_contents[(int) ALL_REGS], first_used, fail);
/* If at least one would be suitable, test each hard reg. */ /* If at least one would be suitable, test each hard reg. */
if (!hard_reg_set_subset_p (reg_class_contents[(int) ALL_REGS], first_used))
for (i = 0; i < FIRST_PSEUDO_REGISTER; i++) for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
{ {
#ifdef REG_ALLOC_ORDER #ifdef REG_ALLOC_ORDER
int regno = reg_alloc_order[i]; int regno = reg_alloc_order[i];
#else #else
int regno = i; int regno = i;
#endif #endif
if (! TEST_HARD_REG_BIT (first_used, regno) if (!TEST_HARD_REG_BIT (first_used, regno)
&& HARD_REGNO_MODE_OK (regno, mode) && HARD_REGNO_MODE_OK (regno, mode)
&& (qty[qtyno].n_calls_crossed == 0 && (qty[qtyno].n_calls_crossed == 0
|| accept_call_clobbered || accept_call_clobbered
|| ! HARD_REGNO_CALL_PART_CLOBBERED (regno, mode))) || !HARD_REGNO_CALL_PART_CLOBBERED (regno, mode)))
{ {
int j; int j;
int size1 = hard_regno_nregs[regno][mode]; int size1 = hard_regno_nregs[regno][mode];
for (j = 1; j < size1 && ! TEST_HARD_REG_BIT (used, regno + j); j++); j = 1;
if (j == size1) while (j < size1 && !TEST_HARD_REG_BIT (used, regno + j))
{ j++;
/* Mark that this register is in use between its birth and death if (j == size1)
insns. */ {
post_mark_life (regno, mode, 1, born_index, dead_index); /* Mark that this register is in use between its birth
return regno; and death insns. */
} post_mark_life (regno, mode, 1, born_index, dead_index);
return regno;
}
#ifndef REG_ALLOC_ORDER #ifndef REG_ALLOC_ORDER
/* Skip starting points we know will lose. */ /* Skip starting points we know will lose. */
i += j; i += j;
#endif #endif
} }
} }
fail:
/* If we are just trying suggested register, we have just tried copy- /* If we are just trying suggested register, we have just tried copy-
suggested registers, and there are arithmetic-suggested registers, suggested registers, and there are arithmetic-suggested registers,
try them. */ try them. */
......
...@@ -2485,9 +2485,7 @@ change_stack (rtx insn, stack old, stack new, enum emit_where where) ...@@ -2485,9 +2485,7 @@ change_stack (rtx insn, stack old, stack new, enum emit_where where)
/* By now, the only difference should be the order of the stack, /* By now, the only difference should be the order of the stack,
not their depth or liveliness. */ not their depth or liveliness. */
GO_IF_HARD_REG_EQUAL (old->reg_set, new->reg_set, win); gcc_assert (hard_reg_set_equal_p (old->reg_set, new->reg_set));
gcc_unreachable ();
win:
gcc_assert (old->top == new->top); gcc_assert (old->top == new->top);
/* If the stack is not empty (new->top != -1), loop here emitting /* If the stack is not empty (new->top != -1), loop here emitting
...@@ -2955,9 +2953,8 @@ convert_regs_1 (basic_block block) ...@@ -2955,9 +2953,8 @@ convert_regs_1 (basic_block block)
/* Something failed if the stack lives don't match. If we had malformed /* Something failed if the stack lives don't match. If we had malformed
asms, we zapped the instruction itself, but that didn't produce the asms, we zapped the instruction itself, but that didn't produce the
same pattern of register kills as before. */ same pattern of register kills as before. */
GO_IF_HARD_REG_EQUAL (regstack.reg_set, bi->out_reg_set, win); gcc_assert (hard_reg_set_equal_p (regstack.reg_set, bi->out_reg_set)
gcc_assert (any_malformed_asm); || any_malformed_asm);
win:
bi->stack_out = regstack; bi->stack_out = regstack;
bi->done = true; bi->done = true;
} }
......
...@@ -338,20 +338,11 @@ init_reg_sets_1 (void) ...@@ -338,20 +338,11 @@ init_reg_sets_1 (void)
COPY_HARD_REG_SET (c, reg_class_contents[i]); COPY_HARD_REG_SET (c, reg_class_contents[i]);
IOR_HARD_REG_SET (c, reg_class_contents[j]); IOR_HARD_REG_SET (c, reg_class_contents[j]);
for (k = 0; k < N_REG_CLASSES; k++) for (k = 0; k < N_REG_CLASSES; k++)
{ if (hard_reg_set_subset_p (reg_class_contents[k], c)
GO_IF_HARD_REG_SUBSET (reg_class_contents[k], c, && !hard_reg_set_subset_p (reg_class_contents[k],
subclass1); reg_class_contents
continue; [(int) reg_class_subunion[i][j]]))
subclass1:
/* Keep the largest subclass. */ /* SPEE 900308 */
GO_IF_HARD_REG_SUBSET (reg_class_contents[k],
reg_class_contents[(int) reg_class_subunion[i][j]],
subclass2);
reg_class_subunion[i][j] = (enum reg_class) k; reg_class_subunion[i][j] = (enum reg_class) k;
subclass2:
;
}
} }
} }
...@@ -369,9 +360,9 @@ init_reg_sets_1 (void) ...@@ -369,9 +360,9 @@ init_reg_sets_1 (void)
COPY_HARD_REG_SET (c, reg_class_contents[i]); COPY_HARD_REG_SET (c, reg_class_contents[i]);
IOR_HARD_REG_SET (c, reg_class_contents[j]); IOR_HARD_REG_SET (c, reg_class_contents[j]);
for (k = 0; k < N_REG_CLASSES; k++) for (k = 0; k < N_REG_CLASSES; k++)
GO_IF_HARD_REG_SUBSET (c, reg_class_contents[k], superclass); if (hard_reg_set_subset_p (c, reg_class_contents[k]))
break;
superclass:
reg_class_superunion[i][j] = (enum reg_class) k; reg_class_superunion[i][j] = (enum reg_class) k;
} }
} }
...@@ -394,23 +385,21 @@ init_reg_sets_1 (void) ...@@ -394,23 +385,21 @@ init_reg_sets_1 (void)
continue; continue;
for (j = i + 1; j < N_REG_CLASSES; j++) for (j = i + 1; j < N_REG_CLASSES; j++)
{ if (hard_reg_set_subset_p (reg_class_contents[i],
enum reg_class *p; reg_class_contents[j]))
{
GO_IF_HARD_REG_SUBSET (reg_class_contents[i], reg_class_contents[j], /* Reg class I is a subclass of J.
subclass); Add J to the table of superclasses of I. */
continue; enum reg_class *p;
subclass:
/* Reg class I is a subclass of J. p = &reg_class_superclasses[i][0];
Add J to the table of superclasses of I. */ while (*p != LIM_REG_CLASSES) p++;
p = &reg_class_superclasses[i][0]; *p = (enum reg_class) j;
while (*p != LIM_REG_CLASSES) p++; /* Add I to the table of superclasses of J. */
*p = (enum reg_class) j; p = &reg_class_subclasses[j][0];
/* Add I to the table of superclasses of J. */ while (*p != LIM_REG_CLASSES) p++;
p = &reg_class_subclasses[j][0]; *p = (enum reg_class) i;
while (*p != LIM_REG_CLASSES) p++; }
*p = (enum reg_class) i;
}
} }
/* Initialize "constant" tables. */ /* Initialize "constant" tables. */
...@@ -2502,15 +2491,10 @@ reg_scan_mark_refs (rtx x, rtx insn, int note_flag, unsigned int min_regno) ...@@ -2502,15 +2491,10 @@ reg_scan_mark_refs (rtx x, rtx insn, int note_flag, unsigned int min_regno)
int int
reg_class_subset_p (enum reg_class c1, enum reg_class c2) reg_class_subset_p (enum reg_class c1, enum reg_class c2)
{ {
if (c1 == c2) return 1; return (c1 == c2
|| c2 == ALL_REGS
if (c2 == ALL_REGS) || hard_reg_set_subset_p (reg_class_contents[(int) c1],
win: reg_class_contents[(int) c2]));
return 1;
GO_IF_HARD_REG_SUBSET (reg_class_contents[(int) c1],
reg_class_contents[(int) c2],
win);
return 0;
} }
/* Return nonzero if there is a register that is in both C1 and C2. */ /* Return nonzero if there is a register that is in both C1 and C2. */
...@@ -2518,21 +2502,11 @@ reg_class_subset_p (enum reg_class c1, enum reg_class c2) ...@@ -2518,21 +2502,11 @@ reg_class_subset_p (enum reg_class c1, enum reg_class c2)
int int
reg_classes_intersect_p (enum reg_class c1, enum reg_class c2) reg_classes_intersect_p (enum reg_class c1, enum reg_class c2)
{ {
HARD_REG_SET c; return (c1 == c2
|| c1 == ALL_REGS
if (c1 == c2) return 1; || c2 == ALL_REGS
|| hard_reg_set_intersect_p (reg_class_contents[(int) c1],
if (c1 == ALL_REGS || c2 == ALL_REGS) reg_class_contents[(int) c2]));
return 1;
COPY_HARD_REG_SET (c, reg_class_contents[(int) c1]);
AND_HARD_REG_SET (c, reg_class_contents[(int) c2]);
GO_IF_HARD_REG_SUBSET (c, reg_class_contents[(int) NO_REGS], lose);
return 1;
lose:
return 0;
} }
#ifdef CANNOT_CHANGE_MODE_CLASS #ifdef CANNOT_CHANGE_MODE_CLASS
......
...@@ -3891,9 +3891,8 @@ finish_spills (int global) ...@@ -3891,9 +3891,8 @@ finish_spills (int global)
AND_HARD_REG_SET (chain->used_spill_regs, used_spill_regs); AND_HARD_REG_SET (chain->used_spill_regs, used_spill_regs);
/* Make sure we only enlarge the set. */ /* Make sure we only enlarge the set. */
GO_IF_HARD_REG_SUBSET (used_by_pseudos2, chain->used_spill_regs, ok); gcc_assert (hard_reg_set_subset_p (used_by_pseudos2,
gcc_unreachable (); chain->used_spill_regs));
ok:;
} }
} }
......
...@@ -865,12 +865,8 @@ death_notes_match_p (rtx i1 ATTRIBUTE_UNUSED, rtx i2 ATTRIBUTE_UNUSED, ...@@ -865,12 +865,8 @@ death_notes_match_p (rtx i1 ATTRIBUTE_UNUSED, rtx i2 ATTRIBUTE_UNUSED,
SET_HARD_REG_BIT (i2_regset, regno); SET_HARD_REG_BIT (i2_regset, regno);
} }
GO_IF_HARD_REG_EQUAL (i1_regset, i2_regset, done); if (!hard_reg_set_equal_p (i1_regset, i2_regset))
return false;
return false;
done:
;
} }
#endif #endif
return true; return true;
......
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