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)) {