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]

EH flow analysis


>>>>> Jim Wilson <wilson@cygnus.com> writes:

> Without the sjlj exceptions, there is no indirect jump, but there is a
> list of exception handler labels, and each block that starts with an
> exception handler label is marked as live.  However, we are still missing
> control flow info here, because we don't know how these exception handler
> labels are reached.  flow notices that it has unreachable blocks which
> are marked as reachable, so it just adds a bogus connection to the
> previous block.  Since the bogus connections all go one way, backwards,
> it is impossible (or at least very unlikely) to get a a circular group of
> unreachable blocks.  But while it happens to work, the flow info is still
> wrong, and this will have to be fixed before it causes problems.  This
> probably needs to be fixed the same way as I mentioned above, i.e. flow
> should know that exception handler regions are reachable from all call
> instructions (or all call instructions in scope).

Yep.  Here's a testcase that breaks with -fno-sjlj-exceptions:

  struct A {
    int i;
    ~A ();
    A () : i (0) {}
  };

  struct B : public A {
    B(): A() {}
  };

  struct C {
    int i;
    B b[1];
  };

  C c;

Mike's earlier patch fixes the flow information, but flow still doesn't
delete all unreachable handlers.  Another jump (and exception_optimize)
pass will delete the rest, but that doesn't happen again until the very end
of compilation, when we've already aborted because we saw a use of a dead
pseudo.

Here's a patch that fixes this test case in a pessimistic way, by assuming
for the purposes of flow analysis that all handlers are reachable from all
calls.  A better solution will be to only note that the innermost handler
is reachable, and make flow delete all unreachable code; then we can do
away with exception_optimize.

Tue Sep 23 09:01:38 1997  Jason Merrill  <jason@yorick.cygnus.com>

	* flow.c (find_basic_blocks): Mark calls as potentially jumping
	to the EH labels.

Index: flow.c
===================================================================
RCS file: /cvs/cvsfiles/devo/gcc/flow.c,v
retrieving revision 1.89
diff -c -r1.89 flow.c
*** flow.c	1997/09/22 01:41:20	1.89
--- flow.c	1997/09/23 16:00:03
***************
*** 467,474 ****
      if (! LABEL_REF_NONLOCAL_P (x))
        block_live[BLOCK_NUM (XEXP (x, 0))] = 1;
  
!   for (x = exception_handler_labels; x; x = XEXP (x, 1))
!     block_live[BLOCK_NUM (XEXP (x, 0))] = 1;
  
    /* Record which basic blocks control can drop in to.  */
  
--- 467,475 ----
      if (! LABEL_REF_NONLOCAL_P (x))
        block_live[BLOCK_NUM (XEXP (x, 0))] = 1;
  
!   if (asynchronous_exceptions)
!     for (x = exception_handler_labels; x; x = XEXP (x, 1))
!       block_live[BLOCK_NUM (XEXP (x, 0))] = 1;
  
    /* Record which basic blocks control can drop in to.  */
  
***************
*** 532,537 ****
--- 533,543 ----
  	    for (x = nonlocal_label_list; x; x = XEXP (x, 1))
  	      mark_label_ref (gen_rtx (LABEL_REF, VOIDmode, XEXP (x, 0)),
  			      insn, 0);
+ 
+ 	    if (! asynchronous_exceptions)
+ 	      for (x = exception_handler_labels; x; x = XEXP (x, 1))
+ 		mark_label_ref (gen_rtx (LABEL_REF, VOIDmode, XEXP (x, 0)),
+ 				insn, 0);
  
  	    /* ??? This could be made smarter:
  	       in some cases it's possible to tell that certain


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