Patchwork Preserve the CFG until after final

login
register
mail settings
Submitter Steven Bosscher
Date May 19, 2013, 3:59 p.m.
Message ID <CABu31nP2zmye87o-mrbJkKQnm0hPQyE8Pu88Bd3z3_1rOtAT0Q@mail.gmail.com>
Download mbox | patch
Permalink /patch/244817/
State New
Headers show

Comments

Steven Bosscher - May 19, 2013, 3:59 p.m.
Hello,

This patch allows targets to keep the CFG around until after final, by
skipping pass_free_cfg and CFG-destructive passes like dbr_schedule,
and by making insn splitting before 'final' use split_all_insns
instead of split_all_insns_noflow if pass_free_cfg was skipped.

Most machine reorg passes also are not able to maintain the CFG, so
I've split the machine_reorg hook into separate CFG-aware and
CFG-unaware versions, renaming the existing hook (to signal that
maintaining the CFG is desirable in new ports ;-).

For the moment, only ix86 uses the CFG-aware version of the hook, but
there are a handful of targets that can be converted to do this also
(ia64, bfin, c6x, sparc, probably others). Other ports can change to
the CFG-aware machine reorg pass and keep part of the current, non
CFG-aware reorg pass for the second hook (mips). Some ports have
CFG-aware machine-reorg passes but verify_flow_info fails after the
machine-reorg pass because the port emits insns between basic blocks,
e.g. for const pools. What's missing is a way for verify_flow_info to
be tolerant of such non-insns but I'm not sure yet what the best
approach for this will be (possibilities I've considered so far are:
allow bare UNSPECV insns between basic blocks after machine-reorg; put
a flag on such non-insns; maintain a bitmap of uids for non-insns;
...).

I hope that maintainers will over time change their machine reorgs to
maintain the CFG, so that passes like pass_dwarf2_frame can use the
CFG instead of creating "a facsimile of one on the fly" (see
dwarf2cfi.c).

Bootstrapped&tested on x86_64-unknown-linux-gnu (unix{,-m32}).
OK for trunk?

Ciao!
Steven
* target.def (machine_dependent_reorg): Add documentation.
	(machine_dependent_reorg_nocfg): New hook.
	* doc/tm.texi.in (TARGET_MACHINE_DEPENDENT_REORG): Remove old
	documentation.
	(TARGET_MACHINE_DEPENDENT_REORG_NOCFG): New hook insert point.
	* doc/tm.texi: Regenerate
	* function.h (struct rtl_data): Add 'cfg_released' member.
	* cfgrtl.c (rest_of_pass_free_cfg): Set it at the end.
	* tree-pass.h (pass_cfg_unaware_passes, pass_machine_reorg_nocfg):
	New passes.
	* passes.c (init_optimization_passes): Schedule the new passes.
	Use pass_machine_reorg_nocfg to group passes that do not maintain
	the control flow graph.
	* reorg.c (gate_handle_machine_reorg_nocfg): New function.
	(rest_of_handle_machine_reorg_nocfg): New Function.
	(gate_cfg_unaware_passes): New function.
	(gate_handle_machine_reorg): New function.
	(rest_of_handle_machine_reorg): New function.
	(pass_machine_reorg_nocfg): New pass.
	(pass_cfg_unaware_passes): New pass.
	* recog.c (rest_of_handle_final_split): New function.
	(pass_split_for_short): Call rest_of_handle_final_split instead
	of directly calling split_all_insns_noflow.
	* sched-ebb.c (schedule_ebbs_init): Do not call compute_bb_for_insn.

	* config/i386/i386.c (ix86_reorg): Do not call compute_bb_for_insn.

	* config/alpha/alpha.c: Replace TARGET_MACHINE_DEPENDENT_REORG
	with TARGET_MACHINE_DEPENDENT_REORG_NOCFG.
	* config/frv/frv.c: Likewise.
	* config/s390/s390.c: Likewise.
	* config/spu/spu.c: Likewise.
	* config/mep/mep.c;
	* config/tilegx/tilegx.c: Likewise.
	* config/sh/sh.c: Likewise.
	* config/avr/avr.c: Likewise.
	* config/stormy16/stormy16.c: Likewise.
	* config/mn10300/mn10300.c: Likewise.
	* config/c6x/c6x.c: Likewise.
	* config/ia64/ia64.c: Likewise.
	* config/picochip/picochip.c: Likewise.
	* config/mcore/mcore.c: Likewise.
	* config/tilepro/tilepro.c: Likewise.
	* config/arm/arm.c: Likewise.
	* config/pa/pa.c: Likewise.
	* config/mips/mips.c: Likewise.
	* config/v850/v850.c: Likewise.
	* config/h8300/h8300.c: Likewise.
	* config/mmix/mmix.c: Likewise.
	* config/bfin/bfin.c: Likewise.
Eric Botcazou - May 21, 2013, 8:57 a.m.
> This patch allows targets to keep the CFG around until after final, by
> skipping pass_free_cfg and CFG-destructive passes like dbr_schedule,
> and by making insn splitting before 'final' use split_all_insns
> instead of split_all_insns_noflow if pass_free_cfg was skipped.

Well, you currently can't skip dbr_schedule if you have delay slots, c6x set 
aside, so I'm not sure whether we want to start another transition before even 
knowing if we can reasonably complete it.

> For the moment, only ix86 uses the CFG-aware version of the hook, but
> there are a handful of targets that can be converted to do this also
> (ia64, bfin, c6x, sparc, probably others).

Not SPARC for sure.

> I hope that maintainers will over time change their machine reorgs to
> maintain the CFG, so that passes like pass_dwarf2_frame can use the
> CFG instead of creating "a facsimile of one on the fly" (see
> dwarf2cfi.c).

I think that an incremental step would be to allow the machine reorg pass to 
use the CFG, even if it doesn't maintain it.  For the rest I'm not sure, as 
long as we have the dbr_schedule blocker.
Steven Bosscher - May 21, 2013, 2:14 p.m.
On Tue, May 21, 2013 at 10:57 AM, Eric Botcazou wrote:
>> This patch allows targets to keep the CFG around until after final, by
>> skipping pass_free_cfg and CFG-destructive passes like dbr_schedule,
>> and by making insn splitting before 'final' use split_all_insns
>> instead of split_all_insns_noflow if pass_free_cfg was skipped.
>
> Well, you currently can't skip dbr_schedule if you have delay slots, c6x set
> aside, so I'm not sure whether we want to start another transition before even
> knowing if we can reasonably complete it.

That is only partially true. Currently the transition is already de
facto going on: Just look at how many back ends use
compute_bb_for_insn to re-initialize the BLOCK_FOR_INSN pointers right
after pass_free_cfg (it's usually the first thing they do in the
machine-reorg pass). Some ports never call free_bb_or_insn after that,
and expect BLOCK_FOR_INSN to be valid in 'final'. One of those ports
is i386, look at where BLOCK_FOR_INSN is used in i386.c (in functions
deciding what asm output templates to use).

Also, right now I'm stuck with a chicken-and-egg problem: dbr_schedule
is not CFG-aware, but my still slowly progressing work on a
replacement can't have a CFG because it has to run after machine-reorg
passes, and therefore after pass_free_cfg.


>> For the moment, only ix86 uses the CFG-aware version of the hook, but
>> there are a handful of targets that can be converted to do this also
>> (ia64, bfin, c6x, sparc, probably others).
>
> Not SPARC for sure.

Right, SPARC doesn't have a machine-reorg pass anymore. I was talking
about pass_work_around_errata, that runs after my CFG-aware
dbr_schedule,  properly maintaining the CFG.


