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

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

Issue 10431006: First step toward an optimizing compiler: (Closed) Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge/dart/
Patch Set: Created 8 years, 7 months 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/il_printer.cc ('k') | runtime/vm/intermediate_language.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) 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"
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after
57 M(AllocateObjectWithBoundsCheck, AllocateObjectWithBoundsCheckComp) \ 57 M(AllocateObjectWithBoundsCheck, AllocateObjectWithBoundsCheckComp) \
58 M(LoadVMField, LoadVMFieldComp) \ 58 M(LoadVMField, LoadVMFieldComp) \
59 M(StoreVMField, StoreVMFieldComp) \ 59 M(StoreVMField, StoreVMFieldComp) \
60 M(InstantiateTypeArguments, InstantiateTypeArgumentsComp) \ 60 M(InstantiateTypeArguments, InstantiateTypeArgumentsComp) \
61 M(ExtractConstructorTypeArguments, ExtractConstructorTypeArgumentsComp) \ 61 M(ExtractConstructorTypeArguments, ExtractConstructorTypeArgumentsComp) \
62 M(ExtractConstructorInstantiator, ExtractConstructorInstantiatorComp) \ 62 M(ExtractConstructorInstantiator, ExtractConstructorInstantiatorComp) \
63 M(AllocateContext, AllocateContextComp) \ 63 M(AllocateContext, AllocateContextComp) \
64 M(ChainContext, ChainContextComp) \ 64 M(ChainContext, ChainContextComp) \
65 M(CloneContext, CloneContextComp) \ 65 M(CloneContext, CloneContextComp) \
66 M(CatchEntry, CatchEntryComp) \ 66 M(CatchEntry, CatchEntryComp) \
67 M(BinaryOp, BinaryOpComp) \
67 68
68 69
69 #define FORWARD_DECLARATION(ShortName, ClassName) class ClassName; 70 #define FORWARD_DECLARATION(ShortName, ClassName) class ClassName;
70 FOR_EACH_COMPUTATION(FORWARD_DECLARATION) 71 FOR_EACH_COMPUTATION(FORWARD_DECLARATION)
71 #undef FORWARD_DECLARATION 72 #undef FORWARD_DECLARATION
72 73
73 // Forward declarations. 74 // Forward declarations.
74 class BufferFormatter; 75 class BufferFormatter;
76 class Instruction;
75 class Value; 77 class Value;
76 78
77 79
78 class Computation : public ZoneAllocated { 80 class Computation : public ZoneAllocated {
79 public: 81 public:
80 static const int kNoCid = -1; 82 static const int kNoCid = -1;
81 83
82 Computation() : cid_(-1), ic_data_(NULL), locs_(NULL) { 84 Computation() : cid_(-1), ic_data_(NULL), instr_(NULL), locs_(NULL) {
83 Isolate* isolate = Isolate::Current(); 85 Isolate* isolate = Isolate::Current();
84 cid_ = GetNextCid(isolate); 86 cid_ = GetNextCid(isolate);
85 ic_data_ = GetICDataForCid(cid_, isolate); 87 ic_data_ = GetICDataForCid(cid_, isolate);
86 } 88 }
87 89
88 // Unique computation/instruction id, used for deoptimization. 90 // Unique computation/instruction id, used for deoptimization.
89 intptr_t cid() const { return cid_; } 91 intptr_t cid() const { return cid_; }
90 92
91 const ICData* ic_data() const { return ic_data_; } 93 ICData* ic_data() const { return ic_data_; }
94 void set_ic_data(ICData* value) { ic_data_ = value; }
92 95
93 // Visiting support. 96 // Visiting support.
94 virtual void Accept(FlowGraphVisitor* visitor) = 0; 97 virtual void Accept(FlowGraphVisitor* visitor) = 0;
95 98
96 virtual intptr_t InputCount() const = 0; 99 virtual intptr_t InputCount() const = 0;
97 virtual Value* InputAt(intptr_t i) const = 0; 100 virtual Value* InputAt(intptr_t i) const = 0;
98 101
99 // Static type of the computation. 102 // Static type of the computation.
100 virtual RawAbstractType* StaticType() const = 0; 103 virtual RawAbstractType* StaticType() const = 0;
101 104
(...skipping 10 matching lines...) Expand all
112 115
113 // Returns structure describing location constraints required 116 // Returns structure describing location constraints required
114 // to emit native code for this computation. 117 // to emit native code for this computation.
115 LocationSummary* locs() { 118 LocationSummary* locs() {
116 if (locs_ == NULL) { 119 if (locs_ == NULL) {
117 locs_ = MakeLocationSummary(); 120 locs_ = MakeLocationSummary();
118 } 121 }
119 return locs_; 122 return locs_;
120 } 123 }
121 124
125 // TODO(srdjan): Eliminate Instructions hierarchy. If 'use' is NULL
126 // it acts as a DoInstr, otherwise a BindInstr.
127 void set_instr(Instruction* value) { instr_ = value; }
128 Instruction* instr() const { return instr_; }
129
122 // Create a location summary for this computation. 130 // Create a location summary for this computation.
123 // TODO(fschneider): Temporarily returns NULL for instructions 131 // TODO(fschneider): Temporarily returns NULL for instructions
124 // that are not yet converted to the location based code generation. 132 // that are not yet converted to the location based code generation.
125 virtual LocationSummary* MakeLocationSummary() const = 0; 133 virtual LocationSummary* MakeLocationSummary() const = 0;
126 134
127 // TODO(fschneider): Make EmitNativeCode and locs const. 135 // TODO(fschneider): Make EmitNativeCode and locs const.
128 virtual void EmitNativeCode(FlowGraphCompiler* compiler) = 0; 136 virtual void EmitNativeCode(FlowGraphCompiler* compiler) = 0;
129 137
130 private: 138 private:
131 friend class Instruction; 139 friend class Instruction;
132 static intptr_t GetNextCid(Isolate* isolate) { 140 static intptr_t GetNextCid(Isolate* isolate) {
133 intptr_t tmp = isolate->computation_id(); 141 intptr_t tmp = isolate->computation_id();
134 isolate->set_computation_id(tmp + 1); 142 isolate->set_computation_id(tmp + 1);
135 return tmp; 143 return tmp;
136 } 144 }
137 static ICData* GetICDataForCid(intptr_t cid, Isolate* isolate) { 145 static ICData* GetICDataForCid(intptr_t cid, Isolate* isolate) {
138 if (isolate->ic_data_array() == Array::null()) { 146 if (isolate->ic_data_array() == Array::null()) {
139 return NULL; 147 return NULL;
140 } else { 148 } else {
141 const Array& array_handle = Array::Handle(isolate->ic_data_array()); 149 const Array& array_handle = Array::Handle(isolate->ic_data_array());
150 if (cid >= array_handle.Length()) {
151 // For computations being added in the optimizing compiler.
152 return NULL;
153 }
142 ICData& ic_data_handle = ICData::ZoneHandle(); 154 ICData& ic_data_handle = ICData::ZoneHandle();
143 if (cid < array_handle.Length()) { 155 ic_data_handle ^= array_handle.At(cid);
144 ic_data_handle ^= array_handle.At(cid);
145 }
146 return &ic_data_handle; 156 return &ic_data_handle;
147 } 157 }
148 } 158 }
149 159
150 intptr_t cid_; 160 intptr_t cid_;
151 ICData* ic_data_; 161 ICData* ic_data_;
162 Instruction* instr_;
152 LocationSummary* locs_; 163 LocationSummary* locs_;
153 164
154 DISALLOW_COPY_AND_ASSIGN(Computation); 165 DISALLOW_COPY_AND_ASSIGN(Computation);
155 }; 166 };
156 167
157 168
158 // An embedded container with N elements of type T. Used (with partial 169 // An embedded container with N elements of type T. Used (with partial
159 // specialization for N=0) because embedded arrays cannot have size 0. 170 // specialization for N=0) because embedded arrays cannot have size 0.
160 template<typename T, intptr_t N> 171 template<typename T, intptr_t N>
161 class EmbeddedArray { 172 class EmbeddedArray {
(...skipping 79 matching lines...) Expand 10 before | Expand all | Expand 10 after
241 virtual LocationSummary* MakeLocationSummary() const; \ 252 virtual LocationSummary* MakeLocationSummary() const; \
242 virtual void EmitNativeCode(FlowGraphCompiler* compiler); 253 virtual void EmitNativeCode(FlowGraphCompiler* compiler);
243 254
244 // Functions defined in all concrete value classes. 255 // Functions defined in all concrete value classes.
245 #define DECLARE_VALUE(ShortName) \ 256 #define DECLARE_VALUE(ShortName) \
246 DECLARE_COMPUTATION(ShortName) \ 257 DECLARE_COMPUTATION(ShortName) \
247 virtual ShortName##Val* As##ShortName() { return this; } \ 258 virtual ShortName##Val* As##ShortName() { return this; } \
248 virtual void PrintTo(BufferFormatter* f) const; 259 virtual void PrintTo(BufferFormatter* f) const;
249 260
250 261
251 // Definitions and uses are mutually recursive. 262 class BindInstr;
252 class Definition;
253 263
254 class UseVal : public Value { 264 class UseVal : public Value {
255 public: 265 public:
256 explicit UseVal(Definition* definition) : definition_(definition) { } 266 explicit UseVal(BindInstr* definition) : definition_(definition) {}
257 267
258 DECLARE_VALUE(Use) 268 DECLARE_VALUE(Use)
259 269
260 Definition* definition() const { return definition_; } 270 BindInstr* definition() const { return definition_; }
261 271
262 private: 272 private:
263 Definition* const definition_; 273 BindInstr* definition_;
264 274
265 DISALLOW_COPY_AND_ASSIGN(UseVal); 275 DISALLOW_COPY_AND_ASSIGN(UseVal);
266 }; 276 };
267 277
268 278
269 class ConstantVal: public Value { 279 class ConstantVal: public Value {
270 public: 280 public:
271 explicit ConstantVal(const Object& value) 281 explicit ConstantVal(const Object& value)
272 : value_(value) { 282 : value_(value) {
273 ASSERT(value.IsZoneHandle()); 283 ASSERT(value.IsZoneHandle());
(...skipping 999 matching lines...) Expand 10 before | Expand all | Expand 10 after
1273 virtual void PrintOperandsTo(BufferFormatter* f) const; 1283 virtual void PrintOperandsTo(BufferFormatter* f) const;
1274 1284
1275 private: 1285 private:
1276 const LocalVariable& exception_var_; 1286 const LocalVariable& exception_var_;
1277 const LocalVariable& stacktrace_var_; 1287 const LocalVariable& stacktrace_var_;
1278 1288
1279 DISALLOW_COPY_AND_ASSIGN(CatchEntryComp); 1289 DISALLOW_COPY_AND_ASSIGN(CatchEntryComp);
1280 }; 1290 };
1281 1291
1282 1292
1293 class BinaryOpComp : public TemplateComputation<2> {
1294 public:
1295 BinaryOpComp(Token::Kind op_kind,
1296 InstanceCallComp* instance_call,
1297 Value* left,
1298 Value* right)
1299 : op_kind_(op_kind), instance_call_(instance_call) {
1300 inputs_[0] = left;
1301 inputs_[1] = right;
1302 }
1303
1304 Value* left() const { return inputs_[0]; }
1305 Value* right() const { return inputs_[1]; }
1306
1307 Token::Kind op_kind() const { return op_kind_; }
1308
1309 InstanceCallComp* instance_call() const { return instance_call_; }
1310
1311 virtual void PrintOperandsTo(BufferFormatter* f) const;
1312
1313 DECLARE_COMPUTATION(BinaryOp)
1314
1315 private:
1316 const Token::Kind op_kind_;
1317 InstanceCallComp* instance_call_;
1318
1319 DISALLOW_COPY_AND_ASSIGN(BinaryOpComp);
1320 };
1321
1283 #undef DECLARE_COMPUTATION 1322 #undef DECLARE_COMPUTATION
1284 1323
1285 1324
1286 // Instructions. 1325 // Instructions.
1287 // 1326 //
1288 // <Instruction> ::= JoinEntry <Instruction> 1327 // <Instruction> ::= JoinEntry <Instruction>
1289 // | TargetEntry <Instruction> 1328 // | TargetEntry <Instruction>
1290 // | Do <Computation> <Instruction> 1329 // | Do <Computation> <Instruction>
1291 // | Return <Value> 1330 // | Return <Value>
1292 // | Branch <Value> <Instruction> <Instruction> 1331 // | Branch <Value> <Instruction> <Instruction>
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after
1337 // Unique computation/instruction id, used for deoptimization, e.g. for 1376 // Unique computation/instruction id, used for deoptimization, e.g. for
1338 // ReturnInstr, ThrowInstr and ReThrowInstr. 1377 // ReturnInstr, ThrowInstr and ReThrowInstr.
1339 intptr_t cid() const { return cid_; } 1378 intptr_t cid() const { return cid_; }
1340 1379
1341 const ICData* ic_data() const { return ic_data_; } 1380 const ICData* ic_data() const { return ic_data_; }
1342 1381
1343 virtual bool IsBlockEntry() const { return false; } 1382 virtual bool IsBlockEntry() const { return false; }
1344 BlockEntryInstr* AsBlockEntry() { 1383 BlockEntryInstr* AsBlockEntry() {
1345 return IsBlockEntry() ? reinterpret_cast<BlockEntryInstr*>(this) : NULL; 1384 return IsBlockEntry() ? reinterpret_cast<BlockEntryInstr*>(this) : NULL;
1346 } 1385 }
1347 virtual bool IsDefinition() const { return false; } 1386 virtual bool IsBindInstr() const { return false; }
1348 Definition* AsDefinition() { 1387 virtual BindInstr* AsBindInstr() {
1349 return IsDefinition() ? reinterpret_cast<Definition*>(this) : NULL; 1388 return NULL;
1350 } 1389 }
1351 1390
1352 virtual intptr_t InputCount() const = 0; 1391 virtual intptr_t InputCount() const = 0;
1353 1392
1354 // Visiting support. 1393 // Visiting support.
1355 virtual Instruction* Accept(FlowGraphVisitor* visitor) = 0; 1394 virtual Instruction* Accept(FlowGraphVisitor* visitor) = 0;
1356 1395
1357 virtual Instruction* StraightLineSuccessor() const = 0; 1396 virtual Instruction* StraightLineSuccessor() const = 0;
1358 virtual void SetSuccessor(Instruction* instr) = 0; 1397 virtual void SetSuccessor(Instruction* instr) = 0;
1359 1398
1399 virtual void replace_computation(Computation* value) {
1400 UNREACHABLE();
1401 }
1360 // Discover basic-block structure by performing a recursive depth first 1402 // Discover basic-block structure by performing a recursive depth first
1361 // traversal of the instruction graph reachable from this instruction. As 1403 // traversal of the instruction graph reachable from this instruction. As
1362 // a side effect, the block entry instructions in the graph are assigned 1404 // a side effect, the block entry instructions in the graph are assigned
1363 // numbers in both preorder and postorder. The array 'preorder' maps 1405 // numbers in both preorder and postorder. The array 'preorder' maps
1364 // preorder block numbers to the block entry instruction with that number 1406 // preorder block numbers to the block entry instruction with that number
1365 // and analogously for the array 'postorder'. The depth first spanning 1407 // and analogously for the array 'postorder'. The depth first spanning
1366 // tree is recorded in the array 'parent', which maps preorder block 1408 // tree is recorded in the array 'parent', which maps preorder block
1367 // numbers to the preorder number of the block's spanning-tree parent. 1409 // numbers to the preorder number of the block's spanning-tree parent.
1368 // The array 'assigned_vars' maps preorder block numbers to the set of 1410 // The array 'assigned_vars' maps preorder block numbers to the set of
1369 // assigned frame-allocated local variables in the block. As a side 1411 // assigned frame-allocated local variables in the block. As a side
(...skipping 223 matching lines...) Expand 10 before | Expand all | Expand 10 after
1593 BlockEntryInstr* predecessor_; 1635 BlockEntryInstr* predecessor_;
1594 Instruction* successor_; 1636 Instruction* successor_;
1595 const intptr_t try_index_; 1637 const intptr_t try_index_;
1596 1638
1597 DISALLOW_COPY_AND_ASSIGN(TargetEntryInstr); 1639 DISALLOW_COPY_AND_ASSIGN(TargetEntryInstr);
1598 }; 1640 };
1599 1641
1600 1642
1601 class DoInstr : public Instruction { 1643 class DoInstr : public Instruction {
1602 public: 1644 public:
1603 explicit DoInstr(Computation* comp) 1645 explicit DoInstr(Computation* computation)
1604 : computation_(comp), successor_(NULL) { } 1646 : computation_(computation), successor_(NULL) {
1647 ASSERT(computation != NULL);
1648 computation->set_instr(this);
1649 }
1605 1650
1606 DECLARE_INSTRUCTION(Do) 1651 DECLARE_INSTRUCTION(Do)
1607 1652
1608 Computation* computation() const { return computation_; } 1653 Computation* computation() const { return computation_; }
1654 virtual void replace_computation(Computation* value) { computation_ = value; }
1609 1655
1610 virtual Instruction* StraightLineSuccessor() const { 1656 virtual Instruction* StraightLineSuccessor() const {
1611 return successor_; 1657 return successor_;
1612 } 1658 }
1613 1659
1614 virtual void SetSuccessor(Instruction* instr) { 1660 virtual void SetSuccessor(Instruction* instr) {
1615 ASSERT(successor_ == NULL); 1661 ASSERT(successor_ == NULL);
1616 successor_ = instr; 1662 successor_ = instr;
1617 } 1663 }
1618 1664
1619 virtual void RecordAssignedVars(BitVector* assigned_vars); 1665 virtual void RecordAssignedVars(BitVector* assigned_vars);
1620 1666
1621 virtual LocationSummary* locs() const { 1667 virtual LocationSummary* locs() const {
1622 return computation()->locs(); 1668 return computation()->locs();
1623 } 1669 }
1624 1670
1625 virtual void EmitNativeCode(FlowGraphCompiler* compiler) { 1671 virtual void EmitNativeCode(FlowGraphCompiler* compiler) {
1626 computation()->EmitNativeCode(compiler); 1672 computation()->EmitNativeCode(compiler);
1627 } 1673 }
1628 1674
1629 private: 1675 private:
1630 Computation* computation_; 1676 Computation* computation_;
1631 Instruction* successor_; 1677 Instruction* successor_;
1632 1678
1633 DISALLOW_COPY_AND_ASSIGN(DoInstr); 1679 DISALLOW_COPY_AND_ASSIGN(DoInstr);
1634 }; 1680 };
1635 1681
1636 1682
1637 class Definition : public Instruction { 1683 class BindInstr : public Instruction {
1638 public: 1684 public:
1639 Definition() : temp_index_(-1) { } 1685 explicit BindInstr(Computation* computation)
1686 : temp_index_(-1), computation_(computation), successor_(NULL) {
1687 ASSERT(computation != NULL);
1688 computation->set_instr(this);
1689 }
1640 1690
1641 virtual bool IsDefinition() const { return true; } 1691 DECLARE_INSTRUCTION(Bind)
1692
1693 virtual bool IsBindInstr() const { return true; }
1694 virtual BindInstr* AsBindInstr() { return this; }
1642 1695
1643 intptr_t temp_index() const { return temp_index_; } 1696 intptr_t temp_index() const { return temp_index_; }
1644 void set_temp_index(intptr_t index) { temp_index_ = index; } 1697 void set_temp_index(intptr_t index) { temp_index_ = index; }
1645 1698
1646 private:
1647 intptr_t temp_index_;
1648
1649 DISALLOW_COPY_AND_ASSIGN(Definition);
1650 };
1651
1652
1653 class BindInstr : public Definition {
1654 public:
1655 explicit BindInstr(Computation* computation)
1656 : Definition(), computation_(computation), successor_(NULL) { }
1657
1658 DECLARE_INSTRUCTION(Bind)
1659
1660 Computation* computation() const { return computation_; } 1699 Computation* computation() const { return computation_; }
1700 virtual void replace_computation(Computation* value) { computation_ = value; }
1661 1701
1662 virtual Instruction* StraightLineSuccessor() const { 1702 virtual Instruction* StraightLineSuccessor() const {
1663 return successor_; 1703 return successor_;
1664 } 1704 }
1665 1705
1666 virtual void SetSuccessor(Instruction* instr) { 1706 virtual void SetSuccessor(Instruction* instr) {
1667 ASSERT(successor_ == NULL); 1707 ASSERT(successor_ == NULL);
1668 successor_ = instr; 1708 successor_ = instr;
1669 } 1709 }
1670 1710
1671 // Static type of the underlying computation. 1711 // Static type of the underlying computation.
1672 virtual RawAbstractType* StaticType() const { 1712 virtual RawAbstractType* StaticType() const {
1673 return computation()->StaticType(); 1713 return computation()->StaticType();
1674 } 1714 }
1675 1715
1676 virtual void RecordAssignedVars(BitVector* assigned_vars); 1716 virtual void RecordAssignedVars(BitVector* assigned_vars);
1677 1717
1678 virtual LocationSummary* locs() const { 1718 virtual LocationSummary* locs() const {
1679 return computation()->locs(); 1719 return computation()->locs();
1680 } 1720 }
1681 1721
1682 virtual void EmitNativeCode(FlowGraphCompiler* compiler); 1722 virtual void EmitNativeCode(FlowGraphCompiler* compiler);
1683 1723
1684 private: 1724 private:
1725 intptr_t temp_index_;
1685 Computation* computation_; 1726 Computation* computation_;
1686 Instruction* successor_; 1727 Instruction* successor_;
1687 1728
1688 DISALLOW_COPY_AND_ASSIGN(BindInstr); 1729 DISALLOW_COPY_AND_ASSIGN(BindInstr);
1689 }; 1730 };
1690 1731
1691 1732
1692 class ReturnInstr : public Instruction { 1733 class ReturnInstr : public Instruction {
1693 public: 1734 public:
1694 ReturnInstr(intptr_t token_index, Value* value) 1735 ReturnInstr(intptr_t token_index, Value* value)
(...skipping 169 matching lines...) Expand 10 before | Expand all | Expand 10 after
1864 const GrowableArray<BlockEntryInstr*>& block_order_; 1905 const GrowableArray<BlockEntryInstr*>& block_order_;
1865 1906
1866 private: 1907 private:
1867 DISALLOW_COPY_AND_ASSIGN(FlowGraphVisitor); 1908 DISALLOW_COPY_AND_ASSIGN(FlowGraphVisitor);
1868 }; 1909 };
1869 1910
1870 1911
1871 } // namespace dart 1912 } // namespace dart
1872 1913
1873 #endif // VM_INTERMEDIATE_LANGUAGE_H_ 1914 #endif // VM_INTERMEDIATE_LANGUAGE_H_
OLDNEW
« no previous file with comments | « runtime/vm/il_printer.cc ('k') | runtime/vm/intermediate_language.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698