Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(30)

Side by Side Diff: runtime/vm/flow_graph_optimizer.cc

Issue 10828319: Cleanup handling of NullType in type propagation. (Closed) Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge/dart/
Patch Set: Created 8 years, 4 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file 1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file
2 // for details. All rights reserved. Use of this source code is governed by a 2 // for details. All rights reserved. Use of this source code is governed by a
3 // BSD-style license that can be found in the LICENSE file. 3 // BSD-style license that can be found in the LICENSE file.
4 4
5 #include "vm/flow_graph_optimizer.h" 5 #include "vm/flow_graph_optimizer.h"
6 6
7 #include "vm/flow_graph_builder.h" 7 #include "vm/flow_graph_builder.h"
8 #include "vm/il_printer.h" 8 #include "vm/il_printer.h"
9 #include "vm/object_store.h" 9 #include "vm/object_store.h"
10 #include "vm/parser.h" 10 #include "vm/parser.h"
(...skipping 578 matching lines...) Expand 10 before | Expand all | Expand 10 after
589 589
590 void FlowGraphOptimizer::VisitBind(BindInstr* instr) { 590 void FlowGraphOptimizer::VisitBind(BindInstr* instr) {
591 instr->computation()->Accept(this, instr); 591 instr->computation()->Accept(this, instr);
592 } 592 }
593 593
594 594
595 void FlowGraphTypePropagator::VisitAssertAssignable(AssertAssignableComp* comp, 595 void FlowGraphTypePropagator::VisitAssertAssignable(AssertAssignableComp* comp,
596 BindInstr* instr) { 596 BindInstr* instr) {
597 if (FLAG_eliminate_type_checks && 597 if (FLAG_eliminate_type_checks &&
598 !comp->is_eliminated() && 598 !comp->is_eliminated() &&
599 !comp->dst_type().IsMalformed() &&
600 comp->value()->CompileTypeIsMoreSpecificThan(comp->dst_type())) { 599 comp->value()->CompileTypeIsMoreSpecificThan(comp->dst_type())) {
600 // TODO(regis): Remove is_eliminated_ field and support.
601 comp->eliminate(); 601 comp->eliminate();
602 if (is_ssa_) {
603 UseVal* use = comp->value()->AsUse();
604 // TODO(regis): Handle constant input value (not a definition).
srdjan 2012/08/15 17:49:56 s/not a definition/cannot access definition/
regis 2012/08/15 22:49:18 Done.
605 if (use != NULL) {
606 Definition* result = use->definition();
607 ASSERT(result != NULL);
608 // Replace uses and remove the current instructions via the iterator.
609 instr->ReplaceUsesWith(result);
610 ASSERT(current_iterator()->Current()->AsBind() == instr);
611 current_iterator()->RemoveCurrentFromGraph();
612 if (FLAG_trace_optimization) {
613 OS::Print("Replacing v%d with v%d\n",
614 instr->ssa_temp_index(),
615 result->ssa_temp_index());
srdjan 2012/08/15 17:49:56 You are not really replacing, but removing. Please
regis 2012/08/15 22:49:18 I have removed the instruction, but replaced its u
616 }
617 }
618 }
602 if (FLAG_trace_type_check_elimination) { 619 if (FLAG_trace_type_check_elimination) {
603 FlowGraphPrinter::PrintTypeCheck(parsed_function(), 620 FlowGraphPrinter::PrintTypeCheck(parsed_function(),
604 comp->token_pos(), 621 comp->token_pos(),
605 comp->value(), 622 comp->value(),
606 comp->dst_type(), 623 comp->dst_type(),
607 comp->dst_name(), 624 comp->dst_name(),
608 comp->is_eliminated()); 625 comp->is_eliminated());
609 } 626 }
610 } 627 }
611 } 628 }
612 629
613 630
614 void FlowGraphTypePropagator::VisitAssertBoolean(AssertBooleanComp* comp, 631 void FlowGraphTypePropagator::VisitAssertBoolean(AssertBooleanComp* comp,
615 BindInstr* instr) { 632 BindInstr* instr) {
633 // TODO(regis): Propagate NullType as well and revise the comment and code
634 // below to also eliminate the test for non-null and non-constant value.
635
636 // We can only eliminate an 'assert boolean' test when the checked value is
637 // a constant time constant. Indeed, a variable of the proper compile time
638 // type (bool) may still hold null at run time and therefore fail the test.
616 if (FLAG_eliminate_type_checks && 639 if (FLAG_eliminate_type_checks &&
617 !comp->is_eliminated() && 640 !comp->is_eliminated() &&
641 comp->value()->IsConstant() &&
642 !comp->value()->IsConstantNull() &&
618 comp->value()->CompileTypeIsMoreSpecificThan( 643 comp->value()->CompileTypeIsMoreSpecificThan(
619 Type::Handle(Type::BoolInterface()))) { 644 Type::Handle(Type::BoolInterface()))) {
645 // TODO(regis): Remove is_eliminated_ field and support.
srdjan 2012/08/15 17:49:56 I do not think this is correct. Let's discuss offl
srdjan 2012/08/15 19:55:56 My mistake. You are doing it only for constant inp
regis 2012/08/15 22:49:18 Yes, we only do this for constants, but this will
620 comp->eliminate(); 646 comp->eliminate();
647 if (is_ssa_) {
648 UseVal* use = comp->value()->AsUse();
649 // TODO(regis): Handle constant input value (not a definition).
650 if (use != NULL) {
651 Definition* result = use->definition();
652 ASSERT(result != NULL);
653 // Replace uses and remove the current instructions via the iterator.
654 instr->ReplaceUsesWith(result);
655 ASSERT(current_iterator()->Current()->AsBind() == instr);
656 current_iterator()->RemoveCurrentFromGraph();
657 if (FLAG_trace_optimization) {
658 OS::Print("Replacing v%d with v%d\n",
659 instr->ssa_temp_index(),
660 result->ssa_temp_index());
661 }
662 }
663 }
621 if (FLAG_trace_type_check_elimination) { 664 if (FLAG_trace_type_check_elimination) {
622 const String& name = String::Handle(Symbols::New("boolean expression")); 665 const String& name = String::Handle(Symbols::New("boolean expression"));
623 FlowGraphPrinter::PrintTypeCheck(parsed_function(), 666 FlowGraphPrinter::PrintTypeCheck(parsed_function(),
624 comp->token_pos(), 667 comp->token_pos(),
625 comp->value(), 668 comp->value(),
626 Type::Handle(Type::BoolInterface()), 669 Type::Handle(Type::BoolInterface()),
627 name, 670 name,
628 comp->is_eliminated()); 671 comp->is_eliminated());
629 } 672 }
630 } 673 }
631 } 674 }
632 675
633 676
677 void FlowGraphTypePropagator::VisitInstanceOf(InstanceOfComp* comp,
678 BindInstr* instr) {
679 // TODO(regis): Propagate NullType as well and revise the comment and code
680 // below to also eliminate the test for non-null and non-constant value.
681
682 // We can only eliminate an 'instance of' test when the checked value is
683 // a constant time constant. Indeed, a variable of the proper compile time
684 // type may still hold null at run time and therefore fail the test.
685 // We do not bother checking for Object destination type, since the graph
686 // builder did already.
687 if (FLAG_eliminate_type_checks &&
688 comp->value()->IsConstant() &&
689 !comp->value()->IsConstantNull() &&
690 comp->value()->CompileTypeIsMoreSpecificThan(comp->type())) {
srdjan 2012/08/15 17:49:56 ditto
691 if (is_ssa_) {
692 UseVal* use = comp->value()->AsUse();
693 // TODO(regis): Handle constant input value (not a definition).
694 if (use != NULL) {
695 Definition* result = use->definition();
696 ASSERT(result != NULL);
697 // Replace uses and remove the current instructions via the iterator.
698 instr->ReplaceUsesWith(result);
699 ASSERT(current_iterator()->Current()->AsBind() == instr);
700 current_iterator()->RemoveCurrentFromGraph();
701 if (FLAG_trace_optimization) {
702 OS::Print("Replacing v%d with v%d\n",
703 instr->ssa_temp_index(),
704 result->ssa_temp_index());
705 }
706 }
707 }
708 if (FLAG_trace_type_check_elimination) {
709 const String& name = String::Handle(Symbols::New("InstanceOf"));
710 FlowGraphPrinter::PrintTypeCheck(parsed_function(),
711 comp->token_pos(),
712 comp->value(),
713 comp->type(),
714 name,
715 /* eliminated = */ true);
716 }
717 }
718 }
719
720
634 void FlowGraphTypePropagator::VisitGraphEntry(GraphEntryInstr* graph_entry) { 721 void FlowGraphTypePropagator::VisitGraphEntry(GraphEntryInstr* graph_entry) {
635 if (graph_entry->start_env() == NULL) { 722 if (graph_entry->start_env() == NULL) {
636 return; 723 return;
637 } 724 }
638 // Visit incoming parameters. 725 // Visit incoming parameters.
639 for (intptr_t i = 0; i < graph_entry->start_env()->values().length(); i++) { 726 for (intptr_t i = 0; i < graph_entry->start_env()->values().length(); i++) {
640 Value* val = graph_entry->start_env()->values()[i]; 727 Value* val = graph_entry->start_env()->values()[i];
641 if (val->IsUse()) { 728 if (val->IsUse()) {
642 ParameterInstr* param = val->AsUse()->definition()->AsParameter(); 729 ParameterInstr* param = val->AsUse()->definition()->AsParameter();
643 if (param != NULL) { 730 if (param != NULL) {
(...skipping 15 matching lines...) Expand all
659 } 746 }
660 } 747 }
661 } 748 }
662 749
663 750
664 void FlowGraphTypePropagator::VisitBind(BindInstr* bind) { 751 void FlowGraphTypePropagator::VisitBind(BindInstr* bind) {
665 // No need to propagate the input types of the bound computation, as long as 752 // No need to propagate the input types of the bound computation, as long as
666 // PhiInstr's are handled as part of JoinEntryInstr. 753 // PhiInstr's are handled as part of JoinEntryInstr.
667 // Visit computation and possibly eliminate type check. 754 // Visit computation and possibly eliminate type check.
668 bind->computation()->Accept(this, bind); 755 bind->computation()->Accept(this, bind);
669 // Cache propagated computation type. 756 // The current bind may have been removed from the graph.
670 AbstractType& type = AbstractType::Handle(bind->computation()->CompileType()); 757 if (current_iterator()->Current()->AsBind() == bind) {
671 bool changed = bind->SetPropagatedType(type); 758 // Current bind was not removed.
672 if (changed) { 759 // Cache propagated computation type.
673 still_changing_ = true; 760 AbstractType& computation_type =
761 AbstractType::Handle(bind->computation()->CompileType());
762 bool changed = bind->SetPropagatedType(computation_type);
763 if (changed) {
764 still_changing_ = true;
765 }
674 } 766 }
675 } 767 }
676 768
677 769
678 void FlowGraphTypePropagator::VisitPhi(PhiInstr* phi) { 770 void FlowGraphTypePropagator::VisitPhi(PhiInstr* phi) {
679 // We could set the propagated type of the phi to the least upper bound of its 771 // We could set the propagated type of the phi to the least upper bound of its
680 // input propagated types. However, keeping all propagated types allows us to 772 // input propagated types. However, keeping all propagated types allows us to
681 // optimize method dispatch. 773 // optimize method dispatch.
682 // TODO(regis): Support a set of propagated types. For now, we compute the 774 // TODO(regis): Support a set of propagated types. For now, we compute the
683 // least specific of the input propagated types. 775 // least specific of the input propagated types.
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after
730 LocationSummary* locs = it.Current()->locs(); 822 LocationSummary* locs = it.Current()->locs();
731 if ((locs != NULL) && locs->can_call()) { 823 if ((locs != NULL) && locs->can_call()) {
732 is_leaf_ = false; 824 is_leaf_ = false;
733 return; 825 return;
734 } 826 }
735 } 827 }
736 } 828 }
737 } 829 }
738 830
739 } // namespace dart 831 } // namespace dart
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698