src/share/vm/opto/lcm.cpp
Index Unified diffs Context diffs Sdiffs Wdiffs Patch New Old Previous File Next File 6954029 Sdiff src/share/vm/opto

src/share/vm/opto/lcm.cpp

Print this page




  15  * You should have received a copy of the GNU General Public License version
  16  * 2 along with this work; if not, write to the Free Software Foundation,
  17  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  18  *
  19  * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
  20  * CA 95054 USA or visit www.sun.com if you need additional information or
  21  * have any questions.
  22  *
  23  */
  24 
  25 // Optimization - Graph Style
  26 
  27 #include "incls/_precompiled.incl"
  28 #include "incls/_lcm.cpp.incl"
  29 
  30 //------------------------------implicit_null_check----------------------------
  31 // Detect implicit-null-check opportunities.  Basically, find NULL checks
  32 // with suitable memory ops nearby.  Use the memory op to do the NULL check.
  33 // I can generate a memory op if there is not one nearby.
  34 // The proj is the control projection for the not-null case.
  35 // The val is the pointer being checked for nullness.

  36 void Block::implicit_null_check(PhaseCFG *cfg, Node *proj, Node *val, int allowed_reasons) {
  37   // Assume if null check need for 0 offset then always needed
  38   // Intel solaris doesn't support any null checks yet and no
  39   // mechanism exists (yet) to set the switches at an os_cpu level
  40   if( !ImplicitNullChecks || MacroAssembler::needs_explicit_null_check(0)) return;
  41 
  42   // Make sure the ptr-is-null path appears to be uncommon!
  43   float f = end()->as_MachIf()->_prob;
  44   if( proj->Opcode() == Op_IfTrue ) f = 1.0f - f;
  45   if( f > PROB_UNLIKELY_MAG(4) ) return;
  46 
  47   uint bidx = 0;                // Capture index of value into memop
  48   bool was_store;               // Memory op is a store op
  49 
  50   // Get the successor block for if the test ptr is non-null
  51   Block* not_null_block;  // this one goes with the proj
  52   Block* null_block;
  53   if (_nodes[_nodes.size()-1] == proj) {
  54     null_block     = _succs[0];
  55     not_null_block = _succs[1];


  79           Deoptimization::DeoptReason reason = Deoptimization::trap_request_reason(tr_con);
  80           Deoptimization::DeoptAction action = Deoptimization::trap_request_action(tr_con);
  81           assert((int)reason < (int)BitsPerInt, "recode bit map");
  82           if (is_set_nth_bit(allowed_reasons, (int) reason)
  83               && action != Deoptimization::Action_none) {
  84             // This uncommon trap is sure to recompile, eventually.
  85             // When that happens, C->too_many_traps will prevent
  86             // this transformation from happening again.
  87             found_trap = true;
  88           }
  89         }
  90         break;
  91       }
  92     }
  93     if (!found_trap) {
  94       // We did not find an uncommon trap.
  95       return;
  96     }
  97   }
  98 




  99   // Search the successor block for a load or store who's base value is also
 100   // the tested value.  There may be several.
 101   Node_List *out = new Node_List(Thread::current()->resource_area());
 102   MachNode *best = NULL;        // Best found so far
 103   for (DUIterator i = val->outs(); val->has_out(i); i++) {
 104     Node *m = val->out(i);
 105     if( !m->is_Mach() ) continue;
 106     MachNode *mach = m->as_Mach();
 107     was_store = false;
 108     switch( mach->ideal_Opcode() ) {
 109     case Op_LoadB:
 110     case Op_LoadUS:
 111     case Op_LoadD:
 112     case Op_LoadF:
 113     case Op_LoadI:
 114     case Op_LoadL:
 115     case Op_LoadP:
 116     case Op_LoadN:
 117     case Op_LoadS:
 118     case Op_LoadKlass:


 131     case Op_StoreL:
 132     case Op_StoreP:
 133     case Op_StoreN:
 134       was_store = true;         // Memory op is a store op
 135       // Stores will have their address in slot 2 (memory in slot 1).
 136       // If the value being nul-checked is in another slot, it means we
 137       // are storing the checked value, which does NOT check the value!
 138       if( mach->in(2) != val ) continue;
 139       break;                    // Found a memory op?
 140     case Op_StrComp:
 141     case Op_StrEquals:
 142     case Op_StrIndexOf:
 143     case Op_AryEq:
 144       // Not a legit memory op for implicit null check regardless of
 145       // embedded loads
 146       continue;
 147     default:                    // Also check for embedded loads
 148       if( !mach->needs_anti_dependence_check() )
 149         continue;               // Not an memory op; skip it
 150       {
 151         // Check that value is used in memory address.

 152         Node* base;
 153         Node* index;
 154         const MachOper* oper = mach->memory_inputs(base, index);
 155         if (oper == NULL || oper == (MachOper*)-1) {
 156           continue;             // Not an memory op; skip it
 157         }
 158         if (val == base ||
 159             val == index && val->bottom_type()->isa_narrowoop()) {
 160           break;                // Found it
 161         } else {
 162           continue;             // Skip it
 163         }
 164       }
 165       break;
 166     }
 167     // check if the offset is not too high for implicit exception
 168     {
 169       intptr_t offset = 0;
 170       const TypePtr *adr_type = NULL;  // Do not need this return value here
 171       const Node* base = mach->get_base_and_disp(offset, adr_type);


 196     // Check ctrl input to see if the null-check dominates the memory op
 197     Block *cb = cfg->_bbs[mach->_idx];
 198     cb = cb->_idom;             // Always hoist at least 1 block
 199     if( !was_store ) {          // Stores can be hoisted only one block
 200       while( cb->_dom_depth > (_dom_depth + 1))
 201         cb = cb->_idom;         // Hoist loads as far as we want
 202       // The non-null-block should dominate the memory op, too. Live
 203       // range spilling will insert a spill in the non-null-block if it is
 204       // needs to spill the memory op for an implicit null check.
 205       if (cb->_dom_depth == (_dom_depth + 1)) {
 206         if (cb != not_null_block) continue;
 207         cb = cb->_idom;
 208       }
 209     }
 210     if( cb != this ) continue;
 211 
 212     // Found a memory user; see if it can be hoisted to check-block
 213     uint vidx = 0;              // Capture index of value into memop
 214     uint j;
 215     for( j = mach->req()-1; j > 0; j-- ) {
 216       if( mach->in(j) == val ) vidx = j;




 217       // Block of memory-op input
 218       Block *inb = cfg->_bbs[mach->in(j)->_idx];
 219       Block *b = this;          // Start from nul check
 220       while( b != inb && b->_dom_depth > inb->_dom_depth )
 221         b = b->_idom;           // search upwards for input
 222       // See if input dominates null check
 223       if( b != inb )
 224         break;
 225     }
 226     if( j > 0 )
 227       continue;
 228     Block *mb = cfg->_bbs[mach->_idx];
 229     // Hoisting stores requires more checks for the anti-dependence case.
 230     // Give up hoisting if we have to move the store past any load.
 231     if( was_store ) {
 232       Block *b = mb;            // Start searching here for a local load
 233       // mach use (faulting) trying to hoist
 234       // n might be blocker to hoisting
 235       while( b != this ) {
 236         uint k;


 254     if( e->is_MachNullCheck() && e->in(1) == mach )
 255       continue;                 // Already being used as a NULL check
 256 
 257     // Found a candidate!  Pick one with least dom depth - the highest
 258     // in the dom tree should be closest to the null check.
 259     if( !best ||
 260         cfg->_bbs[mach->_idx]->_dom_depth < cfg->_bbs[best->_idx]->_dom_depth ) {
 261       best = mach;
 262       bidx = vidx;
 263 
 264     }
 265   }
 266   // No candidate!
 267   if( !best ) return;
 268 
 269   // ---- Found an implicit null check
 270   extern int implicit_null_checks;
 271   implicit_null_checks++;
 272 
 273   // Hoist the memory candidate up to the end of the test block.









 274   Block *old_block = cfg->_bbs[best->_idx];
 275   old_block->find_remove(best);
 276   add_inst(best);
 277   cfg->_bbs.map(best->_idx,this);
 278 
 279   // Move the control dependence
 280   if (best->in(0) && best->in(0) == old_block->_nodes[0])
 281     best->set_req(0, _nodes[0]);
 282 
 283   // Check for flag-killing projections that also need to be hoisted
 284   // Should be DU safe because no edge updates.
 285   for (DUIterator_Fast jmax, j = best->fast_outs(jmax); j < jmax; j++) {
 286     Node* n = best->fast_out(j);
 287     if( n->Opcode() == Op_MachProj ) {
 288       cfg->_bbs[n->_idx]->find_remove(n);
 289       add_inst(n);
 290       cfg->_bbs.map(n->_idx,this);
 291     }
 292   }
 293 




  15  * You should have received a copy of the GNU General Public License version
  16  * 2 along with this work; if not, write to the Free Software Foundation,
  17  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  18  *
  19  * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
  20  * CA 95054 USA or visit www.sun.com if you need additional information or
  21  * have any questions.
  22  *
  23  */
  24 
  25 // Optimization - Graph Style
  26 
  27 #include "incls/_precompiled.incl"
  28 #include "incls/_lcm.cpp.incl"
  29 
  30 //------------------------------implicit_null_check----------------------------
  31 // Detect implicit-null-check opportunities.  Basically, find NULL checks
  32 // with suitable memory ops nearby.  Use the memory op to do the NULL check.
  33 // I can generate a memory op if there is not one nearby.
  34 // The proj is the control projection for the not-null case.
  35 // The val is the pointer being checked for nullness or
  36 // decodeHeapOop_not_null node if it did not fold into address. 
  37 void Block::implicit_null_check(PhaseCFG *cfg, Node *proj, Node *val, int allowed_reasons) {
  38   // Assume if null check need for 0 offset then always needed
  39   // Intel solaris doesn't support any null checks yet and no
  40   // mechanism exists (yet) to set the switches at an os_cpu level
  41   if( !ImplicitNullChecks || MacroAssembler::needs_explicit_null_check(0)) return;
  42 
  43   // Make sure the ptr-is-null path appears to be uncommon!
  44   float f = end()->as_MachIf()->_prob;
  45   if( proj->Opcode() == Op_IfTrue ) f = 1.0f - f;
  46   if( f > PROB_UNLIKELY_MAG(4) ) return;
  47 
  48   uint bidx = 0;                // Capture index of value into memop
  49   bool was_store;               // Memory op is a store op
  50 
  51   // Get the successor block for if the test ptr is non-null
  52   Block* not_null_block;  // this one goes with the proj
  53   Block* null_block;
  54   if (_nodes[_nodes.size()-1] == proj) {
  55     null_block     = _succs[0];
  56     not_null_block = _succs[1];


  80           Deoptimization::DeoptReason reason = Deoptimization::trap_request_reason(tr_con);
  81           Deoptimization::DeoptAction action = Deoptimization::trap_request_action(tr_con);
  82           assert((int)reason < (int)BitsPerInt, "recode bit map");
  83           if (is_set_nth_bit(allowed_reasons, (int) reason)
  84               && action != Deoptimization::Action_none) {
  85             // This uncommon trap is sure to recompile, eventually.
  86             // When that happens, C->too_many_traps will prevent
  87             // this transformation from happening again.
  88             found_trap = true;
  89           }
  90         }
  91         break;
  92       }
  93     }
  94     if (!found_trap) {
  95       // We did not find an uncommon trap.
  96       return;
  97     }
  98   }
  99 
 100   // Check for decodeHeapOop_not_null node which did not fold into address.
 101   bool is_decoden = val->is_Mach() &&
 102                    (val->as_Mach()->ideal_Opcode() == Op_DecodeN);
 103 
 104   // Search the successor block for a load or store who's base value is also
 105   // the tested value.  There may be several.
 106   Node_List *out = new Node_List(Thread::current()->resource_area());
 107   MachNode *best = NULL;        // Best found so far
 108   for (DUIterator i = val->outs(); val->has_out(i); i++) {
 109     Node *m = val->out(i);
 110     if( !m->is_Mach() ) continue;
 111     MachNode *mach = m->as_Mach();
 112     was_store = false;
 113     switch( mach->ideal_Opcode() ) {
 114     case Op_LoadB:
 115     case Op_LoadUS:
 116     case Op_LoadD:
 117     case Op_LoadF:
 118     case Op_LoadI:
 119     case Op_LoadL:
 120     case Op_LoadP:
 121     case Op_LoadN:
 122     case Op_LoadS:
 123     case Op_LoadKlass:


 136     case Op_StoreL:
 137     case Op_StoreP:
 138     case Op_StoreN:
 139       was_store = true;         // Memory op is a store op
 140       // Stores will have their address in slot 2 (memory in slot 1).
 141       // If the value being nul-checked is in another slot, it means we
 142       // are storing the checked value, which does NOT check the value!
 143       if( mach->in(2) != val ) continue;
 144       break;                    // Found a memory op?
 145     case Op_StrComp:
 146     case Op_StrEquals:
 147     case Op_StrIndexOf:
 148     case Op_AryEq:
 149       // Not a legit memory op for implicit null check regardless of
 150       // embedded loads
 151       continue;
 152     default:                    // Also check for embedded loads
 153       if( !mach->needs_anti_dependence_check() )
 154         continue;               // Not an memory op; skip it
 155       {
 156         // Check that value is used in memory address in
 157         // instructions with embedded load (CmpP val1,(val2+off)).
 158         Node* base;
 159         Node* index;
 160         const MachOper* oper = mach->memory_inputs(base, index);
 161         if (oper == NULL || oper == (MachOper*)-1) {
 162           continue;             // Not an memory op; skip it
 163         }
 164         if (val == base ||
 165             val == index && val->bottom_type()->isa_narrowoop()) {
 166           break;                // Found it
 167         } else {
 168           continue;             // Skip it
 169         }
 170       }
 171       break;
 172     }
 173     // check if the offset is not too high for implicit exception
 174     {
 175       intptr_t offset = 0;
 176       const TypePtr *adr_type = NULL;  // Do not need this return value here
 177       const Node* base = mach->get_base_and_disp(offset, adr_type);


 202     // Check ctrl input to see if the null-check dominates the memory op
 203     Block *cb = cfg->_bbs[mach->_idx];
 204     cb = cb->_idom;             // Always hoist at least 1 block
 205     if( !was_store ) {          // Stores can be hoisted only one block
 206       while( cb->_dom_depth > (_dom_depth + 1))
 207         cb = cb->_idom;         // Hoist loads as far as we want
 208       // The non-null-block should dominate the memory op, too. Live
 209       // range spilling will insert a spill in the non-null-block if it is
 210       // needs to spill the memory op for an implicit null check.
 211       if (cb->_dom_depth == (_dom_depth + 1)) {
 212         if (cb != not_null_block) continue;
 213         cb = cb->_idom;
 214       }
 215     }
 216     if( cb != this ) continue;
 217 
 218     // Found a memory user; see if it can be hoisted to check-block
 219     uint vidx = 0;              // Capture index of value into memop
 220     uint j;
 221     for( j = mach->req()-1; j > 0; j-- ) {
 222       if( mach->in(j) == val ) {
 223         vidx = j;
 224         // Ignore DecodeN val since it could be hoisted to where needed.
 225         if( is_decoden ) continue;
 226       }
 227       // Block of memory-op input
 228       Block *inb = cfg->_bbs[mach->in(j)->_idx];
 229       Block *b = this;          // Start from nul check
 230       while( b != inb && b->_dom_depth > inb->_dom_depth )
 231         b = b->_idom;           // search upwards for input
 232       // See if input dominates null check
 233       if( b != inb )
 234         break;
 235     }
 236     if( j > 0 )
 237       continue;
 238     Block *mb = cfg->_bbs[mach->_idx];
 239     // Hoisting stores requires more checks for the anti-dependence case.
 240     // Give up hoisting if we have to move the store past any load.
 241     if( was_store ) {
 242       Block *b = mb;            // Start searching here for a local load
 243       // mach use (faulting) trying to hoist
 244       // n might be blocker to hoisting
 245       while( b != this ) {
 246         uint k;


 264     if( e->is_MachNullCheck() && e->in(1) == mach )
 265       continue;                 // Already being used as a NULL check
 266 
 267     // Found a candidate!  Pick one with least dom depth - the highest
 268     // in the dom tree should be closest to the null check.
 269     if( !best ||
 270         cfg->_bbs[mach->_idx]->_dom_depth < cfg->_bbs[best->_idx]->_dom_depth ) {
 271       best = mach;
 272       bidx = vidx;
 273 
 274     }
 275   }
 276   // No candidate!
 277   if( !best ) return;
 278 
 279   // ---- Found an implicit null check
 280   extern int implicit_null_checks;
 281   implicit_null_checks++;
 282 
 283   // Hoist the memory candidate up to the end of the test block.
 284   if( is_decoden ) {
 285     // Check if we need to hoist DecodeN val first.
 286     Block *valb = cfg->_bbs[val->_idx];
 287     if( this != valb && this->_dom_depth < valb->_dom_depth ) {
 288       valb->find_remove(val);
 289       this->add_inst(val);
 290       cfg->_bbs.map(val->_idx,this);
 291     }
 292   }
 293   Block *old_block = cfg->_bbs[best->_idx];
 294   old_block->find_remove(best);
 295   add_inst(best);
 296   cfg->_bbs.map(best->_idx,this);
 297 
 298   // Move the control dependence
 299   if (best->in(0) && best->in(0) == old_block->_nodes[0])
 300     best->set_req(0, _nodes[0]);
 301 
 302   // Check for flag-killing projections that also need to be hoisted
 303   // Should be DU safe because no edge updates.
 304   for (DUIterator_Fast jmax, j = best->fast_outs(jmax); j < jmax; j++) {
 305     Node* n = best->fast_out(j);
 306     if( n->Opcode() == Op_MachProj ) {
 307       cfg->_bbs[n->_idx]->find_remove(n);
 308       add_inst(n);
 309       cfg->_bbs.map(n->_idx,this);
 310     }
 311   }
 312 


src/share/vm/opto/lcm.cpp
Index Unified diffs Context diffs Sdiffs Wdiffs Patch New Old Previous File Next File