diff mbox

Disable if_conversion2 for Og

Message ID 000001cf584e$66102060$32306120$@arm.com
State New
Headers show

Commit Message

Joey Ye April 15, 2014, 1:59 a.m. UTC
If-converstion is harmful to optimized debugging as it generates conditional
execution instructions with line number information, which resulted in a
dillusion to developers that both then-else branches are executed.

For example:
test.c:
1: unsigned oldest_sequence;
2:
3: unsigned foo(unsigned seq_number)
4: {
5:  if ((seq_number + 5) < 10)
6:    seq_number += 100;
7:   else
8:     seq_number = oldest_sequence;

  if (seq_number < oldest_sequence)
    seq_number = oldest_sequence;

 return seq_number;
}

$ arm-none-eabi-gcc -mthumb -mcpu=cortex-m3 -Og -g3
gets:
        .loc 1 5 0
        adds    r3, r0, #5
        cmp     r3, #9
        .loc 1 6 0       <----- line 6, then branch
        itee    ls
        addls   r0, r0, #100
.LVL1:
        .loc 1 8 0       <----- line 8, else branch. Both branches seems to
be executed in GDB
        ldrhi   r3, .L5
        ldrhi   r0, [r3]

The reason is that if_conversion2 is still enabled in Og. The patch simply
disables it for Og.

Tests:
* -Og bootstrap passed.
* Make check default (no additional option): No regression.
* Make check with -Og: expected regressions. Cases relying on if-conversion2
failed.
> FAIL: gcc.target/arm/its.c scan-assembler-times \\tit 2
> FAIL: gcc.target/arm/pr40956.c scan-assembler-times mov[\\\\t ]*r., #0 1
> FAIL: gcc.target/arm/thumb-ifcvt-2.c scan-assembler asreq
> FAIL: gcc.target/arm/thumb-ifcvt-2.c scan-assembler lslne
> FAIL: gcc.target/arm/thumb-ifcvt.c scan-assembler asrne
> FAIL: gcc.target/arm/thumb-ifcvt.c scan-assembler lslne

OK to trunk and 4.8/4.9 branch?

ChangeLog:
    * opts.c (OPT_fif_conversion2): Disable for Og.

     { OPT_LEVELS_1_PLUS, OPT_fipa_profile, NULL, 1 },

Comments

Richard Biener April 15, 2014, 8:05 a.m. UTC | #1
On Tue, Apr 15, 2014 at 3:59 AM, Joey Ye <joey.ye@arm.com> wrote:
> If-converstion is harmful to optimized debugging as it generates conditional
> execution instructions with line number information, which resulted in a
> dillusion to developers that both then-else branches are executed.
>
> For example:
> test.c:
> 1: unsigned oldest_sequence;
> 2:
> 3: unsigned foo(unsigned seq_number)
> 4: {
> 5:  if ((seq_number + 5) < 10)
> 6:    seq_number += 100;
> 7:   else
> 8:     seq_number = oldest_sequence;
>
>   if (seq_number < oldest_sequence)
>     seq_number = oldest_sequence;
>
>  return seq_number;
> }
>
> $ arm-none-eabi-gcc -mthumb -mcpu=cortex-m3 -Og -g3
> gets:
>         .loc 1 5 0
>         adds    r3, r0, #5
>         cmp     r3, #9
>         .loc 1 6 0       <----- line 6, then branch
>         itee    ls
>         addls   r0, r0, #100
> .LVL1:
>         .loc 1 8 0       <----- line 8, else branch. Both branches seems to
> be executed in GDB
>         ldrhi   r3, .L5
>         ldrhi   r0, [r3]
>
> The reason is that if_conversion2 is still enabled in Og. The patch simply
> disables it for Og.
>
> Tests:
> * -Og bootstrap passed.
> * Make check default (no additional option): No regression.
> * Make check with -Og: expected regressions. Cases relying on if-conversion2
> failed.
>> FAIL: gcc.target/arm/its.c scan-assembler-times \\tit 2
>> FAIL: gcc.target/arm/pr40956.c scan-assembler-times mov[\\\\t ]*r., #0 1
>> FAIL: gcc.target/arm/thumb-ifcvt-2.c scan-assembler asreq
>> FAIL: gcc.target/arm/thumb-ifcvt-2.c scan-assembler lslne
>> FAIL: gcc.target/arm/thumb-ifcvt.c scan-assembler asrne
>> FAIL: gcc.target/arm/thumb-ifcvt.c scan-assembler lslne
>
> OK to trunk and 4.8/4.9 branch?

