+2008-09-20 Richard Sandiford <rdsandiford@googlemail.com>
+
+ * doc/tm.texi (TARGET_IRA_COVER_CLASSES): Define.
+ (IRA_COVER_CLASSES): Refer to TARGET_IRA_COVER_CLASSES.
+ * target.h (gcc_target): Add ira_cover_classes.
+ * ira.c: Remove IRA_COVER_CLASSES guards.
+ (setup_cover_and_important_classes): Use targetm.ira_cover_classes
+ instead of IRA_COVER_CLASSES.
+ (setup_cover_and_important_classes): Remove IRA_COVER_CLASSES guard.
+ (setup_class_translate): Likewise.
+ (setup_reg_class_intersect_union): Likewise.
+ (find_reg_class_closure): Replace IRA_COVER_CLASSES guard with a
+ test of targetm.ira_cover_classes.
+ * opts.c (decode_options): Use targetm.ira_cover_classes instead
+ of IRA_COVER_CLASSES.
+ * target-def.h (TARGET_IRA_COVER_CLASSES): Define.
+ (TARGET_INITIALIZER): Include it.
+ * targhooks.h (default_ira_cover_classes): Declare.
+ * targhooks.c (default_ira_cover_classes): New function.
+
2008-09-19 Bob Wilson <bob.wilson@acm.org>
* config/xtensa/xtensa.md (reload<mode>_literal): Handle MEM operands.
@end smallexample
@end defmac
-@defmac IRA_COVER_CLASSES
-The macro defines cover classes for the Integrated Register Allocator
+@deftypefn {Target Hook} {const enum reg_class *} TARGET_IRA_COVER_CLASSES ()
+Return an array of cover classes for the Integrated Register Allocator
(@acronym{IRA}). Cover classes are a set of non-intersecting register
classes covering all hard registers used for register allocation
purposes. If a move between two registers in the same cover class is
possible, it should be cheaper than a load or store of the registers.
-The macro value should be the initializer for an array of register
-class values, with @code{LIM_REG_CLASSES} used as the end marker.
+The array is terminated by a @code{LIM_REG_CLASSES} element.
+
+This hook is called once at compiler startup, after the command-line
+options have been processed. It is then re-examined by every call to
+@code{target_reinit}.
-You must define this macro in order to use the integrated register
+The default implementation returns @code{IRA_COVER_CLASSES}, if defined,
+otherwise there is no default implementation. You must define either this
+macro or @code{IRA_COVER_CLASSES} in order to use the integrated register
allocator for the target.
+@end deftypefn
+
+@defmac IRA_COVER_CLASSES
+See the documentation for @code{TARGET_IRA_COVER_CLASSES}.
@end defmac
@node Old Constraints
classes. */
int ira_important_class_nums[N_REG_CLASSES];
-#ifdef IRA_COVER_CLASSES
-
/* Check IRA_COVER_CLASSES and sets the four global variables defined
above. */
static void
{
int i, j;
enum reg_class cl;
- static enum reg_class classes[] = IRA_COVER_CLASSES;
+ const enum reg_class *classes;
HARD_REG_SET temp_hard_regset2;
+ classes = targetm.ira_cover_classes ();
ira_reg_class_cover_size = 0;
for (i = 0; (cl = classes[i]) != LIM_REG_CLASSES; i++)
{
}
}
}
-#endif
/* Map of all register classes to corresponding cover class containing
the given class. If given class is not a subset of a cover class,
we translate it into the cheapest cover class. */
enum reg_class ira_class_translate[N_REG_CLASSES];
-#ifdef IRA_COVER_CLASSES
-
/* Set up array IRA_CLASS_TRANSLATE. */
static void
setup_class_translate (void)
ira_class_translate[cl] = best_class;
}
}
-#endif
/* The biggest important reg_class inside of intersection of the two
reg_classes (that is calculated taking only hard registers
reg_class_subunion value. */
enum reg_class ira_reg_class_union[N_REG_CLASSES][N_REG_CLASSES];
-#ifdef IRA_COVER_CLASSES
-
/* Set up IRA_REG_CLASS_INTERSECT and IRA_REG_CLASS_UNION. */
static void
setup_reg_class_intersect_union (void)
}
}
-#endif
-
/* Output all cover classes and the translation map into file F. */
static void
print_class_cover (FILE *f)
find_reg_class_closure (void)
{
setup_reg_subclasses ();
-#ifdef IRA_COVER_CLASSES
- setup_cover_and_important_classes ();
- setup_class_translate ();
- setup_reg_class_intersect_union ();
-#endif
+ if (targetm.ira_cover_classes)
+ {
+ setup_cover_and_important_classes ();
+ setup_class_translate ();
+ setup_reg_class_intersect_union ();
+ }
}
\f
}
}
-#ifdef IRA_COVER_CLASSES
/* Use IRA if it is implemented for the target. */
- flag_ira = 1;
-#endif
+ if (targetm.ira_cover_classes)
+ flag_ira = 1;
/* -O1 optimizations. */
opt1 = (optimize >= 1);
if (!flag_sel_sched_pipelining)
flag_sel_sched_pipelining_outer_loops = 0;
-#ifndef IRA_COVER_CLASSES
- if (flag_ira)
+ if (flag_ira && !targetm.ira_cover_classes)
{
inform (input_location, "-fira does not work on this architecture");
flag_ira = 0;
}
-#endif
/* Save the current optimization options if this is the first call. */
if (first_time_p)
#define TARGET_HANDLE_PRAGMA_EXTERN_PREFIX 0
#endif
+#ifdef IRA_COVER_CLASSES
+#define TARGET_IRA_COVER_CLASSES default_ira_cover_classes
+#else
+#define TARGET_IRA_COVER_CLASSES 0
+#endif
+
#ifndef TARGET_SECONDARY_RELOAD
#define TARGET_SECONDARY_RELOAD default_secondary_reload
#endif
TARGET_INVALID_CONVERSION, \
TARGET_INVALID_UNARY_OP, \
TARGET_INVALID_BINARY_OP, \
+ TARGET_IRA_COVER_CLASSES, \
TARGET_SECONDARY_RELOAD, \
TARGET_EXPAND_TO_RTL_HOOK, \
TARGET_INSTANTIATE_DECLS, \
is not permitted on TYPE1 and TYPE2, NULL otherwise. */
const char *(*invalid_binary_op) (int op, const_tree type1, const_tree type2);
+ /* Return the array of IRA cover classes for the current target. */
+ const enum reg_class *(*ira_cover_classes) (void);
+
/* Return the class for a secondary reload, and fill in extra information. */
enum reg_class (*secondary_reload) (bool, rtx, enum reg_class,
enum machine_mode,
return virtual_incoming_args_rtx;
}
+#ifdef IRA_COVER_CLASSES
+const enum reg_class *
+default_ira_cover_classes (void)
+{
+ static enum reg_class classes[] = IRA_COVER_CLASSES;
+ return classes;
+}
+#endif
+
enum reg_class
default_secondary_reload (bool in_p ATTRIBUTE_UNUSED, rtx x ATTRIBUTE_UNUSED,
enum reg_class reload_class ATTRIBUTE_UNUSED,
extern bool hook_bool_const_rtx_commutative_p (const_rtx, int);
extern rtx default_function_value (const_tree, const_tree, bool);
extern rtx default_internal_arg_pointer (void);
+#ifdef IRA_COVER_CLASSES
+extern const enum reg_class *default_ira_cover_classes (void);
+#endif
extern enum reg_class default_secondary_reload (bool, rtx, enum reg_class,
enum machine_mode,
secondary_reload_info *);