>> I hope that maintainers will over time change their machine reorgs to
>> maintain the CFG, so that passes like pass_dwarf2_frame can use the
>> CFG instead of creating "a facsimile of one on the fly" (see
>> dwarf2cfi.c).
>
> I think that an incremental step would be to allow the machine reorg pass to
> use the CFG, even if it doesn't maintain it.

That is the current state of things already.


>  For the rest I'm not sure, as
> long as we have the dbr_schedule blocker.

But I need this exactly for that reason: To remove that blocker! :-)

Ciao!
Steven
Eric Botcazou - May 22, 2013, 8:21 a.m.
> That is only partially true. Currently the transition is already de
> facto going on: Just look at how many back ends use
> compute_bb_for_insn to re-initialize the BLOCK_FOR_INSN pointers right
> after pass_free_cfg (it's usually the first thing they do in the
> machine-reorg pass).

Yes, and we should do something about it.  Btw, why is the line removed from 
ia64_reorg in the patch (and not mentioned in the ChangeLog)?

> Some ports never call free_bb_or_insn after that,
> and expect BLOCK_FOR_INSN to be valid in 'final'. One of those ports
> is i386, look at where BLOCK_FOR_INSN is used in i386.c (in functions
> deciding what asm output templates to use).

AFAICS it's only used for splitters.  And using BLOCK_FOR_INSN after the last 
split pass (pass_split_for_shorten_branches) is dubious.  Here's the list:

./frv/frv.c:               || BLOCK_FOR_INSN (insn) == ce_info->else_bb

Only used during if-conversion.

./rs6000/rs6000.c:  bb = BLOCK_FOR_INSN (label);

Only used during compute_alignments.

./spu/spu.c:  bitmap_set_bit (blocks, BLOCK_FOR_INSN (branch)->index);

Only used during md_reorg.

./c6x/c6x.c:  BLOCK_FOR_INSN (bundle) = BLOCK_FOR_INSN (slot[0]);

Only used during md_reorg.