Ok for trunk and branches after a while.  Why does if-conversion not have
the same problem?  On the GIMPLE part we avoid all kinds of if-conversion
with -Og.

Thanks,
Richard.

> ChangeLog:
>     * opts.c (OPT_fif_conversion2): Disable for Og.
>
> diff --git a/gcc/opts.c b/gcc/opts.c
> index fdc903f..e076253 100644
> --- a/gcc/opts.c
> +++ b/gcc/opts.c
> @@ -432,7 +432,7 @@ static const struct default_options
> default_options_table[] =
>      { OPT_LEVELS_1_PLUS, OPT_fcprop_registers, NULL, 1 },
>      { OPT_LEVELS_1_PLUS, OPT_fforward_propagate, NULL, 1 },
>      { OPT_LEVELS_1_PLUS, OPT_fif_conversion, NULL, 1 },
> -    { OPT_LEVELS_1_PLUS, OPT_fif_conversion2, NULL, 1 },
> +    { OPT_LEVELS_1_PLUS_NOT_DEBUG, OPT_fif_conversion2, NULL, 1 },
>      { OPT_LEVELS_1_PLUS, OPT_fipa_pure_const, NULL, 1 },
>      { OPT_LEVELS_1_PLUS, OPT_fipa_reference, NULL, 1 },
>      { OPT_LEVELS_1_PLUS, OPT_fipa_profile, NULL, 1 },
>
>
Joey Ye April 15, 2014, 10:37 a.m. UTC | #2
> -----Original Message-----
> From: Richard Biener [mailto:richard.guenther@gmail.com]
> Sent: Tuesday, April 15, 2014 4:05 PM
> To: Joey Ye
> Cc: GCC Patches
> Subject: Re: [patch] Disable if_conversion2 for Og
> 
> On Tue, Apr 15, 2014 at 3:59 AM, Joey Ye <joey.ye@arm.com> wrote:
> > If-converstion is harmful to optimized debugging as it generates
> > conditional execution instructions with line number information, which
> > resulted in a dillusion to developers that both then-else branches are
> executed.
> >
> > For example:
> > test.c:
> > 1: unsigned oldest_sequence;
> > 2:
> > 3: unsigned foo(unsigned seq_number)
> > 4: {
> > 5:  if ((seq_number + 5) < 10)
> > 6:    seq_number += 100;
> > 7:   else
> > 8:     seq_number = oldest_sequence;
> >
> >   if (seq_number < oldest_sequence)
> >     seq_number = oldest_sequence;
> >
> >  return seq_number;
> > }
> >
> > $ arm-none-eabi-gcc -mthumb -mcpu=cortex-m3 -Og -g3
> > gets:
> >         .loc 1 5 0
> >         adds    r3, r0, #5
> >         cmp     r3, #9
> >         .loc 1 6 0       <----- line 6, then branch
> >         itee    ls
> >         addls   r0, r0, #100
> > .LVL1:
> >         .loc 1 8 0       <----- line 8, else branch. Both branches seems to
> > be executed in GDB
> >         ldrhi   r3, .L5
> >         ldrhi   r0, [r3]
> >
> > The reason is that if_conversion2 is still enabled in Og. The patch
> > simply disables it for Og.
> >
> > Tests:
> > * -Og bootstrap passed.
> > * Make check default (no additional option): No regression.
> > * Make check with -Og: expected regressions. Cases relying on
> > if-conversion2 failed.
> >> FAIL: gcc.target/arm/its.c scan-assembler-times \\tit 2
> >> FAIL: gcc.target/arm/pr40956.c scan-assembler-times mov[\\\\t ]*r.,
> >> #0 1
> >> FAIL: gcc.target/arm/thumb-ifcvt-2.c scan-assembler asreq
> >> FAIL: gcc.target/arm/thumb-ifcvt-2.c scan-assembler lslne
> >> FAIL: gcc.target/arm/thumb-ifcvt.c scan-assembler asrne
> >> FAIL: gcc.target/arm/thumb-ifcvt.c scan-assembler lslne
> >
> > OK to trunk and 4.8/4.9 branch?
> 
> Ok for trunk and branches after a while.  Why does if-conversion not have
> the same problem?  On the GIMPLE part we avoid all kinds of if-conversion
> with -Og.
I think if-conversion should be disabled for Og too, but I don't have a case to show that it is harmful. If GIMPLE avoids all if-conversion, it is nature to do the same for RTL. I'll test and send another patch to also disable if-conversion.
Richard Earnshaw April 16, 2014, 9:44 a.m. UTC | #3
On 15/04/14 02:59, Joey Ye wrote:
> If-converstion is harmful to optimized debugging as it generates conditional
> execution instructions with line number information, which resulted in a
> dillusion to developers that both then-else branches are executed.
> 
> For example:
> test.c:
> 1: unsigned oldest_sequence;
> 2:
> 3: unsigned foo(unsigned seq_number)
> 4: {
> 5:  if ((seq_number + 5) < 10)
> 6:    seq_number += 100;
> 7:   else
> 8:     seq_number = oldest_sequence;
> 
>   if (seq_number < oldest_sequence)
>     seq_number = oldest_sequence;
> 
>  return seq_number;
> }

