Non-call exceptions versus cse
Andrew Haley
aph@redhat.com
Wed Nov 20 07:37:00 GMT 2002
Michael Matz writes:
> 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{}?
That's how it appears to me.
> 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
Yes, that's right. That is why, after discussing this with rth, I
concluded that the right thing was to read into a temporary rather
than directly into the destination. As long as the temporary isn't
deleted everything is OK.
> , 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.
That's one idea.
> 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, ...)
> }
That's similar to what I do in the Java front end.
More precisely, what I do transforms
output1 = may_trap (i1);
into
output1 = ({ type t1; t1 = may_trap (i1); t1; });
However, cse removes t1, which is how this disussion started. There's
a hole in my bucket...
> 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.
Well, they aren't so prevented. The two patches I submitted are cases
where the compiler does this combination.
BTW, this is the RTL in question before CSE:
(note 27 22 28 0 ("Array_3.java") 64)
(insn 28 27 30 0 0x40228554 (set (reg/v/f:SI 63)
(const_int 0 [0x0])) -1 (nil)
(nil))
(note 30 28 33 0 ("Array_3.java") 66)
(insn 33 30 233 0 0x402284a4 (set (reg/v:SI 65)
(mem/s:SI (plus:SI (reg/v/f:SI 63)
(const_int 4 [0x4])) [15 <variable>.length+0 S4 A32])) -1 (nil)
(expr_list:REG_EH_REGION (const_int 1 [0x1])
(nil)))
;; End of basic block 0, registers live:
(nil)
;; Start of basic block 1, registers live: (nil)
(note 233 33 35 1 [bb 1] NOTE_INSN_BASIC_BLOCK)
(insn 35 233 39 1 0x40228554 (set (reg/v:SI 61)
(reg/v:SI 65)) -1 (nil)
(nil))
And after CSE:
(note 27 22 30 0 ("Array_3.java") 64)
(note 30 27 33 0 ("Array_3.java") 66)
(insn 33 30 233 0 0x402284a4 (set (reg/v:SI 61)
(mem/s:SI (const_int 4 [0x4]) [15 <variable>.length+0 S4 A32])) 38 {*movsi_1} (nil)
(expr_list:REG_EH_REGION (const_int 1 [0x1])
(nil)))
;; End of basic block 0, registers live:
(nil)
;; Start of basic block 1, registers live: (nil)
Andrew.
More information about the Gcc-patches
mailing list