./mips/mips.c:  basic_block bb = BLOCK_FOR_INSN (insn);
./mips/mips.c:  /* Restore the BLOCK_FOR_INSN pointers, which are needed by 
DF.  Also during

Only used for splitting decision, deal with null BLOCK_FOR_INSN.

./i386/i386.c:  basic_block bb = start ? BLOCK_FOR_INSN (start) : NULL;
./i386/i386.c:  basic_block bb = BLOCK_FOR_INSN (insn);
./i386/i386.c:  basic_block bb = start ? BLOCK_FOR_INSN (start) : NULL;
./i386/i386.c:  basic_block bb = BLOCK_FOR_INSN (insn);
./i386/i386.c:  basic_block bb = BLOCK_FOR_INSN (insn);
./i386/i386.c:  rtx start = BB_HEAD (BLOCK_FOR_INSN (insn));
./i386/i386.c:      basic_block bb =  BLOCK_FOR_INSN (insn);

Only used for splitting decision (and scheduling).

> Also, right now I'm stuck with a chicken-and-egg problem: dbr_schedule
> is not CFG-aware, but my still slowly progressing work on a
> replacement can't have a CFG because it has to run after machine-reorg
> passes, and therefore after pass_free_cfg.

That's why I'm suggesting to get rid of or modify pass_free_cfg so that the 
CFG is still usable up to the point where it is really destroyed.

> > I think that an incremental step would be to allow the machine reorg
> > pass to use the CFG, even if it doesn't maintain it.
> 
> That is the current state of things already.

No, as you noted earlier, because of pass_free_cfg.

> But I need this exactly for that reason: To remove that blocker! :-)

I don't think so.  The goal for now shouldn't be to "preserve the CFG until 
after final" since we know it isn't feasible in the short term, but rather to 
preserve the CFG as long as possible.

So what about doing the following instead:
 1. Remove pass_free_cfg from the pipeline,
 2. Remove compute_bb_for_insn from all the md_reorg passes that call it,
 3. (Optionally) Do pass_free_cfg from all the md_reorg passes that don't,
 4. Do pass_free_cfg at the beginning of pass_delay_slots,
 5. Do pass_free_cfg at the end of pass_split_for_shorten_branches,
Steven Bosscher - May 22, 2013, 9:17 p.m.
On Wed, May 22, 2013 at 10:21 AM, Eric Botcazou wrote:
>> That is only partially true. Currently the transition is already de
>> facto going on: Just look at how many back ends use
>> compute_bb_for_insn to re-initialize the BLOCK_FOR_INSN pointers right
>> after pass_free_cfg (it's usually the first thing they do in the
>> machine-reorg pass).
>
> Yes, and we should do something about it.  Btw, why is the line removed from
> ia64_reorg in the patch (and not mentioned in the ChangeLog)?

Mistake. I wrote these patches on an ia64 machine, an older version of
the patch was also bootstrapped&tested there.


>> Some ports never call free_bb_or_insn after that,
>> and expect BLOCK_FOR_INSN to be valid in 'final'. One of those ports
>> is i386, look at where BLOCK_FOR_INSN is used in i386.c (in functions
>> deciding what asm output templates to use).
>
> AFAICS it's only used for splitters.  And using BLOCK_FOR_INSN after the last
> split pass (pass_split_for_shorten_branches) is dubious.

Actually it's even wrong *during* pass_split_for_shorten_branches
right now. It may work in some ports but not in others, depending
whether the port's machine reorg has done its TLC on the CFG or not.
This can lead to very interesting behavior. I chased a bug recently
where a splitter during split5 used the DF_INSN_USES cache on an insn
introduced by another splitter. Because split5 uses
split_all_insns_noflow, the insn from the splitter somehow ended up a
NULL BLOCK_FOR_INSN (I'm still not sure how that happened, but it
did). It turns out df-scan ignores insns with a NULL BLOCK_FOR_INSN,
and hence NULL DF_INSN_USES, and that lead to a dependency violation
in my splitter because a USE got overlooked!

Ah, the crazy stuff one can do after machine reorg. It's the Wild West
of GCC :-)


>  Here's the list:
>
> ./frv/frv.c:               || BLOCK_FOR_INSN (insn) == ce_info->else_bb
>
> Only used during if-conversion.
>
> ./rs6000/rs6000.c:  bb = BLOCK_FOR_INSN (label);
>
> Only used during compute_alignments.
>
> ./spu/spu.c:  bitmap_set_bit (blocks, BLOCK_FOR_INSN (branch)->index);
>
> Only used during md_reorg.
>
> ./c6x/c6x.c:  BLOCK_FOR_INSN (bundle) = BLOCK_FOR_INSN (slot[0]);
>
> Only used during md_reorg.
>
> ./mips/mips.c:  basic_block bb = BLOCK_FOR_INSN (insn);
> ./mips/mips.c:  /* Restore the BLOCK_FOR_INSN pointers, which are needed by
> DF.  Also during
>
> Only used for splitting decision, deal with null BLOCK_FOR_INSN.

Yes, these are all fine.


> ./i386/i386.c:  basic_block bb = start ? BLOCK_FOR_INSN (start) : NULL;
> ./i386/i386.c:  basic_block bb = BLOCK_FOR_INSN (insn);
> ./i386/i386.c:  basic_block bb = start ? BLOCK_FOR_INSN (start) : NULL;
> ./i386/i386.c:  basic_block bb = BLOCK_FOR_INSN (insn);
> ./i386/i386.c:  basic_block bb = BLOCK_FOR_INSN (insn);
> ./i386/i386.c:  rtx start = BB_HEAD (BLOCK_FOR_INSN (insn));
> ./i386/i386.c:      basic_block bb =  BLOCK_FOR_INSN (insn);
>
> Only used for splitting decision (and scheduling).

Sadly no. Most of these (the *agu* ones) are also reached from final.
For example:

movdi_internal -> ix86_use_lea_for_mov -> ix86_lea_outperforms ->
distance_non_agu_define -> distance_non_agu_define_in_bb

Likewise for movsi_internal, and zero_extendsidi2. For the
mov?i_internal define_insns, it's been like that since at least
r181077 (November 2011).

I must admit I was surprised by that, too. It may have been
coincidence that it worked when this patch was (IMHO wrongfully)
accepted. Someone got away with it because i386 calls
compute_bb_for_insn in its machine-reorg, and does *not* call
free_bb_for_insn, leaving the BLOCK_FOR_INSN pointers in place all the
way through final. There are no passes between machine-reorg and final
that run for i386 and damage the CFG because split5 doesn't run on
i386 (because of STACK_REGS) and the other passes, like
shorten_branches, don't modify the insns chain.

Most ports that call compute_bb_for_insn do not call free_bb_for_insn:

$ grep compute_bb_for_insn config/*/*.c
config/arm/arm.c:  compute_bb_for_insn ();
config/bfin/bfin.c:  compute_bb_for_insn ();
config/c6x/c6x.c:  compute_bb_for_insn ();
config/frv/frv.c:  compute_bb_for_insn ();
config/i386/i386.c:  compute_bb_for_insn ();
config/ia64/ia64.c:  compute_bb_for_insn ();
config/mep/mep.c:  compute_bb_for_insn ();
config/mips/mips.c:    compute_bb_for_insn ();
config/mn10300/mn10300.c:  compute_bb_for_insn ();
config/picochip/picochip.c:  compute_bb_for_insn ();
config/spu/spu.c:      compute_bb_for_insn ();
config/spu/spu.c:  compute_bb_for_insn ();
config/tilegx/tilegx.c:  compute_bb_for_insn ();
config/tilepro/tilepro.c:  compute_bb_for_insn ();
$ grep free_bb_for_insn config/*/*.c
config/mips/mips.c:      free_bb_for_insn ();
config/spu/spu.c:      free_bb_for_insn ();
config/spu/spu.c:  free_bb_for_insn ();

Most of these, eh, let's call them "compute_bb_for_insn ports", they
come out of the machine reorg pass with an insns chain that doesn't
pass verify_flow_info. The most common problem is that there are
objects in the insns chain that verify_flow_info doesn't understand:
Things like SEQUENCEs for bundles (c6x, mep), const-pool fake insns
(arm), and other creative target-specific uses of RTL. But for some
ports the CFG is Just Fine after machine reorg, and only split5
mangles it before final


>> Also, right now I'm stuck with a chicken-and-egg problem: dbr_schedule
>> is not CFG-aware, but my still slowly progressing work on a
>> replacement can't have a CFG because it has to run after machine-reorg
>> passes, and therefore after pass_free_cfg.
>
> That's why I'm suggesting to get rid of or modify pass_free_cfg so that the
> CFG is still usable up to the point where it is really destroyed.

I think you're taking a too dbr_schedule-ports point of view on this.
There are already targets that never really destroy the CFG at all,
all the way through final. Few ports that do destroy it, destroy it as
badly as dbr_schedule. Most only have innocent "damage" that are
really just deficiencies of verify_flow_info.


>> > I think that an incremental step would be to allow the machine reorg
>> > pass to use the CFG, even if it doesn't maintain it.
>>
>> That is the current state of things already.
>
> No, as you noted earlier, because of pass_free_cfg.

Yes, because most compute_bb_for_insn-ports don't clear BLOCK_FOR_INSN anymore.

Remember: the only thing that pass_free_cfg does, is clear the
BLOCK_FOR_INSN pointers (OK, and as of very recently, it insert the
hot/cold section boundary note), but edges and basic blocks are not
released. Targets that compute_bb_for_insn and don't do any RTL tricks
that confuse verify_flow_info all have a valid CFG. On i386,
verify_flow_info still passes in 'final', even now! With my recog.c
patch to use the CFG-aware split_all_insns if the CFG is still alive,
verify_flow_info also passes in final for ia64.

You are absolutely right that formally it should not work. But it
does, given the right circumstances. All I want to do is make it
formally OK for those targets that can handle the truth...


>> But I need this exactly for that reason: To remove that blocker! :-)
>
> I don't think so.  The goal for now shouldn't be to "preserve the CFG until
> after final" since we know it isn't feasible in the short term, but rather to
> preserve the CFG as long as possible.

It is feasible in the short term -- as in: right now -- for some
targets. Is it possible in the short term for all targets? No. But
you've got to start somewhere. I firmly believe that port maintainers
will not find it hard to make it work for their ports, dbr_schedule
ports aside and that's a problem I'm trying to solve (while at it:
ping**2 for http://gcc.gnu.org/ml/gcc-patches/2013-05/msg00595.html
that I need to move ahead).


> So what about doing the following instead:
>  1. Remove pass_free_cfg from the pipeline,
>  2. Remove compute_bb_for_insn from all the md_reorg passes that call it,
>  3. (Optionally) Do pass_free_cfg from all the md_reorg passes that don't,
>  4. Do pass_free_cfg at the beginning of pass_delay_slots,
>  5. Do pass_free_cfg at the end of pass_split_for_shorten_branches,

I've considered that path, too, but I opted against it because we end
up with pass_free_cfg being called from the majority of targets, and
verify_flow_info calls in targets that really maintain a proper CFG.
It also results in unnecessary damage from split5 for targets that
have a valid CFG up to that point. But what worried me the most is
that this approach made it more difficult to see what ports actually
are CFG-safe. I chose the new target hook approach because you can
just grep for the CFG-safe target hook to see what ports are already
OK and which ones are still TODO.

But if I still haven't convince you, I'll prepare a patch along those lines.

Ciao!
Steven
Jeff Law - May 22, 2013, 9:27 p.m.
On 05/22/2013 03:17 PM, Steven Bosscher wrote:
>
>
> Ah, the crazy stuff one can do after machine reorg. It's the Wild West
> of GCC :-)
I still look at that hook as the contribution I most wish I'd never 
made.  The abuses are, umm, amazing.

jeff
Richard Henderson - May 22, 2013, 10:46 p.m.
On 05/19/2013 08:59 AM, Steven Bosscher wrote:
> Some ports have
> CFG-aware machine-reorg passes but verify_flow_info fails after the
> machine-reorg pass because the port emits insns between basic blocks,
> e.g. for const pools. What's missing is a way for verify_flow_info to
> be tolerant of such non-insns but I'm not sure yet what the best
> approach for this will be (possibilities I've considered so far are:
> allow bare UNSPECV insns between basic blocks after machine-reorg; put
> a flag on such non-insns; maintain a bitmap of uids for non-insns;
> ...).

FYI, I once started implementing a DATA_INSN top-level rtx code to be used by
backends for implementing constant pools.  The rtx code had three fields, an
rtx for the data to emit, and integer size and alignment fields.

In theory we can then quit abusing UNSPECV and suchlike and just Know that this
is explicit data that needs to be emitted at this point in the insn stream.

Unfortunately, the tree is really quite old, and it'd be worth starting from
scratch at this point.


r~
Eric Botcazou - May 23, 2013, 3:45 p.m.
> Sadly no. Most of these (the *agu* ones) are also reached from final.
> For example:
> 
> movdi_internal -> ix86_use_lea_for_mov -> ix86_lea_outperforms ->
> distance_non_agu_define -> distance_non_agu_define_in_bb
> 
> Likewise for movsi_internal, and zero_extendsidi2. For the
> mov?i_internal define_insns, it's been like that since at least
> r181077 (November 2011).

OK, I double-checked, but obviously not sufficiently.

> I must admit I was surprised by that, too. It may have been
> coincidence that it worked when this patch was (IMHO wrongfully)
> accepted. Someone got away with it because i386 calls
> compute_bb_for_insn in its machine-reorg, and does *not* call
> free_bb_for_insn, leaving the BLOCK_FOR_INSN pointers in place all the
> way through final. There are no passes between machine-reorg and final
> that run for i386 and damage the CFG because split5 doesn't run on
> i386 (because of STACK_REGS) and the other passes, like
> shorten_branches, don't modify the insns chain.

I see, thanks for the analysis.

> I think you're taking a too dbr_schedule-ports point of view on this
> There are already targets that never really destroy the CFG at all,
> all the way through final. Few ports that do destroy it, destroy it as
> badly as dbr_schedule. Most only have innocent "damage" that are
> really just deficiencies of verify_flow_info.

I cannot deny that I care about the architectures with delay slots and think 
that starting to put them aside is the beginning of a slippery slope.  Unlike 
in other compilers, a few of them are first-class architectures in GCC and I 
think that this should be preserved, even if they are less sexy these days.

> It is feasible in the short term -- as in: right now -- for some
> targets. Is it possible in the short term for all targets? No. But
> you've got to start somewhere. I firmly believe that port maintainers
> will not find it hard to make it work for their ports, dbr_schedule
> ports aside and that's a problem I'm trying to solve (while at it:
> ping**2 for http://gcc.gnu.org/ml/gcc-patches/2013-05/msg00595.html
> that I need to move ahead).

Your efforts are much appreciated but replacing dbr_schedule is a huge 
undertaking which may take longer than expected and I don't think that
we have any guarantee on its outcome.

> I've considered that path, too, but I opted against it because we end
> up with pass_free_cfg being called from the majority of targets, and
> verify_flow_info calls in targets that really maintain a proper CFG.
> It also results in unnecessary damage from split5 for targets that
> have a valid CFG up to that point. But what worried me the most is
> that this approach made it more difficult to see what ports actually
> are CFG-safe. I chose the new target hook approach because you can
> just grep for the CFG-safe target hook to see what ports are already
> OK and which ones are still TODO.

Sure, but IMO one very probable future is that the CFG-safe target hook will 
be quickly enabled for x86, PowerPC and ARM, at which point people will start 
to add CFG-based enhancements to the late generic passes (or entire new CFG-
based late generic passes), leaving the architectures with delay slots dead in 
the water.

> But if I still haven't convince you, I'll prepare a patch along those lines.

I honestly cannot approve a patch that segregates the architectures with delay 
slots from the others.  Now, if another maintainer thinks this is the right 
call to make here, I won't oppose.

Patch

Index: target.def
===================================================================
--- target.def	(revision 199028)
+++ target.def	(working copy)
@@ -1888,11 +1888,37 @@  DEFHOOK
  enum machine_mode, (enum machine_mode m1, enum machine_mode m2),
  default_cc_modes_compatible)
 
-/* Do machine-dependent code transformations.  Called just before
-     delayed-branch scheduling.  */
+/* Do machine-dependent code transformations.  */
 DEFHOOK
 (machine_dependent_reorg,
- "",
+ "If non-null, this hook can be used to perform target-specific passes \
+over the instruction stream near the very end of the compilation of \
+a function.  The hook is called via @code{pass_machine_reorg} just \
+before the delayed-branch scheduling pass.  This hook is optional, \
+@code{pass_machine_reorg} pass only runs if the hook non-null.\n\
+This target hook should maintain the CFG (@code{verify_flow_inf} \
+should not fail after this pass).  Legacy machine dependent reorg \
+passes that destroy the CFG should not define this hook, but instead \
+use tne @code{machine_dependent_reorg_nocfg} hook. \
+\n\
+The hook an be used for various target-specific purposes, such as \
+machine-specific code transformations to work around errata or other \
+hazards, laying out constant pools.  The hook can also be used for \
+the implementation of machine-dependent optimizations, although this \
+practice is discouraged if the optimization may be useful for other \
+target machines as well.  Such optimizations should be implemented \
+in the compiler midde end.",
+ void, (void), NULL)
+
+/* Like machine_dependent_reorg but for legacy machine reorg passes that
+   are not aware of the CFG.  */
+DEFHOOK
+(machine_dependent_reorg_nocfg,
+ "Like @code{machine_dependent_reorg}, but for use by legacy targets. \
+This hook assumes that the machine dependent pass is not aware of \
+the control flow graph and is unable to maintain it properly.  Before \
+the hook is called, the control flow graph is released.  Basic blocks \
+still exist but @code{BLOCK_FOR_INSN} will be nullified.",
  void, (void), NULL)
 
 /* Create the __builtin_va_list type.  */
