equal
deleted
inserted
replaced
435 |
435 |
436 |
436 |
437 // Because of a static contained within (for the purpose of iteration |
437 // Because of a static contained within (for the purpose of iteration |
438 // over instructions), it is only valid to have one of these active at |
438 // over instructions), it is only valid to have one of these active at |
439 // a time |
439 // a time |
440 class NullCheckEliminator { |
440 class NullCheckEliminator: public ValueVisitor { |
441 private: |
441 private: |
442 static NullCheckEliminator* _static_nce; |
|
443 static void do_value(Value* vp); |
|
444 |
|
445 Optimizer* _opt; |
442 Optimizer* _opt; |
446 |
443 |
447 ValueSet* _visitable_instructions; // Visit each instruction only once per basic block |
444 ValueSet* _visitable_instructions; // Visit each instruction only once per basic block |
448 BlockList* _work_list; // Basic blocks to visit |
445 BlockList* _work_list; // Basic blocks to visit |
449 |
446 |
501 Optimizer* opt() { return _opt; } |
498 Optimizer* opt() { return _opt; } |
502 IR* ir () { return opt()->ir(); } |
499 IR* ir () { return opt()->ir(); } |
503 |
500 |
504 // Process a graph |
501 // Process a graph |
505 void iterate(BlockBegin* root); |
502 void iterate(BlockBegin* root); |
|
503 |
|
504 void visit(Value* f); |
506 |
505 |
507 // In some situations (like NullCheck(x); getfield(x)) the debug |
506 // In some situations (like NullCheck(x); getfield(x)) the debug |
508 // information from the explicit NullCheck can be used to populate |
507 // information from the explicit NullCheck can be used to populate |
509 // the getfield, even if the two instructions are in different |
508 // the getfield, even if the two instructions are in different |
510 // scopes; this allows implicit null checks to be used but the |
509 // scopes; this allows implicit null checks to be used but the |
600 void NullCheckVisitor::do_UnsafePrefetchWrite(UnsafePrefetchWrite* x) {} |
599 void NullCheckVisitor::do_UnsafePrefetchWrite(UnsafePrefetchWrite* x) {} |
601 void NullCheckVisitor::do_ProfileCall (ProfileCall* x) { nce()->clear_last_explicit_null_check(); } |
600 void NullCheckVisitor::do_ProfileCall (ProfileCall* x) { nce()->clear_last_explicit_null_check(); } |
602 void NullCheckVisitor::do_ProfileCounter (ProfileCounter* x) {} |
601 void NullCheckVisitor::do_ProfileCounter (ProfileCounter* x) {} |
603 |
602 |
604 |
603 |
605 NullCheckEliminator* NullCheckEliminator::_static_nce = NULL; |
604 void NullCheckEliminator::visit(Value* p) { |
606 |
|
607 |
|
608 void NullCheckEliminator::do_value(Value* p) { |
|
609 assert(*p != NULL, "should not find NULL instructions"); |
605 assert(*p != NULL, "should not find NULL instructions"); |
610 if (_static_nce->visitable(*p)) { |
606 if (visitable(*p)) { |
611 _static_nce->mark_visited(*p); |
607 mark_visited(*p); |
612 (*p)->visit(&_static_nce->_visitor); |
608 (*p)->visit(&_visitor); |
613 } |
609 } |
614 } |
610 } |
615 |
611 |
616 bool NullCheckEliminator::merge_state_for(BlockBegin* block, ValueSet* incoming_state) { |
612 bool NullCheckEliminator::merge_state_for(BlockBegin* block, ValueSet* incoming_state) { |
617 ValueSet* state = state_for(block); |
613 ValueSet* state = state_for(block); |
635 } |
631 } |
636 } |
632 } |
637 |
633 |
638 |
634 |
639 void NullCheckEliminator::iterate_one(BlockBegin* block) { |
635 void NullCheckEliminator::iterate_one(BlockBegin* block) { |
640 _static_nce = this; |
|
641 clear_visitable_state(); |
636 clear_visitable_state(); |
642 // clear out an old explicit null checks |
637 // clear out an old explicit null checks |
643 set_last_explicit_null_check(NULL); |
638 set_last_explicit_null_check(NULL); |
644 |
639 |
645 if (PrintNullCheckElimination) { |
640 if (PrintNullCheckElimination) { |
710 // visiting instructions which are references in other blocks or |
705 // visiting instructions which are references in other blocks or |
711 // visiting instructions more than once. |
706 // visiting instructions more than once. |
712 mark_visitable(instr); |
707 mark_visitable(instr); |
713 if (instr->is_root() || instr->can_trap() || (instr->as_NullCheck() != NULL)) { |
708 if (instr->is_root() || instr->can_trap() || (instr->as_NullCheck() != NULL)) { |
714 mark_visited(instr); |
709 mark_visited(instr); |
715 instr->input_values_do(&NullCheckEliminator::do_value); |
710 instr->input_values_do(this); |
716 instr->visit(&_visitor); |
711 instr->visit(&_visitor); |
717 } |
712 } |
718 } |
713 } |
719 |
714 |
720 // Propagate state to successors if necessary |
715 // Propagate state to successors if necessary |