Discussion:
Bug fix for optimize_mode_switching / NORMAL_MODE
Joern Rennecke
2002-05-27 22:34:08 UTC
Permalink
Since May 2000, optimize_mode_switching has some code to pretend that
the exit block is an ordinary block when NORMAL_MODE is defined.
This does not mix with the new FOR_EACH_BB / FOR_EACH_BB_REVERSE macros.
We can either restore lcm to the state where it doesn't fiddle with the
basic block array, or make the FOR_EACH_BB* macros cope with that.
The included patch implements the latter.
--
--------------------------
SuperH
2430 Aztec West / Almondsbury / BRISTOL / BS32 4AQ
T:+44 1454 462330
Richard Henderson
2002-05-29 00:08:53 UTC
Permalink
Post by Joern Rennecke
Since May 2000, optimize_mode_switching has some code to pretend that
the exit block is an ordinary block when NORMAL_MODE is defined.
This does not mix with the new FOR_EACH_BB / FOR_EACH_BB_REVERSE macros.
We can either restore lcm to the state where it doesn't fiddle with the
basic block array, or make the FOR_EACH_BB* macros cope with that.
The included patch implements the latter.
I'd really prefer the former, if it can be managed without
merely exchanging one form of ugliness for another.


r~
Zdenek Dvorak
2002-05-29 08:05:04 UTC
Permalink
Hello.
Post by Richard Henderson
Post by Joern Rennecke
Since May 2000, optimize_mode_switching has some code to pretend that
the exit block is an ordinary block when NORMAL_MODE is defined.
This does not mix with the new FOR_EACH_BB / FOR_EACH_BB_REVERSE macros.
We can either restore lcm to the state where it doesn't fiddle with the
basic block array, or make the FOR_EACH_BB* macros cope with that.
The included patch implements the latter.
I'd really prefer the former, if it can be managed without
merely exchanging one form of ugliness for another.
I really do not see into what lcm.c does; but would not creating some
sort of fake block at the end of chain and removing it later work?

Zdenek
Joern Rennecke
2002-05-29 12:46:24 UTC
Permalink
Post by Zdenek Dvorak
Post by Richard Henderson
Post by Joern Rennecke
Since May 2000, optimize_mode_switching has some code to pretend that
the exit block is an ordinary block when NORMAL_MODE is defined.
This does not mix with the new FOR_EACH_BB / FOR_EACH_BB_REVERSE macros.
We can either restore lcm to the state where it doesn't fiddle with the
basic block array, or make the FOR_EACH_BB* macros cope with that.
The included patch implements the latter.
I'd really prefer the former, if it can be managed without
merely exchanging one form of ugliness for another.
Well, I don't think that is possible. The way it was before it stuck a switch
to NORMAL_MODE in each predecessor of the exit block that didn't already compute
NORMAL_MODE. The place where to stick that switch is not trivial, since the
basic block might end with a JUMP_INSN and some USEs; in that case, we have to
skip back to the JUMP_INSN and pretend that it is that insn that wants
NORMAL_MODE.
It's also not accurate in that the need only applies to the edge that goes to
the exit block.

Now that I look at the code once more, I see that we have an analogous problem
for the entry block, and it isn't properly solved: when there are other
predecessors
to an entry block successor than the entry block itself, we can incorrectly
assume
that the entry block sucessor has NORMAL_MODE at the start, even if it hasn't.
Post by Zdenek Dvorak
I really do not see into what lcm.c does; but would not creating some
sort of fake block at the end of chain and removing it later work?
Yes, it would; however, you'd have to allocate that fake block, copy the exit
block to it, redirect all the predecessors of the exit block to that fake
block, and make an edge betwen the fake block and the exit block.
At the end, you'd have to remove the edge between exit block and fake block,
redirect the fake block predecessors back to the exit block, and deallocate.

