src/share/vm/c1/c1_Optimizer.cpp

Print this page
rev 4136 : 7153771: array bound check elimination for c1
Summary: when possible optimize out array bound checks, inserting predicates when needed.
Reviewed-by:

@@ -176,11 +176,11 @@
   for_each_phi_fun(f_block, phi, return; );
 
   // 2) substitute conditional expression
   //    with an IfOp followed by a Goto
   // cut if_ away and get node before
-  Instruction* cur_end = if_->prev(block);
+  Instruction* cur_end = if_->prev();
 
   // append constants of true- and false-block if necessary
   // clone constants because original block must not be destroyed
   assert((t_value != f_const && f_value != t_const) || t_const == f_const, "mismatch");
   if (t_value == t_const) {

@@ -200,11 +200,11 @@
     NOT_PRODUCT(result->set_printable_bci(if_->printable_bci()));
     cur_end = cur_end->set_next(result);
   }
 
   // append Goto to successor
-  ValueStack* state_before = if_->is_safepoint() ? if_->state_before() : NULL;
+  ValueStack* state_before = if_->state_before();
   Goto* goto_ = new Goto(sux, state_before, if_->is_safepoint() || t_goto->is_safepoint() || f_goto->is_safepoint());
 
   // prepare state for Goto
   ValueStack* goto_state = if_state;
   goto_state = goto_state->copy(ValueStack::StateAfter, goto_state->bci());

@@ -365,14 +365,15 @@
         }
         assert(sux_state->caller_state() == end_state->caller_state(), "caller not equal");
 #endif
 
         // find instruction before end & append first instruction of sux block
-        Instruction* prev = end->prev(block);
+        Instruction* prev = end->prev();
         Instruction* next = sux->next();
         assert(prev->as_BlockEnd() == NULL, "must not be a BlockEnd");
         prev->set_next(next);
+        prev->fixup_block_pointers();
         sux->disconnect_from_graph();
         block->set_end(sux->end());
         // add exception handlers of deleted block, if any
         for (int k = 0; k < sux->number_of_exception_handlers(); k++) {
           BlockBegin* xhandler = sux->exception_handler_at(k);

@@ -531,10 +532,12 @@
   void do_UnsafePrefetchWrite(UnsafePrefetchWrite* x);
   void do_ProfileCall    (ProfileCall*     x);
   void do_ProfileInvoke  (ProfileInvoke*   x);
   void do_RuntimeCall    (RuntimeCall*     x);
   void do_MemBar         (MemBar*          x);
+  void do_RangeCheckPredicate(RangeCheckPredicate* x);
+  void do_Assert         (Assert*          x);
 };
 
 
 // Because of a static contained within (for the purpose of iteration
 // over instructions), it is only valid to have one of these active at

@@ -712,10 +715,12 @@
 void NullCheckVisitor::do_UnsafePrefetchWrite(UnsafePrefetchWrite* x) {}
 void NullCheckVisitor::do_ProfileCall    (ProfileCall*     x) { nce()->clear_last_explicit_null_check(); }
 void NullCheckVisitor::do_ProfileInvoke  (ProfileInvoke*   x) {}
 void NullCheckVisitor::do_RuntimeCall    (RuntimeCall*     x) {}
 void NullCheckVisitor::do_MemBar         (MemBar*          x) {}
+void NullCheckVisitor::do_RangeCheckPredicate(RangeCheckPredicate* x) {}
+void NullCheckVisitor::do_Assert         (Assert*          x) {}
 
 
 void NullCheckEliminator::visit(Value* p) {
   assert(*p != NULL, "should not find NULL instructions");
   if (visitable(*p)) {