This is the mail archive of the gcc@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: Notes toward re-implementing EH in gimple


On 08/06/2009 01:44 PM, Jan Hubicka wrote:
Hmm, EH_LANDING_PAD will still need to be somewhat special (as moving it
across eh edge or something will change behaviour) but it indeed seems
uite sane representation of fact that the EH/filter is really set by
runtime...

Yes, EH_LANDING_PAD is still somewhat special in that it cannot be moved *at all*. Specifically, it must be the first statement in the block whose label is recorded in the EH Region Table.

But that's not a very onerous special case.

Similarly here, it seemed to me that normal switch would suffice.

A normal switch only suffices after inlining, when we've collected the complete set of types which can be caught within the function. Until then, we must make do with a place holder.

ERT_NOP

	A new type of exception region that merely implies
	a different landing pad to the containing region.
	Inserting one of these below the "current" region
	is how we'll split critical edges, instead of copying
	regions.

I am not sure how this will work. When you have throwing statement inside several catch...try regions with different types caught, you will have multiple EH edges from that statement. It seems that all those edges are neccesary since runtime can really deliver control flow to any of the try..catch handlers.

We might want to redirect edge that does not correspond to the innermost
try...catch that is where we need to copy nontrivial chain of EH regions
for specific redirection.  You intend to represent this by ERT_NOP?

You're misunderstanding how the edges are to be drawn.


Under the current scheme, before rtl's finish_eh_generation runs,
we do have edges that go direct from a call to each of the possible
handlers and cleanups.

Under this proposed scheme, we model how the runtime actually
works, right from the beginning.  There is only *one* EH edge for
any one statement that can throw, and that edge is to the landing
pad.  From the landing pad, the filter value de-multiplexes this
one edge to select the proper handler/cleanup.

It seems extremely unlikely to me that we actually want to put fixup
code before handler X, as opposed to merely on any EH edge, simply
because the CFG won't be drawn that way.

We *can* put anything we want into the landing pad block (after the
actual EH_LANDING_PAD statement).  We can even duplicate the
EH_DISPATCH stmt (nee SWITCH stmt) and so split edges to individual
handlers if we really needed to go that far.

Seems sane.  Removing fully optimized out cleanups still benefits from
RESX not being lowered to _Unwind_Resume, but the lowering can happen
somewhere at later half of the optimization queue, it is not probably
going to bring that much new optimization oppurtunities.

I'd been imagining lowering RESX/EH_DISPATCH here:


  p = &all_passes;
+ NEXT_PASS (pass_lower_eh_dispatch);
  NEXT_PASS (pass_all_optimizations);

so that it happens immediately after inlining even without -O1.

   There are a couple of advantages that ought to be clear immediately.
   First, no more silliness that tree_empty_eh_handler_p has to clean up.
   Second, everything can be properly put into SSA form.
   Third, we're not too late to easily generate switch statements.  See

           /* ??? It is mighty inconvenient to call back into the
              switch statement generation code in expand_end_case.
              Rapid prototyping sez a sequence of ifs.  */

which has been in except.c for nearly 10 years.

Yep, I also found this comment entertaining ;)
We decide we want to split edge BB1->BB7, so we modify:

	EH Region Tree:
	1 cleanup ->  { e1, f1 }, land = BB7, post-land = BB8
	  2 cleanup ->  { e2, f2 }, land = BB5, post-land = BB6
	  3 nop ->  { e1, f1 }, land = BB9, post-land = BB8

	BB1:
	  bar();		[EH 3]
	  # succ 2 9(eh)

	BB9:
	  { e1, f1 } = EH_LANDING_PAD;
	  # succ 8

   Which, if I'm not mistaken, duplicates far less code than you
   do at present to split these edges.

Hmm, if I understand right, edge rediretion now involve creation of new BB. I don't think it is very lucky solution. With current implementation EH redirection behave same way as redirection of normal edges.

Pardon? Edge splitting always involves creation of a new block. The only thing that's different here is that the new block isn't empty -- it must include the EH_LANDING_PAD statement.

What did you think you are doing in the current implementation?
It's the same, except the expansion of the landing pad is hidden
in the rtl code, triggered by the label being in the EH tables.

I almost wish the EH_LANDING_PAD could be hidden within the PHIs,
so that it couldn't be separated from the beginning of the block.

Actually, it occurs to me that we *could* do something really
really special here.  Suppose we make SSA notice EH landing pad
labels, and go off to the EH table to find the statement.  In
that way, the EH_LANDING_PAD statement wouldn't really exist
in the normal code stream, and so it couldn't be mis-placed.

I do wonder if the fact that the statement isn't in the code
stream causes other weird side effects, but I can't imagine it's
any weirder than PHIs not being in the code stream.

We don't duplicate code, just pieces of EH tree and when we end up
redirecting things back, we cleanup.  So passes don't need to care EH
edges specially and also critical edge splitting is fully undone by
cfg+eh cleanup when nothing is inserted over the split paths.

Hmm. Perhaps you could find an example of when this splitting and cleanup is done on the current tree? I have a feeling it would be a similar amount of code with my scheme.

But still there is problem that originally we didn't have RESX->outer
region edges as we do now, so regions that has types completely shadowed
by inner regions we will still have it reachable from the RESX of inner
regions (that no longer have the type info)

We *don't* actually have those RESX->outer edges at the moment. That's one of the things that I'm trying to fix with my trans-mem dominator patch... which I've spent most of the day not working on. :-P


r~



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