Index: doc/tm.texi.in
===================================================================
--- doc/tm.texi.in	(revision 199028)
+++ doc/tm.texi.in	(working copy)
@@ -10707,18 +10707,8 @@  to by @var{ce_info}.
 @end defmac
 
 @hook TARGET_MACHINE_DEPENDENT_REORG
-If non-null, this hook performs a target-specific pass over the
-instruction stream.  The compiler will run it at all optimization levels,
-just before the point at which it normally does delayed-branch scheduling.
 
-The exact purpose of the hook varies from target to target.  Some use
-it to do transformations that are necessary for correctness, such as
-laying out in-function constant pools or avoiding hardware hazards.
-Others use it as an opportunity to do some machine-dependent optimizations.
-
-You need not implement the hook if it has nothing to do.  The default
-definition is null.
-@end deftypefn
+@hook TARGET_MACHINE_DEPENDENT_REORG_NOCFG
 
 @hook TARGET_INIT_BUILTINS
 Define this hook if you have any machine-specific built-in functions
Index: doc/tm.texi
===================================================================
--- doc/tm.texi	(revision 199028)
+++ doc/tm.texi	(working copy)
@@ -10863,17 +10863,13 @@  to by @var{ce_info}.
 @end defmac
 
 @deftypefn {Target Hook} void TARGET_MACHINE_DEPENDENT_REORG (void)
-If non-null, this hook performs a target-specific pass over the
-instruction stream.  The compiler will run it at all optimization levels,
-just before the point at which it normally does delayed-branch scheduling.
-
-The exact purpose of the hook varies from target to target.  Some use
-it to do transformations that are necessary for correctness, such as
-laying out in-function constant pools or avoiding hardware hazards.
-Others use it as an opportunity to do some machine-dependent optimizations.
+If non-null, this hook can be used to perform target-specific passes over the instruction stream near the very end of the compilation of a function.  The hook is called via @code{pass_machine_reorg} just before the delayed-branch scheduling pass.  This hook is optional, @code{pass_machine_reorg} pass only runs if the hook non-null.
+This target hook should maintain the CFG (@code{verify_flow_inf} should not fail after this pass).  Legacy machine dependent reorg passes that destroy the CFG should not define this hook, but instead use tne @code{machine_dependent_reorg_nocfg} hook. 
+The hook an be used for various target-specific purposes, such as machine-specific code transformations to work around errata or other hazards, laying out constant pools.  The hook can also be used for the implementation of machine-dependent optimizations, although this practice is discouraged if the optimization may be useful for other target machines as well.  Such optimizations should be implemented in the compiler midde end.
+@end deftypefn
 
-You need not implement the hook if it has nothing to do.  The default
-definition is null.
+@deftypefn {Target Hook} void TARGET_MACHINE_DEPENDENT_REORG_NOCFG (void)
+Like @code{machine_dependent_reorg}, but for use by legacy targets. This hook assumes that the machine dependent pass is not aware of the control flow graph and is unable to maintain it properly.  Before the hook is called, the control flow graph is released.  Basic blocks still exist but @code{BLOCK_FOR_INSN} will be nullified.
 @end deftypefn
 
 @deftypefn {Target Hook} void TARGET_INIT_BUILTINS (void)
