| OLD | NEW |
| 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/bit_vector.h" | 7 #include "vm/bit_vector.h" |
| 8 #include "vm/cpu.h" | 8 #include "vm/cpu.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" |
| (...skipping 1150 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1161 } | 1161 } |
| 1162 | 1162 |
| 1163 | 1163 |
| 1164 void Instruction::Goto(JoinEntryInstr* entry) { | 1164 void Instruction::Goto(JoinEntryInstr* entry) { |
| 1165 LinkTo(new GotoInstr(entry)); | 1165 LinkTo(new GotoInstr(entry)); |
| 1166 } | 1166 } |
| 1167 | 1167 |
| 1168 | 1168 |
| 1169 bool UnboxedIntConverterInstr::CanDeoptimize() const { | 1169 bool UnboxedIntConverterInstr::CanDeoptimize() const { |
| 1170 return (to() == kUnboxedInt32) && | 1170 return (to() == kUnboxedInt32) && |
| 1171 !is_truncating() && |
| 1171 !RangeUtils::Fits(value()->definition()->range(), | 1172 !RangeUtils::Fits(value()->definition()->range(), |
| 1172 RangeBoundary::kRangeBoundaryInt32); | 1173 RangeBoundary::kRangeBoundaryInt32); |
| 1173 } | 1174 } |
| 1174 | 1175 |
| 1175 | 1176 |
| 1176 bool UnboxInt32Instr::CanDeoptimize() const { | 1177 bool UnboxInt32Instr::CanDeoptimize() const { |
| 1177 const intptr_t value_cid = value()->Type()->ToCid(); | 1178 const intptr_t value_cid = value()->Type()->ToCid(); |
| 1178 if (value_cid == kSmiCid) { | 1179 if (value_cid == kSmiCid) { |
| 1179 return false; | 1180 return (kSmiBits > 32) && |
| 1181 !is_truncating() && |
| 1182 !RangeUtils::Fits(value()->definition()->range(), |
| 1183 RangeBoundary::kRangeBoundaryInt32); |
| 1180 } else if (value_cid == kMintCid) { | 1184 } else if (value_cid == kMintCid) { |
| 1181 return !RangeUtils::Fits(value()->definition()->range(), | 1185 return !is_truncating() && |
| 1182 RangeBoundary::kRangeBoundaryInt32); | 1186 !RangeUtils::Fits(value()->definition()->range(), |
| 1187 RangeBoundary::kRangeBoundaryInt32); |
| 1183 } else { | 1188 } else { |
| 1184 return true; | 1189 return true; |
| 1185 } | 1190 } |
| 1186 } | 1191 } |
| 1187 | 1192 |
| 1188 | 1193 |
| 1189 bool BinaryInt32OpInstr::CanDeoptimize() const { | 1194 bool BinaryInt32OpInstr::CanDeoptimize() const { |
| 1190 switch (op_kind()) { | 1195 switch (op_kind()) { |
| 1191 case Token::kBIT_AND: | 1196 case Token::kBIT_AND: |
| 1192 case Token::kBIT_OR: | 1197 case Token::kBIT_OR: |
| (...skipping 543 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1736 BoxIntNInstr* box_defn = value()->definition()->AsBoxIntN(); | 1741 BoxIntNInstr* box_defn = value()->definition()->AsBoxIntN(); |
| 1737 if (box_defn != NULL) { | 1742 if (box_defn != NULL) { |
| 1738 if (box_defn->value()->definition()->representation() == representation()) { | 1743 if (box_defn->value()->definition()->representation() == representation()) { |
| 1739 return box_defn->value()->definition(); | 1744 return box_defn->value()->definition(); |
| 1740 } else { | 1745 } else { |
| 1741 UnboxedIntConverterInstr* converter = new UnboxedIntConverterInstr( | 1746 UnboxedIntConverterInstr* converter = new UnboxedIntConverterInstr( |
| 1742 box_defn->value()->definition()->representation(), | 1747 box_defn->value()->definition()->representation(), |
| 1743 representation(), | 1748 representation(), |
| 1744 box_defn->value()->CopyWithType(), | 1749 box_defn->value()->CopyWithType(), |
| 1745 representation() == kUnboxedInt32 ? deopt_id_ : Isolate::kNoDeoptId); | 1750 representation() == kUnboxedInt32 ? deopt_id_ : Isolate::kNoDeoptId); |
| 1751 if ((representation() == kUnboxedInt32) && is_truncating()) { |
| 1752 converter->mark_truncating(); |
| 1753 } |
| 1746 flow_graph->InsertBefore(this, converter, env(), FlowGraph::kValue); | 1754 flow_graph->InsertBefore(this, converter, env(), FlowGraph::kValue); |
| 1747 return converter; | 1755 return converter; |
| 1748 } | 1756 } |
| 1749 } | 1757 } |
| 1750 | 1758 |
| 1751 return this; | 1759 return this; |
| 1752 } | 1760 } |
| 1753 | 1761 |
| 1754 | 1762 |
| 1755 Definition* UnboxedIntConverterInstr::Canonicalize(FlowGraph* flow_graph) { | 1763 Definition* UnboxedIntConverterInstr::Canonicalize(FlowGraph* flow_graph) { |
| 1756 if (!HasUses()) return NULL; | 1764 if (!HasUses()) return NULL; |
| 1757 | 1765 |
| 1758 UnboxedIntConverterInstr* box_defn = | 1766 UnboxedIntConverterInstr* box_defn = |
| 1759 value()->definition()->AsUnboxedIntConverter(); | 1767 value()->definition()->AsUnboxedIntConverter(); |
| 1760 if ((box_defn != NULL) && (box_defn->representation() == from())) { | 1768 if ((box_defn != NULL) && (box_defn->representation() == from())) { |
| 1761 if (box_defn->from() == to()) { | 1769 if (box_defn->from() == to()) { |
| 1762 return box_defn->value()->definition(); | 1770 return box_defn->value()->definition(); |
| 1763 } | 1771 } |
| 1764 | 1772 |
| 1765 UnboxedIntConverterInstr* converter = new UnboxedIntConverterInstr( | 1773 UnboxedIntConverterInstr* converter = new UnboxedIntConverterInstr( |
| 1766 box_defn->from(), | 1774 box_defn->from(), |
| 1767 representation(), | 1775 representation(), |
| 1768 box_defn->value()->CopyWithType(), | 1776 box_defn->value()->CopyWithType(), |
| 1769 to() == kUnboxedInt32 ? deopt_id_ : NULL); | 1777 to() == kUnboxedInt32 ? deopt_id_ : NULL); |
| 1778 if ((representation() == kUnboxedInt32) && is_truncating()) { |
| 1779 converter->mark_truncating(); |
| 1780 } |
| 1770 flow_graph->InsertBefore(this, converter, env(), FlowGraph::kValue); | 1781 flow_graph->InsertBefore(this, converter, env(), FlowGraph::kValue); |
| 1771 return converter; | 1782 return converter; |
| 1772 } | 1783 } |
| 1773 | 1784 |
| 1774 UnboxIntegerInstr* unbox_defn = value()->definition()->AsUnboxInteger(); | 1785 UnboxIntegerInstr* unbox_defn = value()->definition()->AsUnboxInteger(); |
| 1775 if (unbox_defn != NULL && | 1786 if (unbox_defn != NULL && |
| 1776 (from() == kUnboxedMint) && | 1787 (from() == kUnboxedMint) && |
| 1777 (to() == kUnboxedInt32) && | 1788 (to() == kUnboxedInt32) && |
| 1778 unbox_defn->HasOnlyInputUse(value())) { | 1789 unbox_defn->HasOnlyInputUse(value())) { |
| 1779 // TODO(vegorov): there is a duplication of code between UnboxedIntCoverter | 1790 // TODO(vegorov): there is a duplication of code between UnboxedIntCoverter |
| 1780 // and code path that unboxes Mint into Int32. We should just schedule | 1791 // and code path that unboxes Mint into Int32. We should just schedule |
| 1781 // these instructions close to each other instead of fusing them. | 1792 // these instructions close to each other instead of fusing them. |
| 1782 Definition* replacement = | 1793 Definition* replacement = |
| 1783 new UnboxInt32Instr(unbox_defn->value()->CopyWithType(), deopt_id_); | 1794 new UnboxInt32Instr(unbox_defn->value()->CopyWithType(), deopt_id_); |
| 1795 if (is_truncating()) { |
| 1796 replacement->AsUnboxInt32()->mark_truncating(); |
| 1797 } |
| 1784 flow_graph->InsertBefore(this, | 1798 flow_graph->InsertBefore(this, |
| 1785 replacement, | 1799 replacement, |
| 1786 env(), | 1800 env(), |
| 1787 FlowGraph::kValue); | 1801 FlowGraph::kValue); |
| 1788 return replacement; | 1802 return replacement; |
| 1789 } | 1803 } |
| 1790 | 1804 |
| 1791 return this; | 1805 return this; |
| 1792 } | 1806 } |
| 1793 | 1807 |
| 1794 | 1808 |
| 1795 Definition* UnboxInt32Instr::Canonicalize(FlowGraph* flow_graph) { | 1809 Definition* UnboxInt32Instr::Canonicalize(FlowGraph* flow_graph) { |
| 1796 Definition* replacement = UnboxIntNInstr::Canonicalize(flow_graph); | 1810 Definition* replacement = UnboxIntNInstr::Canonicalize(flow_graph); |
| 1797 if (replacement != this) { | 1811 if (replacement != this) { |
| 1798 return replacement; | 1812 return replacement; |
| 1799 } | 1813 } |
| 1800 | 1814 |
| 1801 ConstantInstr* c = value()->definition()->AsConstant(); | 1815 ConstantInstr* c = value()->definition()->AsConstant(); |
| 1802 if ((c != NULL) && c->value().IsSmi()) { | 1816 if ((c != NULL) && c->value().IsSmi()) { |
| 1817 if (!is_truncating() && (kSmiBits > 32)) { |
| 1818 // Check that constant fits into 32-bit integer. |
| 1819 const int64_t value = |
| 1820 static_cast<int64_t>(Smi::Cast(c->value()).Value()); |
| 1821 if (!Utils::IsInt(32, value)) { |
| 1822 return this; |
| 1823 } |
| 1824 } |
| 1825 |
| 1803 UnboxedConstantInstr* uc = | 1826 UnboxedConstantInstr* uc = |
| 1804 new UnboxedConstantInstr(c->value(), kUnboxedInt32); | 1827 new UnboxedConstantInstr(c->value(), kUnboxedInt32); |
| 1805 flow_graph->InsertBefore(this, uc, NULL, FlowGraph::kValue); | 1828 flow_graph->InsertBefore(this, uc, NULL, FlowGraph::kValue); |
| 1806 return uc; | 1829 return uc; |
| 1807 } | 1830 } |
| 1808 | 1831 |
| 1809 return this; | 1832 return this; |
| 1810 } | 1833 } |
| 1811 | 1834 |
| 1812 | 1835 |
| (...skipping 1279 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3092 case Token::kTRUNCDIV: return 0; | 3115 case Token::kTRUNCDIV: return 0; |
| 3093 case Token::kMOD: return 1; | 3116 case Token::kMOD: return 1; |
| 3094 default: UNIMPLEMENTED(); return -1; | 3117 default: UNIMPLEMENTED(); return -1; |
| 3095 } | 3118 } |
| 3096 } | 3119 } |
| 3097 | 3120 |
| 3098 | 3121 |
| 3099 #undef __ | 3122 #undef __ |
| 3100 | 3123 |
| 3101 } // namespace dart | 3124 } // namespace dart |
| OLD | NEW |