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

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

Issue 10823022: Improve static type propagation. (Closed) Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge/dart/
Patch Set: Created 8 years, 5 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 | « no previous file | runtime/vm/flow_graph_compiler_ia32.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_builder.h" 5 #include "vm/flow_graph_builder.h"
6 6
7 #include "vm/ast_printer.h" 7 #include "vm/ast_printer.h"
8 #include "vm/bit_vector.h" 8 #include "vm/bit_vector.h"
9 #include "vm/code_descriptors.h" 9 #include "vm/code_descriptors.h"
10 #include "vm/dart_entry.h" 10 #include "vm/dart_entry.h"
(...skipping 447 matching lines...) Expand 10 before | Expand all | Expand 10 after
458 // compile time static type of the value. However, establishing here that 458 // compile time static type of the value. However, establishing here that
459 // the static type is a subtype of the destination type does not guarantee 459 // the static type is a subtype of the destination type does not guarantee
460 // that the run time type will also be a subtype of the destination type, 460 // that the run time type will also be a subtype of the destination type,
461 // because the subtype relation is not transitive. 461 // because the subtype relation is not transitive.
462 // However, the 'more specific than' relation is transitive and is used 462 // However, the 'more specific than' relation is transitive and is used
463 // here. In other words, if the static type of the value is more specific 463 // here. In other words, if the static type of the value is more specific
464 // than the destination type, the run time type of the value, which is 464 // than the destination type, the run time type of the value, which is
465 // guaranteed to be a subtype of the static type, is also guaranteed to be 465 // guaranteed to be a subtype of the static type, is also guaranteed to be
466 // a subtype of the destination type and the type check can therefore be 466 // a subtype of the destination type and the type check can therefore be
467 // eliminated. 467 // eliminated.
468 Error& malformed_error = Error::Handle(); 468 return static_type.IsMoreSpecificThan(dst_type, NULL);
469 return static_type.IsMoreSpecificThan(dst_type, &malformed_error);
470 } 469 }
471 470
472 471
473 // Returns true if the type check can be skipped, for example, if the 472 // Returns true if the type check can be skipped, for example, if the
474 // destination type is Dynamic or if the static type of the value is a subtype 473 // destination type is Dynamic or if the static type of the value is a subtype
475 // of the destination type. 474 // of the destination type.
476 bool EffectGraphVisitor::CanSkipTypeCheck(intptr_t token_pos, 475 bool EffectGraphVisitor::CanSkipTypeCheck(intptr_t token_pos,
477 Value* value, 476 Value* value,
478 const AbstractType& dst_type, 477 const AbstractType& dst_type,
479 const String& dst_name) { 478 const String& dst_name) {
(...skipping 250 matching lines...) Expand 10 before | Expand all | Expand 10 after
730 729
731 void ValueGraphVisitor::BuildTypeTest(ComparisonNode* node) { 730 void ValueGraphVisitor::BuildTypeTest(ComparisonNode* node) {
732 ASSERT(Token::IsTypeTestOperator(node->kind())); 731 ASSERT(Token::IsTypeTestOperator(node->kind()));
733 const Bool& bool_true = Bool::ZoneHandle(Bool::True()); 732 const Bool& bool_true = Bool::ZoneHandle(Bool::True());
734 const Bool& bool_false = Bool::ZoneHandle(Bool::False()); 733 const Bool& bool_false = Bool::ZoneHandle(Bool::False());
735 const AbstractType& type = node->right()->AsTypeNode()->type(); 734 const AbstractType& type = node->right()->AsTypeNode()->type();
736 ASSERT(type.IsFinalized() && !type.IsMalformed()); 735 ASSERT(type.IsFinalized() && !type.IsMalformed());
737 const bool negate_result = (node->kind() == Token::kISNOT); 736 const bool negate_result = (node->kind() == Token::kISNOT);
738 // All objects are instances of type T if Object type is a subtype of type T. 737 // All objects are instances of type T if Object type is a subtype of type T.
739 const Type& object_type = Type::Handle(Type::ObjectType()); 738 const Type& object_type = Type::Handle(Type::ObjectType());
740 Error& malformed_error = Error::Handle(); 739 if (type.IsInstantiated() && object_type.IsSubtypeOf(type, NULL)) {
741 if (type.IsInstantiated() &&
742 object_type.IsSubtypeOf(type, &malformed_error)) {
743 // Must evaluate left side. 740 // Must evaluate left side.
744 EffectGraphVisitor for_left_value(owner(), temp_index()); 741 EffectGraphVisitor for_left_value(owner(), temp_index());
745 node->left()->Visit(&for_left_value); 742 node->left()->Visit(&for_left_value);
746 Append(for_left_value); 743 Append(for_left_value);
747 ReturnComputation(new ConstantVal(negate_result ? bool_false : bool_true)); 744 ReturnComputation(new ConstantVal(negate_result ? bool_false : bool_true));
748 return; 745 return;
749 } 746 }
750 747
751 // Eliminate the test if it can be performed successfully at compile time. 748 // Eliminate the test if it can be performed successfully at compile time.
752 if ((node->left() != NULL) && 749 if ((node->left() != NULL) &&
753 node->left()->IsLiteralNode() && 750 node->left()->IsLiteralNode() &&
754 type.IsInstantiated()) { 751 type.IsInstantiated()) {
755 const Instance& literal_value = node->left()->AsLiteralNode()->literal(); 752 const Instance& literal_value = node->left()->AsLiteralNode()->literal();
756 const Class& cls = Class::Handle(literal_value.clazz()); 753 const Class& cls = Class::Handle(literal_value.clazz());
757 ConstantVal* result = NULL; 754 ConstantVal* result = NULL;
758 if (cls.IsNullClass()) { 755 if (cls.IsNullClass()) {
759 // A null object is only an instance of Object and Dynamic, which has 756 // A null object is only an instance of Object and Dynamic, which has
760 // already been checked above (if the type is instantiated). So we can 757 // already been checked above (if the type is instantiated). So we can
761 // return false here if the instance is null (and if the type is 758 // return false here if the instance is null (and if the type is
762 // instantiated). 759 // instantiated).
763 result = new ConstantVal(negate_result ? bool_true : bool_false); 760 result = new ConstantVal(negate_result ? bool_true : bool_false);
764 } else { 761 } else {
765 Error& malformed_error = Error::Handle(); 762 if (literal_value.IsInstanceOf(type, TypeArguments::Handle(), NULL)) {
766 if (literal_value.IsInstanceOf(type,
767 TypeArguments::Handle(),
768 &malformed_error)) {
769 result = new ConstantVal(negate_result ? bool_false : bool_true); 763 result = new ConstantVal(negate_result ? bool_false : bool_true);
770 } else { 764 } else {
771 ASSERT(malformed_error.IsNull());
772 result = new ConstantVal(negate_result ? bool_true : bool_false); 765 result = new ConstantVal(negate_result ? bool_true : bool_false);
773 } 766 }
774 } 767 }
775 ReturnComputation(result); 768 ReturnComputation(result);
776 return; 769 return;
777 } 770 }
778 771
779 ValueGraphVisitor for_left_value(owner(), temp_index()); 772 ValueGraphVisitor for_left_value(owner(), temp_index());
780 node->left()->Visit(&for_left_value); 773 node->left()->Visit(&for_left_value);
781 Append(for_left_value); 774 Append(for_left_value);
(...skipping 731 matching lines...) Expand 10 before | Expand all | Expand 10 after
1513 const bool requires_type_arguments = cls.HasTypeArguments(); 1506 const bool requires_type_arguments = cls.HasTypeArguments();
1514 1507
1515 ZoneGrowableArray<Value*>* allocate_arguments = 1508 ZoneGrowableArray<Value*>* allocate_arguments =
1516 new ZoneGrowableArray<Value*>(); 1509 new ZoneGrowableArray<Value*>();
1517 if (requires_type_arguments) { 1510 if (requires_type_arguments) {
1518 BuildConstructorTypeArguments(node, allocate_arguments); 1511 BuildConstructorTypeArguments(node, allocate_arguments);
1519 } 1512 }
1520 // In checked mode, if the type arguments are uninstantiated, they may need to 1513 // In checked mode, if the type arguments are uninstantiated, they may need to
1521 // be checked against declared bounds at run time. 1514 // be checked against declared bounds at run time.
1522 Computation* allocate_comp = NULL; 1515 Computation* allocate_comp = NULL;
1523 Error& malformed_error = Error::Handle();
1524 if (FLAG_enable_type_checks && 1516 if (FLAG_enable_type_checks &&
1525 requires_type_arguments && 1517 requires_type_arguments &&
1526 !node->type_arguments().IsNull() && 1518 !node->type_arguments().IsNull() &&
1527 !node->type_arguments().IsInstantiated() && 1519 !node->type_arguments().IsInstantiated() &&
1528 !node->type_arguments().IsWithinBoundsOf(cls, 1520 !node->type_arguments().IsWithinBoundsOf(cls,
1529 node->type_arguments(), 1521 node->type_arguments(),
1530 &malformed_error)) { 1522 NULL)) {
1531 // The uninstantiated type arguments cannot be verified to be within their 1523 // The uninstantiated type arguments cannot be verified to be within their
1532 // bounds at compile time, so verify them at runtime. 1524 // bounds at compile time, so verify them at runtime.
1533 // Although the type arguments may be uninstantiated at compile time, they 1525 // Although the type arguments may be uninstantiated at compile time, they
1534 // may represent the identity vector and may be replaced by the instantiated 1526 // may represent the identity vector and may be replaced by the instantiated
1535 // type arguments of the instantiator at run time. 1527 // type arguments of the instantiator at run time.
1536 allocate_comp = new AllocateObjectWithBoundsCheckComp(node, 1528 allocate_comp = new AllocateObjectWithBoundsCheckComp(node,
1537 owner()->try_index(), 1529 owner()->try_index(),
1538 allocate_arguments); 1530 allocate_arguments);
1539 } else { 1531 } else {
1540 allocate_comp = new AllocateObjectComp(node, 1532 allocate_comp = new AllocateObjectComp(node,
(...skipping 1189 matching lines...) Expand 10 before | Expand all | Expand 10 after
2730 char* chars = reinterpret_cast<char*>( 2722 char* chars = reinterpret_cast<char*>(
2731 Isolate::Current()->current_zone()->Allocate(len)); 2723 Isolate::Current()->current_zone()->Allocate(len));
2732 OS::SNPrint(chars, len, kFormat, function_name, reason); 2724 OS::SNPrint(chars, len, kFormat, function_name, reason);
2733 const Error& error = Error::Handle( 2725 const Error& error = Error::Handle(
2734 LanguageError::New(String::Handle(String::New(chars)))); 2726 LanguageError::New(String::Handle(String::New(chars))));
2735 Isolate::Current()->long_jump_base()->Jump(1, error); 2727 Isolate::Current()->long_jump_base()->Jump(1, error);
2736 } 2728 }
2737 2729
2738 2730
2739 } // namespace dart 2731 } // namespace dart
OLDNEW
« no previous file with comments | « no previous file | runtime/vm/flow_graph_compiler_ia32.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698