C2: cyclic IR for JVMS
Vladimir Kozlov
vladimir.kozlov at oracle.com
Fri Dec 19 20:35:11 UTC 2014
Did you find why "the call node is live, though the loop was dead"?
I think I assumed that calls are safe - can't be in dead loop.
Your fix is reasonable but, first, fins why call is alive.
Thanks,
Vladimir
On 12/19/14 7:46 AM, Vladimir Ivanov wrote:
> So, if return value projection is not considered dead loop safe [1], the
> problem goes away.
>
> I'm curious whether it was an overlook in 6625997 [1] [2].
>
> Best regards,
> Vladimir Ivanov
>
> [1]
> diff --git a/src/share/vm/opto/multnode.hpp
> b/src/share/vm/opto/multnode.hpp
> --- a/src/share/vm/opto/multnode.hpp
> +++ b/src/share/vm/opto/multnode.hpp
> @@ -68,7 +68,7 @@
> {
> init_class_id(Class_Proj);
> // Optimistic setting. Need additional checks in
> Node::is_dead_loop_safe().
> - if (con != TypeFunc::Memory || src->is_Start())
> + if ((con != TypeFunc::Memory && con != TypeFunc::Parms) ||
> src->is_Start())
> init_flags(Flag_is_dead_loop_safe);
> debug_only(check_con());
> }
>
> [2] https://jbs.oracle.com/bugs/browse/JDK-6625997
> [3]
> http://hg.openjdk.java.net/jdk9/hs-comp/hotspot/diff/72f4a668df19/src/share/vm/opto/multnode.hpp
>
>
> On 12/18/14 10:11 PM, Vladimir Ivanov wrote:
>> 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