[Bug java/21855] array bounds checking elimination
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=21855 Andrew Haley changed: What|Removed |Added Status|NEW |RESOLVED Resolution|--- |WONTFIX --- Comment #25 from Andrew Haley --- We'll never do this.
[Bug java/21855] array bounds checking elimination
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=21855 Richard Guenther rguenth at gcc dot gnu.org changed: What|Removed |Added Status|WAITING |NEW Component|tree-optimization |java --- Comment #15 from Richard Guenther rguenth at gcc dot gnu.org 2012-01-10 16:20:13 UTC --- (In reply to comment #14) (In reply to comment #13) We can't optimize this because System.out.println can change args[]. That's the whole point: System.out.println cannot change args[], which is a java array, and the length of a Java array is constant. It is not an invalid test case. I suppose public static void main(String[] args) is passing args by value (but the implementation detail uses reference passing for efficiency?). In this case the Java frontend should do like the C++ frontend and tell this to the middle-end by properly marking args as 1) DECL_BY_REFERENCE, 2) use a TYPE_RESTRICT qualified pointer for the reference. Then we would optimize this case. Java frontend issue.
[Bug java/21855] array bounds checking elimination
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=21855 --- Comment #16 from Andrew Haley aph at gcc dot gnu.org 2012-01-10 16:26:51 UTC --- (In reply to comment #15) (In reply to comment #14) (In reply to comment #13) We can't optimize this because System.out.println can change args[]. That's the whole point: System.out.println cannot change args[], which is a java array, and the length of a Java array is constant. It is not an invalid test case. I suppose public static void main(String[] args) is passing args by value (but the implementation detail uses reference passing for efficiency?). args is indeed a reference to a Java array. The length field of a Java array is immutable. The elements of an array are not immutable. In this case the Java frontend should do like the C++ frontend and tell this to the middle-end by properly marking args as 1) DECL_BY_REFERENCE, 2) use a TYPE_RESTRICT qualified pointer for the reference. Then we would optimize this case. If we could mark the length field as immutable that would fix it. Is there any way to do that?
[Bug java/21855] array bounds checking elimination
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=21855 --- Comment #17 from Richard Guenther rguenth at gcc dot gnu.org 2012-01-10 16:30:30 UTC --- (In reply to comment #16) (In reply to comment #15) (In reply to comment #14) (In reply to comment #13) We can't optimize this because System.out.println can change args[]. That's the whole point: System.out.println cannot change args[], which is a java array, and the length of a Java array is constant. It is not an invalid test case. I suppose public static void main(String[] args) is passing args by value (but the implementation detail uses reference passing for efficiency?). args is indeed a reference to a Java array. The length field of a Java array is immutable. The elements of an array are not immutable. You mean that System.out.println could change the elements of the array (well, it doesn't, but theoretically it could)? In this case the Java frontend should do like the C++ frontend and tell this to the middle-end by properly marking args as 1) DECL_BY_REFERENCE, 2) use a TYPE_RESTRICT qualified pointer for the reference. Then we would optimize this case. If we could mark the length field as immutable that would fix it. Is there any way to do that? No. What you can do is, via the method I outlined, tell GCC that args is to be treated similar to a local automatic variable - thus it cannot be refered to from other functions (unless you pass them its address of course).
[Bug java/21855] array bounds checking elimination
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=21855 --- Comment #18 from Richard Guenther rguenth at gcc dot gnu.org 2012-01-10 16:35:46 UTC --- (In reply to comment #17) (In reply to comment #16) (In reply to comment #15) (In reply to comment #14) (In reply to comment #13) We can't optimize this because System.out.println can change args[]. That's the whole point: System.out.println cannot change args[], which is a java array, and the length of a Java array is constant. It is not an invalid test case. I suppose public static void main(String[] args) is passing args by value (but the implementation detail uses reference passing for efficiency?). args is indeed a reference to a Java array. The length field of a Java array is immutable. The elements of an array are not immutable. You mean that System.out.println could change the elements of the array (well, it doesn't, but theoretically it could)? In this case the Java frontend should do like the C++ frontend and tell this to the middle-end by properly marking args as 1) DECL_BY_REFERENCE, 2) use a TYPE_RESTRICT qualified pointer for the reference. Then we would optimize this case. If we could mark the length field as immutable that would fix it. Is there any way to do that? No. What you can do is, via the method I outlined, tell GCC that args is to be treated similar to a local automatic variable - thus it cannot be refered to from other functions (unless you pass them its address of course). Thus, similar to the C++ case with struct Array { int length; void data[]; } void foo (Array args) { ... } foo cannot change the callers args.length (only its own copy) but it can change the callers args.data[] contents. If the C++ frontend decides to pass args by reference then it sets DECL_BY_REFERENCE and uses a TYPE_RESTRICT qualified pointer. This way the optimization will be the same as if it was passed really by value. Not sure if the Java situation is similar enough.
[Bug java/21855] array bounds checking elimination
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=21855 --- Comment #19 from Andrew Haley aph at gcc dot gnu.org 2012-01-10 16:44:16 UTC --- (In reply to comment #17) (In reply to comment #16) (In reply to comment #15) (In reply to comment #14) (In reply to comment #13) We can't optimize this because System.out.println can change args[]. That's the whole point: System.out.println cannot change args[], which is a java array, and the length of a Java array is constant. It is not an invalid test case. I suppose public static void main(String[] args) is passing args by value (but the implementation detail uses reference passing for efficiency?). args is indeed a reference to a Java array. The length field of a Java array is immutable. The elements of an array are not immutable. You mean that System.out.println could change the elements of the array (well, it doesn't, but theoretically it could)? In theory yes, it could. In this case the Java frontend should do like the C++ frontend and tell this to the middle-end by properly marking args as 1) DECL_BY_REFERENCE, 2) use a TYPE_RESTRICT qualified pointer for the reference. Then we would optimize this case. If we could mark the length field as immutable that would fix it. Is there any way to do that? No. What you can do is, via the method I outlined, tell GCC that args is to be treated similar to a local automatic variable - thus it cannot be refered to from other functions (unless you pass them its address of course). But that doesn't help. args *can* potentially be referred to by other functions. The special property we need to make use of its that fact that once an array is created, its length can never change.
[Bug java/21855] array bounds checking elimination
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=21855 --- Comment #21 from Richard Guenther rguenth at gcc dot gnu.org 2012-01-10 16:57:36 UTC --- The Java frontend could handle this by performing loads of the length field via a SAVE_EXPR and sharing this across a function. That way CSE would happen automagically.
[Bug java/21855] array bounds checking elimination
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=21855 --- Comment #20 from Richard Guenther rguenth at gcc dot gnu.org 2012-01-10 16:55:52 UTC --- (In reply to comment #19) No. What you can do is, via the method I outlined, tell GCC that args is to be treated similar to a local automatic variable - thus it cannot be refered to from other functions (unless you pass them its address of course). But that doesn't help. args *can* potentially be referred to by other functions. The special property we need to make use of its that fact that once an array is created, its length can never change. That is something we cannot express at the moment, and I think it would be hard to implement reliably (thinking of the RTX_UNCHANGING saga - we do have to exclude the stmts that initialize the length field).
[Bug java/21855] array bounds checking elimination
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=21855 --- Comment #22 from Andrew Haley aph at gcc dot gnu.org 2012-01-10 17:08:30 UTC --- (In reply to comment #21) The Java frontend could handle this by performing loads of the length field via a SAVE_EXPR and sharing this across a function. That way CSE would happen automagically. Now that's a nice idea. In this specific case it should be easy, because array.length is used in the control expression for the loop. So. we can create the SAVE_EXPR when the loop is initialized. The problem with doing this in general is that we don't have a CFG, so we don't always know when to create that SAVE_EXPR. If we can find an initial use of an array that dominates all other uses we can create the SAVE_EXPR at that point.
[Bug java/21855] array bounds checking elimination
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=21855 --- Comment #23 from Tom Tromey tromey at gcc dot gnu.org 2012-01-10 17:17:50 UTC --- I thought I wrote a pass to do this optimization, but I can't find it now. Anyway I think that would be the simplest approach by far.
[Bug java/21855] array bounds checking elimination
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=21855 --- Comment #24 from Tom Tromey tromey at gcc dot gnu.org 2012-01-10 17:21:02 UTC --- I found my code and it turns out I never finished it. (I did write a java-specific devirtualization pass.) Here is an introductory comment that explains my plans: /* This pass implements a few simple gcj-specific optimizations related to handling of invariants. In Java, certain fields of some objects are known to be invariant after the object has been created. For instance, the vtable pointer of an object cannot change; neither can the length of an array. Also, this pass knows that 'new Type[n]' sets the length of an array to 'n'. Ideally GCC would recognize these cases and optimize for us. However, currently there is no way to express these properties to the optimizers. */