It would be easier if we just redefine EXIT_BLOCK_PTR and ENTRY_BLOCK_PTR in
lcm.c
to be global pointer variables - initialized to entry_exit_block[[01]], and set
them to new values in the NORMAL_MODE case.
--
--------------------------
SuperH
2430 Aztec West / Almondsbury / BRISTOL / BS32 4AQ
T:+44 1454 462330
Zdenek Dvorak
2002-05-29 14:34:25 UTC
Permalink
Hello.
Post by Joern Rennecke
Post by Zdenek Dvorak
I really do not see into what lcm.c does; but would not creating some
sort of fake block at the end of chain and removing it later work?
Yes, it would; however, you'd have to allocate that fake block, copy the exit
block to it, redirect all the predecessors of the exit block to that fake
block, and make an edge betwen the fake block and the exit block.
At the end, you'd have to remove the edge between exit block and fake block,
redirect the fake block predecessors back to the exit block, and deallocate.
Unfortunatelly neither split_block nor merge_blocks_nomove can be
directly used with exit block; so it is not that straightforward as I
thought :-( It might however be beneficial to modify them so that they
can handle this special case (it seems to me that this transformation may
be generally useful).
Post by Joern Rennecke
It would be easier if we just redefine EXIT_BLOCK_PTR and ENTRY_BLOCK_PTR in
lcm.c
to be global pointer variables - initialized to entry_exit_block[[01]], and set
them to new values in the NORMAL_MODE case.
I would prefer to avoid this kind of hacks.

Zdenek
Richard Henderson
2002-05-29 18:18:27 UTC
Permalink
Post by Joern Rennecke
Now that I look at the code once more, I see that we have an analogous
problem for the entry block, and it isn't properly solved: when there
are other predecessors to an entry block successor than the entry block
itself, we can incorrectly assume that the entry block sucessor has
NORMAL_MODE at the start, even if it hasn't.
Indeed. Splitting the entry edge here would cure that problem.
Post by Joern Rennecke
Yes, it would; however, you'd have to allocate that fake block, copy the exit
block to it, redirect all the predecessors of the exit block to that fake
block, and make an edge betwen the fake block and the exit block.
True.

Well, hmm. This is pre-reload, thus return insns can't exist yet.
Therefore there are only two ways to have an edge to the exit block:
the last block fallthru and sibcalls. But sibcalls are calls, and
so we must return to normal mode before the call, so there is only
one exit predecessor to concern ourselves with -- the fallthru block.

At which point the problem seems much reduced, since we can simply
split that one edge.
Post by Joern Rennecke
At the end, you'd have to remove the edge between exit block and fake block,
redirect the fake block predecessors back to the exit block, and deallocate.
Actually, you wouldn't have to do anything of the sort. One, it would
seem that it's possible that code might have been dropped into the block
to return to normal mode. Two, if the block is really empty, then a
subsequent call to cleanup_cfg should remove the block.


r~
Joern Rennecke
2002-05-30 11:07:05 UTC
Permalink
Post by Richard Henderson
Well, hmm. This is pre-reload, thus return insns can't exist yet.
the last block fallthru and sibcalls. But sibcalls are calls, and
so we must return to normal mode before the call, so there is only
one exit predecessor to concern ourselves with -- the fallthru block.
At which point the problem seems much reduced, since we can simply
split that one edge.
Post by Joern Rennecke
At the end, you'd have to remove the edge between exit block and fake block,
redirect the fake block predecessors back to the exit block, and deallocate.
Actually, you wouldn't have to do anything of the sort. One, it would
seem that it's possible that code might have been dropped into the block
to return to normal mode. Two, if the block is really empty, then a
subsequent call to cleanup_cfg should remove the block.
I have attached a patch that fixes the discussed problems by useing split_edge
to split the edge from the entry block and the fallthrough edge to the exit
block.
--
--------------------------
SuperH
2430 Aztec West / Almondsbury / BRISTOL / BS32 4AQ
T:+44 1454 462330
Richard Henderson
2002-05-30 17:59:52 UTC
Permalink
* lcm.c (output.h): #include.
(compute_earliest): Remove hack to treat renumbered EXIT_BLOCK
as an ordinary block.
(optimize_mode_switching): Don't pretend that the exit block is
an ordinary block, or handle sucessors of entry block specially.
Instead, split edges from entry block and to exit block, and
put a computing definition on the thus gained post-entry-block,
and a need on the pre-exit-block.
Ok.

Thanks for cleaning this up.


r~

Continue reading on narkive:
Loading...