This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
Re: Help w/ CFG/loop optimization problem?
- From: Jan Hubicka <jh at suse dot cz>
- To: Dale Johannesen <dalej at apple dot com>
- Cc: gcc at gcc dot gnu dot org, gcc-patches at gcc dot gnu dot org
- Date: Wed, 11 Sep 2002 09:57:21 +0200
- Subject: Re: Help w/ CFG/loop optimization problem?
- References: <A21CD16A-C4F8-11D6-93B1-003065C86F94@apple.com>
> 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)