src/share/vm/opto/lcm.cpp

changeset 1934
e9ff18c4ace7
parent 1907
c18cbe5936b8
parent 1930
3657cb01ffc5
child 2040
0e35fa8ebccd
     1.1 --- a/src/share/vm/opto/lcm.cpp	Tue Jun 01 11:48:33 2010 -0700
     1.2 +++ b/src/share/vm/opto/lcm.cpp	Wed Jun 02 22:45:42 2010 -0700
     1.3 @@ -32,7 +32,8 @@
     1.4  // with suitable memory ops nearby.  Use the memory op to do the NULL check.
     1.5  // I can generate a memory op if there is not one nearby.
     1.6  // The proj is the control projection for the not-null case.
     1.7 -// The val is the pointer being checked for nullness.
     1.8 +// The val is the pointer being checked for nullness or
     1.9 +// decodeHeapOop_not_null node if it did not fold into address.
    1.10  void Block::implicit_null_check(PhaseCFG *cfg, Node *proj, Node *val, int allowed_reasons) {
    1.11    // Assume if null check need for 0 offset then always needed
    1.12    // Intel solaris doesn't support any null checks yet and no
    1.13 @@ -96,6 +97,13 @@
    1.14      }
    1.15    }
    1.16  
    1.17 +  // Check for decodeHeapOop_not_null node which did not fold into address
    1.18 +  bool is_decoden = ((intptr_t)val) & 1;
    1.19 +  val = (Node*)(((intptr_t)val) & ~1);
    1.20 +
    1.21 +  assert(!is_decoden || (val->in(0) == NULL) && val->is_Mach() &&
    1.22 +         (val->as_Mach()->ideal_Opcode() == Op_DecodeN), "sanity");
    1.23 +
    1.24    // Search the successor block for a load or store who's base value is also
    1.25    // the tested value.  There may be several.
    1.26    Node_List *out = new Node_List(Thread::current()->resource_area());
    1.27 @@ -148,7 +156,8 @@
    1.28        if( !mach->needs_anti_dependence_check() )
    1.29          continue;               // Not an memory op; skip it
    1.30        {
    1.31 -        // Check that value is used in memory address.
    1.32 +        // Check that value is used in memory address in
    1.33 +        // instructions with embedded load (CmpP val1,(val2+off)).
    1.34          Node* base;
    1.35          Node* index;
    1.36          const MachOper* oper = mach->memory_inputs(base, index);
    1.37 @@ -213,7 +222,11 @@
    1.38      uint vidx = 0;              // Capture index of value into memop
    1.39      uint j;
    1.40      for( j = mach->req()-1; j > 0; j-- ) {
    1.41 -      if( mach->in(j) == val ) vidx = j;
    1.42 +      if( mach->in(j) == val ) {
    1.43 +        vidx = j;
    1.44 +        // Ignore DecodeN val which could be hoisted to where needed.
    1.45 +        if( is_decoden ) continue;
    1.46 +      }
    1.47        // Block of memory-op input
    1.48        Block *inb = cfg->_bbs[mach->in(j)->_idx];
    1.49        Block *b = this;          // Start from nul check
    1.50 @@ -270,6 +283,26 @@
    1.51    extern int implicit_null_checks;
    1.52    implicit_null_checks++;
    1.53  
    1.54 +  if( is_decoden ) {
    1.55 +    // Check if we need to hoist decodeHeapOop_not_null first.
    1.56 +    Block *valb = cfg->_bbs[val->_idx];
    1.57 +    if( this != valb && this->_dom_depth < valb->_dom_depth ) {
    1.58 +      // Hoist it up to the end of the test block.
    1.59 +      valb->find_remove(val);
    1.60 +      this->add_inst(val);
    1.61 +      cfg->_bbs.map(val->_idx,this);
    1.62 +      // DecodeN on x86 may kill flags. Check for flag-killing projections
    1.63 +      // that also need to be hoisted.
    1.64 +      for (DUIterator_Fast jmax, j = val->fast_outs(jmax); j < jmax; j++) {
    1.65 +        Node* n = val->fast_out(j);
    1.66 +        if( n->Opcode() == Op_MachProj ) {
    1.67 +          cfg->_bbs[n->_idx]->find_remove(n);
    1.68 +          this->add_inst(n);
    1.69 +          cfg->_bbs.map(n->_idx,this);
    1.70 +        }
    1.71 +      }
    1.72 +    }
    1.73 +  }
    1.74    // Hoist the memory candidate up to the end of the test block.
    1.75    Block *old_block = cfg->_bbs[best->_idx];
    1.76    old_block->find_remove(best);

mercurial