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

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

Issue 27307005: Change == into an instance call to allow polymorphic inlining of ==. (Closed) Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge/dart/
Patch Set: rebased, addressed comments Created 7 years, 1 month 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') | runtime/vm/intermediate_language_arm.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) 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/intermediate_language.h" 5 #include "vm/intermediate_language.h"
6 6
7 #include "vm/bigint_operations.h" 7 #include "vm/bigint_operations.h"
8 #include "vm/bit_vector.h" 8 #include "vm/bit_vector.h"
9 #include "vm/dart_entry.h" 9 #include "vm/dart_entry.h"
10 #include "vm/flow_graph_allocator.h" 10 #include "vm/flow_graph_allocator.h"
11 #include "vm/flow_graph_builder.h" 11 #include "vm/flow_graph_builder.h"
12 #include "vm/flow_graph_compiler.h" 12 #include "vm/flow_graph_compiler.h"
13 #include "vm/flow_graph_optimizer.h" 13 #include "vm/flow_graph_optimizer.h"
14 #include "vm/locations.h" 14 #include "vm/locations.h"
15 #include "vm/object.h" 15 #include "vm/object.h"
16 #include "vm/object_store.h" 16 #include "vm/object_store.h"
17 #include "vm/os.h" 17 #include "vm/os.h"
18 #include "vm/resolver.h" 18 #include "vm/resolver.h"
19 #include "vm/scopes.h" 19 #include "vm/scopes.h"
20 #include "vm/stub_code.h" 20 #include "vm/stub_code.h"
21 #include "vm/symbols.h" 21 #include "vm/symbols.h"
22 22
23 #include "vm/il_printer.h" 23 #include "vm/il_printer.h"
24 24
25 namespace dart { 25 namespace dart {
26 26
27 DEFINE_FLAG(int, max_equality_polymorphic_checks, 32,
28 "Maximum number of polymorphic checks in equality operator,"
29 " otherwise use megamorphic dispatch.");
30 DEFINE_FLAG(bool, new_identity_spec, true, 27 DEFINE_FLAG(bool, new_identity_spec, true,
31 "Use new identity check rules for numbers."); 28 "Use new identity check rules for numbers.");
32 DEFINE_FLAG(bool, propagate_ic_data, true, 29 DEFINE_FLAG(bool, propagate_ic_data, true,
33 "Propagate IC data from unoptimized to optimized IC calls."); 30 "Propagate IC data from unoptimized to optimized IC calls.");
34 DECLARE_FLAG(bool, enable_type_checks); 31 DECLARE_FLAG(bool, enable_type_checks);
35 DECLARE_FLAG(bool, eliminate_type_checks); 32 DECLARE_FLAG(bool, eliminate_type_checks);
36 DECLARE_FLAG(int, max_polymorphic_checks);
37 DECLARE_FLAG(bool, trace_optimization); 33 DECLARE_FLAG(bool, trace_optimization);
38 DECLARE_FLAG(bool, trace_constant_propagation); 34 DECLARE_FLAG(bool, trace_constant_propagation);
39 DECLARE_FLAG(bool, throw_on_javascript_int_overflow); 35 DECLARE_FLAG(bool, throw_on_javascript_int_overflow);
40 36
41 Definition::Definition() 37 Definition::Definition()
42 : range_(NULL), 38 : range_(NULL),
43 type_(NULL), 39 type_(NULL),
44 temp_index_(-1), 40 temp_index_(-1),
45 ssa_temp_index_(-1), 41 ssa_temp_index_(-1),
46 input_use_list_(NULL), 42 input_use_list_(NULL),
(...skipping 116 matching lines...) Expand 10 before | Expand all | Expand 10 after
163 } 159 }
164 160
165 161
166 bool MathMinMaxInstr::AttributesEqual(Instruction* other) const { 162 bool MathMinMaxInstr::AttributesEqual(Instruction* other) const {
167 MathMinMaxInstr* other_op = other->AsMathMinMax(); 163 MathMinMaxInstr* other_op = other->AsMathMinMax();
168 ASSERT(other_op != NULL); 164 ASSERT(other_op != NULL);
169 return (op_kind() == other_op->op_kind()) && 165 return (op_kind() == other_op->op_kind()) &&
170 (result_cid() == other_op->result_cid()); 166 (result_cid() == other_op->result_cid());
171 } 167 }
172 168
169
173 bool BinarySmiOpInstr::AttributesEqual(Instruction* other) const { 170 bool BinarySmiOpInstr::AttributesEqual(Instruction* other) const {
174 BinarySmiOpInstr* other_op = other->AsBinarySmiOp(); 171 BinarySmiOpInstr* other_op = other->AsBinarySmiOp();
175 ASSERT(other_op != NULL); 172 ASSERT(other_op != NULL);
176 return (op_kind() == other_op->op_kind()) && 173 return (op_kind() == other_op->op_kind()) &&
177 (overflow_ == other_op->overflow_) && 174 (overflow_ == other_op->overflow_) &&
178 (is_truncating_ == other_op->is_truncating_); 175 (is_truncating_ == other_op->is_truncating_);
179 } 176 }
180 177
181 178
182 EffectSet LoadFieldInstr::Dependencies() const { 179 EffectSet LoadFieldInstr::Dependencies() const {
(...skipping 929 matching lines...) Expand 10 before | Expand all | Expand 10 after
1112 ASSERT(index == 0); 1109 ASSERT(index == 0);
1113 return successor(); 1110 return successor();
1114 } 1111 }
1115 1112
1116 1113
1117 void Instruction::Goto(JoinEntryInstr* entry) { 1114 void Instruction::Goto(JoinEntryInstr* entry) {
1118 LinkTo(new GotoInstr(entry)); 1115 LinkTo(new GotoInstr(entry));
1119 } 1116 }
1120 1117
1121 1118
1122 bool EqualityCompareInstr::IsPolymorphic() const {
1123 return HasICData() &&
1124 (ic_data()->NumberOfChecks() > 0) &&
1125 (ic_data()->NumberOfChecks() <= FLAG_max_polymorphic_checks);
1126 }
1127
1128
1129 bool EqualityCompareInstr::IsCheckedStrictEqual() const {
1130 if (!HasICData()) return false;
1131 return ic_data()->AllTargetsHaveSameOwner(kInstanceCid) &&
1132 (unary_ic_data_->NumberOfChecks() <=
1133 FLAG_max_equality_polymorphic_checks);
1134 }
1135
1136
1137 bool BinarySmiOpInstr::CanDeoptimize() const { 1119 bool BinarySmiOpInstr::CanDeoptimize() const {
1138 if (FLAG_throw_on_javascript_int_overflow && (Smi::kBits > 32)) { 1120 if (FLAG_throw_on_javascript_int_overflow && (Smi::kBits > 32)) {
1139 // If Smi's are bigger than 32-bits, then the instruction could deoptimize 1121 // If Smi's are bigger than 32-bits, then the instruction could deoptimize
1140 // if the result is too big. 1122 // if the result is too big.
1141 return true; 1123 return true;
1142 } 1124 }
1143 switch (op_kind()) { 1125 switch (op_kind()) {
1144 case Token::kBIT_AND: 1126 case Token::kBIT_AND:
1145 case Token::kBIT_OR: 1127 case Token::kBIT_OR:
1146 case Token::kBIT_XOR: 1128 case Token::kBIT_XOR:
(...skipping 388 matching lines...) Expand 10 before | Expand all | Expand 10 after
1535 1517
1536 Definition* UnboxUint32x4Instr::Canonicalize(FlowGraph* flow_graph) { 1518 Definition* UnboxUint32x4Instr::Canonicalize(FlowGraph* flow_graph) {
1537 // Fold away UnboxUint32x4(BoxUint32x4(v)). 1519 // Fold away UnboxUint32x4(BoxUint32x4(v)).
1538 BoxUint32x4Instr* defn = value()->definition()->AsBoxUint32x4(); 1520 BoxUint32x4Instr* defn = value()->definition()->AsBoxUint32x4();
1539 return (defn != NULL) ? defn->value()->definition() : this; 1521 return (defn != NULL) ? defn->value()->definition() : this;
1540 } 1522 }
1541 1523
1542 1524
1543 Definition* BooleanNegateInstr::Canonicalize(FlowGraph* flow_graph) { 1525 Definition* BooleanNegateInstr::Canonicalize(FlowGraph* flow_graph) {
1544 Definition* defn = value()->definition(); 1526 Definition* defn = value()->definition();
1545 if (defn->IsComparison() && 1527 if (defn->IsComparison() && defn->HasOnlyUse(value())) {
1546 (value()->Type()->ToCid() == kBoolCid) && 1528 // Comparisons always have a bool result.
1547 defn->HasOnlyUse(value())) { 1529 ASSERT(value()->Type()->ToCid() == kBoolCid);
1548 defn->AsComparison()->NegateComparison(); 1530 defn->AsComparison()->NegateComparison();
1549 return defn; 1531 return defn;
1550 } 1532 }
1551 return this; 1533 return this;
1552 } 1534 }
1553 1535
1554 1536
1555 static bool MayBeBoxableNumber(intptr_t cid) { 1537 static bool MayBeBoxableNumber(intptr_t cid) {
1556 return (cid == kDynamicCid) || 1538 return (cid == kDynamicCid) ||
1557 (cid == kMintCid) || 1539 (cid == kMintCid) ||
(...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after
1606 (constant.raw() == Bool::True().raw()) && 1588 (constant.raw() == Bool::True().raw()) &&
1607 (other->Type()->ToCid() == kBoolCid)) { 1589 (other->Type()->ToCid() == kBoolCid)) {
1608 return other_defn; 1590 return other_defn;
1609 } 1591 }
1610 // Handle e !== false. 1592 // Handle e !== false.
1611 if ((kind == Token::kNE_STRICT) && 1593 if ((kind == Token::kNE_STRICT) &&
1612 (constant.raw() == Bool::False().raw()) && 1594 (constant.raw() == Bool::False().raw()) &&
1613 (other->Type()->ToCid() == kBoolCid)) { 1595 (other->Type()->ToCid() == kBoolCid)) {
1614 return other_defn; 1596 return other_defn;
1615 } 1597 }
1616 // Handle e !== true 1598 // Handle e !== true.
1617 if ((kind == Token::kNE_STRICT) && 1599 if ((kind == Token::kNE_STRICT) &&
1618 (constant.raw() == Bool::True().raw()) && 1600 (constant.raw() == Bool::True().raw()) &&
1619 other_defn->IsComparison() && 1601 other_defn->IsComparison() &&
1620 (other->Type()->ToCid() == kBoolCid) && 1602 (other->Type()->ToCid() == kBoolCid) &&
1621 other_defn->HasOnlyUse(other)) { 1603 other_defn->HasOnlyUse(other)) {
1622 *negated = true; 1604 *negated = true;
1623 return other_defn; 1605 return other_defn;
1624 } 1606 }
1607 // Handle e === false.
1625 if ((kind == Token::kEQ_STRICT) && 1608 if ((kind == Token::kEQ_STRICT) &&
1626 (constant.raw() == Bool::False().raw()) && 1609 (constant.raw() == Bool::False().raw()) &&
1627 other_defn->IsComparison() && 1610 other_defn->IsComparison() &&
1628 (other->Type()->ToCid() == kBoolCid) && 1611 (other->Type()->ToCid() == kBoolCid) &&
1629 other_defn->HasOnlyUse(other)) { 1612 other_defn->HasOnlyUse(other)) {
1630 *negated = true; 1613 *negated = true;
1631 return other_defn; 1614 return other_defn;
1632 } 1615 }
1633 return compare; 1616 return compare;
1634 } 1617 }
(...skipping 24 matching lines...) Expand all
1659 1642
1660 // Replace the comparison if the replacement is used at this branch, 1643 // Replace the comparison if the replacement is used at this branch,
1661 // and has exactly one use. 1644 // and has exactly one use.
1662 Value* use = comp->input_use_list(); 1645 Value* use = comp->input_use_list();
1663 if ((use->instruction() == this) && comp->HasOnlyUse(use)) { 1646 if ((use->instruction() == this) && comp->HasOnlyUse(use)) {
1664 if (negated) { 1647 if (negated) {
1665 comp->NegateComparison(); 1648 comp->NegateComparison();
1666 } 1649 }
1667 RemoveEnvironment(); 1650 RemoveEnvironment();
1668 flow_graph->CopyDeoptTarget(this, comp); 1651 flow_graph->CopyDeoptTarget(this, comp);
1652 // Unlink environment from the comparison since it is copied to the
1653 // branch instruction.
1654 comp->RemoveEnvironment();
1669 1655
1670 comp->RemoveFromGraph(); 1656 comp->RemoveFromGraph();
1671 SetComparison(comp); 1657 SetComparison(comp);
1672 if (FLAG_trace_optimization) { 1658 if (FLAG_trace_optimization) {
1673 OS::Print("Merging comparison v%" Pd "\n", comp->ssa_temp_index()); 1659 OS::Print("Merging comparison v%" Pd "\n", comp->ssa_temp_index());
1674 } 1660 }
1675 // Clear the comparison's temp index and ssa temp index since the 1661 // Clear the comparison's temp index and ssa temp index since the
1676 // value of the comparison is not used outside the branch anymore. 1662 // value of the comparison is not used outside the branch anymore.
1677 ASSERT(comp->input_use_list() == NULL); 1663 ASSERT(comp->input_use_list() == NULL);
1678 comp->ClearSSATempIndex(); 1664 comp->ClearSSATempIndex();
(...skipping 1212 matching lines...) Expand 10 before | Expand all | Expand 10 after
2891 return kCosRuntimeEntry; 2877 return kCosRuntimeEntry;
2892 default: 2878 default:
2893 UNREACHABLE(); 2879 UNREACHABLE();
2894 } 2880 }
2895 return kSinRuntimeEntry; 2881 return kSinRuntimeEntry;
2896 } 2882 }
2897 2883
2898 #undef __ 2884 #undef __
2899 2885
2900 } // namespace dart 2886 } // namespace dart
OLDNEW
« no previous file with comments | « runtime/vm/intermediate_language.h ('k') | runtime/vm/intermediate_language_arm.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698