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]

Re: Analysis of Brad's GCSE problem with computed gotos.



  In message <Pine.GSO.4.21.0012010355270.1643-100000@platon>you write:
  > 
  > Bah, seems, I'm a little bit tired. Shouldn't have gone to gcc-patches ;-)
  > 
  > ---------- Forwarded message ----------
  > 
  > Hi,
  > 
  > after some battling with RTL dumps > 18 Mb I guess I know, where the
  > problem with computed goto's and GCSE lies, which manifests for Brad's
  > _io.i file (see also optimization/732 and the thread there). The problem
  > are memory accesses hoisted over abnormal edges (like in computed
  > jumps). The program below demonstrates that (see below):
  > 
  > ------ snip ------
  > extern void abort (void);
  > extern int ei;
  > extern int * get_ip ();
  >  
  > int main(void)
  > {
  >   static void * table[] = {
  >     &&jump ,&&L0, &&L1, &&L2
  >   };
  >   int *ip;
  >   int e = 0, f = 0, state = 3;
  >  
  >   goto jump;
  >  
  > L0:
  >   f = ip[35];
  >   goto L1;
  > L1:
  >   e = ip[35];
  >   goto end;
  > L2:  ip = (int*)4;
  >   goto end;
  >  
  > jump:
  >   ei = 23;
  >   ip = get_ip ();
  >   goto *table[state];
  >  
  > end:
  >   if (ip != (int*) 4 || (e+f) != 0) abort();
  >   return 0;
  > }
  > 
  > int ei;
  >  
  > int * get_ip ()
  > {
  >   return 0 /*&ei*/ ;
  > }
  > -------- snap --------
  > 
  > This program crashes when compiled with -O2 but not with "-O2 -fno-gcse".
  > The reason is, that the second "ip[35]" is partial redundant. Normally
  > this would be eliminated, and instead a ip[35] evaluation placed on the
  > edge <jump,L1>. As this is a abnormal edge, which can't be split that
  > easily, GCSE simply adds this instruction to the end of the source block.
  > Of course nothing could be more wrong, if the instruction in question is a
  > trapping one (like memory access) which wouldn't be called in normal flow
  > (like in the above program, where ip==0, which traps, when placed before
  > the table jump). There is also some commentary in pre_edge_insert()
  > regarding this situation.
  > 
  > Basically the same situation also happens with Brads testcase. There a
  > redundant memory access is moved up from some (around 37) blocks to
  > the dispatch block, without noticing, that now there is the possibility,
  > that this memory access is reached by a def which is invalid for mem
  > access (basically something like:
  > "int* i=12; goto L; ...; L: a=*i; table-jump;" )
  > 
  > We could either disable the moving of (mem:...) over abnormal edges (which
  > then would mean, that we would have to undelete the PR instruction), or we
  > could avoid to mark these instructions as deleted from the beginning
  > (which is not that easy, as we only want to disable them, if there are any
  > disturbing abnormal edges). Suggestions?
It's fairly simple to prevent unsafe movement across an abnormal edge.

Just consider any expression which might trap dead at the start of any block
which is the destination for an abnormal edge.

It's not perfect (in the sense that we can lose some optimization), but
it is simple and will always generate correct code.

jeff


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