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

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 1454 matching lines...) Expand 10 before | Expand all | Expand 10 after
1465 return AbstractType::null(); 1465 return AbstractType::null();
1466 } 1466 }
1467 1467
1468 1468
1469 RawAbstractType* CheckEitherNonSmiInstr::CompileType() const { 1469 RawAbstractType* CheckEitherNonSmiInstr::CompileType() const {
1470 return AbstractType::null(); 1470 return AbstractType::null();
1471 } 1471 }
1472 1472
1473 1473
1474 // Optimizations that eliminate or simplify individual instructions. 1474 // Optimizations that eliminate or simplify individual instructions.
1475 Instruction* Instruction::Canonicalize() { 1475 Instruction* Instruction::Canonicalize(FlowGraphOptimizer* optimizer) {
1476 return this; 1476 return this;
1477 } 1477 }
1478 1478
1479 1479
1480 Definition* Definition::Canonicalize() { 1480 Definition* Definition::Canonicalize(FlowGraphOptimizer* optimizer) {
1481 return this; 1481 return this;
1482 } 1482 }
1483 1483
1484 1484
1485 Definition* AssertBooleanInstr::Canonicalize() { 1485 Definition* AssertBooleanInstr::Canonicalize(FlowGraphOptimizer* optimizer) {
1486 const intptr_t value_cid = value()->ResultCid(); 1486 const intptr_t value_cid = value()->ResultCid();
1487 return (value_cid == kBoolCid) ? value()->definition() : this; 1487 return (value_cid == kBoolCid) ? value()->definition() : this;
1488 } 1488 }
1489 1489
1490 1490
1491 Definition* AssertAssignableInstr::Canonicalize() { 1491 Definition* AssertAssignableInstr::Canonicalize(FlowGraphOptimizer* optimizer) {
1492 // (1) Replace the assert with its input if the input has a known compatible 1492 // (1) Replace the assert with its input if the input has a known compatible
1493 // class-id. The class-ids handled here are those that are known to be 1493 // class-id. The class-ids handled here are those that are known to be
1494 // results of IL instructions. 1494 // results of IL instructions.
1495 intptr_t cid = value()->ResultCid(); 1495 intptr_t cid = value()->ResultCid();
1496 bool is_redundant = false; 1496 bool is_redundant = false;
1497 if (dst_type().IsIntType()) { 1497 if (dst_type().IsIntType()) {
1498 is_redundant = (cid == kSmiCid) || (cid == kMintCid); 1498 is_redundant = (cid == kSmiCid) || (cid == kMintCid);
1499 } else if (dst_type().IsDoubleType()) { 1499 } else if (dst_type().IsDoubleType()) {
1500 is_redundant = (cid == kDoubleCid); 1500 is_redundant = (cid == kDoubleCid);
1501 } else if (dst_type().IsBoolType()) { 1501 } else if (dst_type().IsBoolType()) {
1502 is_redundant = (cid == kBoolCid); 1502 is_redundant = (cid == kBoolCid);
1503 } 1503 }
1504 if (is_redundant) return value()->definition(); 1504 if (is_redundant) return value()->definition();
1505 1505
1506 // (2) Replace the assert with its input if the input is the result of a 1506 // (2) Replace the assert with its input if the input is the result of a
1507 // compatible assert itself. 1507 // compatible assert itself.
1508 AssertAssignableInstr* check = value()->definition()->AsAssertAssignable(); 1508 AssertAssignableInstr* check = value()->definition()->AsAssertAssignable();
1509 if ((check != NULL) && (check->dst_type().raw() == dst_type().raw())) { 1509 if ((check != NULL) &&
1510 (check->dst_type().Canonicalize() == dst_type().Canonicalize())) {
regis 2012/11/29 16:25:19 Aren't the types canonicalized already? It may be
Florian Schneider 2012/12/04 14:48:04 They are not all canonicalized. For now, I'm using
regis 2012/12/05 19:08:02 "For now"? Please add a TODO. Why are they not can
1510 // TODO(fschneider): Propagate type-assertions across phi-nodes. 1511 // TODO(fschneider): Propagate type-assertions across phi-nodes.
1511 // TODO(fschneider): Eliminate more asserts with subtype relation. 1512 // TODO(fschneider): Eliminate more asserts with subtype relation.
1512 return check; 1513 return check;
1513 } 1514 }
1515
1516 // (3) For uninstantiated target types: If the instantiator type arguments
1517 // are constant, instantiate the target type here.
1518 if (dst_type().IsInstantiated()) return this;
1519
1520 ConstantInstr* constant_type_args =
1521 instantiator_type_arguments()->definition()->AsConstant();
1522 if (constant_type_args != NULL &&
1523 !constant_type_args->value().IsNull() &&
1524 constant_type_args->value().IsTypeArguments()) {
1525 const TypeArguments& instantiator_type_args =
1526 TypeArguments::Cast(constant_type_args->value());
1527 const AbstractType& new_dst_type = AbstractType::ZoneHandle(
1528 dst_type().InstantiateFrom(instantiator_type_args));
regis 2012/11/29 16:25:19 You should canonicalize new_dst_type here.
Florian Schneider 2012/12/04 14:48:04 Done.
1529 set_dst_type(new_dst_type);
1530 ConstantInstr* null_constant = new ConstantInstr(Object::ZoneHandle());
1531 // It is ok to insert instructions before the current during
1532 // forward iteration.
1533 optimizer->InsertBefore(this, null_constant, NULL, Definition::kValue);
1534 instantiator_type_arguments()->RemoveFromInputUseList();
1535 instantiator_type_arguments()->set_definition(null_constant);
1536 instantiator_type_arguments()->AddToInputUseList();
1537 }
1514 return this; 1538 return this;
1515 } 1539 }
1516 1540
1517 Definition* StrictCompareInstr::Canonicalize() { 1541 Definition* StrictCompareInstr::Canonicalize(FlowGraphOptimizer* optimizer) {
1518 if (!right()->BindsToConstant()) return this; 1542 if (!right()->BindsToConstant()) return this;
1519 const Object& right_constant = right()->BoundConstant(); 1543 const Object& right_constant = right()->BoundConstant();
1520 Definition* left_defn = left()->definition(); 1544 Definition* left_defn = left()->definition();
1521 // TODO(fschneider): Handle other cases: e === false and e !== true/false. 1545 // TODO(fschneider): Handle other cases: e === false and e !== true/false.
1522 // Handles e === true. 1546 // Handles e === true.
1523 if ((kind() == Token::kEQ_STRICT) && 1547 if ((kind() == Token::kEQ_STRICT) &&
1524 (right_constant.raw() == Bool::True()) && 1548 (right_constant.raw() == Bool::True()) &&
1525 (left()->ResultCid() == kBoolCid)) { 1549 (left()->ResultCid() == kBoolCid)) {
1526 // Return left subexpression as the replacement for this instruction. 1550 // Return left subexpression as the replacement for this instruction.
1527 return left_defn; 1551 return left_defn;
1528 } 1552 }
1529 return this; 1553 return this;
1530 } 1554 }
1531 1555
1532 1556
1533 Instruction* CheckClassInstr::Canonicalize() { 1557 Instruction* CheckClassInstr::Canonicalize(FlowGraphOptimizer* optimizer) {
1534 const intptr_t value_cid = value()->ResultCid(); 1558 const intptr_t value_cid = value()->ResultCid();
1535 const intptr_t num_checks = unary_checks().NumberOfChecks(); 1559 const intptr_t num_checks = unary_checks().NumberOfChecks();
1536 if ((num_checks == 1) && 1560 if ((num_checks == 1) &&
1537 (value_cid == unary_checks().GetReceiverClassIdAt(0))) { 1561 (value_cid == unary_checks().GetReceiverClassIdAt(0))) {
1538 // No checks needed. 1562 // No checks needed.
1539 return NULL; 1563 return NULL;
1540 } 1564 }
1541 return this; 1565 return this;
1542 } 1566 }
1543 1567
1544 1568
1545 Instruction* CheckSmiInstr::Canonicalize() { 1569 Instruction* CheckSmiInstr::Canonicalize(FlowGraphOptimizer* optimizer) {
1546 return (value()->ResultCid() == kSmiCid) ? NULL : this; 1570 return (value()->ResultCid() == kSmiCid) ? NULL : this;
1547 } 1571 }
1548 1572
1549 1573
1550 Instruction* CheckEitherNonSmiInstr::Canonicalize() { 1574 Instruction* CheckEitherNonSmiInstr::Canonicalize(
1575 FlowGraphOptimizer* optimizer) {
1551 if ((left()->ResultCid() == kDoubleCid) || 1576 if ((left()->ResultCid() == kDoubleCid) ||
1552 (right()->ResultCid() == kDoubleCid)) { 1577 (right()->ResultCid() == kDoubleCid)) {
1553 return NULL; // Remove from the graph. 1578 return NULL; // Remove from the graph.
1554 } 1579 }
1555 return this; 1580 return this;
1556 } 1581 }
1557 1582
1558 1583
1559 // Shared code generation methods (EmitNativeCode, MakeLocationSummary, and 1584 // Shared code generation methods (EmitNativeCode, MakeLocationSummary, and
1560 // PrepareEntry). Only assembly code that can be shared across all architectures 1585 // PrepareEntry). Only assembly code that can be shared across all architectures
(...skipping 1149 matching lines...) Expand 10 before | Expand all | Expand 10 after
2710 default: 2735 default:
2711 UNREACHABLE(); 2736 UNREACHABLE();
2712 return -1; 2737 return -1;
2713 } 2738 }
2714 } 2739 }
2715 2740
2716 2741
2717 #undef __ 2742 #undef __
2718 2743
2719 } // namespace dart 2744 } // 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