From 5791f55d02239dc7172884f9d5143632b8ca602d Mon Sep 17 00:00:00 2001 From: Kyrylo Tkachov Date: Fri, 26 Aug 2016 10:22:08 +0000 Subject: [PATCH] [ARM] Refactor MOVW/MOVT fusion logic to allow extension * config/arm/arm.c (arm_sets_movw_movt_fusible_p): New function. (aarch_macro_fusion_pair_p): Use above to avoid early return. From-SVN: r239771 --- gcc/ChangeLog | 5 +++ gcc/config/arm/arm.c | 89 +++++++++++++++++++++++++------------------- 2 files changed, 55 insertions(+), 39 deletions(-) diff --git a/gcc/ChangeLog b/gcc/ChangeLog index d4360f766f5..9c82debc2f4 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,8 @@ +2016-08-26 Kyrylo Tkachov + + * config/arm/arm.c (arm_sets_movw_movt_fusible_p): New function. + (aarch_macro_fusion_pair_p): Use above to avoid early return. + 2016-08-26 Prathamesh Kulkarni Martin Jambhor diff --git a/gcc/config/arm/arm.c b/gcc/config/arm/arm.c index c775807e76b..43a832eeb5c 100644 --- a/gcc/config/arm/arm.c +++ b/gcc/config/arm/arm.c @@ -29914,11 +29914,57 @@ arm_macro_fusion_p (void) return current_tune->fusible_ops != tune_params::FUSE_NOTHING; } +/* Return true if the two back-to-back sets PREV_SET, CURR_SET are suitable + for MOVW / MOVT macro fusion. */ + +static bool +arm_sets_movw_movt_fusible_p (rtx prev_set, rtx curr_set) +{ + /* We are trying to fuse + movw imm / movt imm + instructions as a group that gets scheduled together. */ + + rtx set_dest = SET_DEST (curr_set); + + if (GET_MODE (set_dest) != SImode) + return false; + + /* We are trying to match: + prev (movw) == (set (reg r0) (const_int imm16)) + curr (movt) == (set (zero_extract (reg r0) + (const_int 16) + (const_int 16)) + (const_int imm16_1)) + or + prev (movw) == (set (reg r1) + (high (symbol_ref ("SYM")))) + curr (movt) == (set (reg r0) + (lo_sum (reg r1) + (symbol_ref ("SYM")))) */ + + if (GET_CODE (set_dest) == ZERO_EXTRACT) + { + if (CONST_INT_P (SET_SRC (curr_set)) + && CONST_INT_P (SET_SRC (prev_set)) + && REG_P (XEXP (set_dest, 0)) + && REG_P (SET_DEST (prev_set)) + && REGNO (XEXP (set_dest, 0)) == REGNO (SET_DEST (prev_set))) + return true; + + } + else if (GET_CODE (SET_SRC (curr_set)) == LO_SUM + && REG_P (SET_DEST (curr_set)) + && REG_P (SET_DEST (prev_set)) + && GET_CODE (SET_SRC (prev_set)) == HIGH + && REGNO (SET_DEST (curr_set)) == REGNO (SET_DEST (prev_set))) + return true; + + return false; +} static bool aarch_macro_fusion_pair_p (rtx_insn* prev, rtx_insn* curr) { - rtx set_dest; rtx prev_set = single_set (prev); rtx curr_set = single_set (curr); @@ -29936,45 +29982,10 @@ aarch_macro_fusion_pair_p (rtx_insn* prev, rtx_insn* curr) && aarch_crypto_can_dual_issue (prev, curr)) return true; - if (current_tune->fusible_ops & tune_params::FUSE_MOVW_MOVT) - { - /* We are trying to fuse - movw imm / movt imm - instructions as a group that gets scheduled together. */ - - set_dest = SET_DEST (curr_set); - - if (GET_MODE (set_dest) != SImode) - return false; + if (current_tune->fusible_ops & tune_params::FUSE_MOVW_MOVT + && arm_sets_movw_movt_fusible_p (prev_set, curr_set)) + return true; - /* We are trying to match: - prev (movw) == (set (reg r0) (const_int imm16)) - curr (movt) == (set (zero_extract (reg r0) - (const_int 16) - (const_int 16)) - (const_int imm16_1)) - or - prev (movw) == (set (reg r1) - (high (symbol_ref ("SYM")))) - curr (movt) == (set (reg r0) - (lo_sum (reg r1) - (symbol_ref ("SYM")))) */ - if (GET_CODE (set_dest) == ZERO_EXTRACT) - { - if (CONST_INT_P (SET_SRC (curr_set)) - && CONST_INT_P (SET_SRC (prev_set)) - && REG_P (XEXP (set_dest, 0)) - && REG_P (SET_DEST (prev_set)) - && REGNO (XEXP (set_dest, 0)) == REGNO (SET_DEST (prev_set))) - return true; - } - else if (GET_CODE (SET_SRC (curr_set)) == LO_SUM - && REG_P (SET_DEST (curr_set)) - && REG_P (SET_DEST (prev_set)) - && GET_CODE (SET_SRC (prev_set)) == HIGH - && REGNO (SET_DEST (curr_set)) == REGNO (SET_DEST (prev_set))) - return true; - } return false; } -- 2.30.2