From: jakub Date: Tue, 30 Mar 2010 20:17:39 +0000 (+0000) Subject: * var-tracking.c (use_narrower_mode_test, use_narrower_mode): New X-Git-Url: http://git.sourceforge.jp/view?p=pf3gnuchains%2Fgcc-fork.git;a=commitdiff_plain;h=7d5e5c9296c26aedf54e118f6a35e8bdbf0ac2ea * var-tracking.c (use_narrower_mode_test, use_narrower_mode): New functions. (adjust_mems): Replace narrowing SUBREG of expression containing just PLUS, MINUS, MULT and ASHIFT of registers and constants with operations in the narrower mode. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@157835 138bc75d-0d04-0410-961f-82ee72b054a4 --- diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 6b1fcba0e14..89aaa5a0c0b 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,5 +1,11 @@ 2010-03-30 Jakub Jelinek + * var-tracking.c (use_narrower_mode_test, use_narrower_mode): New + functions. + (adjust_mems): Replace narrowing SUBREG of expression containing + just PLUS, MINUS, MULT and ASHIFT of registers and constants + with operations in the narrower mode. + PR debug/43593 * var-tracking.c (dataflow_set_clear_at_call): Invalidate just regs_invalidated_by_call instead all call_used_reg_set diff --git a/gcc/var-tracking.c b/gcc/var-tracking.c index 3777ae8fba6..c1df06b48c8 100644 --- a/gcc/var-tracking.c +++ b/gcc/var-tracking.c @@ -726,6 +726,65 @@ struct adjust_mem_data rtx side_effects; }; +/* Helper for adjust_mems. Return 1 if *loc is unsuitable for + transformation of wider mode arithmetics to narrower mode, + -1 if it is suitable and subexpressions shouldn't be + traversed and 0 if it is suitable and subexpressions should + be traversed. Called through for_each_rtx. */ + +static int +use_narrower_mode_test (rtx *loc, void *data) +{ + rtx subreg = (rtx) data; + + if (CONSTANT_P (*loc)) + return -1; + switch (GET_CODE (*loc)) + { + case REG: + if (cselib_lookup (*loc, GET_MODE (SUBREG_REG (subreg)), 0)) + return 1; + return -1; + case PLUS: + case MINUS: + case MULT: + return 0; + case ASHIFT: + if (for_each_rtx (&XEXP (*loc, 0), use_narrower_mode_test, data)) + return 1; + else + return -1; + default: + return 1; + } +} + +/* Transform X into narrower mode MODE from wider mode WMODE. */ + +static rtx +use_narrower_mode (rtx x, enum machine_mode mode, enum machine_mode wmode) +{ + rtx op0, op1; + if (CONSTANT_P (x)) + return lowpart_subreg (mode, x, wmode); + switch (GET_CODE (x)) + { + case REG: + return lowpart_subreg (mode, x, wmode); + case PLUS: + case MINUS: + case MULT: + op0 = use_narrower_mode (XEXP (x, 0), mode, wmode); + op1 = use_narrower_mode (XEXP (x, 1), mode, wmode); + return simplify_gen_binary (GET_CODE (x), mode, op0, op1); + case ASHIFT: + op0 = use_narrower_mode (XEXP (x, 0), mode, wmode); + return simplify_gen_binary (ASHIFT, mode, op0, XEXP (x, 1)); + default: + gcc_unreachable (); + } +} + /* Helper function for adjusting used MEMs. */ static rtx @@ -819,18 +878,36 @@ adjust_mems (rtx loc, const_rtx old_rtx, void *data) amd->store = store_save; mem = simplify_replace_fn_rtx (addr, old_rtx, adjust_mems, data); if (mem == SUBREG_REG (loc)) - return loc; + { + tem = loc; + goto finish_subreg; + } tem = simplify_gen_subreg (GET_MODE (loc), mem, GET_MODE (SUBREG_REG (loc)), SUBREG_BYTE (loc)); if (tem) - return tem; + goto finish_subreg; tem = simplify_gen_subreg (GET_MODE (loc), addr, GET_MODE (SUBREG_REG (loc)), SUBREG_BYTE (loc)); - if (tem) - return tem; - return gen_rtx_raw_SUBREG (GET_MODE (loc), addr, SUBREG_BYTE (loc)); + if (tem == NULL_RTX) + tem = gen_rtx_raw_SUBREG (GET_MODE (loc), addr, SUBREG_BYTE (loc)); + finish_subreg: + if (MAY_HAVE_DEBUG_INSNS + && GET_CODE (tem) == SUBREG + && (GET_CODE (SUBREG_REG (tem)) == PLUS + || GET_CODE (SUBREG_REG (tem)) == MINUS + || GET_CODE (SUBREG_REG (tem)) == MULT + || GET_CODE (SUBREG_REG (tem)) == ASHIFT) + && GET_MODE_CLASS (GET_MODE (tem)) == MODE_INT + && GET_MODE_CLASS (GET_MODE (SUBREG_REG (tem))) == MODE_INT + && GET_MODE_SIZE (GET_MODE (tem)) + < GET_MODE_SIZE (GET_MODE (SUBREG_REG (tem))) + && subreg_lowpart_p (tem) + && !for_each_rtx (&SUBREG_REG (tem), use_narrower_mode_test, tem)) + return use_narrower_mode (SUBREG_REG (tem), GET_MODE (tem), + GET_MODE (SUBREG_REG (tem))); + return tem; default: break; }