RFR(M): 8080289: Intermediate writes in a loop not eliminated by optimizer

Vladimir Kozlov vladimir.kozlov at oracle.com
Wed Jun 10 19:31:20 UTC 2015


We don't call previous node as 'user' - we call them definitions or 
inputs. Your comment change in memnode.cpp sound strange because of 
that. The original statement was correct:
// If anybody other than 'this' uses 'mem', we cannot fold 'mem' away.

in your case it will be:

// If anybody other than 'this' uses 'st', we cannot fold 'st' away.

Also code does not seems right. The code should go through input memory 
chain and remove all preceding similar stores - 'this' node remains and 
we change its memory input which makes previous stores dead. So you 
can't do 'prev = st'.

You need to set improved = true since 'this' will not change. We also 
use 'make_progress' variable's name in such cases.

I try_move_store_before_loop() add check (n_loop->_head == n_ctrl) to 
make sure it is not other control node inside loop. Then you can check 
Phi's control as (mem->in(0) == n_ctrl).

I don't understand verification code "Check that store's control does 
post dominate loop entry". In first comment you said "Store has to be 
first in the loop body" - I understand this as Store's control should be 
loop's head. You can't allow store to be on one of branches (it will not 
post dominate) but your check code allow that. Also the check done only 
in debug VM.

If you really want to accept cases when a store is placed after diamond 
control then you need checks in product to make sure that it is really 
post dominate head. For that I think you need to go from loopend to 
loophead through idom links and see if you meet n_ctrl.

I don't see assert(n->in(0) in try_move_store_before_loop() but you have 
it in try_move_store_after_loop().

Why you need next assert?:
+         assert(n_loop != address_loop, "address is loop varying");

Should you check phi == NULL instead of assert to make sure you have 
only one Phi node?

conflict between assert and following check:
+               assert(new_loop->_child != NULL, "");
+               if (new_loop->_child == NULL) new_loop->_body.push(st);

Thanks,
Vladimir

On 6/10/15 8:03 AM, Roland Westrelin wrote:
> http://cr.openjdk.java.net/~roland/8080289/webrev.00/
>
> Sink stores out of loops when possible:
>
> for (int i = 0; i < 1000; i++) {
>      // Some stuff that doesn’t prevent the optimization
>      array[idx] = i;
> }
>
> becomes:
>
> for (int i = 0; i < 1000; i++) {
>      // Some stuff
> }
> array[idx] = 999;
>
> Or move stores before the loop when possible:
>
> for (int i = 0; i < 1000; i++) {
>      array[idx] = 999;
>      // Some stuff that doesn’t prevent the optimization
> }
>
> becomes:
>
> array[idx] = 999;
> for (int i = 0; i < 1000; i++) {
>      // Some stuff
> }
>
> The change in memnode.cpp is useful to clean up code generated from test_after_5 because the stores are moved out of the loop only after the loop is split and unrolled. That code removes duplicate stores.
>
> Roland.
>


More information about the hotspot-compiler-dev mailing list