This patch returns false in HARD_REGNO_CALL_PART_CLOBBERED if
!HARD_REGNO_MODE_OK.

Returning true for such registers might lead to performance
degradation that eat up all performance gained from 4.6 to 4.7
for example.

Ok to apply?

Johann

        PR 53595
        * config/avr/avr.c (avr_hard_regno_call_part_clobbered): New.
        * config/avr/avr-protos.h (avr_hard_regno_call_part_clobbered): New.
        * config/avr/avr.h (HARD_REGNO_CALL_PART_CLOBBERED): Forward to
        avr_hard_regno_call_part_clobbered.
Index: config/avr/avr-protos.h
===================================================================
--- config/avr/avr-protos.h	(revision 189011)
+++ config/avr/avr-protos.h	(working copy)
@@ -47,6 +47,7 @@ extern void init_cumulative_args (CUMULA
 #endif /* TREE_CODE */
 
 #ifdef RTX_CODE
+extern int avr_hard_regno_call_part_clobbered (unsigned, enum machine_mode);
 extern const char *output_movqi (rtx insn, rtx operands[], int *l);
 extern const char *output_movhi (rtx insn, rtx operands[], int *l);
 extern const char *output_movsisf (rtx insn, rtx operands[], int *l);
Index: config/avr/avr.c
===================================================================
--- config/avr/avr.c	(revision 189011)
+++ config/avr/avr.c	(working copy)
@@ -8856,6 +8856,28 @@ avr_hard_regno_mode_ok (int regno, enum
 }
 
 
+/* Implement `HARD_REGNO_CALL_PART_CLOBBERED'.  */
+
+int
+avr_hard_regno_call_part_clobbered (unsigned regno, enum machine_mode mode)
+{
+  /* FIXME: This hook gets called with MODE:REGNO combinations that don't
+        represent valid hard registers like, e.g. HI:29.  Returning TRUE
+        for such registers can lead to performance degradation as mentioned
+        in PR53595.  Thus, report invalid hard registers as FALSE.  */
+  
+  if (!avr_hard_regno_mode_ok (regno, mode))
+    return 0;
+  
+  /* Return true if any of the following boundaries is crossed:
+     17/18, 27/28 and 29/30.  */
+  
+  return ((regno < 18 && regno + GET_MODE_SIZE (mode) > 18)
+          || (regno < REG_Y && regno + GET_MODE_SIZE (mode) > REG_Y)
+          || (regno < REG_Z && regno + GET_MODE_SIZE (mode) > REG_Z));
+}
+
+
 /* Implement `MODE_CODE_BASE_REG_CLASS'.  */
 
 enum reg_class
Index: config/avr/avr.h
===================================================================
--- config/avr/avr.h	(revision 189011)
+++ config/avr/avr.h	(working copy)
@@ -402,10 +402,8 @@ enum reg_class {
 
 #define REGNO_OK_FOR_INDEX_P(NUM) 0
 
-#define HARD_REGNO_CALL_PART_CLOBBERED(REGNO, MODE)                    \
-  (((REGNO) < 18 && (REGNO) + GET_MODE_SIZE (MODE) > 18)               \
-   || ((REGNO) < REG_Y && (REGNO) + GET_MODE_SIZE (MODE) > REG_Y)      \
-   || ((REGNO) < REG_Z && (REGNO) + GET_MODE_SIZE (MODE) > REG_Z))
+#define HARD_REGNO_CALL_PART_CLOBBERED(REGNO, MODE)     \
+  avr_hard_regno_call_part_clobbered (REGNO, MODE)
 
 #define TARGET_SMALL_REGISTER_CLASSES_FOR_MODE_P hook_bool_mode_true
 

Reply via email to