src/share/vm/opto/matcher.cpp

changeset 803
36ccc817fca4
parent 802
194b8e3a2fc4
child 855
a1980da045cc
     1.1 --- a/src/share/vm/opto/matcher.cpp	Wed Sep 17 12:59:52 2008 -0700
     1.2 +++ b/src/share/vm/opto/matcher.cpp	Tue Sep 23 12:29:06 2008 -0700
     1.3 @@ -840,7 +840,7 @@
     1.4                _new2old_map.map(m->_idx, n);
     1.5  #endif
     1.6                if (m->in(0) != NULL) // m might be top
     1.7 -                collect_null_checks(m);
     1.8 +                collect_null_checks(m, n);
     1.9              } else {                // Else just a regular 'ol guy
    1.10                m = n->clone();       // So just clone into new-space
    1.11  #ifdef ASSERT
    1.12 @@ -1478,12 +1478,19 @@
    1.13          m = _mem_node;
    1.14          assert(m != NULL && m->is_Mem(), "expecting memory node");
    1.15        }
    1.16 -      if (m->adr_type() != mach->adr_type()) {
    1.17 +      const Type* mach_at = mach->adr_type();
    1.18 +      // DecodeN node consumed by an address may have different type
    1.19 +      // then its input. Don't compare types for such case.
    1.20 +      if (m->adr_type() != mach_at && m->in(MemNode::Address)->is_AddP() &&
    1.21 +          m->in(MemNode::Address)->in(AddPNode::Address)->is_DecodeN()) {
    1.22 +        mach_at = m->adr_type();
    1.23 +      }
    1.24 +      if (m->adr_type() != mach_at) {
    1.25          m->dump();
    1.26          tty->print_cr("mach:");
    1.27          mach->dump(1);
    1.28        }
    1.29 -      assert(m->adr_type() == mach->adr_type(), "matcher should not change adr type");
    1.30 +      assert(m->adr_type() == mach_at, "matcher should not change adr type");
    1.31      }
    1.32  #endif
    1.33    }
    1.34 @@ -1995,7 +2002,7 @@
    1.35  // it.  Used by later implicit-null-check handling.  Actually collects
    1.36  // either an IfTrue or IfFalse for the common NOT-null path, AND the ideal
    1.37  // value being tested.
    1.38 -void Matcher::collect_null_checks( Node *proj ) {
    1.39 +void Matcher::collect_null_checks( Node *proj, Node *orig_proj ) {
    1.40    Node *iff = proj->in(0);
    1.41    if( iff->Opcode() == Op_If ) {
    1.42      // During matching If's have Bool & Cmp side-by-side
    1.43 @@ -2008,20 +2015,47 @@
    1.44      if (ct == TypePtr::NULL_PTR ||
    1.45          (opc == Op_CmpN && ct == TypeNarrowOop::NULL_PTR)) {
    1.46  
    1.47 +      bool push_it = false;
    1.48        if( proj->Opcode() == Op_IfTrue ) {
    1.49          extern int all_null_checks_found;
    1.50          all_null_checks_found++;
    1.51          if( b->_test._test == BoolTest::ne ) {
    1.52 -          _null_check_tests.push(proj);
    1.53 -          _null_check_tests.push(cmp->in(1));
    1.54 +          push_it = true;
    1.55          }
    1.56        } else {
    1.57          assert( proj->Opcode() == Op_IfFalse, "" );
    1.58          if( b->_test._test == BoolTest::eq ) {
    1.59 -          _null_check_tests.push(proj);
    1.60 -          _null_check_tests.push(cmp->in(1));
    1.61 +          push_it = true;
    1.62          }
    1.63        }
    1.64 +      if( push_it ) {
    1.65 +        _null_check_tests.push(proj);
    1.66 +        Node* val = cmp->in(1);
    1.67 +#ifdef _LP64
    1.68 +        if (UseCompressedOops && !Matcher::clone_shift_expressions &&
    1.69 +            val->bottom_type()->isa_narrowoop()) {
    1.70 +          //
    1.71 +          // Look for DecodeN node which should be pinned to orig_proj.
    1.72 +          // On platforms (Sparc) which can not handle 2 adds
    1.73 +          // in addressing mode we have to keep a DecodeN node and
    1.74 +          // use it to do implicit NULL check in address.
    1.75 +          //
    1.76 +          // DecodeN node was pinned to non-null path (orig_proj) during
    1.77 +          // CastPP transformation in final_graph_reshaping_impl().
    1.78 +          //
    1.79 +          uint cnt = orig_proj->outcnt();
    1.80 +          for (uint i = 0; i < orig_proj->outcnt(); i++) {
    1.81 +            Node* d = orig_proj->raw_out(i);
    1.82 +            if (d->is_DecodeN() && d->in(1) == val) {
    1.83 +              val = d;
    1.84 +              val->set_req(0, NULL); // Unpin now.
    1.85 +              break;
    1.86 +            }
    1.87 +          }
    1.88 +        }
    1.89 +#endif
    1.90 +        _null_check_tests.push(val);
    1.91 +      }
    1.92      }
    1.93    }
    1.94  }

mercurial