From patchwork Thu Jun 28 12:28:28 2012 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit Subject: : Fix PR53595 (hard_regno_call_part_clobbered called with invalid regno) Date: Thu, 28 Jun 2012 02:28:28 -0000 From: Georg-Johann Lay X-Patchwork-Id: 167861 Message-Id: <4FEC4DEC.6050107@gjlay.de> To: gcc-patches@gcc.gnu.org Cc: Denis Chertykov , Eric Weddington , Vladimir Makarov 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