Commit 36dafbd1 by Adam Nemet Committed by Adam Nemet

re PR middle-end/36194 (Truncation optimization in combine can remove necessary truncations)

	PR middle-end/36194
        * combine.c (check_conversion): Rename to check_promoted_subreg. 
        Don't call record_truncated_value from here. 
        (record_truncated_value): Turn it into a for_each_rtx callback. 
        (record_truncated_values): New function. 
        (combine_instructions): Call note_uses with 
        record_truncated_values.  Change name of check_conversion to 
        check_promoted_subreg. 

testsuite/

	* gcc.dg/pr36194.c: New test.

From-SVN: r135392
parent fda9d38f
2008-05-15 Adam Nemet <anemet@caviumnetworks.com>
PR middle-end/36194
* combine.c (check_conversion): Rename back to check_promoted_subreg.
Don't call record_truncated_value from here.
(record_truncated_value): Turn it into a for_each_rtx callback.
(record_truncated_values): New function.
(combine_instructions): Call note_uses with
record_truncated_values. Change name of check_conversion to
check_promoted_subreg.
2008-05-15 Janis Johnson <janis187@us.ibm.com> 2008-05-15 Janis Johnson <janis187@us.ibm.com>
* doc/sourcebuild.texi: Document support for torture tests. * doc/sourcebuild.texi: Document support for torture tests.
......
...@@ -425,7 +425,7 @@ static rtx gen_lowpart_for_combine (enum machine_mode, rtx); ...@@ -425,7 +425,7 @@ static rtx gen_lowpart_for_combine (enum machine_mode, rtx);
static enum rtx_code simplify_comparison (enum rtx_code, rtx *, rtx *); static enum rtx_code simplify_comparison (enum rtx_code, rtx *, rtx *);
static void update_table_tick (rtx); static void update_table_tick (rtx);
static void record_value_for_reg (rtx, rtx, rtx); static void record_value_for_reg (rtx, rtx, rtx);
static void check_conversions (rtx, rtx); static void check_promoted_subreg (rtx, rtx);
static void record_dead_and_set_regs_1 (rtx, const_rtx, void *); static void record_dead_and_set_regs_1 (rtx, const_rtx, void *);
static void record_dead_and_set_regs (rtx); static void record_dead_and_set_regs (rtx);
static int get_last_value_validate (rtx *, rtx, int, int); static int get_last_value_validate (rtx *, rtx, int, int);
...@@ -441,7 +441,8 @@ static void mark_used_regs_combine (rtx); ...@@ -441,7 +441,8 @@ static void mark_used_regs_combine (rtx);
static void record_promoted_value (rtx, rtx); static void record_promoted_value (rtx, rtx);
static int unmentioned_reg_p_1 (rtx *, void *); static int unmentioned_reg_p_1 (rtx *, void *);
static bool unmentioned_reg_p (rtx, rtx); static bool unmentioned_reg_p (rtx, rtx);
static void record_truncated_value (rtx); static int record_truncated_value (rtx *, void *);
static void record_truncated_values (rtx *, void *);
static bool reg_truncated_to_mode (enum machine_mode, const_rtx); static bool reg_truncated_to_mode (enum machine_mode, const_rtx);
static rtx gen_lowpart_or_truncate (enum machine_mode, rtx); static rtx gen_lowpart_or_truncate (enum machine_mode, rtx);
...@@ -1137,7 +1138,12 @@ combine_instructions (rtx f, unsigned int nregs) ...@@ -1137,7 +1138,12 @@ combine_instructions (rtx f, unsigned int nregs)
{ {
/* See if we know about function return values before this /* See if we know about function return values before this
insn based upon SUBREG flags. */ insn based upon SUBREG flags. */
check_conversions (insn, PATTERN (insn)); check_promoted_subreg (insn, PATTERN (insn));
/* See if we can find hardregs and subreg of pseudos in
narrower modes. This could help turning TRUNCATEs
into SUBREGs. */
note_uses (&PATTERN (insn), record_truncated_values, NULL);
/* Try this insn with each insn it links back to. */ /* Try this insn with each insn it links back to. */
...@@ -11610,13 +11616,15 @@ reg_truncated_to_mode (enum machine_mode mode, const_rtx x) ...@@ -11610,13 +11616,15 @@ reg_truncated_to_mode (enum machine_mode mode, const_rtx x)
return false; return false;
} }
/* X is a REG or a SUBREG. If X is some sort of a truncation record /* Callback for for_each_rtx. If *P is a hard reg or a subreg record the mode
it. For non-TRULY_NOOP_TRUNCATION targets we might be able to turn that the register is accessed in. For non-TRULY_NOOP_TRUNCATION targets we
a truncate into a subreg using this information. */ might be able to turn a truncate into a subreg using this information.
Return -1 if traversing *P is complete or 0 otherwise. */
static void static int
record_truncated_value (rtx x) record_truncated_value (rtx *p, void *data ATTRIBUTE_UNUSED)
{ {
rtx x = *p;
enum machine_mode truncated_mode; enum machine_mode truncated_mode;
reg_stat_type *rsp; reg_stat_type *rsp;
...@@ -11626,11 +11634,11 @@ record_truncated_value (rtx x) ...@@ -11626,11 +11634,11 @@ record_truncated_value (rtx x)
truncated_mode = GET_MODE (x); truncated_mode = GET_MODE (x);
if (GET_MODE_SIZE (original_mode) <= GET_MODE_SIZE (truncated_mode)) if (GET_MODE_SIZE (original_mode) <= GET_MODE_SIZE (truncated_mode))
return; return -1;
if (TRULY_NOOP_TRUNCATION (GET_MODE_BITSIZE (truncated_mode), if (TRULY_NOOP_TRUNCATION (GET_MODE_BITSIZE (truncated_mode),
GET_MODE_BITSIZE (original_mode))) GET_MODE_BITSIZE (original_mode)))
return; return -1;
x = SUBREG_REG (x); x = SUBREG_REG (x);
} }
...@@ -11639,7 +11647,7 @@ record_truncated_value (rtx x) ...@@ -11639,7 +11647,7 @@ record_truncated_value (rtx x)
else if (REG_P (x) && REGNO (x) < FIRST_PSEUDO_REGISTER) else if (REG_P (x) && REGNO (x) < FIRST_PSEUDO_REGISTER)
truncated_mode = GET_MODE (x); truncated_mode = GET_MODE (x);
else else
return; return 0;
rsp = VEC_index (reg_stat_type, reg_stat, REGNO (x)); rsp = VEC_index (reg_stat_type, reg_stat, REGNO (x));
if (rsp->truncated_to_mode == 0 if (rsp->truncated_to_mode == 0
...@@ -11650,23 +11658,30 @@ record_truncated_value (rtx x) ...@@ -11650,23 +11658,30 @@ record_truncated_value (rtx x)
rsp->truncated_to_mode = truncated_mode; rsp->truncated_to_mode = truncated_mode;
rsp->truncation_label = label_tick; rsp->truncation_label = label_tick;
} }
return -1;
} }
/* Scan X for promoted SUBREGs and truncated REGs. For each one /* Callback for note_uses. Find hardregs and subregs of pseudos and
found, note what it implies to the registers used in it. */ the modes they are used in. This can help truning TRUNCATEs into
SUBREGs. */
static void static void
check_conversions (rtx insn, rtx x) record_truncated_values (rtx *x, void *data ATTRIBUTE_UNUSED)
{
for_each_rtx (x, record_truncated_value, NULL);
}
/* Scan X for promoted SUBREGs. For each one found,
note what it implies to the registers used in it. */
static void
check_promoted_subreg (rtx insn, rtx x)
{ {
if (GET_CODE (x) == SUBREG || REG_P (x))
{
if (GET_CODE (x) == SUBREG if (GET_CODE (x) == SUBREG
&& SUBREG_PROMOTED_VAR_P (x) && SUBREG_PROMOTED_VAR_P (x)
&& REG_P (SUBREG_REG (x))) && REG_P (SUBREG_REG (x)))
record_promoted_value (insn, x); record_promoted_value (insn, x);
record_truncated_value (x);
}
else else
{ {
const char *format = GET_RTX_FORMAT (GET_CODE (x)); const char *format = GET_RTX_FORMAT (GET_CODE (x));
...@@ -11676,13 +11691,13 @@ check_conversions (rtx insn, rtx x) ...@@ -11676,13 +11691,13 @@ check_conversions (rtx insn, rtx x)
switch (format[i]) switch (format[i])
{ {
case 'e': case 'e':
check_conversions (insn, XEXP (x, i)); check_promoted_subreg (insn, XEXP (x, i));
break; break;
case 'V': case 'V':
case 'E': case 'E':
if (XVEC (x, i) != 0) if (XVEC (x, i) != 0)
for (j = 0; j < XVECLEN (x, i); j++) for (j = 0; j < XVECLEN (x, i); j++)
check_conversions (insn, XVECEXP (x, i, j)); check_promoted_subreg (insn, XVECEXP (x, i, j));
break; break;
} }
} }
......
2008-05-15 Adam Nemet <anemet@caviumnetworks.com>
PR middle-end/36194
* gcc.dg/pr36194.c: New test.
2008-05-15 Janne Blomqvist <jb@gcc.gnu.org> 2008-05-15 Janne Blomqvist <jb@gcc.gnu.org>
PR libfortran/34974 PR libfortran/34974
/* { dg-do run } */
/* { dg-options "-O2" } */
void abort (void);
__attribute__ ((noinline)) void
f (int i)
{
if (i != 0x87654321)
abort ();
asm ("");
}
__attribute__ ((noinline)) void
g (long long a)
{
f (a);
asm ("");
}
main ()
{
g (0x1234567887654321ll);
return 0;
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment