http://gcc.gnu.org/bugzilla/show_bug.cgi?id=59986

            Bug ID: 59986
           Summary: Unnecessary edges in the CFG due to setjmp
           Product: gcc
           Version: unknown
            Status: UNCONFIRMED
          Severity: normal
          Priority: P3
         Component: tree-optimization
          Assignee: unassigned at gcc dot gnu.org
          Reporter: law at redhat dot com

In a function with a setjmp call, we create unnecessary edges in the CFG.

An example from 59919:

typedef int jmp_buf[10];
struct S
{
  int i;
  jmp_buf buf;
};

void setjmp (jmp_buf);
void foo (int *);
__attribute__ ((__noreturn__, __nonnull__)) void bar (struct S *);

void
baz (struct S *p)
{
  bar (p);
  setjmp (p->buf);
  foo (&p->i);
}

In this case bar() is considered as ending a basic block (due to its noreturn
attribute) and we create an abnormal outgoing edge from the block (due to the
setjmp call later)

Conceptually ISTM that if we were to partition calls into two sets, those that
are not reached by a setjmp and those which are reached by a setjmp.  The
former do not need outgoing abnormal edges from their blocks.  Note that in
turn may make some setjmp calls unreachable (as in the example above) which
implies some kind of worklist algorithm.

The big question in my mind is how often we're able to eliminate those
unnecessary edges and do we actually gain anything in real world code as a
result of removing those unnecessary edges from the CFG.

Obviously if experiments show there isn't much gained, I'd suggest we just
close/wontfix.

Reply via email to