C2: cyclic IR for JVMS

Vladimir Ivanov vladimir.x.ivanov at oracle.com
Thu Dec 18 19:11:15 UTC 2014


Roland,

The code is reachable by the time inlining occurs, but the call node is 
broken.

The transformation which breaks the code is performed in 
RegionNode::Ideal()
Phi (Region) (Proj #5 (CallStaticJava ... Phi(backref)...))
==>
(Proj #5 (CallStaticJava ... Proj(backref)...))

The RegionNode and Phi are removed, but CallStaticJava is broken.

It seems that if RegionNode::is_unreachable_region() detected that 
RegionNode is dead, it would break the vicious circle (PhiNode is 
replaced by top()).

Not sure why the call node is live, though the loop was dead.

Best regards,
Vladimir Ivanov

On 12/18/14, 8:25 PM, Roland Westrelin wrote:
>> As my investigations show, it's a leftover from a loop.
>> CallStaticJava represents loop counter increment.
>>
>> The graph is as follows:
>> Phi (Region) (Proj #5 (CallStaticJava ... Phi(backref)...))
>>
>> The Region is dead, but RegionNode::is_unreachable_region doesn't detect that. Node::simple_data_loop_check(Phi, Proj) doesn't find the cycle, because most of Proj nodes have Flag_is_dead_loop_safe set [1].
>> And I don't understand why it is so. Is the check in Node::is_dead_loop_safe() too weak or Flag_is_dead_loop_safe too "optimistic"? :-)
>
> Isn’t the problem that you try to late inline a call that is dead and that the checks in LateInlineCallGenerator::do_late_inline():
>
>    if (call == NULL || call->outcnt() == 0 ||
>        call->in(0) == NULL || call->in(0)->is_top()) {
>      return;
>    }
>
>    const TypeTuple *r = call->tf()->domain();
>    for (int i1 = 0; i1 < method()->arg_size(); i1++) {
>      if (call->in(TypeFunc::Parms + i1)->is_top() && r->field_at(TypeFunc::Parms + i1) != Type::HALF) {
>        assert(Compile::current()->inlining_incrementally(), "shouldn't happen during parsing");
>        return;
>      }
>    }
>
>    if (call->in(TypeFunc::Memory)->is_top()) {
>      assert(Compile::current()->inlining_incrementally(), "shouldn't happen during parsing");
>      return;
>    }
>
> don’t detect it?
> FWIW, I know there are rare cases where those tests are not sufficient. Ideally, you would need  Compile::inline_incrementally() to do:
> PhaseIdealLoop ideal_loop( igvn, false, true );
> after every inline but that’s very expensive.
>
> Roland.
>


More information about the hotspot-compiler-dev mailing list