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,186 **** 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); // 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) { --- 176,186 ---- 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(); // 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,210 **** 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; 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()); --- 200,210 ---- NOT_PRODUCT(result->set_printable_bci(if_->printable_bci())); cur_end = cur_end->set_next(result); } // append Goto to successor ! 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,378 **** } 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* next = sux->next(); assert(prev->as_BlockEnd() == NULL, "must not be a BlockEnd"); prev->set_next(next); 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); --- 365,379 ---- } 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(); 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,540 **** --- 532,543 ---- 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,721 **** --- 715,726 ---- 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)) {