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" |
(...skipping 1101 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1112 #undef DECLARE_COMPUTATION | 1112 #undef DECLARE_COMPUTATION |
1113 | 1113 |
1114 | 1114 |
1115 // Instructions. | 1115 // Instructions. |
1116 // | 1116 // |
1117 // <Instruction> ::= JoinEntry <Instruction> | 1117 // <Instruction> ::= JoinEntry <Instruction> |
1118 // | TargetEntry <Instruction> | 1118 // | TargetEntry <Instruction> |
1119 // | Do <Computation> <Instruction> | 1119 // | Do <Computation> <Instruction> |
1120 // | Return <Value> | 1120 // | Return <Value> |
1121 // | Branch <Value> <Instruction> <Instruction> | 1121 // | Branch <Value> <Instruction> <Instruction> |
1122 // <Definition> ::= PickTemp <int> <int> <Instruction> | 1122 // <Definition> ::= Bind <int> <Computation> <Instruction> |
1123 // | TuckTemp <int> <int> <Instruction> | |
1124 // | Bind <int> <Computation> <Instruction> | |
1125 | 1123 |
1126 // M is a single argument macro. It is applied to each concrete instruction | 1124 // M is a single argument macro. It is applied to each concrete instruction |
1127 // type name. The concrete instruction classes are the name with Instr | 1125 // type name. The concrete instruction classes are the name with Instr |
1128 // concatenated. | 1126 // concatenated. |
1129 #define FOR_EACH_INSTRUCTION(M) \ | 1127 #define FOR_EACH_INSTRUCTION(M) \ |
1130 M(JoinEntry) \ | 1128 M(JoinEntry) \ |
1131 M(TargetEntry) \ | 1129 M(TargetEntry) \ |
1132 M(Do) \ | 1130 M(Do) \ |
1133 M(Bind) \ | 1131 M(Bind) \ |
1134 M(PickTemp) \ | |
1135 M(TuckTemp) \ | |
1136 M(Return) \ | 1132 M(Return) \ |
1137 M(Throw) \ | 1133 M(Throw) \ |
1138 M(ReThrow) \ | 1134 M(ReThrow) \ |
1139 M(Branch) \ | 1135 M(Branch) \ |
1140 | 1136 |
1141 | 1137 |
1142 // Forward declarations for Instruction classes. | 1138 // Forward declarations for Instruction classes. |
1143 class BlockEntryInstr; | 1139 class BlockEntryInstr; |
1144 #define FORWARD_DECLARATION(type) class type##Instr; | 1140 #define FORWARD_DECLARATION(type) class type##Instr; |
1145 FOR_EACH_INSTRUCTION(FORWARD_DECLARATION) | 1141 FOR_EACH_INSTRUCTION(FORWARD_DECLARATION) |
(...skipping 264 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1410 } | 1406 } |
1411 | 1407 |
1412 private: | 1408 private: |
1413 Computation* computation_; | 1409 Computation* computation_; |
1414 Instruction* successor_; | 1410 Instruction* successor_; |
1415 | 1411 |
1416 DISALLOW_COPY_AND_ASSIGN(BindInstr); | 1412 DISALLOW_COPY_AND_ASSIGN(BindInstr); |
1417 }; | 1413 }; |
1418 | 1414 |
1419 | 1415 |
1420 // The non-optimizing compiler assumes that there is exactly one use of | |
1421 // every temporary so they can be deallocated at their use. Some AST nodes, | |
1422 // e.g., expr0[expr1]++, violate this assumption (there are two uses of each | |
1423 // of the values expr0 and expr1). | |
1424 // | |
1425 // PickTemp is used to name (with 'destination') a copy of a live temporary | |
1426 // (named 'source') without counting as the use of the source. | |
1427 class PickTempInstr : public Definition { | |
1428 public: | |
1429 explicit PickTempInstr(intptr_t source) | |
1430 : Definition(), source_(source), successor_(NULL) { } | |
1431 | |
1432 DECLARE_INSTRUCTION(PickTemp) | |
1433 | |
1434 intptr_t source() const { return source_; } | |
1435 | |
1436 virtual Instruction* StraightLineSuccessor() const { | |
1437 return successor_; | |
1438 } | |
1439 virtual void SetSuccessor(Instruction* instr) { | |
1440 ASSERT(successor_ == NULL && instr != NULL); | |
1441 successor_ = instr; | |
1442 } | |
1443 | |
1444 private: | |
1445 const intptr_t source_; | |
1446 Instruction* successor_; | |
1447 | |
1448 DISALLOW_COPY_AND_ASSIGN(PickTempInstr); | |
1449 }; | |
1450 | |
1451 | |
1452 // The non-optimizing compiler assumes that temporary definitions and uses | |
1453 // obey a stack discipline, so they can be allocated and deallocated with | |
1454 // push and pop. Some Some AST nodes, e.g., expr++, violate this assumption | |
1455 // (the value expr+1 is produced after the value of expr, and also consumed | |
1456 // after it). | |
1457 // | |
1458 // We 'preallocate' temporaries (named with 'destination') such as the one | |
1459 // for expr+1 and use TuckTemp to mutate them by overwriting them with a | |
1460 // copy of a temporary (named with 'source'). | |
1461 class TuckTempInstr : public Instruction { | |
1462 public: | |
1463 TuckTempInstr(intptr_t destination, intptr_t source) | |
1464 : destination_(destination), source_(source), successor_(NULL) { } | |
1465 | |
1466 DECLARE_INSTRUCTION(TuckTemp) | |
1467 | |
1468 intptr_t destination() const { return destination_; } | |
1469 intptr_t source() const { return source_; } | |
1470 | |
1471 virtual Instruction* StraightLineSuccessor() const { | |
1472 return successor_; | |
1473 } | |
1474 virtual void SetSuccessor(Instruction* instr) { | |
1475 ASSERT(successor_ == NULL && instr != NULL); | |
1476 successor_ = instr; | |
1477 } | |
1478 | |
1479 private: | |
1480 const intptr_t destination_; | |
1481 const intptr_t source_; | |
1482 Instruction* successor_; | |
1483 | |
1484 DISALLOW_COPY_AND_ASSIGN(TuckTempInstr); | |
1485 }; | |
1486 | |
1487 | |
1488 class ReturnInstr : public Instruction { | 1416 class ReturnInstr : public Instruction { |
1489 public: | 1417 public: |
1490 ReturnInstr(intptr_t token_index, Value* value) | 1418 ReturnInstr(intptr_t token_index, Value* value) |
1491 : token_index_(token_index), value_(value) { | 1419 : token_index_(token_index), value_(value) { |
1492 ASSERT(value_ != NULL); | 1420 ASSERT(value_ != NULL); |
1493 } | 1421 } |
1494 | 1422 |
1495 DECLARE_INSTRUCTION(Return) | 1423 DECLARE_INSTRUCTION(Return) |
1496 | 1424 |
1497 Value* value() const { return value_; } | 1425 Value* value() const { return value_; } |
(...skipping 162 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1660 const GrowableArray<BlockEntryInstr*>& block_order_; | 1588 const GrowableArray<BlockEntryInstr*>& block_order_; |
1661 | 1589 |
1662 private: | 1590 private: |
1663 DISALLOW_COPY_AND_ASSIGN(FlowGraphVisitor); | 1591 DISALLOW_COPY_AND_ASSIGN(FlowGraphVisitor); |
1664 }; | 1592 }; |
1665 | 1593 |
1666 | 1594 |
1667 } // namespace dart | 1595 } // namespace dart |
1668 | 1596 |
1669 #endif // VM_INTERMEDIATE_LANGUAGE_H_ | 1597 #endif // VM_INTERMEDIATE_LANGUAGE_H_ |
OLD | NEW |