Request for reviews (M): 6957939: Reduce registers usage by DecodeN/EncodeP

Vladimir Kozlov vladimir.kozlov at
Thu Jun 3 18:13:50 PDT 2010

Tom Rodriguez wrote:
> It might be nice to use this with Conv's as well.  Maybe we should have a new Node flag to tag nodes that have this copy like behaviour.

Yes, it is good idea and I tried CastX2P/CastP2X but I am concern about next comment in PhaseCoalesce::combine_these_two():

     // Not an oop->int cast; oop->oop, int->int, AND int->oop are OK.

     // Now, why is int->oop OK?  We end up declaring a raw-pointer as an oop
     // and in general that's a bad thing.  However, int->oop conversions only
     // happen at GC points, so the lifetime of the misclassified raw-pointer
     // is from the CheckCastPP (that converts it to an oop) backwards up
     // through a merge point and into the slow-path call, and around the
     // diamond up to the heap-top check and back down into the slow-path call.
     // The misclassified raw pointer is NOT live across the slow-path call,
     // and so does not appear in any GC info, so the fact that it is
     // misclassified is OK.

and in adlc/formssel.cpp (btw we don't have CastIP node anymore):

int MatchRule::is_ideal_copy() const {
   if( _rChild ) {
     const char  *opType = _rChild->_opType;
#if 1
     if( strcmp(opType,"CastIP")==0 )
       return 1;
     if( strcmp(opType,"CastII")==0 )
       return 1;
     // Do not treat *CastPP this way, because it
     // may transfer a raw pointer to an oop.
     // If the register allocator were to coalesce this
     // into a single LRG, the GC maps would be incorrect.
     //if( strcmp(opType,"CastPP")==0 )
     //  return 1;
     //if( strcmp(opType,"CheckCastPP")==0 )
     //  return 1;
     // Do not treat CastX2P or CastP2X this way, because
     // raw pointers and int types are treated differently
     // when saving local & stack info for safepoints in
     // Output().
     //if( strcmp(opType,"CastX2P")==0 )
     //  return 1;
     //if( strcmp(opType,"CastP2X")==0 )
     //  return 1;

>  Can we avoid doing a whole second pass over the instruction to record the bias, maybe by tagging LRGs as copy LRGs and overwriting non-copy LRGs in record_bias?

record_bias() is called only for SpillCopy nodes. I tried to do it in Conservative coalesce() but it is not called before Select() if there are no spills. And I am concern about putting the code into build_ifg_physical() since it removes nodes.
Also I am not sure who should have priority in copy bias: SpillCopy nodes or DecodeN/EncodeP.


> tom
> On Jun 3, 2010, at 2:33 PM, Vladimir Kozlov wrote:
>> Fixed 6957939: Reduce registers usage by DecodeN/EncodeP
>> DecodeN/EncodeP usually produce result in the different
>> from input register because types difference (32bit narrow
>> oop vs 64bit oop).
>> Try to reuse input regiser for result if DecodeN/EncodeP is
>> the only user by recording bias for input and ouput lrgs.
>> It is done after copy bias for spill copies was recorded
>> so they will get priority since only one copy bias could
>> be recorded.
>> Tested with CTW, GCBasher with +VerifyOops.

More information about the hotspot-compiler-dev mailing list