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

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

Issue 11280230: Optimize checked mode asserts with uninstantiated types and known constant type-arguments. (Closed) Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge/dart/
Patch Set: Created 8 years 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/intermediate_language.h ('k') | no next file » | 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/intermediate_language.h" 5 #include "vm/intermediate_language.h"
6 6
7 #include "vm/bit_vector.h" 7 #include "vm/bit_vector.h"
8 #include "vm/dart_entry.h" 8 #include "vm/dart_entry.h"
9 #include "vm/flow_graph_allocator.h" 9 #include "vm/flow_graph_allocator.h"
10 #include "vm/flow_graph_builder.h" 10 #include "vm/flow_graph_builder.h"
(...skipping 1449 matching lines...) Expand 10 before | Expand all | Expand 10 after
1460 return AbstractType::null(); 1460 return AbstractType::null();
1461 } 1461 }
1462 1462
1463 1463
1464 RawAbstractType* CheckEitherNonSmiInstr::CompileType() const { 1464 RawAbstractType* CheckEitherNonSmiInstr::CompileType() const {
1465 return AbstractType::null(); 1465 return AbstractType::null();
1466 } 1466 }
1467 1467
1468 1468
1469 // Optimizations that eliminate or simplify individual instructions. 1469 // Optimizations that eliminate or simplify individual instructions.
1470 Instruction* Instruction::Canonicalize() { 1470 Instruction* Instruction::Canonicalize(FlowGraphOptimizer* optimizer) {
1471 return this; 1471 return this;
1472 } 1472 }
1473 1473
1474 1474
1475 Definition* Definition::Canonicalize() { 1475 Definition* Definition::Canonicalize(FlowGraphOptimizer* optimizer) {
1476 return this; 1476 return this;
1477 } 1477 }
1478 1478
1479 1479
1480 Definition* AssertBooleanInstr::Canonicalize() { 1480 Definition* AssertBooleanInstr::Canonicalize(FlowGraphOptimizer* optimizer) {
1481 const intptr_t value_cid = value()->ResultCid(); 1481 const intptr_t value_cid = value()->ResultCid();
1482 return (value_cid == kBoolCid) ? value()->definition() : this; 1482 return (value_cid == kBoolCid) ? value()->definition() : this;
1483 } 1483 }
1484 1484
1485 1485
1486 Definition* AssertAssignableInstr::Canonicalize() { 1486 Definition* AssertAssignableInstr::Canonicalize(FlowGraphOptimizer* optimizer) {
1487 // (1) Replace the assert with its input if the input has a known compatible 1487 // (1) Replace the assert with its input if the input has a known compatible
1488 // class-id. The class-ids handled here are those that are known to be 1488 // class-id. The class-ids handled here are those that are known to be
1489 // results of IL instructions. 1489 // results of IL instructions.
1490 intptr_t cid = value()->ResultCid(); 1490 intptr_t cid = value()->ResultCid();
1491 bool is_redundant = false; 1491 bool is_redundant = false;
1492 if (dst_type().IsIntType()) { 1492 if (dst_type().IsIntType()) {
1493 is_redundant = (cid == kSmiCid) || (cid == kMintCid); 1493 is_redundant = (cid == kSmiCid) || (cid == kMintCid);
1494 } else if (dst_type().IsDoubleType()) { 1494 } else if (dst_type().IsDoubleType()) {
1495 is_redundant = (cid == kDoubleCid); 1495 is_redundant = (cid == kDoubleCid);
1496 } else if (dst_type().IsBoolType()) { 1496 } else if (dst_type().IsBoolType()) {
1497 is_redundant = (cid == kBoolCid); 1497 is_redundant = (cid == kBoolCid);
1498 } 1498 }
1499 if (is_redundant) return value()->definition(); 1499 if (is_redundant) return value()->definition();
1500 1500
1501 // (2) Replace the assert with its input if the input is the result of a 1501 // (2) Replace the assert with its input if the input is the result of a
1502 // compatible assert itself. 1502 // compatible assert itself.
1503 AssertAssignableInstr* check = value()->definition()->AsAssertAssignable(); 1503 AssertAssignableInstr* check = value()->definition()->AsAssertAssignable();
1504 if ((check != NULL) && (check->dst_type().raw() == dst_type().raw())) { 1504 if ((check != NULL) && check->dst_type().Equals(dst_type())) {
1505 // TODO(fschneider): Propagate type-assertions across phi-nodes. 1505 // TODO(fschneider): Propagate type-assertions across phi-nodes.
1506 // TODO(fschneider): Eliminate more asserts with subtype relation. 1506 // TODO(fschneider): Eliminate more asserts with subtype relation.
1507 return check; 1507 return check;
1508 } 1508 }
1509
1510 // (3) For uninstantiated target types: If the instantiator type arguments
1511 // are constant, instantiate the target type here.
1512 if (dst_type().IsInstantiated()) return this;
1513
1514 ConstantInstr* constant_type_args =
1515 instantiator_type_arguments()->definition()->AsConstant();
1516 if (constant_type_args != NULL &&
1517 !constant_type_args->value().IsNull() &&
1518 constant_type_args->value().IsTypeArguments()) {
1519 const TypeArguments& instantiator_type_args =
1520 TypeArguments::Cast(constant_type_args->value());
1521 const AbstractType& new_dst_type = AbstractType::Handle(
1522 dst_type().InstantiateFrom(instantiator_type_args));
1523 set_dst_type(AbstractType::ZoneHandle(new_dst_type.Canonicalize()));
1524 ConstantInstr* null_constant = new ConstantInstr(Object::ZoneHandle());
1525 // It is ok to insert instructions before the current during
1526 // forward iteration.
1527 optimizer->InsertBefore(this, null_constant, NULL, Definition::kValue);
1528 instantiator_type_arguments()->RemoveFromInputUseList();
1529 instantiator_type_arguments()->set_definition(null_constant);
1530 instantiator_type_arguments()->AddToInputUseList();
1531 }
1509 return this; 1532 return this;
1510 } 1533 }
1511 1534
1512 Definition* StrictCompareInstr::Canonicalize() { 1535 Definition* StrictCompareInstr::Canonicalize(FlowGraphOptimizer* optimizer) {
1513 if (!right()->BindsToConstant()) return this; 1536 if (!right()->BindsToConstant()) return this;
1514 const Object& right_constant = right()->BoundConstant(); 1537 const Object& right_constant = right()->BoundConstant();
1515 Definition* left_defn = left()->definition(); 1538 Definition* left_defn = left()->definition();
1516 // TODO(fschneider): Handle other cases: e === false and e !== true/false. 1539 // TODO(fschneider): Handle other cases: e === false and e !== true/false.
1517 // Handles e === true. 1540 // Handles e === true.
1518 if ((kind() == Token::kEQ_STRICT) && 1541 if ((kind() == Token::kEQ_STRICT) &&
1519 (right_constant.raw() == Bool::True()) && 1542 (right_constant.raw() == Bool::True()) &&
1520 (left()->ResultCid() == kBoolCid)) { 1543 (left()->ResultCid() == kBoolCid)) {
1521 // Return left subexpression as the replacement for this instruction. 1544 // Return left subexpression as the replacement for this instruction.
1522 return left_defn; 1545 return left_defn;
1523 } 1546 }
1524 return this; 1547 return this;
1525 } 1548 }
1526 1549
1527 1550
1528 Instruction* CheckClassInstr::Canonicalize() { 1551 Instruction* CheckClassInstr::Canonicalize(FlowGraphOptimizer* optimizer) {
1529 const intptr_t value_cid = value()->ResultCid(); 1552 const intptr_t value_cid = value()->ResultCid();
1530 const intptr_t num_checks = unary_checks().NumberOfChecks(); 1553 const intptr_t num_checks = unary_checks().NumberOfChecks();
1531 if ((num_checks == 1) && 1554 if ((num_checks == 1) &&
1532 (value_cid == unary_checks().GetReceiverClassIdAt(0))) { 1555 (value_cid == unary_checks().GetReceiverClassIdAt(0))) {
1533 // No checks needed. 1556 // No checks needed.
1534 return NULL; 1557 return NULL;
1535 } 1558 }
1536 return this; 1559 return this;
1537 } 1560 }
1538 1561
1539 1562
1540 Instruction* CheckSmiInstr::Canonicalize() { 1563 Instruction* CheckSmiInstr::Canonicalize(FlowGraphOptimizer* optimizer) {
1541 return (value()->ResultCid() == kSmiCid) ? NULL : this; 1564 return (value()->ResultCid() == kSmiCid) ? NULL : this;
1542 } 1565 }
1543 1566
1544 1567
1545 Instruction* CheckEitherNonSmiInstr::Canonicalize() { 1568 Instruction* CheckEitherNonSmiInstr::Canonicalize(
1569 FlowGraphOptimizer* optimizer) {
1546 if ((left()->ResultCid() == kDoubleCid) || 1570 if ((left()->ResultCid() == kDoubleCid) ||
1547 (right()->ResultCid() == kDoubleCid)) { 1571 (right()->ResultCid() == kDoubleCid)) {
1548 return NULL; // Remove from the graph. 1572 return NULL; // Remove from the graph.
1549 } 1573 }
1550 return this; 1574 return this;
1551 } 1575 }
1552 1576
1553 1577
1554 // Shared code generation methods (EmitNativeCode, MakeLocationSummary, and 1578 // Shared code generation methods (EmitNativeCode, MakeLocationSummary, and
1555 // PrepareEntry). Only assembly code that can be shared across all architectures 1579 // PrepareEntry). Only assembly code that can be shared across all architectures
(...skipping 1172 matching lines...) Expand 10 before | Expand all | Expand 10 after
2728 default: 2752 default:
2729 UNREACHABLE(); 2753 UNREACHABLE();
2730 return -1; 2754 return -1;
2731 } 2755 }
2732 } 2756 }
2733 2757
2734 2758
2735 #undef __ 2759 #undef __
2736 2760
2737 } // namespace dart 2761 } // namespace dart
OLDNEW
« no previous file with comments | « runtime/vm/intermediate_language.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698