RFR(S): 8078866: compiler/eliminateAutobox/6934604/TestIntBoxing.java assert(p_f->Opcode() == Op_IfFalse) failed
Vladimir Kozlov
vladimir.kozlov at oracle.com
Wed May 13 21:28:02 UTC 2015
Why do you think that main- and post- loops will be empty too and it is
safe to replace them with pre-loop? Why it is safe?
Opaque1 node is used only when RCE and align is requsted:
cmp_end->set_req(2, peel_only ? pre_limit : pre_opaq);
In peel_only case pre-loop have only 1 iteration and can be eliminated
too. The assert could be hit in such case too. So your change may not
fix the problem.
I think eliminating main- and post- is good investigation for separate
RFE. And we need to make sure it is safe.
To fix this bug, I think, we should bailout from do_range_check() when
we can't find pre-loop.
Typo 'cab':
+ // post loop cab be removed as well
Thanks,
Vladimir
On 5/13/15 6:02 AM, Roland Westrelin wrote:
> http://cr.openjdk.java.net/~roland/8078866/webrev.00/
>
> The assert fires when optimizing that code:
>
> static int remi_sumb() {
> Integer j = Integer.valueOf(1);
> for (int i = 0; i< 1000; i++) {
> j = j + 1;
> }
> return j;
> }
>
> The compiler tries to find the pre loop from the main loop but fails because the pre loop isn’t there.
>
> Here is the chain of events that leads to the pre loop being optimized out:
>
> 1- The CountedLoopNode is created
> 2- PhiNode::Value() for the induction variable’s Phi is called and capture that 0 <= i < 1000
> 3- SplitIf is applied and moves the LoadI that reads the value from the Integer through the Phi that merges successive value of j
> 4- pre-loop, main-loop, post-loop are created
> 5- SplitIf is applied again and moves the LoadI of the loop through the Phi that merges both branches of:
>
> public static Integer valueOf(int i) {
> if (i >= IntegerCache.low && i <= IntegerCache.high)
> return IntegerCache.cache[i + (-IntegerCache.low)];
> return new Integer(i);
> }
>
> 6- The LoadI is optimized out, the Phi for j is now a Phi that merges integer values, PhaseIdealLoop::replace_parallel_iv() replaces j by an expression that depends on i
> 7- In the preloop, the range of values of i are known because of 2- so and the if of valueOf() can be optimized out
> 8- the preloop is empty and is removed by IdealLoopTree::policy_do_remove_empty_loop()
>
> SplitIf doesn’t find all opportunities for improvements before the pre/main/post loops are built. I considered trying to fix that but that seems complex and not robust enough: some optimizations after SplitIf could uncover more opportunities for SplitIf. The valueOf’s if cannot be optimized out in the main loop because the range of values of i in the main depends on the Phi for the iv of the pre loop and is not [0, 1000[ so I don’t see a way to make sure the compiler always optimizes the main loop out when the pre loop is empty.
>
> Instead, I’m proposing that when IdealLoopTree::policy_do_remove_empty_loop() removes a loop, it checks whether it is a pre-loop and if it is, removes the main and post loops.
>
> I don’t have a test case because it seems this only occurs under well defined conditions that are hard to reproduce with a simple test case: PhiNode::Value() must be called early, SplitIf must do a little work but not too much before pre/main/post loops are built. Actually, this occurs only when remi_sumb is inlined. If remi_sumb is not, we don’t optimize the loop out at all.
>
> Roland.
>
More information about the hotspot-compiler-dev
mailing list