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

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

Issue 2789943002: Reland "VM: Handle null-comparisons in the flow graph type propagation" (Closed)
Patch Set: addressed comments Created 3 years, 8 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
« no previous file with comments | « runtime/vm/flow_graph.cc ('k') | runtime/vm/intermediate_language.h » ('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) 2013, the Dart project authors. Please see the AUTHORS file 1 // Copyright (c) 2013, 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_type_propagator.h" 5 #include "vm/flow_graph_type_propagator.h"
6 6
7 #include "vm/cha.h" 7 #include "vm/cha.h"
8 #include "vm/bit_vector.h" 8 #include "vm/bit_vector.h"
9 #include "vm/il_printer.h" 9 #include "vm/il_printer.h"
10 #include "vm/object_store.h" 10 #include "vm/object_store.h"
(...skipping 332 matching lines...) Expand 10 before | Expand all | Expand 10 after
343 if (load_cid != NULL && comparison->InputAt(1)->BindsToConstant()) { 343 if (load_cid != NULL && comparison->InputAt(1)->BindsToConstant()) {
344 intptr_t cid = Smi::Cast(comparison->InputAt(1)->BoundConstant()).Value(); 344 intptr_t cid = Smi::Cast(comparison->InputAt(1)->BoundConstant()).Value();
345 BlockEntryInstr* true_successor = 345 BlockEntryInstr* true_successor =
346 negated ? instr->false_successor() : instr->true_successor(); 346 negated ? instr->false_successor() : instr->true_successor();
347 redef = flow_graph_->EnsureRedefinition(true_successor, 347 redef = flow_graph_->EnsureRedefinition(true_successor,
348 load_cid->object()->definition(), 348 load_cid->object()->definition(),
349 CompileType::FromCid(cid)); 349 CompileType::FromCid(cid));
350 } else if ((call != NULL) && 350 } else if ((call != NULL) &&
351 call->MatchesCoreName(Symbols::_simpleInstanceOf()) && 351 call->MatchesCoreName(Symbols::_simpleInstanceOf()) &&
352 comparison->InputAt(1)->BindsToConstant() && 352 comparison->InputAt(1)->BindsToConstant() &&
353 (comparison->InputAt(1)->BoundConstant().IsBool())) { 353 comparison->InputAt(1)->BoundConstant().IsBool()) {
354 ASSERT(call->ArgumentAt(1)->IsConstant()); 354 ASSERT(call->ArgumentAt(1)->IsConstant());
355 if (comparison->InputAt(1)->BoundConstant().raw() == Bool::False().raw()) { 355 if (comparison->InputAt(1)->BoundConstant().raw() == Bool::False().raw()) {
356 negated = !negated; 356 negated = !negated;
357 } 357 }
358 BlockEntryInstr* true_successor = 358 BlockEntryInstr* true_successor =
359 negated ? instr->false_successor() : instr->true_successor(); 359 negated ? instr->false_successor() : instr->true_successor();
360 const Object& type = call->ArgumentAt(1)->AsConstant()->value(); 360 const Object& type = call->ArgumentAt(1)->AsConstant()->value();
361 if (type.IsType() && !Type::Cast(type).IsDynamicType() && 361 if (type.IsType() && !Type::Cast(type).IsDynamicType() &&
362 !Type::Cast(type).IsObjectType()) { 362 !Type::Cast(type).IsObjectType()) {
363 const bool is_nullable = Type::Cast(type).IsNullType() 363 const bool is_nullable = Type::Cast(type).IsNullType()
364 ? CompileType::kNullable 364 ? CompileType::kNullable
365 : CompileType::kNonNullable; 365 : CompileType::kNonNullable;
366 redef = flow_graph_->EnsureRedefinition( 366 redef = flow_graph_->EnsureRedefinition(
367 true_successor, call->ArgumentAt(0), 367 true_successor, call->ArgumentAt(0),
368 CompileType::FromAbstractType(Type::Cast(type), is_nullable)); 368 CompileType::FromAbstractType(Type::Cast(type), is_nullable));
369 } 369 }
370 } else if (comparison->InputAt(0)->BindsToConstant() &&
371 comparison->InputAt(0)->BoundConstant().IsNull()) {
372 // Handle for expr != null.
373 BlockEntryInstr* true_successor =
374 negated ? instr->true_successor() : instr->false_successor();
375 redef = flow_graph_->EnsureRedefinition(
376 true_successor, comparison->InputAt(1)->definition(),
377 comparison->InputAt(1)->Type()->CopyNonNullable());
378
379 } else if (comparison->InputAt(1)->BindsToConstant() &&
380 comparison->InputAt(1)->BoundConstant().IsNull()) {
381 // Handle for null != expr.
382 BlockEntryInstr* true_successor =
383 negated ? instr->true_successor() : instr->false_successor();
384 redef = flow_graph_->EnsureRedefinition(
385 true_successor, comparison->InputAt(0)->definition(),
386 comparison->InputAt(0)->Type()->CopyNonNullable());
370 } 387 }
371 // TODO(fschneider): Add propagation for null-comparisons.
372 // TODO(fschneider): Add propagation for generic is-tests. 388 // TODO(fschneider): Add propagation for generic is-tests.
373 389
374 // Grow types array if a new redefinition was inserted. 390 // Grow types array if a new redefinition was inserted.
375 if (redef != NULL) { 391 if (redef != NULL) {
376 for (intptr_t i = types_.length(); i <= redef->ssa_temp_index() + 1; ++i) { 392 for (intptr_t i = types_.length(); i <= redef->ssa_temp_index() + 1; ++i) {
377 types_.Add(NULL); 393 types_.Add(NULL);
378 } 394 }
379 } 395 }
380 } 396 }
381 397
(...skipping 161 matching lines...) Expand 10 before | Expand all | Expand 10 after
543 return Create(kNullCid, Type::ZoneHandle(Type::NullType())); 559 return Create(kNullCid, Type::ZoneHandle(Type::NullType()));
544 } 560 }
545 561
546 562
547 CompileType CompileType::Bool() { 563 CompileType CompileType::Bool() {
548 return Create(kBoolCid, Type::ZoneHandle(Type::BoolType())); 564 return Create(kBoolCid, Type::ZoneHandle(Type::BoolType()));
549 } 565 }
550 566
551 567
552 CompileType CompileType::Int() { 568 CompileType CompileType::Int() {
553 return FromAbstractType(Type::ZoneHandle(Type::IntType()), kNonNullable); 569 return FromAbstractType(Type::ZoneHandle(Type::Int64Type()), kNonNullable);
554 } 570 }
555 571
556 572
557 CompileType CompileType::Smi() { 573 CompileType CompileType::Smi() {
558 return Create(kSmiCid, Type::ZoneHandle(Type::SmiType())); 574 return Create(kSmiCid, Type::ZoneHandle(Type::SmiType()));
559 } 575 }
560 576
561 577
562 CompileType CompileType::String() { 578 CompileType CompileType::String() {
563 return FromAbstractType(Type::ZoneHandle(Type::StringType()), kNonNullable); 579 return FromAbstractType(Type::ZoneHandle(Type::StringType()), kNonNullable);
(...skipping 200 matching lines...) Expand 10 before | Expand all | Expand 10 after
764 return UpdateType(result); 780 return UpdateType(result);
765 } 781 }
766 782
767 783
768 CompileType RedefinitionInstr::ComputeType() const { 784 CompileType RedefinitionInstr::ComputeType() const {
769 if (constrained_type_ != NULL) { 785 if (constrained_type_ != NULL) {
770 // Check if the type associated with this redefinition is more specific 786 // Check if the type associated with this redefinition is more specific
771 // than the type of its input. If yes, return it. Otherwise, fall back 787 // than the type of its input. If yes, return it. Otherwise, fall back
772 // to the input's type. 788 // to the input's type.
773 789
774 // If either type has a concrete cid, stick with it.
775 if (value()->Type()->ToCid() != kDynamicCid) {
776 return *value()->Type();
777 }
778 if (constrained_type_->ToCid() != kDynamicCid) {
779 return *constrained_type_;
780 }
781 // If either type is non-nullable, the resulting type is non-nullable. 790 // If either type is non-nullable, the resulting type is non-nullable.
782 const bool is_nullable = 791 const bool is_nullable =
783 value()->Type()->is_nullable() && constrained_type_->is_nullable(); 792 value()->Type()->is_nullable() && constrained_type_->is_nullable();
793
794 // If either type has a concrete cid, stick with it.
795 if (value()->Type()->ToNullableCid() != kDynamicCid) {
796 return CompileType::CreateNullable(is_nullable,
797 value()->Type()->ToNullableCid());
798 }
799 if (constrained_type_->ToNullableCid() != kDynamicCid) {
800 return CompileType::CreateNullable(is_nullable,
801 constrained_type_->ToNullableCid());
802 }
784 if (value()->Type()->IsMoreSpecificThan( 803 if (value()->Type()->IsMoreSpecificThan(
785 *constrained_type_->ToAbstractType())) { 804 *constrained_type_->ToAbstractType())) {
786 return is_nullable ? *value()->Type() 805 return is_nullable ? *value()->Type()
787 : value()->Type()->CopyNonNullable(); 806 : value()->Type()->CopyNonNullable();
788 } else { 807 } else {
789 return is_nullable ? *constrained_type_ 808 return is_nullable ? *constrained_type_
790 : constrained_type_->CopyNonNullable(); 809 : constrained_type_->CopyNonNullable();
791 } 810 }
792 } 811 }
793 return *value()->Type(); 812 return *value()->Type();
(...skipping 731 matching lines...) Expand 10 before | Expand all | Expand 10 after
1525 CompileType MergedMathInstr::ComputeType() const { 1544 CompileType MergedMathInstr::ComputeType() const {
1526 return CompileType::Dynamic(); 1545 return CompileType::Dynamic();
1527 } 1546 }
1528 1547
1529 1548
1530 CompileType ExtractNthOutputInstr::ComputeType() const { 1549 CompileType ExtractNthOutputInstr::ComputeType() const {
1531 return CompileType::FromCid(definition_cid_); 1550 return CompileType::FromCid(definition_cid_);
1532 } 1551 }
1533 1552
1534 } // namespace dart 1553 } // namespace dart
OLDNEW
« no previous file with comments | « runtime/vm/flow_graph.cc ('k') | runtime/vm/intermediate_language.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698