Patchwork : Fix PR53595 (hard_regno_call_part_clobbered called with invalid regno)

login
register
mail settings
Submitter Georg-Johann Lay
Date June 28, 2012, 12:28 p.m.
Message ID <4FEC4DEC.6050107@gjlay.de>
Download mbox | patch
Permalink /patch/167861/
State New
Headers show

Comments

Georg-Johann Lay - June 28, 2012, 12:28 p.m.
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.
Denis Chertykov - June 28, 2012, 1 p.m.
2012/6/28 Georg-Johann Lay <avr@gjlay.de>:
> 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.

Please, apply.

Denis

Patch

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