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

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
« no previous file with comments | « runtime/vm/flow_graph_optimizer.h ('k') | runtime/vm/il_printer.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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 566 matching lines...) Expand 10 before | Expand all | Expand 10 after
577 577
578 void FlowGraphOptimizer::VisitBind(BindInstr* instr) { 578 void FlowGraphOptimizer::VisitBind(BindInstr* instr) {
579 instr->computation()->Accept(this, instr); 579 instr->computation()->Accept(this, instr);
580 } 580 }
581 581
582 582
583 void FlowGraphTypePropagator::VisitAssertAssignable(AssertAssignableComp* comp, 583 void FlowGraphTypePropagator::VisitAssertAssignable(AssertAssignableComp* comp,
584 BindInstr* instr) { 584 BindInstr* instr) {
585 if (FLAG_eliminate_type_checks && 585 if (FLAG_eliminate_type_checks &&
586 !comp->is_eliminated() && 586 !comp->is_eliminated() &&
587 !comp->dst_type().IsMalformed() &&
588 comp->value()->CompileTypeIsMoreSpecificThan(comp->dst_type())) { 587 comp->value()->CompileTypeIsMoreSpecificThan(comp->dst_type())) {
589 comp->eliminate(); 588 comp->eliminate();
589 #if 0
590 UseVal* use = comp->value()->AsUse();
591 // TODO(regis): Handle constant input value (not a definition).
592 if (use != NULL) {
593 Definition* result = use->definition();
594 ASSERT(result != NULL);
595 // Replace uses and remove the current instructions via the iterator.
596 instr->ReplaceUsesWith(result);
597 ASSERT(current_iterator()->Current()->AsBind() == instr);
598 current_iterator()->RemoveCurrentFromGraph();
599 instr->RemoveInputUses();
600 if (result->use_list() == NULL) {
601 // Remove the definition of the input as well, since it has no uses.
Kevin Millikin (Google) 2012/08/15 09:04:25 This is not really safe if it happens, because it
regis 2012/08/15 17:25:27 Thanks! I removed the code removing the unused inp
602 current_iterator()->RemoveCurrentFromGraph();
603 }
604
605 // TODO(regis): The above instruction removal results in an assert fault:
Kevin Millikin (Google) 2012/08/15 09:04:25 We should just skip this optimization if we're usi
regis 2012/08/15 17:25:27 Done. That takes care of the assert fault.
606 // ../runtime/vm/flow_graph_compiler.cc:754: error: expected:
607 // val->AsUse()->definition() == registers_[src]
608
609 if (FLAG_trace_optimization) {
610 OS::Print("Replacing v%d with v%d\n",
611 instr->ssa_temp_index(),
612 result->ssa_temp_index());
613 }
614 }
615 #endif
srdjan 2012/08/15 02:07:31 Removed dead code before submitting
regis 2012/08/15 17:25:27 The code is now enabled and working.
590 if (FLAG_trace_type_check_elimination) { 616 if (FLAG_trace_type_check_elimination) {
591 FlowGraphPrinter::PrintTypeCheck(parsed_function(), 617 FlowGraphPrinter::PrintTypeCheck(parsed_function(),
592 comp->token_pos(), 618 comp->token_pos(),
593 comp->value(), 619 comp->value(),
594 comp->dst_type(), 620 comp->dst_type(),
595 comp->dst_name(), 621 comp->dst_name(),
596 comp->is_eliminated()); 622 comp->is_eliminated());
597 } 623 }
598 } 624 }
599 } 625 }
600 626
601 627
602 void FlowGraphTypePropagator::VisitAssertBoolean(AssertBooleanComp* comp, 628 void FlowGraphTypePropagator::VisitAssertBoolean(AssertBooleanComp* comp,
603 BindInstr* instr) { 629 BindInstr* instr) {
604 if (FLAG_eliminate_type_checks && 630 if (FLAG_eliminate_type_checks &&
605 !comp->is_eliminated() && 631 !comp->is_eliminated() &&
632 !comp->value()->IsConstantNull() &&
606 comp->value()->CompileTypeIsMoreSpecificThan( 633 comp->value()->CompileTypeIsMoreSpecificThan(
607 Type::Handle(Type::BoolInterface()))) { 634 Type::Handle(Type::BoolInterface()))) {
635 // TODO(regis): This optimization may not be correct, since a value of
636 // compile time type bool may still be null at run time. In this case,
637 // the bool expression will evaluate to false without throwing a dynamic
638 // type error.
608 comp->eliminate(); 639 comp->eliminate();
609 if (FLAG_trace_type_check_elimination) { 640 if (FLAG_trace_type_check_elimination) {
610 const String& name = String::Handle(Symbols::New("boolean expression")); 641 const String& name = String::Handle(Symbols::New("boolean expression"));
611 FlowGraphPrinter::PrintTypeCheck(parsed_function(), 642 FlowGraphPrinter::PrintTypeCheck(parsed_function(),
612 comp->token_pos(), 643 comp->token_pos(),
613 comp->value(), 644 comp->value(),
614 Type::Handle(Type::BoolInterface()), 645 Type::Handle(Type::BoolInterface()),
615 name, 646 name,
616 comp->is_eliminated()); 647 comp->is_eliminated());
617 } 648 }
618 } 649 }
619 } 650 }
620 651
621 652
653 void FlowGraphTypePropagator::VisitInstanceOf(InstanceOfComp* comp,
654 BindInstr* instr) {
655 // We can only eliminate an 'instance of' test when the checked value is
656 // a constant time constant. Indeed, a variable of the proper compile time
657 // type may still hold null at run time and therefore fail the test.
658 // We do not bother checking for Object destination type, since the graph
659 // builder did already.
660 if (FLAG_eliminate_type_checks &&
661 comp->value()->IsConstant() &&
662 !comp->value()->IsConstantNull() &&
663 comp->value()->CompileTypeIsMoreSpecificThan(comp->type())) {
664 // Remove instr from graph and replace uses with use of true or false.
665 UNIMPLEMENTED(); // TODO(regis): We never encounter this case so far.
666 if (FLAG_trace_type_check_elimination) {
667 const String& name = String::Handle(Symbols::New("InstanceOf"));
668 FlowGraphPrinter::PrintTypeCheck(parsed_function(),
669 comp->token_pos(),
670 comp->value(),
671 comp->type(),
672 name,
673 /* eliminated = */ true);
srdjan 2012/08/15 02:07:31 You cannot eliminate instance of using CompileType
regis 2012/08/15 17:25:27 I will be able to remove a non-constant value once
674 }
675 }
676 }
677
678
622 void FlowGraphTypePropagator::VisitGraphEntry(GraphEntryInstr* graph_entry) { 679 void FlowGraphTypePropagator::VisitGraphEntry(GraphEntryInstr* graph_entry) {
623 if (graph_entry->start_env() == NULL) { 680 if (graph_entry->start_env() == NULL) {
624 return; 681 return;
625 } 682 }
626 // Visit incoming parameters. 683 // Visit incoming parameters.
627 for (intptr_t i = 0; i < graph_entry->start_env()->values().length(); i++) { 684 for (intptr_t i = 0; i < graph_entry->start_env()->values().length(); i++) {
628 Value* val = graph_entry->start_env()->values()[i]; 685 Value* val = graph_entry->start_env()->values()[i];
629 if (val->IsUse()) { 686 if (val->IsUse()) {
630 ParameterInstr* param = val->AsUse()->definition()->AsParameter(); 687 ParameterInstr* param = val->AsUse()->definition()->AsParameter();
631 if (param != NULL) { 688 if (param != NULL) {
(...skipping 15 matching lines...) Expand all
647 } 704 }
648 } 705 }
649 } 706 }
650 707
651 708
652 void FlowGraphTypePropagator::VisitBind(BindInstr* bind) { 709 void FlowGraphTypePropagator::VisitBind(BindInstr* bind) {
653 // No need to propagate the input types of the bound computation, as long as 710 // No need to propagate the input types of the bound computation, as long as
654 // PhiInstr's are handled as part of JoinEntryInstr. 711 // PhiInstr's are handled as part of JoinEntryInstr.
655 // Visit computation and possibly eliminate type check. 712 // Visit computation and possibly eliminate type check.
656 bind->computation()->Accept(this, bind); 713 bind->computation()->Accept(this, bind);
657 // Cache propagated computation type. 714 // The current bind may have been removed from the graph.
srdjan 2012/08/15 02:07:31 Can this happen, since you are not removing instru
regis 2012/08/15 17:25:27 I am now.
658 AbstractType& type = AbstractType::Handle(bind->computation()->CompileType()); 715 if (current_iterator()->Current()->AsBind() == bind) {
659 bool changed = bind->SetPropagatedType(type); 716 // Current bind was not removed.
660 if (changed) { 717 // Cache propagated computation type.
661 still_changing_ = true; 718 AbstractType& computation_type =
719 AbstractType::Handle(bind->computation()->CompileType());
720 bool changed = bind->SetPropagatedType(computation_type);
721 if (changed) {
722 still_changing_ = true;
723 }
662 } 724 }
663 } 725 }
664 726
665 727
666 void FlowGraphTypePropagator::VisitPhi(PhiInstr* phi) { 728 void FlowGraphTypePropagator::VisitPhi(PhiInstr* phi) {
667 // We could set the propagated type of the phi to the least upper bound of its 729 // We could set the propagated type of the phi to the least upper bound of its
668 // input propagated types. However, keeping all propagated types allows us to 730 // input propagated types. However, keeping all propagated types allows us to
669 // optimize method dispatch. 731 // optimize method dispatch.
670 // TODO(regis): Support a set of propagated types. For now, we compute the 732 // TODO(regis): Support a set of propagated types. For now, we compute the
671 // least specific of the input propagated types. 733 // least specific of the input propagated types.
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after
718 LocationSummary* locs = it.Current()->locs(); 780 LocationSummary* locs = it.Current()->locs();
719 if ((locs != NULL) && locs->contains_call()) { 781 if ((locs != NULL) && locs->contains_call()) {
720 is_leaf_ = false; 782 is_leaf_ = false;
721 return; 783 return;
722 } 784 }
723 } 785 }
724 } 786 }
725 } 787 }
726 788
727 } // namespace dart 789 } // namespace dart
OLDNEW
« no previous file with comments | « runtime/vm/flow_graph_optimizer.h ('k') | runtime/vm/il_printer.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698