aboutsummaryrefslogtreecommitdiff
path: root/gcc/regclass.c
diff options
context:
space:
mode:
Diffstat (limited to 'gcc/regclass.c')
-rw-r--r--gcc/regclass.c114
1 files changed, 58 insertions, 56 deletions
diff --git a/gcc/regclass.c b/gcc/regclass.c
index 28c2a6f..20c7d3b0 100644
--- a/gcc/regclass.c
+++ b/gcc/regclass.c
@@ -26,10 +26,10 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
#include "config.h"
#include "system.h"
+#include "hard-reg-set.h"
#include "rtl.h"
#include "expr.h"
#include "tm_p.h"
-#include "hard-reg-set.h"
#include "flags.h"
#include "basic-block.h"
#include "regs.h"
@@ -227,20 +227,11 @@ static char *in_inc_dec;
#endif /* FORBIDDEN_INC_DEC_CLASSES */
-#ifdef CLASS_CANNOT_CHANGE_MODE
-
-/* These are the classes containing only registers that can be used in
- a SUBREG expression that changes the mode of the register in some
- way that is illegal. */
-
-static int class_can_change_mode[N_REG_CLASSES];
-
-/* Registers, including pseudos, which change modes in some way that
- is illegal. */
-
-static regset reg_changes_mode;
-
-#endif /* CLASS_CANNOT_CHANGE_MODE */
+#ifdef CANNOT_CHANGE_MODE_CLASS
+/* All registers that have been subreged. Indexed by mode, where each
+ entry is a regset of registers. */
+regset_head subregs_of_mode [NUM_MACHINE_MODES];
+#endif
/* Sample MEM values for use by memory_move_secondary_cost. */
@@ -549,22 +540,6 @@ init_reg_sets_1 ()
may_move_out_cost[m][i][j] = 65536;
}
}
-
-#ifdef CLASS_CANNOT_CHANGE_MODE
- {
- HARD_REG_SET c;
- COMPL_HARD_REG_SET (c, reg_class_contents[CLASS_CANNOT_CHANGE_MODE]);
-
- for (i = 0; i < N_REG_CLASSES; i++)
- {
- GO_IF_HARD_REG_SUBSET (reg_class_contents[i], c, ok_class);
- class_can_change_mode [i] = 0;
- continue;
- ok_class:
- class_can_change_mode [i] = 1;
- }
- }
-#endif /* CLASS_CANNOT_CHANGE_MODE */
}
/* Compute the table of register modes.
@@ -952,9 +927,9 @@ dump_regclass (dump)
&& (!in_inc_dec[i]
|| !forbidden_inc_dec_class[(enum reg_class) class])
#endif
-#ifdef CLASS_CANNOT_CHANGE_MODE
- && (!REGNO_REG_SET_P (reg_changes_mode, i)
- || class_can_change_mode [(enum reg_class) class])
+#ifdef CANNOT_CHANGE_MODE_CLASS
+ && ! invalid_mode_change_p (i, (enum reg_class) class,
+ PSEUDO_REGNO_MODE (i))
#endif
)
fprintf (dump, " %s:%i", reg_class_names[class],
@@ -994,15 +969,7 @@ record_operand_costs (insn, op_costs, reg_pref)
op_costs[i] = init_cost;
if (GET_CODE (recog_data.operand[i]) == SUBREG)
- {
- rtx inner = SUBREG_REG (recog_data.operand[i]);
-#ifdef CLASS_CANNOT_CHANGE_MODE
- if (GET_CODE (inner) == REG
- && CLASS_CANNOT_CHANGE_MODE_P (modes[i], GET_MODE (inner)))
- SET_REGNO_REG_SET (reg_changes_mode, REGNO (inner));
-#endif
- recog_data.operand[i] = inner;
- }
+ recog_data.operand[i] = SUBREG_REG (recog_data.operand[i]);
if (GET_CODE (recog_data.operand[i]) == MEM)
record_address_regs (XEXP (recog_data.operand[i], 0),
@@ -1193,10 +1160,6 @@ regclass (f, nregs, dump)
costs = (struct costs *) xmalloc (nregs * sizeof (struct costs));
-#ifdef CLASS_CANNOT_CHANGE_MODE
- reg_changes_mode = BITMAP_XMALLOC ();
-#endif
-
#ifdef FORBIDDEN_INC_DEC_CLASSES
in_inc_dec = (char *) xmalloc (nregs);
@@ -1329,9 +1292,9 @@ regclass (f, nregs, dump)
#ifdef FORBIDDEN_INC_DEC_CLASSES
|| (in_inc_dec[i] && forbidden_inc_dec_class[class])
#endif
-#ifdef CLASS_CANNOT_CHANGE_MODE
- || (REGNO_REG_SET_P (reg_changes_mode, i)
- && ! class_can_change_mode [class])
+#ifdef CANNOT_CHANGE_MODE_CLASS
+ || invalid_mode_change_p (i, (enum reg_class) class,
+ PSEUDO_REGNO_MODE (i))
#endif
)
;
@@ -1359,9 +1322,9 @@ regclass (f, nregs, dump)
#ifdef FORBIDDEN_INC_DEC_CLASSES
&& ! (in_inc_dec[i] && forbidden_inc_dec_class[class])
#endif
-#ifdef CLASS_CANNOT_CHANGE_MODE
- && ! (REGNO_REG_SET_P (reg_changes_mode, i)
- && ! class_can_change_mode [class])
+#ifdef CANNOT_CHANGE_MODE_CLASS
+ && ! invalid_mode_change_p (i, (enum reg_class) class,
+ PSEUDO_REGNO_MODE (i))
#endif
)
alt = reg_class_subunion[(int) alt][class];
@@ -1395,9 +1358,6 @@ regclass (f, nregs, dump)
#ifdef FORBIDDEN_INC_DEC_CLASSES
free (in_inc_dec);
#endif
-#ifdef CLASS_CANNOT_CHANGE_MODE
- BITMAP_XFREE (reg_changes_mode);
-#endif
free (costs);
}
@@ -2643,4 +2603,46 @@ regset_release_memory ()
bitmap_release_memory ();
}
+#ifdef CANNOT_CHANGE_MODE_CLASS
+/* Set bits in *USED which correspond to registers which can't change
+ their mode from FROM to any mode in which REGNO was encountered. */
+
+void
+cannot_change_mode_set_regs (used, from, regno)
+ HARD_REG_SET *used;
+ enum machine_mode from;
+ unsigned int regno;
+{
+ enum machine_mode to;
+ enum reg_class class;
+
+ for (to = VOIDmode; to < MAX_MACHINE_MODE; ++to)
+ if (REGNO_REG_SET_P (&subregs_of_mode[to], regno))
+ {
+ class = CANNOT_CHANGE_MODE_CLASS (from, to);
+ if (class != NO_REGS)
+ IOR_HARD_REG_SET (*used, reg_class_contents [(int) class]);
+ }
+}
+
+/* Return 1 if REGNO has had an invalid mode change in CLASS from FROM
+ mode. */
+
+bool
+invalid_mode_change_p (regno, class, from_mode)
+ unsigned int regno;
+ enum reg_class class;
+ enum machine_mode from_mode;
+{
+ enum machine_mode to_mode;
+
+ for (to_mode = 0; to_mode < NUM_MACHINE_MODES; ++to_mode)
+ if (REGNO_REG_SET_P (&subregs_of_mode[(int) to_mode], regno)
+ && reg_classes_intersect_p
+ (class, CANNOT_CHANGE_MODE_CLASS (from_mode, to_mode)))
+ return 1;
+ return 0;
+}
+#endif /* CANNOT_CHANGE_MODE_CLASS */
+
#include "gt-regclass.h"