From aa1572b551275839303525efd5673c512b5e76c5 Mon Sep 17 00:00:00 2001 From: ramana Date: Wed, 9 May 2012 12:51:36 +0000 Subject: [PATCH] 2012-05-09 Ramana Radhakrishnan * tree-ssa-loop-ivopts.c (add_autoinc_candidates, get_address_cost): Replace use of HAVE_{POST/PRE}_{INCREMENT/DECREMENT} with USE_{LOAD/STORE}_{PRE/POST}_{INCREMENT/DECREMENT} appropriately. * config/arm/arm.h (ARM_AUTOINC_VALID_FOR_MODE_P): New. (USE_LOAD_POST_INCREMENT): Define. (USE_LOAD_PRE_INCREMENT): Define. (USE_LOAD_POST_DECREMENT): Define. (USE_LOAD_PRE_DECREMENT): Define. (USE_STORE_PRE_DECREMENT): Define. (USE_STORE_PRE_INCREMENT): Define. (USE_STORE_POST_DECREMENT): Define. (USE_STORE_POST_INCREMENT): Define. (arm_auto_incmodes): Add enumeration. * config/arm/arm-protos.h (arm_autoinc_modes_ok_p): Declare. * config/arm/arm.c (arm_autoinc_modes_ok_p): Define. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@187329 138bc75d-0d04-0410-961f-82ee72b054a4 --- gcc/ChangeLog | 18 +++++++++++++++++ gcc/config/arm/arm-protos.h | 2 ++ gcc/config/arm/arm.c | 48 ++++++++++++++++++++++++++++++++++++++++++++- gcc/config/arm/arm.h | 24 +++++++++++++++++++++++ gcc/tree-ssa-loop-ivopts.c | 28 ++++++++++++++++++-------- 5 files changed, 111 insertions(+), 9 deletions(-) diff --git a/gcc/ChangeLog b/gcc/ChangeLog index b96afa0803c..605ea10a98f 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,21 @@ +2012-05-09 Ramana Radhakrishnan + + * tree-ssa-loop-ivopts.c (add_autoinc_candidates, get_address_cost): + Replace use of HAVE_{POST/PRE}_{INCREMENT/DECREMENT} with + USE_{LOAD/STORE}_{PRE/POST}_{INCREMENT/DECREMENT} appropriately. + * config/arm/arm.h (ARM_AUTOINC_VALID_FOR_MODE_P): New. + (USE_LOAD_POST_INCREMENT): Define. + (USE_LOAD_PRE_INCREMENT): Define. + (USE_LOAD_POST_DECREMENT): Define. + (USE_LOAD_PRE_DECREMENT): Define. + (USE_STORE_PRE_DECREMENT): Define. + (USE_STORE_PRE_INCREMENT): Define. + (USE_STORE_POST_DECREMENT): Define. + (USE_STORE_POST_INCREMENT): Define. + (arm_auto_incmodes): Add enumeration. + * config/arm/arm-protos.h (arm_autoinc_modes_ok_p): Declare. + * config/arm/arm.c (arm_autoinc_modes_ok_p): Define. + 2012-05-09 Jakub Jelinek PR tree-optimization/53226 diff --git a/gcc/config/arm/arm-protos.h b/gcc/config/arm/arm-protos.h index 53c2aef257e..cb74d707c21 100644 --- a/gcc/config/arm/arm-protos.h +++ b/gcc/config/arm/arm-protos.h @@ -250,4 +250,6 @@ extern int vfp3_const_double_for_fract_bits (rtx); extern void arm_expand_vec_perm (rtx target, rtx op0, rtx op1, rtx sel); extern bool arm_expand_vec_perm_const (rtx target, rtx op0, rtx op1, rtx sel); +extern bool arm_autoinc_modes_ok_p (enum machine_mode, enum arm_auto_incmodes); + #endif /* ! GCC_ARM_PROTOS_H */ diff --git a/gcc/config/arm/arm.c b/gcc/config/arm/arm.c index 17b4b5d43de..2c62c518e67 100644 --- a/gcc/config/arm/arm.c +++ b/gcc/config/arm/arm.c @@ -25886,5 +25886,51 @@ arm_vectorize_vec_perm_const_ok (enum machine_mode vmode, return ret; } - +bool +arm_autoinc_modes_ok_p (enum machine_mode mode, enum arm_auto_incmodes code) +{ + /* If we are soft float and we do not have ldrd + then all auto increment forms are ok. */ + if (TARGET_SOFT_FLOAT && (TARGET_LDRD || GET_MODE_SIZE (mode) <= 4)) + return true; + + switch (code) + { + /* Post increment and Pre Decrement are supported for all + instruction forms except for vector forms. */ + case ARM_POST_INC: + case ARM_PRE_DEC: + if (VECTOR_MODE_P (mode)) + { + if (code != ARM_PRE_DEC) + return true; + else + return false; + } + + return true; + + case ARM_POST_DEC: + case ARM_PRE_INC: + /* Without LDRD and mode size greater than + word size, there is no point in auto-incrementing + because ldm and stm will not have these forms. */ + if (!TARGET_LDRD && GET_MODE_SIZE (mode) > 4) + return false; + + /* Vector and floating point modes do not support + these auto increment forms. */ + if (FLOAT_MODE_P (mode) || VECTOR_MODE_P (mode)) + return false; + + return true; + + default: + return false; + + } + + return false; +} + #include "gt-arm.h" diff --git a/gcc/config/arm/arm.h b/gcc/config/arm/arm.h index c6b4cc09a46..f4204e4857a 100644 --- a/gcc/config/arm/arm.h +++ b/gcc/config/arm/arm.h @@ -1613,6 +1613,30 @@ typedef struct #define HAVE_PRE_MODIFY_REG TARGET_32BIT #define HAVE_POST_MODIFY_REG TARGET_32BIT +enum arm_auto_incmodes + { + ARM_POST_INC, + ARM_PRE_INC, + ARM_POST_DEC, + ARM_PRE_DEC + }; + +#define ARM_AUTOINC_VALID_FOR_MODE_P(mode, code) \ + (TARGET_32BIT && arm_autoinc_modes_ok_p (mode, code)) +#define USE_LOAD_POST_INCREMENT(mode) \ + ARM_AUTOINC_VALID_FOR_MODE_P(mode, ARM_POST_INC) +#define USE_LOAD_PRE_INCREMENT(mode) \ + ARM_AUTOINC_VALID_FOR_MODE_P(mode, ARM_PRE_INC) +#define USE_LOAD_POST_DECREMENT(mode) \ + ARM_AUTOINC_VALID_FOR_MODE_P(mode, ARM_POST_DEC) +#define USE_LOAD_PRE_DECREMENT(mode) \ + ARM_AUTOINC_VALID_FOR_MODE_P(mode, ARM_PRE_DEC) + +#define USE_STORE_PRE_DECREMENT(mode) USE_LOAD_PRE_DECREMENT(mode) +#define USE_STORE_PRE_INCREMENT(mode) USE_LOAD_PRE_INCREMENT(mode) +#define USE_STORE_POST_DECREMENT(mode) USE_LOAD_POST_DECREMENT(mode) +#define USE_STORE_POST_INCREMENT(mode) USE_LOAD_POST_INCREMENT(mode) + /* Macros to check register numbers against specific register classes. */ /* These assume that REGNO is a hard or pseudo reg number. diff --git a/gcc/tree-ssa-loop-ivopts.c b/gcc/tree-ssa-loop-ivopts.c index af7a1cf1d5e..3016f08e7e3 100644 --- a/gcc/tree-ssa-loop-ivopts.c +++ b/gcc/tree-ssa-loop-ivopts.c @@ -2362,8 +2362,12 @@ add_autoinc_candidates (struct ivopts_data *data, tree base, tree step, cstepi = int_cst_value (step); mem_mode = TYPE_MODE (TREE_TYPE (*use->op_p)); - if ((HAVE_PRE_INCREMENT && GET_MODE_SIZE (mem_mode) == cstepi) - || (HAVE_PRE_DECREMENT && GET_MODE_SIZE (mem_mode) == -cstepi)) + if (((USE_LOAD_PRE_INCREMENT (mem_mode) + || USE_STORE_PRE_INCREMENT (mem_mode)) + && GET_MODE_SIZE (mem_mode) == cstepi) + || ((USE_LOAD_PRE_DECREMENT (mem_mode) + || USE_STORE_PRE_DECREMENT (mem_mode)) + && GET_MODE_SIZE (mem_mode) == -cstepi)) { enum tree_code code = MINUS_EXPR; tree new_base; @@ -2380,8 +2384,12 @@ add_autoinc_candidates (struct ivopts_data *data, tree base, tree step, add_candidate_1 (data, new_base, step, important, IP_BEFORE_USE, use, use->stmt); } - if ((HAVE_POST_INCREMENT && GET_MODE_SIZE (mem_mode) == cstepi) - || (HAVE_POST_DECREMENT && GET_MODE_SIZE (mem_mode) == -cstepi)) + if (((USE_LOAD_POST_INCREMENT (mem_mode) + || USE_STORE_POST_INCREMENT (mem_mode)) + && GET_MODE_SIZE (mem_mode) == cstepi) + || ((USE_LOAD_POST_DECREMENT (mem_mode) + || USE_STORE_POST_DECREMENT (mem_mode)) + && GET_MODE_SIZE (mem_mode) == -cstepi)) { add_candidate_1 (data, base, step, important, IP_AFTER_USE, use, use->stmt); @@ -3315,25 +3323,29 @@ get_address_cost (bool symbol_present, bool var_present, reg0 = gen_raw_REG (address_mode, LAST_VIRTUAL_REGISTER + 1); reg1 = gen_raw_REG (address_mode, LAST_VIRTUAL_REGISTER + 2); - if (HAVE_PRE_DECREMENT) + if (USE_LOAD_PRE_DECREMENT (mem_mode) + || USE_STORE_PRE_DECREMENT (mem_mode)) { addr = gen_rtx_PRE_DEC (address_mode, reg0); has_predec[mem_mode] = memory_address_addr_space_p (mem_mode, addr, as); } - if (HAVE_POST_DECREMENT) + if (USE_LOAD_POST_DECREMENT (mem_mode) + || USE_STORE_POST_DECREMENT (mem_mode)) { addr = gen_rtx_POST_DEC (address_mode, reg0); has_postdec[mem_mode] = memory_address_addr_space_p (mem_mode, addr, as); } - if (HAVE_PRE_INCREMENT) + if (USE_LOAD_PRE_INCREMENT (mem_mode) + || USE_STORE_PRE_DECREMENT (mem_mode)) { addr = gen_rtx_PRE_INC (address_mode, reg0); has_preinc[mem_mode] = memory_address_addr_space_p (mem_mode, addr, as); } - if (HAVE_POST_INCREMENT) + if (USE_LOAD_POST_INCREMENT (mem_mode) + || USE_STORE_POST_INCREMENT (mem_mode)) { addr = gen_rtx_POST_INC (address_mode, reg0); has_postinc[mem_mode] -- 2.11.4.GIT