Arguably, this is a bug in gdb.  The debugger should understand when a
breakpointed conditional instruction is not going to execute and
silently continue.  That preserves the illusion of not executing the
code without requiring the compiler to de-optimize things.

R.

> 
> $ arm-none-eabi-gcc -mthumb -mcpu=cortex-m3 -Og -g3
> gets:
>         .loc 1 5 0
>         adds    r3, r0, #5
>         cmp     r3, #9
>         .loc 1 6 0       <----- line 6, then branch
>         itee    ls
>         addls   r0, r0, #100
> .LVL1:
>         .loc 1 8 0       <----- line 8, else branch. Both branches seems to
> be executed in GDB
>         ldrhi   r3, .L5
>         ldrhi   r0, [r3]
> 
> The reason is that if_conversion2 is still enabled in Og. The patch simply
> disables it for Og.
> 
> Tests:
> * -Og bootstrap passed.
> * Make check default (no additional option): No regression.
> * Make check with -Og: expected regressions. Cases relying on if-conversion2
> failed.
>> FAIL: gcc.target/arm/its.c scan-assembler-times \\tit 2
>> FAIL: gcc.target/arm/pr40956.c scan-assembler-times mov[\\\\t ]*r., #0 1
>> FAIL: gcc.target/arm/thumb-ifcvt-2.c scan-assembler asreq
>> FAIL: gcc.target/arm/thumb-ifcvt-2.c scan-assembler lslne
>> FAIL: gcc.target/arm/thumb-ifcvt.c scan-assembler asrne
>> FAIL: gcc.target/arm/thumb-ifcvt.c scan-assembler lslne
> 
> OK to trunk and 4.8/4.9 branch?
> 
> ChangeLog:
>     * opts.c (OPT_fif_conversion2): Disable for Og.
> 
> diff --git a/gcc/opts.c b/gcc/opts.c
> index fdc903f..e076253 100644
> --- a/gcc/opts.c
> +++ b/gcc/opts.c
> @@ -432,7 +432,7 @@ static const struct default_options
> default_options_table[] =
>      { OPT_LEVELS_1_PLUS, OPT_fcprop_registers, NULL, 1 },
>      { OPT_LEVELS_1_PLUS, OPT_fforward_propagate, NULL, 1 },
>      { OPT_LEVELS_1_PLUS, OPT_fif_conversion, NULL, 1 },
> -    { OPT_LEVELS_1_PLUS, OPT_fif_conversion2, NULL, 1 },
> +    { OPT_LEVELS_1_PLUS_NOT_DEBUG, OPT_fif_conversion2, NULL, 1 },
>      { OPT_LEVELS_1_PLUS, OPT_fipa_pure_const, NULL, 1 },
>      { OPT_LEVELS_1_PLUS, OPT_fipa_reference, NULL, 1 },
>      { OPT_LEVELS_1_PLUS, OPT_fipa_profile, NULL, 1 },
> 
> 
>
Joey Ye April 16, 2014, 10:02 a.m. UTC | #4
> -----Original Message-----
> From: Richard Earnshaw
> Sent: Wednesday, April 16, 2014 5:44 PM
> To: Joey Ye
> Cc: gcc-patches@gcc.gnu.org
> Subject: Re: [patch] Disable if_conversion2 for Og
> 
> Arguably, this is a bug in gdb.  The debugger should understand when a
> breakpointed conditional instruction is not going to execute and silently
> continue.  That preserves the illusion of not executing the code without
> requiring the compiler to de-optimize things.
> 
> R.
Or compiler just optimizes it, and emits generic DWARFx information to help
GDB handle it in more target independently?

