This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: Help w/ CFG/loop optimization problem?


> I've run into an optimization problem with
> 
>     if (count > 10)
>         for (i = 0; i < count; ++i)
>             pcb += i;
>     else...
> 
> Basically what happens is the unconditional branch from the 'else'
> is brought inside the loop by cfg, which prevents the doloop
> optimization from recognizing this as a valid doloop.  I'm not
> sure where best to fix this; cfg doesn't seem to know much of
> anything about loops, and pushing the unconditional branch outside
> the loop seems outside the loop optimizer's normal view of things.
> Advice?

This will go away with the new loop optimizer work, but before that
cfg-cleanup is supposed to disable any forwarding of branch edges over
the loop notes (see code in forward edges).  CFG_CLEANUP_PRE_LOOP has
been invented for this.
In case it is missing some cases we probably should add these as it is
relatively important performance regression. I can try after returning
from trip at 29th but I will likely be quite busy then....

Honza
> 
> RTL before cfg:
> (note 27 25 28 NOTE_INSN_LOOP_CONT)
> 
> (code_label 28 27 74 3 5 "" [0 uses])
> 
> (note 74 28 29 3 [bb 3] NOTE_INSN_BASIC_BLOCK)
> 
> (insn 29 74 17 3 0x0 (set (reg/v:SI 121)
>         (plus:SI (reg/v:SI 121)
>             (const_int 1 [0x1]))) -1 (nil)
>     (nil))
> 
> (code_label 17 29 75 4 3 "" [1 uses])
> 
> (note 75 17 18 4 [bb 4] NOTE_INSN_BASIC_BLOCK)
> 
> (insn 18 75 19 4 0x0 (set (reg:CC 123)
>         (compare:CC (reg/v:SI 121)
>             (reg/v:SI 118))) -1 (nil)
>     (nil))
> 
> (jump_insn 19 18 76 4 0x0 (set (pc)
>         (if_then_else (lt (reg:CC 123)
>                 (const_int 0 [0x0]))
>             (label_ref 22)
>             (pc))) -1 (nil)
>     (nil))
> 
> (note 76 19 20 5 [bb 5] NOTE_INSN_BASIC_BLOCK)
> 
> (jump_insn 20 76 21 5 0x0 (set (pc)   ... this branch exits the loop
>         (label_ref 36)) -1 (nil)
>     (nil))
> 
> (barrier 21 20 22)
> 
> (code_label 22 21 77 6 6 "" [1 uses])
> 
> (note 77 22 33 6 [bb 6] NOTE_INSN_BASIC_BLOCK)
> 
> (jump_insn 33 77 34 6 0x0 (set (pc)
>         (label_ref 30)) -1 (nil)
>     (nil))
> 
> (barrier 34 33 35)
> 
> (note 35 34 36 NOTE_INSN_LOOP_END)
> 
> (code_label 36 35 78 7 4 "" [1 uses])
> 
> (note 78 36 37 7 [bb 7] NOTE_INSN_BASIC_BLOCK)
> 
> (jump_insn 37 78 38 7 0x0 (set (pc)     ... and is changed to point to 
> 63 instead of 36
>         (label_ref 63)) -1 (nil)
>     (nil))
> 
> If insn 20 were not changed, it would branch to the next instruction
> and would be removed, leaving the loop in a clean form.
> 
> RTL after cfg:
> (note 27 25 29 2 NOTE_INSN_LOOP_CONT)
> 
> (insn 29 27 17 2 0x0 (set (reg/v:SI 121)
>         (plus:SI (reg/v:SI 121)
>             (const_int 1 [0x1]))) -1 (nil)
>     (nil))
> 
> (code_label 17 29 75 4 3 "" [1 uses])
> 
> (note 75 17 18 4 [bb 4] NOTE_INSN_BASIC_BLOCK)
> 
> (insn 18 75 19 4 0x0 (set (reg:CC 123)
>         (compare:CC (reg/v:SI 121)
>             (reg/v:SI 118))) -1 (nil)
>     (nil))
> 
> (jump_insn 19 18 76 4 0x0 (set (pc)
>         (if_then_else (lt (reg:CC 123)
>                 (const_int 0 [0x0]))
>             (label_ref 30)
>             (pc))) 530 {*rs6000.md:14592} (nil)
>     (nil))
> 
> (note 76 19 20 5 [bb 5] NOTE_INSN_BASIC_BLOCK)
> 
> (jump_insn 20 76 21 5 0x0 (set (pc)
>         (label_ref 63)) 538 {jump} (nil)
>     (nil))
> 
> (barrier 21 20 35)
> 
> (note 35 21 39 NOTE_INSN_LOOP_END)


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]