Index: function.h
===================================================================
--- function.h	(revision 199028)
+++ function.h	(working copy)
@@ -455,6 +455,9 @@  struct GTY(()) rtl_data {
      pass.  */
   bool bb_reorder_complete;
 
+  /* Nonzero if pass_free_cfg has run.  */
+  bool cfg_released;
+
   /* Like regs_ever_live, but 1 if a reg is set or clobbered from an
      asm.  Unlike regs_ever_live, elements of this array corresponding
      to eliminable regs (like the frame pointer) are set if an asm
Index: cfgrtl.c
===================================================================
--- cfgrtl.c	(revision 199028)
+++ cfgrtl.c	(working copy)
@@ -452,6 +452,7 @@  rest_of_pass_free_cfg (void)
 #endif
 
   free_bb_for_insn ();
+  crtl->cfg_released = true;
   return 0;
 }
 
Index: tree-pass.h
===================================================================
--- tree-pass.h	(revision 199028)
+++ tree-pass.h	(working copy)
@@ -474,6 +474,8 @@  extern struct rtl_opt_pass pass_duplicat
 extern struct rtl_opt_pass pass_variable_tracking;
 extern struct rtl_opt_pass pass_free_cfg;
 extern struct rtl_opt_pass pass_machine_reorg;
+extern struct rtl_opt_pass pass_cfg_unaware_passes;
+extern struct rtl_opt_pass pass_machine_reorg_nocfg;
 extern struct rtl_opt_pass pass_cleanup_barriers;
 extern struct rtl_opt_pass pass_delay_slots;
 extern struct rtl_opt_pass pass_split_for_shorten_branches;
Index: passes.c
===================================================================
--- passes.c	(revision 199028)
+++ passes.c	(working copy)
@@ -1659,10 +1659,15 @@  init_optimization_passes (void)
 	  NEXT_PASS (pass_compute_alignments);
 	  NEXT_PASS (pass_duplicate_computed_gotos);
 	  NEXT_PASS (pass_variable_tracking);
-	  NEXT_PASS (pass_free_cfg);
 	  NEXT_PASS (pass_machine_reorg);
-	  NEXT_PASS (pass_cleanup_barriers);
-	  NEXT_PASS (pass_delay_slots);
+	  NEXT_PASS (pass_cfg_unaware_passes);
+	    {
+	      struct opt_pass **p = &pass_cfg_unaware_passes.pass.sub;
+	      NEXT_PASS (pass_free_cfg);
+	      NEXT_PASS (pass_machine_reorg_nocfg);
+	      NEXT_PASS (pass_cleanup_barriers);
+	      NEXT_PASS (pass_delay_slots);
+	    }
 	  NEXT_PASS (pass_split_for_shorten_branches);
 	  NEXT_PASS (pass_convert_to_eh_region_ranges);
 	  NEXT_PASS (pass_shorten_branches);
Index: reorg.c
===================================================================
--- reorg.c	(revision 199028)
+++ reorg.c	(working copy)
@@ -3871,15 +3871,83 @@  struct rtl_opt_pass pass_delay_slots =
   0                                     /* todo_flags_finish */
  }
 };
+
+/* Machine dependent reorg pass, not CFG aware.  */
+static bool
+gate_handle_machine_reorg_nocfg (void)
+{
+  return targetm.machine_dependent_reorg_nocfg != 0;
+}
+
+static unsigned int
+rest_of_handle_machine_reorg_nocfg (void)
+{
+  targetm.machine_dependent_reorg_nocfg ();
+  return 0;
+}
+
+struct rtl_opt_pass pass_machine_reorg_nocfg =
+{
+ {
+  RTL_PASS,
+  "mach_nocfg",                         /* name */
+  OPTGROUP_NONE,                        /* optinfo_flags */
+  gate_handle_machine_reorg_nocfg,      /* gate */
+  rest_of_handle_machine_reorg_nocfg,   /* execute */
+  NULL,                                 /* sub */
+  NULL,                                 /* next */
+  0,                                    /* static_pass_number */
+  TV_MACH_DEP,                          /* tv_id */
+  0,                                    /* properties_required */
+  0,                                    /* properties_provided */
+  0,                                    /* properties_destroyed */
+  0,                                    /* todo_flags_start */
+  0                                     /* todo_flags_finish */
+ }
+};
+
+/* pass_delay_slots and rest_of_handle_machine_reorg_nocfg are not CFG-aware,
+   which means they do not properly maintain it and may even fail if the
+   BLOCK_FOR_INSN pointers are not cleared.
+   These CFG-unaware passes are grouped in pass_cfg_unaware_passes.  */
 
-/* Machine dependent reorg pass.  */
+static bool
+gate_cfg_unaware_passes (void)
+{
+#ifdef DELAY_SLOTS
+  return 1;
+#else
+  return gate_handle_machine_reorg_nocfg ();
+#endif
+}
+
+struct rtl_opt_pass pass_cfg_unaware_passes =
+{
+ {
+  RTL_PASS,
+  "*cfg_unaware",                       /* name */
+  OPTGROUP_NONE,                        /* optinfo_flags */
+  gate_cfg_unaware_passes,              /* gate */
+  NULL,					/* execute */
+  NULL,                                 /* sub */
+  NULL,                                 /* next */
+  0,                                    /* static_pass_number */
+  TV_NONE,                              /* tv_id */
+  0,                                    /* properties_required */
+  0,                                    /* properties_provided */
+  0,                                    /* properties_destroyed */
+  0,                                    /* todo_flags_start */
+  0                                     /* todo_flags_finish */
+ }
+};
+
+/* CFG-aware machine dependent reorg pass.  */
 static bool
 gate_handle_machine_reorg (void)
 {
   return targetm.machine_dependent_reorg != 0;
 }
 
-
 static unsigned int
 rest_of_handle_machine_reorg (void)
 {
@@ -3903,6 +3971,7 @@  struct rtl_opt_pass pass_machine_reorg =
   0,                                    /* properties_provided */
   0,                                    /* properties_destroyed */
   0,                                    /* todo_flags_start */
-  0                                     /* todo_flags_finish */
+  TODO_verify_flow                      /* todo_flags_finish */
  }
 };
+
Index: recog.c
===================================================================
--- recog.c	(revision 199028)
+++ recog.c	(working copy)
@@ -3927,6 +3927,23 @@  gate_do_final_split (void)
 #endif
 }
 