- Joey
Richard Earnshaw April 16, 2014, 10:03 a.m. UTC | #5
On 16/04/14 11:02, Joey Ye wrote:
> 
> 
>> -----Original Message-----
>> From: Richard Earnshaw
>> Sent: Wednesday, April 16, 2014 5:44 PM
>> To: Joey Ye
>> Cc: gcc-patches@gcc.gnu.org
>> Subject: Re: [patch] Disable if_conversion2 for Og
>>
>> Arguably, this is a bug in gdb.  The debugger should understand when a
>> breakpointed conditional instruction is not going to execute and silently
>> continue.  That preserves the illusion of not executing the code without
>> requiring the compiler to de-optimize things.
>>
>> R.
> Or compiler just optimizes it, and emits generic DWARFx information to help
> GDB handle it in more target independently?
> 
> - Joey
> 

I'm not sure extra dwarf info would help much.  The debugger still has
to understand that the breakpoint has not really been hit.

R.
Richard Earnshaw April 16, 2014, 10:21 a.m. UTC | #6
On 16/04/14 11:17, Joey Ye wrote:
>> -----Original Message-----
>> From: Richard Earnshaw
>> Sent: Wednesday, April 16, 2014 6:04 PM
>> To: Joey Ye
>> Cc: gcc-patches@gcc.gnu.org
>> Subject: Re: [patch] Disable if_conversion2 for Og
>>
>> On 16/04/14 11:02, Joey Ye wrote:
>>>
>>>
>>>> -----Original Message-----
>>>> From: Richard Earnshaw
>>>> Sent: Wednesday, April 16, 2014 5:44 PM
>>>> To: Joey Ye
>>>> Cc: gcc-patches@gcc.gnu.org
>>>> Subject: Re: [patch] Disable if_conversion2 for Og
>>>>
>>>> Arguably, this is a bug in gdb.  The debugger should understand when
>>>> a breakpointed conditional instruction is not going to execute and
>>>> silently continue.  That preserves the illusion of not executing the
>>>> code without requiring the compiler to de-optimize things.
>>>>
>>>> R.
>>> Or compiler just optimizes it, and emits generic DWARFx information to
>>> help GDB handle it in more target independently?
>>>
>>> - Joey
>>>
>>
>> I'm not sure extra dwarf info would help much.  The debugger still has to
>> understand that the breakpoint has not really been hit.
>>
>> R.
> Yes, it is inevitable. But without extra dwarf info it will be even more painful: each time setting break-point or break-point hits it has to decode the break-pointed instructions and its context to search for conditional execution and IT blocks.
> 

