This is the mail archive of the gcc-patches@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: Non-call exceptions versus cse


Hi,

On Wed, 20 Nov 2002, Andrew Haley wrote:

> From what I remember, you said that flow would work correctly in this
> case iff the value read from memory were first copied to a temporary,
> and that's what I'm trying to do.
>
> This is the Java code that is not compiled correctly:
>
>     boolean ok = false;
>     int nn = 0;
>
> [ ... ]
>
>     ok = false;
>     try
>       {
> 	int[] x = (int[])null;
> 	nn = x[0];
>       }
>     catch (NullPointerException _)
>       {
> 	ok = true;
>       }
>
>     if (!ok || nn != 0)
>       throw new RuntimeException("test failed:3");
>
> The problem is that nn is assigned to a register for the period
> between the assignment in the try block and the test after the catch.

But it's not assigned the same register before the begin of the try{}?
This would indicate a problem in flow, because the use of nn is reached by
both defs (the =0 one through the exception edge, and the =x[0] one
through the fallthrough).  This means that either all refs of nn have to
be the same register, or all memory.  The problem here of course is, that
if the assignement is only one insn, that we have a choice what should
happen to the outputs of the insn, if the exception happens _during_ that
insn.  It seems java wants to define the output's as untouched in that
case, or?  This seems different to what Ada wants.  Maybe this should be
really differentiated in the backend depending on a
flag_exception_clobbers_outputs, which Ada would set.  If it's set we can
depend on the change of the outputs no matter if the exceptions occurs or
not.

Hmm, OTOH the above (java semantic) can be implemented without a flag
already in the frontends by using short temporaries.  I.e. transforming
any
  (output1, output2, ...) <== may_trap (i1, i2, ...)
into
  { type t1,t2, ...;
    (t1, t2, ...) <== may_trap (i1, i2, ...)
    /* Point 1 */
    (output1, output2, ...) <== (t1, t2, ...)
  }

Double hmm.  Then it must be ensured, that these two statements are not
combined again, indeed.  But that shouldn't happen anyway, because at
"Point 1" above a new basic block begins, and the first block can be left
(by throwing) _without_ setting (output1, ...).  Ergo combining both
should already be prevented, if you emit such code sequence in the
frontend.  But that should not be prevented by the existance of a trapping
insn, but simply based on the fact, that this would combine invalidly over
a basic block border.


Ciao,
Michael.


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