| 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 #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 1166 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1177 GrowableArray<BlockEntryInstr*>* preorder, | 1177 GrowableArray<BlockEntryInstr*>* preorder, |
| 1178 GrowableArray<BlockEntryInstr*>* postorder, | 1178 GrowableArray<BlockEntryInstr*>* postorder, |
| 1179 GrowableArray<intptr_t>* parent, | 1179 GrowableArray<intptr_t>* parent, |
| 1180 intptr_t variable_count, | 1180 intptr_t variable_count, |
| 1181 intptr_t fixed_parameter_count); | 1181 intptr_t fixed_parameter_count); |
| 1182 | 1182 |
| 1183 // Perform a depth first search to prune code not reachable from an OSR | 1183 // Perform a depth first search to prune code not reachable from an OSR |
| 1184 // entry point. | 1184 // entry point. |
| 1185 bool PruneUnreachable(FlowGraphBuilder* builder, | 1185 bool PruneUnreachable(FlowGraphBuilder* builder, |
| 1186 GraphEntryInstr* graph_entry, | 1186 GraphEntryInstr* graph_entry, |
| 1187 Instruction* parent, |
| 1187 intptr_t osr_id, | 1188 intptr_t osr_id, |
| 1188 BitVector* block_marks); | 1189 BitVector* block_marks); |
| 1189 | 1190 |
| 1190 virtual intptr_t InputCount() const { return 0; } | 1191 virtual intptr_t InputCount() const { return 0; } |
| 1191 virtual Value* InputAt(intptr_t i) const { | 1192 virtual Value* InputAt(intptr_t i) const { |
| 1192 UNREACHABLE(); | 1193 UNREACHABLE(); |
| 1193 return NULL; | 1194 return NULL; |
| 1194 } | 1195 } |
| 1195 | 1196 |
| 1196 virtual intptr_t ArgumentCount() const { return 0; } | 1197 virtual intptr_t ArgumentCount() const { return 0; } |
| (...skipping 145 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1342 | 1343 |
| 1343 CatchBlockEntryInstr* GetCatchEntry(intptr_t index); | 1344 CatchBlockEntryInstr* GetCatchEntry(intptr_t index); |
| 1344 | 1345 |
| 1345 GrowableArray<Definition*>* initial_definitions() { | 1346 GrowableArray<Definition*>* initial_definitions() { |
| 1346 return &initial_definitions_; | 1347 return &initial_definitions_; |
| 1347 } | 1348 } |
| 1348 ConstantInstr* constant_null(); | 1349 ConstantInstr* constant_null(); |
| 1349 | 1350 |
| 1350 bool IsCompiledForOsr() const { return osr_id_ != Isolate::kNoDeoptId; } | 1351 bool IsCompiledForOsr() const { return osr_id_ != Isolate::kNoDeoptId; } |
| 1351 | 1352 |
| 1353 intptr_t entry_count() const { return entry_count_; } |
| 1354 void set_entry_count(intptr_t count) { entry_count_ = count; } |
| 1355 |
| 1352 intptr_t spill_slot_count() const { return spill_slot_count_; } | 1356 intptr_t spill_slot_count() const { return spill_slot_count_; } |
| 1353 void set_spill_slot_count(intptr_t count) { | 1357 void set_spill_slot_count(intptr_t count) { |
| 1354 ASSERT(count >= 0); | 1358 ASSERT(count >= 0); |
| 1355 spill_slot_count_ = count; | 1359 spill_slot_count_ = count; |
| 1356 } | 1360 } |
| 1357 | 1361 |
| 1358 // Number of stack slots reserved for compiling try-catch. For functions | 1362 // Number of stack slots reserved for compiling try-catch. For functions |
| 1359 // without try-catch, this is 0. Otherwise, it is the number of local | 1363 // without try-catch, this is 0. Otherwise, it is the number of local |
| 1360 // variables. | 1364 // variables. |
| 1361 intptr_t fixed_slot_count() const { return fixed_slot_count_; } | 1365 intptr_t fixed_slot_count() const { return fixed_slot_count_; } |
| (...skipping 15 matching lines...) Expand all Loading... |
| 1377 | 1381 |
| 1378 private: | 1382 private: |
| 1379 virtual void ClearPredecessors() {} | 1383 virtual void ClearPredecessors() {} |
| 1380 virtual void AddPredecessor(BlockEntryInstr* predecessor) { UNREACHABLE(); } | 1384 virtual void AddPredecessor(BlockEntryInstr* predecessor) { UNREACHABLE(); } |
| 1381 | 1385 |
| 1382 const ParsedFunction& parsed_function_; | 1386 const ParsedFunction& parsed_function_; |
| 1383 TargetEntryInstr* normal_entry_; | 1387 TargetEntryInstr* normal_entry_; |
| 1384 GrowableArray<CatchBlockEntryInstr*> catch_entries_; | 1388 GrowableArray<CatchBlockEntryInstr*> catch_entries_; |
| 1385 GrowableArray<Definition*> initial_definitions_; | 1389 GrowableArray<Definition*> initial_definitions_; |
| 1386 const intptr_t osr_id_; | 1390 const intptr_t osr_id_; |
| 1391 intptr_t entry_count_; |
| 1387 intptr_t spill_slot_count_; | 1392 intptr_t spill_slot_count_; |
| 1388 intptr_t fixed_slot_count_; // For try-catch in optimized code. | 1393 intptr_t fixed_slot_count_; // For try-catch in optimized code. |
| 1389 | 1394 |
| 1390 DISALLOW_COPY_AND_ASSIGN(GraphEntryInstr); | 1395 DISALLOW_COPY_AND_ASSIGN(GraphEntryInstr); |
| 1391 }; | 1396 }; |
| 1392 | 1397 |
| 1393 | 1398 |
| 1394 class JoinEntryInstr : public BlockEntryInstr { | 1399 class JoinEntryInstr : public BlockEntryInstr { |
| 1395 public: | 1400 public: |
| 1396 JoinEntryInstr(intptr_t block_id, intptr_t try_index) | 1401 JoinEntryInstr(intptr_t block_id, intptr_t try_index) |
| (...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1460 | 1465 |
| 1461 private: | 1466 private: |
| 1462 ZoneGrowableArray<PhiInstr*>* phis_; | 1467 ZoneGrowableArray<PhiInstr*>* phis_; |
| 1463 intptr_t index_; | 1468 intptr_t index_; |
| 1464 }; | 1469 }; |
| 1465 | 1470 |
| 1466 | 1471 |
| 1467 class TargetEntryInstr : public BlockEntryInstr { | 1472 class TargetEntryInstr : public BlockEntryInstr { |
| 1468 public: | 1473 public: |
| 1469 TargetEntryInstr(intptr_t block_id, intptr_t try_index) | 1474 TargetEntryInstr(intptr_t block_id, intptr_t try_index) |
| 1470 : BlockEntryInstr(block_id, try_index), predecessor_(NULL) { } | 1475 : BlockEntryInstr(block_id, try_index), |
| 1476 predecessor_(NULL), |
| 1477 edge_weight_(0.0) { |
| 1478 } |
| 1471 | 1479 |
| 1472 DECLARE_INSTRUCTION(TargetEntry) | 1480 DECLARE_INSTRUCTION(TargetEntry) |
| 1473 | 1481 |
| 1482 double edge_weight() const { return edge_weight_; } |
| 1483 void set_edge_weight(double weight) { edge_weight_ = weight; } |
| 1484 void adjust_edge_weight(double scale_factor) { edge_weight_ *= scale_factor; } |
| 1485 |
| 1474 virtual intptr_t PredecessorCount() const { | 1486 virtual intptr_t PredecessorCount() const { |
| 1475 return (predecessor_ == NULL) ? 0 : 1; | 1487 return (predecessor_ == NULL) ? 0 : 1; |
| 1476 } | 1488 } |
| 1477 virtual BlockEntryInstr* PredecessorAt(intptr_t index) const { | 1489 virtual BlockEntryInstr* PredecessorAt(intptr_t index) const { |
| 1478 ASSERT((index == 0) && (predecessor_ != NULL)); | 1490 ASSERT((index == 0) && (predecessor_ != NULL)); |
| 1479 return predecessor_; | 1491 return predecessor_; |
| 1480 } | 1492 } |
| 1481 | 1493 |
| 1482 virtual void PrintTo(BufferFormatter* f) const; | 1494 virtual void PrintTo(BufferFormatter* f) const; |
| 1483 | 1495 |
| 1484 private: | 1496 private: |
| 1485 friend class BlockEntryInstr; // Access to predecessor_ when inlining. | 1497 friend class BlockEntryInstr; // Access to predecessor_ when inlining. |
| 1486 | 1498 |
| 1487 virtual void ClearPredecessors() { predecessor_ = NULL; } | 1499 virtual void ClearPredecessors() { predecessor_ = NULL; } |
| 1488 virtual void AddPredecessor(BlockEntryInstr* predecessor) { | 1500 virtual void AddPredecessor(BlockEntryInstr* predecessor) { |
| 1489 ASSERT(predecessor_ == NULL); | 1501 ASSERT(predecessor_ == NULL); |
| 1490 predecessor_ = predecessor; | 1502 predecessor_ = predecessor; |
| 1491 } | 1503 } |
| 1492 | 1504 |
| 1493 BlockEntryInstr* predecessor_; | 1505 BlockEntryInstr* predecessor_; |
| 1506 double edge_weight_; |
| 1494 | 1507 |
| 1495 DISALLOW_COPY_AND_ASSIGN(TargetEntryInstr); | 1508 DISALLOW_COPY_AND_ASSIGN(TargetEntryInstr); |
| 1496 }; | 1509 }; |
| 1497 | 1510 |
| 1498 | 1511 |
| 1499 class CatchBlockEntryInstr : public BlockEntryInstr { | 1512 class CatchBlockEntryInstr : public BlockEntryInstr { |
| 1500 public: | 1513 public: |
| 1501 CatchBlockEntryInstr(intptr_t block_id, | 1514 CatchBlockEntryInstr(intptr_t block_id, |
| 1502 intptr_t try_index, | 1515 intptr_t try_index, |
| 1503 const Array& handler_types, | 1516 const Array& handler_types, |
| (...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1563 Definition(); | 1576 Definition(); |
| 1564 | 1577 |
| 1565 virtual Definition* AsDefinition() { return this; } | 1578 virtual Definition* AsDefinition() { return this; } |
| 1566 | 1579 |
| 1567 bool IsComparison() { return (AsComparison() != NULL); } | 1580 bool IsComparison() { return (AsComparison() != NULL); } |
| 1568 virtual ComparisonInstr* AsComparison() { return NULL; } | 1581 virtual ComparisonInstr* AsComparison() { return NULL; } |
| 1569 | 1582 |
| 1570 // Overridden by definitions that push arguments. | 1583 // Overridden by definitions that push arguments. |
| 1571 virtual intptr_t ArgumentCount() const { return 0; } | 1584 virtual intptr_t ArgumentCount() const { return 0; } |
| 1572 | 1585 |
| 1586 // Overridden by definitions that have call counts. |
| 1587 virtual intptr_t CallCount() const { |
| 1588 UNREACHABLE(); |
| 1589 return -1; |
| 1590 } |
| 1591 |
| 1573 intptr_t temp_index() const { return temp_index_; } | 1592 intptr_t temp_index() const { return temp_index_; } |
| 1574 void set_temp_index(intptr_t index) { temp_index_ = index; } | 1593 void set_temp_index(intptr_t index) { temp_index_ = index; } |
| 1575 void ClearTempIndex() { temp_index_ = -1; } | 1594 void ClearTempIndex() { temp_index_ = -1; } |
| 1576 | 1595 |
| 1577 intptr_t ssa_temp_index() const { return ssa_temp_index_; } | 1596 intptr_t ssa_temp_index() const { return ssa_temp_index_; } |
| 1578 void set_ssa_temp_index(intptr_t index) { | 1597 void set_ssa_temp_index(intptr_t index) { |
| 1579 ASSERT(index >= 0); | 1598 ASSERT(index >= 0); |
| 1580 ASSERT(is_used()); | 1599 ASSERT(is_used()); |
| 1581 ssa_temp_index_ = index; | 1600 ssa_temp_index_ = index; |
| 1582 } | 1601 } |
| (...skipping 397 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1980 const intptr_t token_pos_; | 1999 const intptr_t token_pos_; |
| 1981 | 2000 |
| 1982 DISALLOW_COPY_AND_ASSIGN(ReThrowInstr); | 2001 DISALLOW_COPY_AND_ASSIGN(ReThrowInstr); |
| 1983 }; | 2002 }; |
| 1984 | 2003 |
| 1985 | 2004 |
| 1986 class GotoInstr : public TemplateInstruction<0> { | 2005 class GotoInstr : public TemplateInstruction<0> { |
| 1987 public: | 2006 public: |
| 1988 explicit GotoInstr(JoinEntryInstr* entry) | 2007 explicit GotoInstr(JoinEntryInstr* entry) |
| 1989 : successor_(entry), | 2008 : successor_(entry), |
| 1990 parallel_move_(NULL) { } | 2009 edge_weight_(0.0), |
| 2010 parallel_move_(NULL) { |
| 2011 } |
| 1991 | 2012 |
| 1992 DECLARE_INSTRUCTION(Goto) | 2013 DECLARE_INSTRUCTION(Goto) |
| 1993 | 2014 |
| 1994 virtual intptr_t ArgumentCount() const { return 0; } | 2015 virtual intptr_t ArgumentCount() const { return 0; } |
| 1995 | 2016 |
| 1996 JoinEntryInstr* successor() const { return successor_; } | 2017 JoinEntryInstr* successor() const { return successor_; } |
| 1997 void set_successor(JoinEntryInstr* successor) { successor_ = successor; } | 2018 void set_successor(JoinEntryInstr* successor) { successor_ = successor; } |
| 1998 virtual intptr_t SuccessorCount() const; | 2019 virtual intptr_t SuccessorCount() const; |
| 1999 virtual BlockEntryInstr* SuccessorAt(intptr_t index) const; | 2020 virtual BlockEntryInstr* SuccessorAt(intptr_t index) const; |
| 2000 | 2021 |
| 2022 double edge_weight() const { return edge_weight_; } |
| 2023 void set_edge_weight(double weight) { edge_weight_ = weight; } |
| 2024 void adjust_edge_weight(double scale_factor) { edge_weight_ *= scale_factor; } |
| 2025 |
| 2001 virtual bool CanBecomeDeoptimizationTarget() const { | 2026 virtual bool CanBecomeDeoptimizationTarget() const { |
| 2002 // Goto instruction can be used as a deoptimization target when LICM | 2027 // Goto instruction can be used as a deoptimization target when LICM |
| 2003 // hoists instructions out of the loop. | 2028 // hoists instructions out of the loop. |
| 2004 return true; | 2029 return true; |
| 2005 } | 2030 } |
| 2006 | 2031 |
| 2007 virtual bool CanDeoptimize() const { return false; } | 2032 virtual bool CanDeoptimize() const { return false; } |
| 2008 | 2033 |
| 2009 virtual EffectSet Effects() const { return EffectSet::None(); } | 2034 virtual EffectSet Effects() const { return EffectSet::None(); } |
| 2010 | 2035 |
| (...skipping 11 matching lines...) Expand all Loading... |
| 2022 } | 2047 } |
| 2023 return parallel_move_; | 2048 return parallel_move_; |
| 2024 } | 2049 } |
| 2025 | 2050 |
| 2026 virtual void PrintTo(BufferFormatter* f) const; | 2051 virtual void PrintTo(BufferFormatter* f) const; |
| 2027 | 2052 |
| 2028 virtual bool MayThrow() const { return false; } | 2053 virtual bool MayThrow() const { return false; } |
| 2029 | 2054 |
| 2030 private: | 2055 private: |
| 2031 JoinEntryInstr* successor_; | 2056 JoinEntryInstr* successor_; |
| 2057 double edge_weight_; |
| 2032 | 2058 |
| 2033 // Parallel move that will be used by linear scan register allocator to | 2059 // Parallel move that will be used by linear scan register allocator to |
| 2034 // connect live ranges at the end of the block and resolve phis. | 2060 // connect live ranges at the end of the block and resolve phis. |
| 2035 ParallelMoveInstr* parallel_move_; | 2061 ParallelMoveInstr* parallel_move_; |
| 2036 }; | 2062 }; |
| 2037 | 2063 |
| 2038 | 2064 |
| 2039 class ControlInstruction : public Instruction { | 2065 class ControlInstruction : public Instruction { |
| 2040 public: | 2066 public: |
| 2041 ControlInstruction() : true_successor_(NULL), false_successor_(NULL) { } | 2067 ControlInstruction() : true_successor_(NULL), false_successor_(NULL) { } |
| (...skipping 547 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2589 DECLARE_INSTRUCTION(ClosureCall) | 2615 DECLARE_INSTRUCTION(ClosureCall) |
| 2590 | 2616 |
| 2591 const Array& argument_names() const { return ast_node_.arguments()->names(); } | 2617 const Array& argument_names() const { return ast_node_.arguments()->names(); } |
| 2592 intptr_t token_pos() const { return ast_node_.token_pos(); } | 2618 intptr_t token_pos() const { return ast_node_.token_pos(); } |
| 2593 | 2619 |
| 2594 virtual intptr_t ArgumentCount() const { return arguments_->length(); } | 2620 virtual intptr_t ArgumentCount() const { return arguments_->length(); } |
| 2595 virtual PushArgumentInstr* PushArgumentAt(intptr_t index) const { | 2621 virtual PushArgumentInstr* PushArgumentAt(intptr_t index) const { |
| 2596 return (*arguments_)[index]; | 2622 return (*arguments_)[index]; |
| 2597 } | 2623 } |
| 2598 | 2624 |
| 2625 // TODO(kmillikin): implement exact call counts for closure calls. |
| 2626 virtual intptr_t CallCount() const { return 1; } |
| 2627 |
| 2599 virtual void PrintOperandsTo(BufferFormatter* f) const; | 2628 virtual void PrintOperandsTo(BufferFormatter* f) const; |
| 2600 | 2629 |
| 2601 virtual bool CanDeoptimize() const { return true; } | 2630 virtual bool CanDeoptimize() const { return true; } |
| 2602 | 2631 |
| 2603 virtual EffectSet Effects() const { return EffectSet::All(); } | 2632 virtual EffectSet Effects() const { return EffectSet::All(); } |
| 2604 | 2633 |
| 2605 virtual bool MayThrow() const { return true; } | 2634 virtual bool MayThrow() const { return true; } |
| 2606 | 2635 |
| 2607 private: | 2636 private: |
| 2608 const ClosureCallNode& ast_node_; | 2637 const ClosureCallNode& ast_node_; |
| (...skipping 94 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2703 | 2732 |
| 2704 virtual intptr_t ArgumentCount() const { | 2733 virtual intptr_t ArgumentCount() const { |
| 2705 return instance_call()->ArgumentCount(); | 2734 return instance_call()->ArgumentCount(); |
| 2706 } | 2735 } |
| 2707 virtual PushArgumentInstr* PushArgumentAt(intptr_t index) const { | 2736 virtual PushArgumentInstr* PushArgumentAt(intptr_t index) const { |
| 2708 return instance_call()->PushArgumentAt(index); | 2737 return instance_call()->PushArgumentAt(index); |
| 2709 } | 2738 } |
| 2710 | 2739 |
| 2711 bool HasRecognizedTarget() const; | 2740 bool HasRecognizedTarget() const; |
| 2712 | 2741 |
| 2742 virtual intptr_t CallCount() const { return ic_data().AggregateCount(); } |
| 2743 |
| 2713 DECLARE_INSTRUCTION(PolymorphicInstanceCall) | 2744 DECLARE_INSTRUCTION(PolymorphicInstanceCall) |
| 2714 | 2745 |
| 2715 const ICData& ic_data() const { return ic_data_; } | 2746 const ICData& ic_data() const { return ic_data_; } |
| 2716 | 2747 |
| 2717 virtual bool CanDeoptimize() const { return true; } | 2748 virtual bool CanDeoptimize() const { return true; } |
| 2718 | 2749 |
| 2719 virtual EffectSet Effects() const { return EffectSet::All(); } | 2750 virtual EffectSet Effects() const { return EffectSet::All(); } |
| 2720 | 2751 |
| 2721 virtual void PrintOperandsTo(BufferFormatter* f) const; | 2752 virtual void PrintOperandsTo(BufferFormatter* f) const; |
| 2722 | 2753 |
| (...skipping 384 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3107 // Accessors forwarded to the AST node. | 3138 // Accessors forwarded to the AST node. |
| 3108 const Function& function() const { return function_; } | 3139 const Function& function() const { return function_; } |
| 3109 const Array& argument_names() const { return argument_names_; } | 3140 const Array& argument_names() const { return argument_names_; } |
| 3110 intptr_t token_pos() const { return token_pos_; } | 3141 intptr_t token_pos() const { return token_pos_; } |
| 3111 | 3142 |
| 3112 virtual intptr_t ArgumentCount() const { return arguments_->length(); } | 3143 virtual intptr_t ArgumentCount() const { return arguments_->length(); } |
| 3113 virtual PushArgumentInstr* PushArgumentAt(intptr_t index) const { | 3144 virtual PushArgumentInstr* PushArgumentAt(intptr_t index) const { |
| 3114 return (*arguments_)[index]; | 3145 return (*arguments_)[index]; |
| 3115 } | 3146 } |
| 3116 | 3147 |
| 3148 virtual intptr_t CallCount() const { return ic_data()->AggregateCount(); } |
| 3149 |
| 3117 virtual void PrintOperandsTo(BufferFormatter* f) const; | 3150 virtual void PrintOperandsTo(BufferFormatter* f) const; |
| 3118 | 3151 |
| 3119 virtual bool CanDeoptimize() const { return true; } | 3152 virtual bool CanDeoptimize() const { return true; } |
| 3120 | 3153 |
| 3121 virtual EffectSet Effects() const { return EffectSet::All(); } | 3154 virtual EffectSet Effects() const { return EffectSet::All(); } |
| 3122 | 3155 |
| 3123 void set_result_cid(intptr_t value) { result_cid_ = value; } | 3156 void set_result_cid(intptr_t value) { result_cid_ = value; } |
| 3124 | 3157 |
| 3125 bool is_known_list_constructor() const { return is_known_list_constructor_; } | 3158 bool is_known_list_constructor() const { return is_known_list_constructor_; } |
| 3126 void set_is_known_list_constructor(bool value) { | 3159 void set_is_known_list_constructor(bool value) { |
| (...skipping 3621 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 6748 ForwardInstructionIterator* current_iterator_; | 6781 ForwardInstructionIterator* current_iterator_; |
| 6749 | 6782 |
| 6750 private: | 6783 private: |
| 6751 DISALLOW_COPY_AND_ASSIGN(FlowGraphVisitor); | 6784 DISALLOW_COPY_AND_ASSIGN(FlowGraphVisitor); |
| 6752 }; | 6785 }; |
| 6753 | 6786 |
| 6754 | 6787 |
| 6755 } // namespace dart | 6788 } // namespace dart |
| 6756 | 6789 |
| 6757 #endif // VM_INTERMEDIATE_LANGUAGE_H_ | 6790 #endif // VM_INTERMEDIATE_LANGUAGE_H_ |
| OLD | NEW |