For thumb code it can get the conditional information it needs from the
IT state in the PSR; for ARM code it has to look no further than the
instruction itself.

R.
Joey Ye April 16, 2014, 10:26 a.m. UTC | #7
> -----Original Message-----
> From: Richard Earnshaw
> Sent: Wednesday, April 16, 2014 6:04 PM
> To: Joey Ye
> Cc: gcc-patches@gcc.gnu.org
> Subject: Re: [patch] Disable if_conversion2 for Og
> 
> On 16/04/14 11:02, Joey Ye wrote:
> >
> >
> >> -----Original Message-----
> >> From: Richard Earnshaw
> >> Sent: Wednesday, April 16, 2014 5:44 PM
> >> To: Joey Ye
> >> Cc: gcc-patches@gcc.gnu.org
> >> Subject: Re: [patch] Disable if_conversion2 for Og
> >>
> >> Arguably, this is a bug in gdb.  The debugger should understand when
> >> a breakpointed conditional instruction is not going to execute and
> >> silently continue.  That preserves the illusion of not executing the
> >> code without requiring the compiler to de-optimize things.
> >>
> >> R.
> > Or compiler just optimizes it, and emits generic DWARFx information to
> > help GDB handle it in more target independently?
> >
> > - Joey
> >
> 
> I'm not sure extra dwarf info would help much.  The debugger still has to
> understand that the breakpoint has not really been hit.
> 
> R.
Yes, it is inevitable. But without extra dwarf info it will be even more
painful: each time setting break-point or break-point hits it has to decode
the break-pointed instructions and its context to search for conditional
execution and IT blocks.