+static unsigned int
+rest_of_handle_final_split (void)
+{
+  if (crtl->cfg_released)
+    split_all_insns_noflow ();
+  else
+    {
+      /* Most targets expect the CFG to be destroyed at this point,
+	 but some keep the CFG alive all the way to the final pass.  */
+      split_all_insns ();
+#ifdef ENABLE_CHECKING
+      verify_flow_info ();
+#endif
+    }
+  return 0;
+}
+
 struct rtl_opt_pass pass_split_for_shorten_branches =
 {
  {
@@ -3934,7 +3951,7 @@  struct rtl_opt_pass pass_split_for_short
   "split5",                             /* name */
   OPTGROUP_NONE,                        /* optinfo_flags */
   gate_do_final_split,                  /* gate */
-  split_all_insns_noflow,               /* execute */
+  rest_of_handle_final_split,           /* execute */
   NULL,                                 /* sub */
   NULL,                                 /* next */
   0,                                    /* static_pass_number */
Index: sched-ebb.c
===================================================================
--- sched-ebb.c	(revision 199028)
+++ sched-ebb.c	(working copy)
@@ -593,8 +593,6 @@  schedule_ebbs_init (void)
 
   haifa_sched_init ();
 
-  compute_bb_for_insn ();
-
   /* Initialize DONT_CALC_DEPS and ebb-{start, end} markers.  */
   bitmap_initialize (&dont_calc_deps, 0);
   bitmap_clear (&dont_calc_deps);
Index: config/i386/i386.c
===================================================================
--- config/i386/i386.c	(revision 199028)
+++ config/i386/i386.c	(working copy)
@@ -35569,10 +35569,6 @@  ix86_pad_short_function (void)
 static void
 ix86_reorg (void)
 {
-  /* We are freeing block_for_insn in the toplev to keep compatibility
-     with old MDEP_REORGS that are not CFG based.  Recompute it now.  */
-  compute_bb_for_insn ();
-
   if (optimize && optimize_function_for_speed_p (cfun))
     {
       if (TARGET_PAD_SHORT_FUNCTION)
Index: config/alpha/alpha.c
===================================================================
--- config/alpha/alpha.c	(revision 199028)
+++ config/alpha/alpha.c	(working copy)
@@ -9807,8 +9807,8 @@  alpha_canonicalize_comparison (int *code
 #undef TARGET_ADDRESS_COST
 #define TARGET_ADDRESS_COST hook_int_rtx_mode_as_bool_0
 
-#undef TARGET_MACHINE_DEPENDENT_REORG
-#define TARGET_MACHINE_DEPENDENT_REORG alpha_reorg
+#undef TARGET_MACHINE_DEPENDENT_REORG_NOCFG
+#define TARGET_MACHINE_DEPENDENT_REORG_NOCFG alpha_reorg
 
 #undef TARGET_PROMOTE_FUNCTION_MODE
 #define TARGET_PROMOTE_FUNCTION_MODE default_promote_function_mode_always_promote
Index: config/frv/frv.c
===================================================================
--- config/frv/frv.c	(revision 199028)
+++ config/frv/frv.c	(working copy)
@@ -477,8 +477,8 @@  static bool frv_class_likely_spilled_p
 #define TARGET_EXPAND_BUILTIN_SAVEREGS frv_expand_builtin_saveregs
 #undef TARGET_SETUP_INCOMING_VARARGS
 #define TARGET_SETUP_INCOMING_VARARGS frv_setup_incoming_varargs
-#undef TARGET_MACHINE_DEPENDENT_REORG
-#define TARGET_MACHINE_DEPENDENT_REORG frv_reorg
+#undef TARGET_MACHINE_DEPENDENT_REORG_NOCFG
+#define TARGET_MACHINE_DEPENDENT_REORG_NOCFG frv_reorg
 
 #undef TARGET_EXPAND_BUILTIN_VA_START
 #define TARGET_EXPAND_BUILTIN_VA_START frv_expand_builtin_va_start
@@ -8182,7 +8182,7 @@  frv_register_nop (rtx nop)
   frv_nops[frv_num_nops++] = nop;
 }
 
-/* Implement TARGET_MACHINE_DEPENDENT_REORG.  Divide the instructions
+/* Implement TARGET_MACHINE_DEPENDENT_REORG_NOCFG.  Divide the instructions
    into packets and check whether we need to insert nops in order to
    fulfill the processor's issue requirements.  Also, if the user has
    requested a certain alignment for a label, try to meet that alignment
Index: config/s390/s390.c
===================================================================
--- config/s390/s390.c	(revision 199028)
+++ config/s390/s390.c	(working copy)
@@ -11036,8 +11036,8 @@  s390_loop_unroll_adjust (unsigned nunrol
 #undef TARGET_MEMORY_MOVE_COST
 #define TARGET_MEMORY_MOVE_COST s390_memory_move_cost
 
-#undef TARGET_MACHINE_DEPENDENT_REORG
-#define TARGET_MACHINE_DEPENDENT_REORG s390_reorg
+#undef TARGET_MACHINE_DEPENDENT_REORG_NOCFG
+#define TARGET_MACHINE_DEPENDENT_REORG_NOCFG s390_reorg
 
 #undef TARGET_VALID_POINTER_MODE
 #define TARGET_VALID_POINTER_MODE s390_valid_pointer_mode
Index: config/spu/spu.c
===================================================================
--- config/spu/spu.c	(revision 199028)
+++ config/spu/spu.c	(working copy)
@@ -7240,8 +7240,8 @@  static const struct attribute_spec spu_a
 #undef TARGET_SETUP_INCOMING_VARARGS
 #define TARGET_SETUP_INCOMING_VARARGS spu_setup_incoming_varargs
 
-#undef TARGET_MACHINE_DEPENDENT_REORG
-#define TARGET_MACHINE_DEPENDENT_REORG spu_machine_dependent_reorg
+#undef TARGET_MACHINE_DEPENDENT_REORG_NOCFG
+#define TARGET_MACHINE_DEPENDENT_REORG_NOCFG spu_machine_dependent_reorg
 
 #undef TARGET_GIMPLIFY_VA_ARG_EXPR
 #define TARGET_GIMPLIFY_VA_ARG_EXPR spu_gimplify_va_arg_expr
Index: config/mep/mep.c
===================================================================
--- config/mep/mep.c	(revision 199028)
+++ config/mep/mep.c	(working copy)
@@ -7242,8 +7242,8 @@  mep_asm_init_sections (void)
 #define TARGET_RTX_COSTS		mep_rtx_cost
 #undef  TARGET_ADDRESS_COST
 #define TARGET_ADDRESS_COST 		mep_address_cost
-#undef  TARGET_MACHINE_DEPENDENT_REORG
-#define TARGET_MACHINE_DEPENDENT_REORG  mep_reorg
+#undef  TARGET_MACHINE_DEPENDENT_REORG_NOCFG
+#define TARGET_MACHINE_DEPENDENT_REORG_NOCFG  mep_reorg
 #undef  TARGET_SETUP_INCOMING_VARARGS
 #define TARGET_SETUP_INCOMING_VARARGS	mep_setup_incoming_varargs
 #undef  TARGET_PASS_BY_REFERENCE
Index: config/tilegx/tilegx.c
===================================================================
--- config/tilegx/tilegx.c	(revision 199028)
+++ config/tilegx/tilegx.c	(working copy)
@@ -5549,8 +5549,8 @@  tilegx_file_end (void)
 #undef  TARGET_SCHED_ADJUST_COST
 #define TARGET_SCHED_ADJUST_COST tilegx_sched_adjust_cost
 
-#undef  TARGET_MACHINE_DEPENDENT_REORG
-#define TARGET_MACHINE_DEPENDENT_REORG tilegx_reorg
+#undef  TARGET_MACHINE_DEPENDENT_REORG_NOCFG
+#define TARGET_MACHINE_DEPENDENT_REORG_NOCFG tilegx_reorg
 
 #undef  TARGET_ASM_CAN_OUTPUT_MI_THUNK
 #define TARGET_ASM_CAN_OUTPUT_MI_THUNK \
Index: config/sh/sh.c
===================================================================
--- config/sh/sh.c	(revision 199028)
+++ config/sh/sh.c	(working copy)
@@ -490,8 +490,8 @@  static const struct attribute_spec sh_at
 #undef TARGET_ALLOCATE_INITIAL_VALUE
 #define TARGET_ALLOCATE_INITIAL_VALUE sh_allocate_initial_value
 
-#undef TARGET_MACHINE_DEPENDENT_REORG
-#define TARGET_MACHINE_DEPENDENT_REORG sh_reorg
+#undef TARGET_MACHINE_DEPENDENT_REORG_NOCFG
+#define TARGET_MACHINE_DEPENDENT_REORG_NOCFG sh_reorg
 
 #undef TARGET_DWARF_REGISTER_SPAN
 #define TARGET_DWARF_REGISTER_SPAN sh_dwarf_register_span
Index: config/avr/avr.c
===================================================================
--- config/avr/avr.c	(revision 199028)
+++ config/avr/avr.c	(working copy)
@@ -9683,7 +9683,7 @@  avr_reorg_remove_redundant_compare (rtx
 }
 
 
-/* Implement `TARGET_MACHINE_DEPENDENT_REORG'.  */
+/* Implement `TARGET_MACHINE_DEPENDENT_REORG_NOCFG'.  */
 /* Optimize conditional jumps.  */
 
 static void
@@ -12141,8 +12141,8 @@  avr_fold_builtin (tree fndecl, int n_arg
 #define TARGET_RTX_COSTS avr_rtx_costs
 #undef  TARGET_ADDRESS_COST
 #define TARGET_ADDRESS_COST avr_address_cost
-#undef  TARGET_MACHINE_DEPENDENT_REORG
-#define TARGET_MACHINE_DEPENDENT_REORG avr_reorg
+#undef  TARGET_MACHINE_DEPENDENT_REORG_NOCFG
+#define TARGET_MACHINE_DEPENDENT_REORG_NOCFG avr_reorg
 #undef  TARGET_FUNCTION_ARG
 #define TARGET_FUNCTION_ARG avr_function_arg
 #undef  TARGET_FUNCTION_ARG_ADVANCE
Index: config/stormy16/stormy16.c
===================================================================
--- config/stormy16/stormy16.c	(revision 199028)
+++ config/stormy16/stormy16.c	(working copy)
@@ -2664,8 +2664,8 @@  xstormy16_return_in_memory (const_tree t
 #undef TARGET_FUNCTION_VALUE_REGNO_P
 #define TARGET_FUNCTION_VALUE_REGNO_P xstormy16_function_value_regno_p
 
-#undef  TARGET_MACHINE_DEPENDENT_REORG
-#define TARGET_MACHINE_DEPENDENT_REORG xstormy16_reorg
+#undef  TARGET_MACHINE_DEPENDENT_REORG_NOCFG
+#define TARGET_MACHINE_DEPENDENT_REORG_NOCFG xstormy16_reorg
 
 #undef  TARGET_PREFERRED_RELOAD_CLASS
 #define TARGET_PREFERRED_RELOAD_CLASS xstormy16_preferred_reload_class
Index: config/mn10300/mn10300.c
===================================================================
--- config/mn10300/mn10300.c	(revision 199028)
+++ config/mn10300/mn10300.c	(working copy)
@@ -3308,8 +3308,8 @@  mn10300_reorg (void)
 
 /* Initialize the GCC target structure.  */
 
-#undef  TARGET_MACHINE_DEPENDENT_REORG
-#define TARGET_MACHINE_DEPENDENT_REORG mn10300_reorg
+#undef  TARGET_MACHINE_DEPENDENT_REORG_NOCFG
+#define TARGET_MACHINE_DEPENDENT_REORG_NOCFG mn10300_reorg
 
 #undef  TARGET_ASM_ALIGNED_HI_OP
 #define TARGET_ASM_ALIGNED_HI_OP "\t.hword\t"
Index: config/c6x/c6x.c
===================================================================
--- config/c6x/c6x.c	(revision 199028)
+++ config/c6x/c6x.c	(working copy)
@@ -5893,9 +5893,9 @@  c6x_hwloops (void)
     reorg_loops (true, &c6x_doloop_hooks);
 }
 
-/* Implement the TARGET_MACHINE_DEPENDENT_REORG pass.  We split call insns here
-   into a sequence that loads the return register and performs the call,
-   and emit the return label.
+/* Implement the TARGET_MACHINE_DEPENDENT_REORG_NOCFG pass.
+   We split call insns here into a sequence that loads the return
+   register and performs the call, and emit the return label.
    If scheduling after reload is requested, it happens here.  */
 
 static void
@@ -6796,8 +6796,8 @@  c6x_debug_unwind_info (void)
 #undef TARGET_PREFERRED_RENAME_CLASS
 #define TARGET_PREFERRED_RENAME_CLASS c6x_preferred_rename_class
 
-#undef TARGET_MACHINE_DEPENDENT_REORG
-#define TARGET_MACHINE_DEPENDENT_REORG c6x_reorg
+#undef TARGET_MACHINE_DEPENDENT_REORG_NOCFG
+#define TARGET_MACHINE_DEPENDENT_REORG_NOCFG c6x_reorg
 
 #undef TARGET_ASM_FILE_START
 #define TARGET_ASM_FILE_START c6x_file_start
Index: config/ia64/ia64.c
===================================================================
--- config/ia64/ia64.c	(revision 199028)
+++ config/ia64/ia64.c	(working copy)
@@ -527,8 +527,8 @@  static const struct attribute_spec ia64_
 #undef TARGET_UNSPEC_MAY_TRAP_P
 #define TARGET_UNSPEC_MAY_TRAP_P ia64_unspec_may_trap_p
 
-#undef TARGET_MACHINE_DEPENDENT_REORG
-#define TARGET_MACHINE_DEPENDENT_REORG ia64_reorg
+#undef TARGET_MACHINE_DEPENDENT_REORG_NOCFG
+#define TARGET_MACHINE_DEPENDENT_REORG_NOCFG ia64_reorg
 
 #undef TARGET_ENCODE_SECTION_INFO
 #define TARGET_ENCODE_SECTION_INFO ia64_encode_section_info
@@ -9637,10 +9637,6 @@  emit_predicate_relation_info (void)
 static void
 ia64_reorg (void)
 {
-  /* We are freeing block_for_insn in the toplev to keep compatibility
-     with old MDEP_REORGS that are not CFG based.  Recompute it now.  */
-  compute_bb_for_insn ();
-
   /* If optimizing, we'll have split before scheduling.  */
   if (optimize == 0)
     split_all_insns ();
Index: config/picochip/picochip.c
===================================================================
--- config/picochip/picochip.c	(revision 199028)
+++ config/picochip/picochip.c	(working copy)
@@ -255,8 +255,8 @@  static char picochip_get_vliw_alu_id (vo
 #undef TARGET_ASM_FILE_END
 #define TARGET_ASM_FILE_END picochip_asm_file_end
 
-#undef TARGET_MACHINE_DEPENDENT_REORG
-#define TARGET_MACHINE_DEPENDENT_REORG picochip_reorg
+#undef TARGET_MACHINE_DEPENDENT_REORG_NOCFG
+#define TARGET_MACHINE_DEPENDENT_REORG_NOCFG picochip_reorg
 
 #undef TARGET_ARG_PARTIAL_BYTES
 #define TARGET_ARG_PARTIAL_BYTES picochip_arg_partial_bytes
Index: config/mcore/mcore.c
===================================================================
--- config/mcore/mcore.c	(revision 199028)
+++ config/mcore/mcore.c	(working copy)
@@ -191,8 +191,8 @@  static const struct attribute_spec mcore
 #define TARGET_RTX_COSTS 		mcore_rtx_costs
 #undef  TARGET_ADDRESS_COST
 #define TARGET_ADDRESS_COST 		hook_int_rtx_mode_as_bool_0
-#undef  TARGET_MACHINE_DEPENDENT_REORG
-#define TARGET_MACHINE_DEPENDENT_REORG	mcore_reorg
+#undef  TARGET_MACHINE_DEPENDENT_REORG_NOCFG
+#define TARGET_MACHINE_DEPENDENT_REORG_NOCFG	mcore_reorg
 
 #undef  TARGET_PROMOTE_FUNCTION_MODE
 #define TARGET_PROMOTE_FUNCTION_MODE	default_promote_function_mode_always_promote
Index: config/tilepro/tilepro.c
===================================================================
--- config/tilepro/tilepro.c	(revision 199028)
+++ config/tilepro/tilepro.c	(working copy)
@@ -5041,8 +5041,8 @@  tilepro_file_end (void)
 #undef  TARGET_SCHED_ADJUST_COST
 #define TARGET_SCHED_ADJUST_COST tilepro_sched_adjust_cost
 
-#undef  TARGET_MACHINE_DEPENDENT_REORG
-#define TARGET_MACHINE_DEPENDENT_REORG tilepro_reorg
+#undef  TARGET_MACHINE_DEPENDENT_REORG_NOCFG
+#define TARGET_MACHINE_DEPENDENT_REORG_NOCFG tilepro_reorg
 
 #undef  TARGET_ASM_CAN_OUTPUT_MI_THUNK
 #define TARGET_ASM_CAN_OUTPUT_MI_THUNK \
Index: config/arm/arm.c
===================================================================
--- config/arm/arm.c	(revision 199028)
+++ config/arm/arm.c	(working copy)
@@ -434,8 +434,8 @@  static const struct attribute_spec arm_a
 #define TARGET_VECTORIZE_AUTOVECTORIZE_VECTOR_SIZES \
   arm_autovectorize_vector_sizes
 
-#undef  TARGET_MACHINE_DEPENDENT_REORG
-#define TARGET_MACHINE_DEPENDENT_REORG arm_reorg
+#undef  TARGET_MACHINE_DEPENDENT_REORG_NOCFG
+#define TARGET_MACHINE_DEPENDENT_REORG_NOCFG arm_reorg
 
 #undef  TARGET_INIT_BUILTINS
 #define TARGET_INIT_BUILTINS  arm_init_builtins
Index: config/pa/pa.c
===================================================================
--- config/pa/pa.c	(revision 199028)
+++ config/pa/pa.c	(working copy)
@@ -313,8 +313,8 @@  static size_t n_deferred_plabels = 0;
 #undef TARGET_ADDRESS_COST
 #define TARGET_ADDRESS_COST hppa_address_cost
 
-#undef TARGET_MACHINE_DEPENDENT_REORG
-#define TARGET_MACHINE_DEPENDENT_REORG pa_reorg
+#undef TARGET_MACHINE_DEPENDENT_REORG_NOCFG
+#define TARGET_MACHINE_DEPENDENT_REORG_NOCFG pa_reorg
 
 #undef TARGET_INIT_LIBFUNCS
 #define TARGET_INIT_LIBFUNCS pa_init_libfuncs
Index: config/mips/mips.c
===================================================================
--- config/mips/mips.c	(revision 199028)
+++ config/mips/mips.c	(working copy)
@@ -16255,7 +16255,7 @@  mips16_split_long_branches (void)
   while (something_changed);
 }
 
-/* Implement TARGET_MACHINE_DEPENDENT_REORG.  */
+/* Implement TARGET_MACHINE_DEPENDENT_REORG_NOCFG.  */
 
 static void
 mips_reorg (void)
@@ -18619,8 +18619,8 @@  mips_expand_vec_minmax (rtx target, rtx
 #undef TARGET_IN_SMALL_DATA_P
 #define TARGET_IN_SMALL_DATA_P mips_in_small_data_p
 
-#undef TARGET_MACHINE_DEPENDENT_REORG
-#define TARGET_MACHINE_DEPENDENT_REORG mips_reorg
+#undef TARGET_MACHINE_DEPENDENT_REORG_NOCFG
+#define TARGET_MACHINE_DEPENDENT_REORG_NOCFG mips_reorg
 
 #undef  TARGET_PREFERRED_RELOAD_CLASS
 #define TARGET_PREFERRED_RELOAD_CLASS mips_preferred_reload_class
Index: config/v850/v850.c
===================================================================
--- config/v850/v850.c	(revision 199028)
+++ config/v850/v850.c	(working copy)
@@ -1212,7 +1212,7 @@  Saved %d bytes (%d uses of register %s)
 }
 
 
-/* TARGET_MACHINE_DEPENDENT_REORG.  On the 850, we use it to implement
+/* TARGET_MACHINE_DEPENDENT_REORG_NOCFG.  On the 850, we use it to implement
    the -mep mode to copy heavily used pointers to ep to use the implicit
    addressing.  */
 
@@ -3223,8 +3223,8 @@  v850_gen_movdi (rtx * operands)
 #undef  TARGET_ADDRESS_COST
 #define TARGET_ADDRESS_COST hook_int_rtx_mode_as_bool_0
 
-#undef  TARGET_MACHINE_DEPENDENT_REORG
-#define TARGET_MACHINE_DEPENDENT_REORG v850_reorg
+#undef  TARGET_MACHINE_DEPENDENT_REORG_NOCFG
+#define TARGET_MACHINE_DEPENDENT_REORG_NOCFG v850_reorg
 
 #undef  TARGET_SCHED_ISSUE_RATE
 #define TARGET_SCHED_ISSUE_RATE v850_issue_rate
Index: config/h8300/h8300.c
===================================================================
--- config/h8300/h8300.c	(revision 199028)
+++ config/h8300/h8300.c	(working copy)
@@ -6071,8 +6071,8 @@  h8300_trampoline_init (rtx m_tramp, tree
 #undef TARGET_FUNCTION_ARG_ADVANCE
 #define TARGET_FUNCTION_ARG_ADVANCE h8300_function_arg_advance
 
-#undef  TARGET_MACHINE_DEPENDENT_REORG
-#define TARGET_MACHINE_DEPENDENT_REORG h8300_reorg
+#undef  TARGET_MACHINE_DEPENDENT_REORG_NOCFG
+#define TARGET_MACHINE_DEPENDENT_REORG_NOCFG h8300_reorg
 
 #undef TARGET_HARD_REGNO_SCRATCH_OK
 #define TARGET_HARD_REGNO_SCRATCH_OK h8300_hard_regno_scratch_ok
Index: config/mmix/mmix.c
===================================================================
--- config/mmix/mmix.c	(revision 199028)
+++ config/mmix/mmix.c	(working copy)
@@ -226,8 +226,8 @@  static void mmix_conditional_register_us
 #undef TARGET_REGISTER_MOVE_COST
 #define TARGET_REGISTER_MOVE_COST mmix_register_move_cost
 
-#undef TARGET_MACHINE_DEPENDENT_REORG
-#define TARGET_MACHINE_DEPENDENT_REORG mmix_reorg
+#undef TARGET_MACHINE_DEPENDENT_REORG_NOCFG
+#define TARGET_MACHINE_DEPENDENT_REORG_NOCFG mmix_reorg
 
 #undef TARGET_PROMOTE_FUNCTION_MODE
 #define TARGET_PROMOTE_FUNCTION_MODE mmix_promote_function_mode
@@ -828,7 +828,7 @@  mmix_target_asm_function_end_prologue (F
   cfun->machine->in_prologue = 0;
 }
 
-/* Implement TARGET_MACHINE_DEPENDENT_REORG.  No actual rearrangements
+/* Implement TARGET_MACHINE_DEPENDENT_REORG_NOCFG.  No actual rearrangements
    done here; just virtually by calculating the highest saved stack
    register number used to modify the register numbers at output time.  */
 
Index: config/bfin/bfin.c
===================================================================
--- config/bfin/bfin.c	(revision 199028)
+++ config/bfin/bfin.c	(working copy)
@@ -5717,8 +5717,8 @@  bfin_conditional_register_usage (void)
 #undef  TARGET_ASM_INTEGER
 #define TARGET_ASM_INTEGER bfin_assemble_integer
 
-#undef TARGET_MACHINE_DEPENDENT_REORG
-#define TARGET_MACHINE_DEPENDENT_REORG bfin_reorg
+#undef TARGET_MACHINE_DEPENDENT_REORG_NOCFG
+#define TARGET_MACHINE_DEPENDENT_REORG_NOCFG bfin_reorg
 
 #undef TARGET_FUNCTION_OK_FOR_SIBCALL
 #define TARGET_FUNCTION_OK_FOR_SIBCALL bfin_function_ok_for_sibcall