161 Value t_value = t_goto->state()->stack_at(if_state->stack_size());
162 Value f_value = f_goto->state()->stack_at(if_state->stack_size());
163
164 // backend does not support floats
165 assert(t_value->type()->base() == f_value->type()->base(), "incompatible types");
166 if (t_value->type()->is_float_kind()) return;
167
168 // check that successor has no other phi functions but sux_phi
169 // this can happen when t_block or f_block contained additonal stores to local variables
170 // that are no longer represented by explicit instructions
171 for_each_phi_fun(sux, phi,
172 if (phi != sux_phi) return;
173 );
174 // true and false blocks can't have phis
175 for_each_phi_fun(t_block, phi, return; );
176 for_each_phi_fun(f_block, phi, return; );
177
178 // 2) substitute conditional expression
179 // with an IfOp followed by a Goto
180 // cut if_ away and get node before
181 Instruction* cur_end = if_->prev(block);
182
183 // append constants of true- and false-block if necessary
184 // clone constants because original block must not be destroyed
185 assert((t_value != f_const && f_value != t_const) || t_const == f_const, "mismatch");
186 if (t_value == t_const) {
187 t_value = new Constant(t_const->type());
188 NOT_PRODUCT(t_value->set_printable_bci(if_->printable_bci()));
189 cur_end = cur_end->set_next(t_value);
190 }
191 if (f_value == f_const) {
192 f_value = new Constant(f_const->type());
193 NOT_PRODUCT(f_value->set_printable_bci(if_->printable_bci()));
194 cur_end = cur_end->set_next(f_value);
195 }
196
197 Value result = make_ifop(if_->x(), if_->cond(), if_->y(), t_value, f_value);
198 assert(result != NULL, "make_ifop must return a non-null instruction");
199 if (!result->is_linked() && result->can_be_linked()) {
200 NOT_PRODUCT(result->set_printable_bci(if_->printable_bci()));
201 cur_end = cur_end->set_next(result);
202 }
203
204 // append Goto to successor
205 ValueStack* state_before = if_->is_safepoint() ? if_->state_before() : NULL;
206 Goto* goto_ = new Goto(sux, state_before, if_->is_safepoint() || t_goto->is_safepoint() || f_goto->is_safepoint());
207
208 // prepare state for Goto
209 ValueStack* goto_state = if_state;
210 goto_state = goto_state->copy(ValueStack::StateAfter, goto_state->bci());
211 goto_state->push(result->type(), result);
212 assert(goto_state->is_same(sux_state), "states must match now");
213 goto_->set_state(goto_state);
214
215 cur_end = cur_end->set_next(goto_, goto_state->bci());
216
217 // Adjust control flow graph
218 BlockBegin::disconnect_edge(block, t_block);
219 BlockBegin::disconnect_edge(block, f_block);
220 if (t_block->number_of_preds() == 0) {
221 BlockBegin::disconnect_edge(t_block, sux);
222 }
223 adjust_exception_edges(block, t_block);
224 if (f_block->number_of_preds() == 0) {
225 BlockBegin::disconnect_edge(f_block, sux);
350 // no phi functions must be present at beginning of sux
351 ValueStack* sux_state = sux->state();
352 ValueStack* end_state = end->state();
353
354 assert(end_state->scope() == sux_state->scope(), "scopes must match");
355 assert(end_state->stack_size() == sux_state->stack_size(), "stack not equal");
356 assert(end_state->locals_size() == sux_state->locals_size(), "locals not equal");
357
358 int index;
359 Value sux_value;
360 for_each_stack_value(sux_state, index, sux_value) {
361 assert(sux_value == end_state->stack_at(index), "stack not equal");
362 }
363 for_each_local_value(sux_state, index, sux_value) {
364 assert(sux_value == end_state->local_at(index), "locals not equal");
365 }
366 assert(sux_state->caller_state() == end_state->caller_state(), "caller not equal");
367 #endif
368
369 // find instruction before end & append first instruction of sux block
370 Instruction* prev = end->prev(block);
371 Instruction* next = sux->next();
372 assert(prev->as_BlockEnd() == NULL, "must not be a BlockEnd");
373 prev->set_next(next);
374 sux->disconnect_from_graph();
375 block->set_end(sux->end());
376 // add exception handlers of deleted block, if any
377 for (int k = 0; k < sux->number_of_exception_handlers(); k++) {
378 BlockBegin* xhandler = sux->exception_handler_at(k);
379 block->add_exception_handler(xhandler);
380
381 // also substitute predecessor of exception handler
382 assert(xhandler->is_predecessor(sux), "missing predecessor");
383 xhandler->remove_predecessor(sux);
384 if (!xhandler->is_predecessor(block)) {
385 xhandler->add_predecessor(block);
386 }
387 }
388
389 // debugging output
390 _merge_count++;
391 if (PrintBlockElimination) {
392 tty->print_cr("%d. merged B%d & B%d (stack size = %d)",
393 _merge_count, block->block_id(), sux->block_id(), sux->state()->stack_size());
516 void do_IfInstanceOf (IfInstanceOf* x);
517 void do_TableSwitch (TableSwitch* x);
518 void do_LookupSwitch (LookupSwitch* x);
519 void do_Return (Return* x);
520 void do_Throw (Throw* x);
521 void do_Base (Base* x);
522 void do_OsrEntry (OsrEntry* x);
523 void do_ExceptionObject(ExceptionObject* x);
524 void do_RoundFP (RoundFP* x);
525 void do_UnsafeGetRaw (UnsafeGetRaw* x);
526 void do_UnsafePutRaw (UnsafePutRaw* x);
527 void do_UnsafeGetObject(UnsafeGetObject* x);
528 void do_UnsafePutObject(UnsafePutObject* x);
529 void do_UnsafeGetAndSetObject(UnsafeGetAndSetObject* x);
530 void do_UnsafePrefetchRead (UnsafePrefetchRead* x);
531 void do_UnsafePrefetchWrite(UnsafePrefetchWrite* x);
532 void do_ProfileCall (ProfileCall* x);
533 void do_ProfileInvoke (ProfileInvoke* x);
534 void do_RuntimeCall (RuntimeCall* x);
535 void do_MemBar (MemBar* x);
536 };
537
538
539 // Because of a static contained within (for the purpose of iteration
540 // over instructions), it is only valid to have one of these active at
541 // a time
542 class NullCheckEliminator: public ValueVisitor {
543 private:
544 Optimizer* _opt;
545
546 ValueSet* _visitable_instructions; // Visit each instruction only once per basic block
547 BlockList* _work_list; // Basic blocks to visit
548
549 bool visitable(Value x) {
550 assert(_visitable_instructions != NULL, "check");
551 return _visitable_instructions->contains(x);
552 }
553 void mark_visited(Value x) {
554 assert(_visitable_instructions != NULL, "check");
555 _visitable_instructions->remove(x);
697 void NullCheckVisitor::do_IfInstanceOf (IfInstanceOf* x) {}
698 void NullCheckVisitor::do_TableSwitch (TableSwitch* x) {}
699 void NullCheckVisitor::do_LookupSwitch (LookupSwitch* x) {}
700 void NullCheckVisitor::do_Return (Return* x) {}
701 void NullCheckVisitor::do_Throw (Throw* x) { nce()->clear_last_explicit_null_check(); }
702 void NullCheckVisitor::do_Base (Base* x) {}
703 void NullCheckVisitor::do_OsrEntry (OsrEntry* x) {}
704 void NullCheckVisitor::do_ExceptionObject(ExceptionObject* x) { nce()->handle_ExceptionObject(x); }
705 void NullCheckVisitor::do_RoundFP (RoundFP* x) {}
706 void NullCheckVisitor::do_UnsafeGetRaw (UnsafeGetRaw* x) {}
707 void NullCheckVisitor::do_UnsafePutRaw (UnsafePutRaw* x) {}
708 void NullCheckVisitor::do_UnsafeGetObject(UnsafeGetObject* x) {}
709 void NullCheckVisitor::do_UnsafePutObject(UnsafePutObject* x) {}
710 void NullCheckVisitor::do_UnsafeGetAndSetObject(UnsafeGetAndSetObject* x) {}
711 void NullCheckVisitor::do_UnsafePrefetchRead (UnsafePrefetchRead* x) {}
712 void NullCheckVisitor::do_UnsafePrefetchWrite(UnsafePrefetchWrite* x) {}
713 void NullCheckVisitor::do_ProfileCall (ProfileCall* x) { nce()->clear_last_explicit_null_check(); }
714 void NullCheckVisitor::do_ProfileInvoke (ProfileInvoke* x) {}
715 void NullCheckVisitor::do_RuntimeCall (RuntimeCall* x) {}
716 void NullCheckVisitor::do_MemBar (MemBar* x) {}
717
718
719 void NullCheckEliminator::visit(Value* p) {
720 assert(*p != NULL, "should not find NULL instructions");
721 if (visitable(*p)) {
722 mark_visited(*p);
723 (*p)->visit(&_visitor);
724 }
725 }
726
727 bool NullCheckEliminator::merge_state_for(BlockBegin* block, ValueSet* incoming_state) {
728 ValueSet* state = state_for(block);
729 if (state == NULL) {
730 state = incoming_state->copy();
731 set_state_for(block, state);
732 return true;
733 } else {
734 bool changed = state->set_intersect(incoming_state);
735 if (PrintNullCheckElimination && changed) {
736 tty->print_cr("Block %d's null check state changed", block->block_id());
|
161 Value t_value = t_goto->state()->stack_at(if_state->stack_size());
162 Value f_value = f_goto->state()->stack_at(if_state->stack_size());
163
164 // backend does not support floats
165 assert(t_value->type()->base() == f_value->type()->base(), "incompatible types");
166 if (t_value->type()->is_float_kind()) return;
167
168 // check that successor has no other phi functions but sux_phi
169 // this can happen when t_block or f_block contained additonal stores to local variables
170 // that are no longer represented by explicit instructions
171 for_each_phi_fun(sux, phi,
172 if (phi != sux_phi) return;
173 );
174 // true and false blocks can't have phis
175 for_each_phi_fun(t_block, phi, return; );
176 for_each_phi_fun(f_block, phi, return; );
177
178 // 2) substitute conditional expression
179 // with an IfOp followed by a Goto
180 // cut if_ away and get node before
181 Instruction* cur_end = if_->prev();
182
183 // append constants of true- and false-block if necessary
184 // clone constants because original block must not be destroyed
185 assert((t_value != f_const && f_value != t_const) || t_const == f_const, "mismatch");
186 if (t_value == t_const) {
187 t_value = new Constant(t_const->type());
188 NOT_PRODUCT(t_value->set_printable_bci(if_->printable_bci()));
189 cur_end = cur_end->set_next(t_value);
190 }
191 if (f_value == f_const) {
192 f_value = new Constant(f_const->type());
193 NOT_PRODUCT(f_value->set_printable_bci(if_->printable_bci()));
194 cur_end = cur_end->set_next(f_value);
195 }
196
197 Value result = make_ifop(if_->x(), if_->cond(), if_->y(), t_value, f_value);
198 assert(result != NULL, "make_ifop must return a non-null instruction");
199 if (!result->is_linked() && result->can_be_linked()) {
200 NOT_PRODUCT(result->set_printable_bci(if_->printable_bci()));
201 cur_end = cur_end->set_next(result);
202 }
203
204 // append Goto to successor
205 ValueStack* state_before = if_->state_before();
206 Goto* goto_ = new Goto(sux, state_before, if_->is_safepoint() || t_goto->is_safepoint() || f_goto->is_safepoint());
207
208 // prepare state for Goto
209 ValueStack* goto_state = if_state;
210 goto_state = goto_state->copy(ValueStack::StateAfter, goto_state->bci());
211 goto_state->push(result->type(), result);
212 assert(goto_state->is_same(sux_state), "states must match now");
213 goto_->set_state(goto_state);
214
215 cur_end = cur_end->set_next(goto_, goto_state->bci());
216
217 // Adjust control flow graph
218 BlockBegin::disconnect_edge(block, t_block);
219 BlockBegin::disconnect_edge(block, f_block);
220 if (t_block->number_of_preds() == 0) {
221 BlockBegin::disconnect_edge(t_block, sux);
222 }
223 adjust_exception_edges(block, t_block);
224 if (f_block->number_of_preds() == 0) {
225 BlockBegin::disconnect_edge(f_block, sux);
350 // no phi functions must be present at beginning of sux
351 ValueStack* sux_state = sux->state();
352 ValueStack* end_state = end->state();
353
354 assert(end_state->scope() == sux_state->scope(), "scopes must match");
355 assert(end_state->stack_size() == sux_state->stack_size(), "stack not equal");
356 assert(end_state->locals_size() == sux_state->locals_size(), "locals not equal");
357
358 int index;
359 Value sux_value;
360 for_each_stack_value(sux_state, index, sux_value) {
361 assert(sux_value == end_state->stack_at(index), "stack not equal");
362 }
363 for_each_local_value(sux_state, index, sux_value) {
364 assert(sux_value == end_state->local_at(index), "locals not equal");
365 }
366 assert(sux_state->caller_state() == end_state->caller_state(), "caller not equal");
367 #endif
368
369 // find instruction before end & append first instruction of sux block
370 Instruction* prev = end->prev();
371 Instruction* next = sux->next();
372 assert(prev->as_BlockEnd() == NULL, "must not be a BlockEnd");
373 prev->set_next(next);
374 prev->fixup_block_pointers();
375 sux->disconnect_from_graph();
376 block->set_end(sux->end());
377 // add exception handlers of deleted block, if any
378 for (int k = 0; k < sux->number_of_exception_handlers(); k++) {
379 BlockBegin* xhandler = sux->exception_handler_at(k);
380 block->add_exception_handler(xhandler);
381
382 // also substitute predecessor of exception handler
383 assert(xhandler->is_predecessor(sux), "missing predecessor");
384 xhandler->remove_predecessor(sux);
385 if (!xhandler->is_predecessor(block)) {
386 xhandler->add_predecessor(block);
387 }
388 }
389
390 // debugging output
391 _merge_count++;
392 if (PrintBlockElimination) {
393 tty->print_cr("%d. merged B%d & B%d (stack size = %d)",
394 _merge_count, block->block_id(), sux->block_id(), sux->state()->stack_size());
517 void do_IfInstanceOf (IfInstanceOf* x);
518 void do_TableSwitch (TableSwitch* x);
519 void do_LookupSwitch (LookupSwitch* x);
520 void do_Return (Return* x);
521 void do_Throw (Throw* x);
522 void do_Base (Base* x);
523 void do_OsrEntry (OsrEntry* x);
524 void do_ExceptionObject(ExceptionObject* x);
525 void do_RoundFP (RoundFP* x);
526 void do_UnsafeGetRaw (UnsafeGetRaw* x);
527 void do_UnsafePutRaw (UnsafePutRaw* x);
528 void do_UnsafeGetObject(UnsafeGetObject* x);
529 void do_UnsafePutObject(UnsafePutObject* x);
530 void do_UnsafeGetAndSetObject(UnsafeGetAndSetObject* x);
531 void do_UnsafePrefetchRead (UnsafePrefetchRead* x);
532 void do_UnsafePrefetchWrite(UnsafePrefetchWrite* x);
533 void do_ProfileCall (ProfileCall* x);
534 void do_ProfileInvoke (ProfileInvoke* x);
535 void do_RuntimeCall (RuntimeCall* x);
536 void do_MemBar (MemBar* x);
537 void do_RangeCheckPredicate(RangeCheckPredicate* x);
538 void do_Assert (Assert* x);
539 };
540
541
542 // Because of a static contained within (for the purpose of iteration
543 // over instructions), it is only valid to have one of these active at
544 // a time
545 class NullCheckEliminator: public ValueVisitor {
546 private:
547 Optimizer* _opt;
548
549 ValueSet* _visitable_instructions; // Visit each instruction only once per basic block
550 BlockList* _work_list; // Basic blocks to visit
551
552 bool visitable(Value x) {
553 assert(_visitable_instructions != NULL, "check");
554 return _visitable_instructions->contains(x);
555 }
556 void mark_visited(Value x) {
557 assert(_visitable_instructions != NULL, "check");
558 _visitable_instructions->remove(x);
700 void NullCheckVisitor::do_IfInstanceOf (IfInstanceOf* x) {}
701 void NullCheckVisitor::do_TableSwitch (TableSwitch* x) {}
702 void NullCheckVisitor::do_LookupSwitch (LookupSwitch* x) {}
703 void NullCheckVisitor::do_Return (Return* x) {}
704 void NullCheckVisitor::do_Throw (Throw* x) { nce()->clear_last_explicit_null_check(); }
705 void NullCheckVisitor::do_Base (Base* x) {}
706 void NullCheckVisitor::do_OsrEntry (OsrEntry* x) {}
707 void NullCheckVisitor::do_ExceptionObject(ExceptionObject* x) { nce()->handle_ExceptionObject(x); }
708 void NullCheckVisitor::do_RoundFP (RoundFP* x) {}
709 void NullCheckVisitor::do_UnsafeGetRaw (UnsafeGetRaw* x) {}
710 void NullCheckVisitor::do_UnsafePutRaw (UnsafePutRaw* x) {}
711 void NullCheckVisitor::do_UnsafeGetObject(UnsafeGetObject* x) {}
712 void NullCheckVisitor::do_UnsafePutObject(UnsafePutObject* x) {}
713 void NullCheckVisitor::do_UnsafeGetAndSetObject(UnsafeGetAndSetObject* x) {}
714 void NullCheckVisitor::do_UnsafePrefetchRead (UnsafePrefetchRead* x) {}
715 void NullCheckVisitor::do_UnsafePrefetchWrite(UnsafePrefetchWrite* x) {}
716 void NullCheckVisitor::do_ProfileCall (ProfileCall* x) { nce()->clear_last_explicit_null_check(); }
717 void NullCheckVisitor::do_ProfileInvoke (ProfileInvoke* x) {}
718 void NullCheckVisitor::do_RuntimeCall (RuntimeCall* x) {}
719 void NullCheckVisitor::do_MemBar (MemBar* x) {}
720 void NullCheckVisitor::do_RangeCheckPredicate(RangeCheckPredicate* x) {}
721 void NullCheckVisitor::do_Assert (Assert* x) {}
722
723
724 void NullCheckEliminator::visit(Value* p) {
725 assert(*p != NULL, "should not find NULL instructions");
726 if (visitable(*p)) {
727 mark_visited(*p);
728 (*p)->visit(&_visitor);
729 }
730 }
731
732 bool NullCheckEliminator::merge_state_for(BlockBegin* block, ValueSet* incoming_state) {
733 ValueSet* state = state_for(block);
734 if (state == NULL) {
735 state = incoming_state->copy();
736 set_state_for(block, state);
737 return true;
738 } else {
739 bool changed = state->set_intersect(incoming_state);
740 if (PrintNullCheckElimination && changed) {
741 tty->print_cr("Block %d's null check state changed", block->block_id());
|