- Joey
Joey Ye April 16, 2014, 10:30 a.m. UTC | #8
> -----Original Message-----
> From: Richard Earnshaw
> Sent: Wednesday, April 16, 2014 6:21 PM
> To: Joey Ye
> Cc: gcc-patches@gcc.gnu.org
> Subject: Re: [patch] Disable if_conversion2 for Og
> 
> On 16/04/14 11:17, Joey Ye wrote:
> >> -----Original Message-----
> >> From: Richard Earnshaw
> >> Sent: Wednesday, April 16, 2014 6:04 PM
> >> To: Joey Ye
> >> Cc: gcc-patches@gcc.gnu.org
> >> Subject: Re: [patch] Disable if_conversion2 for Og
> >>
> >> On 16/04/14 11:02, Joey Ye wrote:
> >>>
> >>>
> >>>> -----Original Message-----
> >>>> From: Richard Earnshaw
> >>>> Sent: Wednesday, April 16, 2014 5:44 PM
> >>>> To: Joey Ye
> >>>> Cc: gcc-patches@gcc.gnu.org
> >>>> Subject: Re: [patch] Disable if_conversion2 for Og
> >>>>
> >>>> Arguably, this is a bug in gdb.  The debugger should understand
> >>>> when a breakpointed conditional instruction is not going to execute
> >>>> and silently continue.  That preserves the illusion of not
> >>>> executing the code without requiring the compiler to de-optimize
> things.
> >>>>
> >>>> R.
> >>> Or compiler just optimizes it, and emits generic DWARFx information
> >>> to help GDB handle it in more target independently?
> >>>
> >>> - Joey
> >>>
> >>
> >> I'm not sure extra dwarf info would help much.  The debugger still
> >> has to understand that the breakpoint has not really been hit.
> >>
> >> R.
> > Yes, it is inevitable. But without extra dwarf info it will be even more
painful:
> each time setting break-point or break-point hits it has to decode the
break-
> pointed instructions and its context to search for conditional execution
and IT
> blocks.
> >
> 
> For thumb code it can get the conditional information it needs from the IT
> state in the PSR; for ARM code it has to look no further than the
instruction
> itself.
> 
> R.
The thing is, debugger has to do this for every breakpoint, even though more
of them are not conditional execution, which isn't efficient.
Richard Earnshaw April 16, 2014, 10:32 a.m. UTC | #9
On 16/04/14 11:30, Joey Ye wrote:
> 
> 
>> -----Original Message-----
>> From: Richard Earnshaw
>> Sent: Wednesday, April 16, 2014 6:21 PM
>> To: Joey Ye
>> Cc: gcc-patches@gcc.gnu.org
>> Subject: Re: [patch] Disable if_conversion2 for Og
>>
>> On 16/04/14 11:17, Joey Ye wrote:
>>>> -----Original Message-----
>>>> From: Richard Earnshaw
>>>> Sent: Wednesday, April 16, 2014 6:04 PM
>>>> To: Joey Ye
>>>> Cc: gcc-patches@gcc.gnu.org
>>>> Subject: Re: [patch] Disable if_conversion2 for Og
>>>>
>>>> On 16/04/14 11:02, Joey Ye wrote:
>>>>>
>>>>>
>>>>>> -----Original Message-----
>>>>>> From: Richard Earnshaw
>>>>>> Sent: Wednesday, April 16, 2014 5:44 PM
>>>>>> To: Joey Ye
>>>>>> Cc: gcc-patches@gcc.gnu.org
>>>>>> Subject: Re: [patch] Disable if_conversion2 for Og
>>>>>>
>>>>>> Arguably, this is a bug in gdb.  The debugger should understand
>>>>>> when a breakpointed conditional instruction is not going to execute
>>>>>> and silently continue.  That preserves the illusion of not
>>>>>> executing the code without requiring the compiler to de-optimize
>> things.
>>>>>>
>>>>>> R.
>>>>> Or compiler just optimizes it, and emits generic DWARFx information
>>>>> to help GDB handle it in more target independently?
>>>>>
>>>>> - Joey
>>>>>
>>>>
>>>> I'm not sure extra dwarf info would help much.  The debugger still
>>>> has to understand that the breakpoint has not really been hit.
>>>>
>>>> R.
>>> Yes, it is inevitable. But without extra dwarf info it will be even more
> painful:
>> each time setting break-point or break-point hits it has to decode the
> break-
>> pointed instructions and its context to search for conditional execution
> and IT
>> blocks.
>>>
>>
>> For thumb code it can get the conditional information it needs from the IT
>> state in the PSR; for ARM code it has to look no further than the
> instruction
>> itself.
>>
>> R.
> The thing is, debugger has to do this for every breakpoint, even though more
> of them are not conditional execution, which isn't efficient.
> 
> 

Then cache whether the instruction might be conditional when it's
created.  That's more work when creating the bp (and you do have to scan
back to check if a thumb instruction might be made conditional with IT),
but would save time when hitting it.

Anyway, this is getting off-topic for the GCC-patches list.

R.
diff mbox

Patch

diff --git a/gcc/opts.c b/gcc/opts.c
index fdc903f..e076253 100644
--- a/gcc/opts.c
+++ b/gcc/opts.c
@@ -432,7 +432,7 @@  static const struct default_options
default_options_table[] =
     { OPT_LEVELS_1_PLUS, OPT_fcprop_registers, NULL, 1 },
     { OPT_LEVELS_1_PLUS, OPT_fforward_propagate, NULL, 1 },
     { OPT_LEVELS_1_PLUS, OPT_fif_conversion, NULL, 1 },
-    { OPT_LEVELS_1_PLUS, OPT_fif_conversion2, NULL, 1 },
+    { OPT_LEVELS_1_PLUS_NOT_DEBUG, OPT_fif_conversion2, NULL, 1 },
     { OPT_LEVELS_1_PLUS, OPT_fipa_pure_const, NULL, 1 },
     { OPT_LEVELS_1_PLUS, OPT_fipa_reference, NULL, 1 },