OLD | NEW |
---|---|
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 #ifndef VM_INTERMEDIATE_LANGUAGE_H_ | 5 #ifndef VM_INTERMEDIATE_LANGUAGE_H_ |
6 #define VM_INTERMEDIATE_LANGUAGE_H_ | 6 #define VM_INTERMEDIATE_LANGUAGE_H_ |
7 | 7 |
8 #include "vm/allocation.h" | 8 #include "vm/allocation.h" |
9 #include "vm/ast.h" | 9 #include "vm/ast.h" |
10 #include "vm/growable_array.h" | 10 #include "vm/growable_array.h" |
11 #include "vm/handles_impl.h" | 11 #include "vm/handles_impl.h" |
12 #include "vm/object.h" | 12 #include "vm/object.h" |
13 | 13 |
14 namespace dart { | 14 namespace dart { |
15 | 15 |
16 class BitVector; | 16 class BitVector; |
17 class FlowGraphVisitor; | 17 class FlowGraphVisitor; |
18 class LocalVariable; | 18 class LocalVariable; |
19 class LocationSummary; | |
19 | 20 |
20 // M is a two argument macro. It is applied to each concrete value's | 21 // M is a two argument macro. It is applied to each concrete value's |
21 // typename and classname. | 22 // typename and classname. |
22 #define FOR_EACH_VALUE(M) \ | 23 #define FOR_EACH_VALUE(M) \ |
23 M(Use, UseVal) \ | 24 M(Use, UseVal) \ |
24 M(Constant, ConstantVal) \ | 25 M(Constant, ConstantVal) \ |
25 | 26 |
26 | 27 |
27 // M is a two argument macro. It is applied to each concrete instruction's | 28 // M is a two argument macro. It is applied to each concrete instruction's |
28 // (including the values) typename and classname. | 29 // (including the values) typename and classname. |
(...skipping 72 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
101 // frame-allocated locals assigned to by the computation. | 102 // frame-allocated locals assigned to by the computation. |
102 virtual void RecordAssignedVars(BitVector* assigned_vars); | 103 virtual void RecordAssignedVars(BitVector* assigned_vars); |
103 | 104 |
104 virtual const char* DebugName() const = 0; | 105 virtual const char* DebugName() const = 0; |
105 | 106 |
106 // Printing support. These functions are sometimes overridden for custom | 107 // Printing support. These functions are sometimes overridden for custom |
107 // formatting. Otherwise, it prints in the format "opcode(op1, op2, op3)". | 108 // formatting. Otherwise, it prints in the format "opcode(op1, op2, op3)". |
108 virtual void PrintTo(BufferFormatter* f) const; | 109 virtual void PrintTo(BufferFormatter* f) const; |
109 virtual void PrintOperandsTo(BufferFormatter* f) const; | 110 virtual void PrintOperandsTo(BufferFormatter* f) const; |
110 | 111 |
112 // Returns structure describing location constraints required | |
113 // to emit native code for this computation. | |
114 virtual LocationSummary* GetLocationSummary() const { | |
115 // TODO(vegorov): This should be pure virtual method. | |
116 // However we are temporary using NULL for instructions that | |
117 // were not converted to the location based code generation yet. | |
118 return NULL; | |
119 } | |
120 | |
111 private: | 121 private: |
112 friend class Instruction; | 122 friend class Instruction; |
113 static intptr_t GetNextCid(Isolate* isolate) { | 123 static intptr_t GetNextCid(Isolate* isolate) { |
114 intptr_t tmp = isolate->computation_id(); | 124 intptr_t tmp = isolate->computation_id(); |
115 isolate->set_computation_id(tmp + 1); | 125 isolate->set_computation_id(tmp + 1); |
116 return tmp; | 126 return tmp; |
117 } | 127 } |
118 static ICData* GetICDataForCid(intptr_t cid, Isolate* isolate) { | 128 static ICData* GetICDataForCid(intptr_t cid, Isolate* isolate) { |
119 if (isolate->ic_data_array() == Array::null()) { | 129 if (isolate->ic_data_array() == Array::null()) { |
120 return NULL; | 130 return NULL; |
(...skipping 321 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
442 }; | 452 }; |
443 | 453 |
444 | 454 |
445 class StrictCompareComp : public TemplateComputation<2> { | 455 class StrictCompareComp : public TemplateComputation<2> { |
446 public: | 456 public: |
447 StrictCompareComp(Token::Kind kind, Value* left, Value* right) | 457 StrictCompareComp(Token::Kind kind, Value* left, Value* right) |
448 : kind_(kind) { | 458 : kind_(kind) { |
449 ASSERT((kind_ == Token::kEQ_STRICT) || (kind_ == Token::kNE_STRICT)); | 459 ASSERT((kind_ == Token::kEQ_STRICT) || (kind_ == Token::kNE_STRICT)); |
450 inputs_[0] = left; | 460 inputs_[0] = left; |
451 inputs_[1] = right; | 461 inputs_[1] = right; |
462 location_summary_ = MakeLocationSummary(); | |
452 } | 463 } |
453 | 464 |
454 DECLARE_COMPUTATION(StrictCompare) | 465 DECLARE_COMPUTATION(StrictCompare) |
455 | 466 |
456 Token::Kind kind() const { return kind_; } | 467 Token::Kind kind() const { return kind_; } |
457 Value* left() const { return inputs_[0]; } | 468 Value* left() const { return inputs_[0]; } |
458 Value* right() const { return inputs_[1]; } | 469 Value* right() const { return inputs_[1]; } |
459 | 470 |
460 virtual void PrintOperandsTo(BufferFormatter* f) const; | 471 virtual void PrintOperandsTo(BufferFormatter* f) const; |
461 | 472 |
473 virtual LocationSummary* GetLocationSummary() const { | |
474 return location_summary_; | |
475 } | |
476 | |
477 // Platform specific summary factory for this instruction. | |
478 LocationSummary* MakeLocationSummary(); | |
479 | |
462 private: | 480 private: |
463 const Token::Kind kind_; | 481 const Token::Kind kind_; |
464 | 482 |
483 LocationSummary* location_summary_; | |
484 | |
465 DISALLOW_COPY_AND_ASSIGN(StrictCompareComp); | 485 DISALLOW_COPY_AND_ASSIGN(StrictCompareComp); |
466 }; | 486 }; |
467 | 487 |
468 | 488 |
469 class EqualityCompareComp : public TemplateComputation<2> { | 489 class EqualityCompareComp : public TemplateComputation<2> { |
470 public: | 490 public: |
471 EqualityCompareComp(intptr_t token_index, | 491 EqualityCompareComp(intptr_t token_index, |
472 intptr_t try_index, | 492 intptr_t try_index, |
473 Value* left, | 493 Value* left, |
474 Value* right) | 494 Value* right) |
(...skipping 881 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1356 virtual type##Instr* As##type() { return NULL; } | 1376 virtual type##Instr* As##type() { return NULL; } |
1357 FOR_EACH_INSTRUCTION(INSTRUCTION_TYPE_CHECK) | 1377 FOR_EACH_INSTRUCTION(INSTRUCTION_TYPE_CHECK) |
1358 #undef INSTRUCTION_TYPE_CHECK | 1378 #undef INSTRUCTION_TYPE_CHECK |
1359 | 1379 |
1360 // Static type of the instruction. | 1380 // Static type of the instruction. |
1361 virtual RawAbstractType* StaticType() const { | 1381 virtual RawAbstractType* StaticType() const { |
1362 UNREACHABLE(); | 1382 UNREACHABLE(); |
1363 return AbstractType::null(); | 1383 return AbstractType::null(); |
1364 } | 1384 } |
1365 | 1385 |
1386 // Returns structure describing location constraints required | |
1387 // to emit native code for this instruction. | |
1388 virtual LocationSummary* GetLocationSummary() const { | |
1389 // TODO(vegorov): This should be pure virtual method. | |
1390 // However we are temporary using NULL for instructions that | |
1391 // were not converted to the location based code generation yet. | |
1392 return NULL; | |
srdjan
2012/05/18 18:00:14
Will we need this? I would guess that we are only
Vyacheslav Egorov (Google)
2012/05/20 12:07:46
Some instructions also pop and push things (see fo
srdjan
2012/05/21 16:05:22
Please add comment why this is needed (essentially
| |
1393 } | |
1394 | |
1366 private: | 1395 private: |
1367 intptr_t cid_; | 1396 intptr_t cid_; |
1368 ICData* ic_data_; | 1397 ICData* ic_data_; |
1369 DISALLOW_COPY_AND_ASSIGN(Instruction); | 1398 DISALLOW_COPY_AND_ASSIGN(Instruction); |
1370 }; | 1399 }; |
1371 | 1400 |
1372 | 1401 |
1373 // Basic block entries are administrative nodes. There is a distinguished | 1402 // Basic block entries are administrative nodes. There is a distinguished |
1374 // graph entry with no predecessor. Joins are the only nodes with multiple | 1403 // graph entry with no predecessor. Joins are the only nodes with multiple |
1375 // predecessors. Targets are all other basic block entries. The types | 1404 // predecessors. Targets are all other basic block entries. The types |
(...skipping 184 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1560 virtual Instruction* StraightLineSuccessor() const { | 1589 virtual Instruction* StraightLineSuccessor() const { |
1561 return successor_; | 1590 return successor_; |
1562 } | 1591 } |
1563 virtual void SetSuccessor(Instruction* instr) { | 1592 virtual void SetSuccessor(Instruction* instr) { |
1564 ASSERT(successor_ == NULL); | 1593 ASSERT(successor_ == NULL); |
1565 successor_ = instr; | 1594 successor_ = instr; |
1566 } | 1595 } |
1567 | 1596 |
1568 virtual void RecordAssignedVars(BitVector* assigned_vars); | 1597 virtual void RecordAssignedVars(BitVector* assigned_vars); |
1569 | 1598 |
1599 virtual LocationSummary* GetLocationSummary() const { | |
1600 return computation()->GetLocationSummary(); | |
1601 } | |
1602 | |
1570 private: | 1603 private: |
1571 Computation* computation_; | 1604 Computation* computation_; |
1572 Instruction* successor_; | 1605 Instruction* successor_; |
1573 | 1606 |
1574 DISALLOW_COPY_AND_ASSIGN(DoInstr); | 1607 DISALLOW_COPY_AND_ASSIGN(DoInstr); |
1575 }; | 1608 }; |
1576 | 1609 |
1577 | 1610 |
1578 class Definition : public Instruction { | 1611 class Definition : public Instruction { |
1579 public: | 1612 public: |
(...skipping 28 matching lines...) Expand all Loading... | |
1608 successor_ = instr; | 1641 successor_ = instr; |
1609 } | 1642 } |
1610 | 1643 |
1611 // Static type of the underlying computation. | 1644 // Static type of the underlying computation. |
1612 virtual RawAbstractType* StaticType() const { | 1645 virtual RawAbstractType* StaticType() const { |
1613 return computation()->StaticType(); | 1646 return computation()->StaticType(); |
1614 } | 1647 } |
1615 | 1648 |
1616 virtual void RecordAssignedVars(BitVector* assigned_vars); | 1649 virtual void RecordAssignedVars(BitVector* assigned_vars); |
1617 | 1650 |
1651 virtual LocationSummary* GetLocationSummary() const { | |
1652 return computation()->GetLocationSummary(); | |
1653 } | |
1654 | |
1618 private: | 1655 private: |
1619 Computation* computation_; | 1656 Computation* computation_; |
1620 Instruction* successor_; | 1657 Instruction* successor_; |
1621 | 1658 |
1622 DISALLOW_COPY_AND_ASSIGN(BindInstr); | 1659 DISALLOW_COPY_AND_ASSIGN(BindInstr); |
1623 }; | 1660 }; |
1624 | 1661 |
1625 | 1662 |
1626 class ReturnInstr : public Instruction { | 1663 class ReturnInstr : public Instruction { |
1627 public: | 1664 public: |
(...skipping 165 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1793 // block_order for reverse iterations. | 1830 // block_order for reverse iterations. |
1794 intptr_t reverse_index(intptr_t index) { | 1831 intptr_t reverse_index(intptr_t index) { |
1795 return block_order_.length() - index - 1; | 1832 return block_order_.length() - index - 1; |
1796 } | 1833 } |
1797 | 1834 |
1798 const GrowableArray<BlockEntryInstr*>& block_order_; | 1835 const GrowableArray<BlockEntryInstr*>& block_order_; |
1799 | 1836 |
1800 private: | 1837 private: |
1801 DISALLOW_COPY_AND_ASSIGN(FlowGraphVisitor); | 1838 DISALLOW_COPY_AND_ASSIGN(FlowGraphVisitor); |
1802 }; | 1839 }; |
1803 | 1840 |
srdjan
2012/05/18 18:00:14
All these classes need a small amount of comment,
Vyacheslav Egorov (Google)
2012/05/20 12:07:46
Commented, moved to location.{cc,h}
| |
1804 | 1841 |
1842 class Location : public ValueObject { | |
srdjan
2012/05/18 18:00:14
Add comment about formatting.
Vyacheslav Egorov (Google)
2012/05/20 12:07:46
Done.
| |
1843 public: | |
1844 enum Kind { | |
1845 INVALID, | |
1846 UNALLOCATED, | |
1847 REGISTER | |
srdjan
2012/05/18 18:00:14
enums are typically named kInvalid, kUnallocated e
Vyacheslav Egorov (Google)
2012/05/20 12:07:46
Renamed to match style.
Did not add kStack/kAddr
| |
1848 }; | |
1849 | |
1850 Location() : value_(KindField::encode(INVALID)) { } | |
1851 | |
1852 Kind kind() const { return KindField::decode(value_); } | |
1853 | |
1854 uword value() const { return value_; } | |
srdjan
2012/05/18 18:00:14
This belongs in protected?
Vyacheslav Egorov (Google)
2012/05/20 12:07:46
Can't be in the protected because it is used from
srdjan
2012/05/21 16:05:22
Ha!
| |
1855 | |
1856 protected: | |
1857 explicit Location(uword value) : value_(value) { } | |
srdjan
2012/05/18 18:00:14
Do you need this constructor?
Vyacheslav Egorov (Google)
2012/05/20 12:07:46
It is called by similar constructors of children w
| |
1858 | |
1859 Location(Kind kind, uword payload) | |
1860 : value_(KindField::encode(kind) | PayloadField::encode(payload)) { } | |
srdjan
2012/05/18 18:00:14
BitField::encode needs range checks.
Vyacheslav Egorov (Google)
2012/05/20 12:07:46
It does use is_valid(), I think that should be eno
| |
1861 | |
1862 uword payload() const { return PayloadField::decode(value_); } | |
1863 | |
1864 private: | |
1865 typedef BitField<Kind, 0, 2> KindField; | |
1866 typedef BitField<uword, 2, kWordSize * kBitsPerByte - 2> PayloadField; | |
1867 | |
1868 uword value_; | |
srdjan
2012/05/18 18:00:14
const
Vyacheslav Egorov (Google)
2012/05/20 12:07:46
If I put const here I would need to implement my o
| |
1869 }; | |
1870 | |
1871 | |
1872 class UnallocatedLocation : public Location { | |
1873 public: | |
1874 enum Policy { | |
1875 REGISTER, | |
1876 SAME_AS_FIRST_INPUT | |
1877 }; | |
1878 | |
1879 explicit UnallocatedLocation(Policy policy) | |
1880 : Location(UNALLOCATED, PolicyField::encode(policy)) { | |
1881 } | |
1882 | |
1883 Policy policy() { return PolicyField::decode(payload()); } | |
1884 | |
1885 static UnallocatedLocation Cast(Location loc) { | |
srdjan
2012/05/18 18:00:14
Maybe AsUnaloocatedLocation instead of Cast? And d
Vyacheslav Egorov (Google)
2012/05/20 12:07:46
I can put helper methods into Location but then I
| |
1886 ASSERT(loc.kind() == UNALLOCATED); | |
1887 return UnallocatedLocation(loc.value()); | |
1888 } | |
1889 | |
1890 private: | |
1891 explicit UnallocatedLocation(uword value) : Location(value) { } | |
1892 | |
1893 typedef BitField<Policy, 0, 1> PolicyField; | |
1894 }; | |
1895 | |
1896 | |
1897 class RegisterLocation : public Location { | |
1898 public: | |
1899 explicit RegisterLocation(Register reg) | |
srdjan
2012/05/18 18:00:14
This cannot handle XMMRegisters, maybe add the reg
Vyacheslav Egorov (Google)
2012/05/20 12:07:46
see above about organically growing Location as we
| |
1900 : Location(REGISTER, reg) { } | |
1901 | |
1902 Register reg() const { | |
1903 return static_cast<Register>(payload()); | |
1904 } | |
1905 | |
1906 static RegisterLocation Cast(Location loc) { | |
1907 ASSERT(loc.kind() == REGISTER); | |
1908 return RegisterLocation(loc.value()); | |
1909 } | |
1910 | |
1911 private: | |
1912 explicit RegisterLocation(uword value) : Location(value) { } | |
1913 }; | |
1914 | |
1915 | |
1916 class LocationSummary : public ZoneAllocated { | |
srdjan
2012/05/18 18:00:14
I am not too happy with the name LocationSummary a
Vyacheslav Egorov (Google)
2012/05/20 12:07:46
ComputationLocations does not work because instruc
| |
1917 public: | |
1918 explicit LocationSummary(intptr_t count) | |
1919 : count_(count) { | |
1920 Zone* zone = Isolate::Current()->current_zone(); | |
srdjan
2012/05/18 18:00:14
Use ZoneGrowableArray fro now, and we can replace
Vyacheslav Egorov (Google)
2012/05/20 12:07:46
Using ZoneGrowableArray. Added TODO to use ZoneArr
| |
1921 input_locations_ = reinterpret_cast<Location*>( | |
1922 zone->Allocate(sizeof(Location) * count)); | |
1923 } | |
1924 | |
1925 intptr_t InputLocationsCount() const { | |
1926 return count_; | |
1927 } | |
1928 | |
1929 Location InputLocationAt(intptr_t index) const { | |
1930 ASSERT(0 <= index && index < count_); | |
1931 return input_locations_[index]; | |
1932 } | |
1933 | |
1934 void SetInputLocationAt(intptr_t index, Location loc) { | |
1935 ASSERT(0 <= index && index < count_); | |
1936 input_locations_[index] = loc; | |
1937 } | |
1938 | |
1939 Location result_location() const { | |
1940 return result_location_; | |
1941 } | |
1942 | |
1943 void set_result_location(Location loc) { | |
1944 result_location_ = loc; | |
1945 } | |
1946 | |
1947 private: | |
1948 intptr_t count_; | |
1949 Location* input_locations_; | |
1950 Location result_location_; | |
1951 }; | |
1952 | |
1953 | |
1805 } // namespace dart | 1954 } // namespace dart |
1806 | 1955 |
1807 #endif // VM_INTERMEDIATE_LANGUAGE_H_ | 1956 #endif // VM_INTERMEDIATE_LANGUAGE_H_ |
OLD | NEW |