| 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/locations.h" | 12 #include "vm/locations.h" |
| 13 #include "vm/object.h" | 13 #include "vm/object.h" |
| 14 | 14 |
| 15 namespace dart { | 15 namespace dart { |
| 16 | 16 |
| 17 class BindInstr; | 17 class BindInstr; |
| 18 class BitVector; | 18 class BitVector; |
| 19 class BlockEntryInstr; | 19 class BlockEntryInstr; |
| 20 class BufferFormatter; | 20 class BufferFormatter; |
| 21 class ComparisonComp; | 21 class ComparisonComp; |
| 22 class Computation; | 22 class Computation; |
| 23 class ControlInstruction; |
| 23 class Definition; | 24 class Definition; |
| 24 class Environment; | 25 class Environment; |
| 25 class FlowGraphCompiler; | 26 class FlowGraphCompiler; |
| 26 class FlowGraphVisitor; | 27 class FlowGraphVisitor; |
| 27 class Instruction; | 28 class Instruction; |
| 28 class LocalVariable; | 29 class LocalVariable; |
| 29 | 30 |
| 30 | 31 |
| 31 // TODO(srdjan): Add _ByteArrayBase, get:length. | 32 // TODO(srdjan): Add _ByteArrayBase, get:length. |
| 32 | 33 |
| (...skipping 162 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 195 | 196 |
| 196 | 197 |
| 197 #define FORWARD_DECLARATION(type) class type##Instr; | 198 #define FORWARD_DECLARATION(type) class type##Instr; |
| 198 FOR_EACH_INSTRUCTION(FORWARD_DECLARATION) | 199 FOR_EACH_INSTRUCTION(FORWARD_DECLARATION) |
| 199 #undef FORWARD_DECLARATION | 200 #undef FORWARD_DECLARATION |
| 200 | 201 |
| 201 | 202 |
| 202 // Functions required in all concrete instruction classes. | 203 // Functions required in all concrete instruction classes. |
| 203 #define DECLARE_INSTRUCTION(type) \ | 204 #define DECLARE_INSTRUCTION(type) \ |
| 204 virtual void Accept(FlowGraphVisitor* visitor); \ | 205 virtual void Accept(FlowGraphVisitor* visitor); \ |
| 205 virtual bool Is##type() const { return true; } \ | |
| 206 virtual type##Instr* As##type() { return this; } \ | 206 virtual type##Instr* As##type() { return this; } \ |
| 207 virtual const char* DebugName() const { return #type; } \ | 207 virtual const char* DebugName() const { return #type; } \ |
| 208 virtual void PrintTo(BufferFormatter* f) const; \ | 208 virtual void PrintTo(BufferFormatter* f) const; \ |
| 209 virtual void PrintToVisualizer(BufferFormatter* f) const; | 209 virtual void PrintToVisualizer(BufferFormatter* f) const; |
| 210 | 210 |
| 211 | 211 |
| 212 class Instruction : public ZoneAllocated { | 212 class Instruction : public ZoneAllocated { |
| 213 public: | 213 public: |
| 214 Instruction() | 214 Instruction() |
| 215 : lifetime_position_(-1), previous_(NULL), next_(NULL), env_(NULL) { } | 215 : lifetime_position_(-1), previous_(NULL), next_(NULL), env_(NULL) { } |
| 216 | 216 |
| 217 virtual bool IsBlockEntry() const { return false; } | 217 bool IsBlockEntry() { return (AsBlockEntry() != NULL); } |
| 218 BlockEntryInstr* AsBlockEntry() { | 218 virtual BlockEntryInstr* AsBlockEntry() { return NULL; } |
| 219 return IsBlockEntry() ? reinterpret_cast<BlockEntryInstr*>(this) : NULL; | 219 |
| 220 } | 220 bool IsDefinition() { return (AsDefinition() != NULL); } |
| 221 virtual bool IsDefinition() const { return false; } | |
| 222 virtual Definition* AsDefinition() { return NULL; } | 221 virtual Definition* AsDefinition() { return NULL; } |
| 223 virtual bool IsControl() const { return false; } | 222 |
| 223 bool IsControl() { return (AsControl() != NULL); } |
| 224 virtual ControlInstruction* AsControl() { return NULL; } |
| 224 | 225 |
| 225 virtual intptr_t InputCount() const = 0; | 226 virtual intptr_t InputCount() const = 0; |
| 226 virtual Value* InputAt(intptr_t i) const = 0; | 227 virtual Value* InputAt(intptr_t i) const = 0; |
| 227 virtual void SetInputAt(intptr_t i, Value* value) = 0; | 228 virtual void SetInputAt(intptr_t i, Value* value) = 0; |
| 228 | 229 |
| 229 // Call instructions override this function and return the | 230 // Call instructions override this function and return the |
| 230 // number of pushed arguments. | 231 // number of pushed arguments. |
| 231 virtual intptr_t ArgumentCount() const = 0; | 232 virtual intptr_t ArgumentCount() const = 0; |
| 232 | 233 |
| 233 // Returns true, if this instruction can deoptimize. | 234 // Returns true, if this instruction can deoptimize. |
| (...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 295 // Mutate assigned_vars to add the local variable index for all | 296 // Mutate assigned_vars to add the local variable index for all |
| 296 // frame-allocated locals assigned to by the instruction. | 297 // frame-allocated locals assigned to by the instruction. |
| 297 virtual void RecordAssignedVars(BitVector* assigned_vars, | 298 virtual void RecordAssignedVars(BitVector* assigned_vars, |
| 298 intptr_t fixed_parameter_count); | 299 intptr_t fixed_parameter_count); |
| 299 | 300 |
| 300 // Printing support. | 301 // Printing support. |
| 301 virtual void PrintTo(BufferFormatter* f) const = 0; | 302 virtual void PrintTo(BufferFormatter* f) const = 0; |
| 302 virtual void PrintToVisualizer(BufferFormatter* f) const = 0; | 303 virtual void PrintToVisualizer(BufferFormatter* f) const = 0; |
| 303 | 304 |
| 304 #define INSTRUCTION_TYPE_CHECK(type) \ | 305 #define INSTRUCTION_TYPE_CHECK(type) \ |
| 305 virtual bool Is##type() const { return false; } \ | 306 bool Is##type() { return (As##type() != NULL); } \ |
| 306 virtual type##Instr* As##type() { return NULL; } | 307 virtual type##Instr* As##type() { return NULL; } |
| 307 FOR_EACH_INSTRUCTION(INSTRUCTION_TYPE_CHECK) | 308 FOR_EACH_INSTRUCTION(INSTRUCTION_TYPE_CHECK) |
| 308 #undef INSTRUCTION_TYPE_CHECK | 309 #undef INSTRUCTION_TYPE_CHECK |
| 309 | 310 |
| 310 // Returns structure describing location constraints required | 311 // Returns structure describing location constraints required |
| 311 // to emit native code for this instruction. | 312 // to emit native code for this instruction. |
| 312 virtual LocationSummary* locs() { | 313 virtual LocationSummary* locs() { |
| 313 // TODO(vegorov): This should be pure virtual method. | 314 // TODO(vegorov): This should be pure virtual method. |
| 314 // However we are temporary using NULL for instructions that | 315 // However we are temporary using NULL for instructions that |
| 315 // were not converted to the location based code generation yet. | 316 // were not converted to the location based code generation yet. |
| (...skipping 28 matching lines...) Expand all Loading... |
| 344 | 345 |
| 345 // Returns deoptimization id that corresponds to the deoptimization target | 346 // Returns deoptimization id that corresponds to the deoptimization target |
| 346 // that input operands conversions inserted for this instruction can jump | 347 // that input operands conversions inserted for this instruction can jump |
| 347 // to. | 348 // to. |
| 348 virtual intptr_t DeoptimizationTarget() const { | 349 virtual intptr_t DeoptimizationTarget() const { |
| 349 UNREACHABLE(); | 350 UNREACHABLE(); |
| 350 return Isolate::kNoDeoptId; | 351 return Isolate::kNoDeoptId; |
| 351 } | 352 } |
| 352 | 353 |
| 353 private: | 354 private: |
| 354 friend class BindInstr; // Needed for BindInstr::InsertBefore. | 355 friend class Definition; // Needed for InsertBefore, InsertAfter. |
| 355 | 356 |
| 356 intptr_t lifetime_position_; // Position used by register allocator. | 357 intptr_t lifetime_position_; // Position used by register allocator. |
| 357 Instruction* previous_; | 358 Instruction* previous_; |
| 358 Instruction* next_; | 359 Instruction* next_; |
| 359 Environment* env_; | 360 Environment* env_; |
| 360 DISALLOW_COPY_AND_ASSIGN(Instruction); | 361 DISALLOW_COPY_AND_ASSIGN(Instruction); |
| 361 }; | 362 }; |
| 362 | 363 |
| 363 | 364 |
| 364 template<intptr_t N> | 365 template<intptr_t N> |
| (...skipping 117 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 482 }; | 483 }; |
| 483 | 484 |
| 484 | 485 |
| 485 // Basic block entries are administrative nodes. There is a distinguished | 486 // Basic block entries are administrative nodes. There is a distinguished |
| 486 // graph entry with no predecessor. Joins are the only nodes with multiple | 487 // graph entry with no predecessor. Joins are the only nodes with multiple |
| 487 // predecessors. Targets are all other basic block entries. The types | 488 // predecessors. Targets are all other basic block entries. The types |
| 488 // enforce edge-split form---joins are forbidden as the successors of | 489 // enforce edge-split form---joins are forbidden as the successors of |
| 489 // branches. | 490 // branches. |
| 490 class BlockEntryInstr : public Instruction { | 491 class BlockEntryInstr : public Instruction { |
| 491 public: | 492 public: |
| 492 virtual bool IsBlockEntry() const { return true; } | 493 virtual BlockEntryInstr* AsBlockEntry() { return this; } |
| 493 | 494 |
| 494 virtual intptr_t PredecessorCount() const = 0; | 495 virtual intptr_t PredecessorCount() const = 0; |
| 495 virtual BlockEntryInstr* PredecessorAt(intptr_t index) const = 0; | 496 virtual BlockEntryInstr* PredecessorAt(intptr_t index) const = 0; |
| 496 virtual void AddPredecessor(BlockEntryInstr* predecessor) = 0; | 497 virtual void AddPredecessor(BlockEntryInstr* predecessor) = 0; |
| 497 virtual void PrepareEntry(FlowGraphCompiler* compiler) = 0; | 498 virtual void PrepareEntry(FlowGraphCompiler* compiler) = 0; |
| 498 | 499 |
| 499 intptr_t preorder_number() const { return preorder_number_; } | 500 intptr_t preorder_number() const { return preorder_number_; } |
| 500 void set_preorder_number(intptr_t number) { preorder_number_ = number; } | 501 void set_preorder_number(intptr_t number) { preorder_number_ = number; } |
| 501 | 502 |
| 502 intptr_t postorder_number() const { return postorder_number_; } | 503 intptr_t postorder_number() const { return postorder_number_; } |
| (...skipping 276 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 779 BlockEntryInstr* predecessor_; | 780 BlockEntryInstr* predecessor_; |
| 780 const intptr_t catch_try_index_; | 781 const intptr_t catch_try_index_; |
| 781 | 782 |
| 782 DISALLOW_COPY_AND_ASSIGN(TargetEntryInstr); | 783 DISALLOW_COPY_AND_ASSIGN(TargetEntryInstr); |
| 783 }; | 784 }; |
| 784 | 785 |
| 785 | 786 |
| 786 // Abstract super-class of all instructions that define a value (Bind, Phi). | 787 // Abstract super-class of all instructions that define a value (Bind, Phi). |
| 787 class Definition : public Instruction { | 788 class Definition : public Instruction { |
| 788 public: | 789 public: |
| 790 enum UseKind { kEffect, kValue }; |
| 791 |
| 789 Definition() | 792 Definition() |
| 790 : temp_index_(-1), | 793 : temp_index_(-1), |
| 791 ssa_temp_index_(-1), | 794 ssa_temp_index_(-1), |
| 792 propagated_type_(AbstractType::Handle()), | 795 propagated_type_(AbstractType::Handle()), |
| 793 propagated_cid_(kIllegalCid), | 796 propagated_cid_(kIllegalCid), |
| 794 input_use_list_(NULL), | 797 input_use_list_(NULL), |
| 795 env_use_list_(NULL) { } | 798 env_use_list_(NULL), |
| 799 use_kind_(kValue) { // Phis and parameters rely on this default. |
| 800 } |
| 796 | 801 |
| 797 virtual bool IsDefinition() const { return true; } | |
| 798 virtual Definition* AsDefinition() { return this; } | 802 virtual Definition* AsDefinition() { return this; } |
| 799 | 803 |
| 800 intptr_t temp_index() const { return temp_index_; } | 804 intptr_t temp_index() const { return temp_index_; } |
| 801 void set_temp_index(intptr_t index) { temp_index_ = index; } | 805 void set_temp_index(intptr_t index) { temp_index_ = index; } |
| 802 | 806 |
| 803 intptr_t ssa_temp_index() const { return ssa_temp_index_; } | 807 intptr_t ssa_temp_index() const { return ssa_temp_index_; } |
| 804 void set_ssa_temp_index(intptr_t index) { | 808 void set_ssa_temp_index(intptr_t index) { |
| 805 ASSERT(index >= 0); | 809 ASSERT(index >= 0); |
| 810 ASSERT(is_used()); |
| 806 ssa_temp_index_ = index; | 811 ssa_temp_index_ = index; |
| 807 } | 812 } |
| 808 bool HasSSATemp() const { return ssa_temp_index_ >= 0; } | 813 bool HasSSATemp() const { return ssa_temp_index_ >= 0; } |
| 809 | 814 |
| 815 bool is_used() const { return (use_kind_ != kEffect); } |
| 816 void set_use_kind(UseKind kind) { use_kind_ = kind; } |
| 817 |
| 810 // Compile time type of the definition, which may be requested before type | 818 // Compile time type of the definition, which may be requested before type |
| 811 // propagation during graph building. | 819 // propagation during graph building. |
| 812 virtual RawAbstractType* CompileType() const = 0; | 820 virtual RawAbstractType* CompileType() const = 0; |
| 813 | 821 |
| 814 bool HasPropagatedType() const { | 822 bool HasPropagatedType() const { |
| 815 return !propagated_type_.IsNull(); | 823 return !propagated_type_.IsNull(); |
| 816 } | 824 } |
| 817 RawAbstractType* PropagatedType() const { | 825 RawAbstractType* PropagatedType() const { |
| 818 ASSERT(HasPropagatedType()); | 826 ASSERT(HasPropagatedType()); |
| 819 return propagated_type_.raw(); | 827 return propagated_type_.raw(); |
| (...skipping 22 matching lines...) Expand all Loading... |
| 842 void set_input_use_list(Value* head) { input_use_list_ = head; } | 850 void set_input_use_list(Value* head) { input_use_list_ = head; } |
| 843 | 851 |
| 844 Value* env_use_list() { return env_use_list_; } | 852 Value* env_use_list() { return env_use_list_; } |
| 845 void set_env_use_list(Value* head) { env_use_list_ = head; } | 853 void set_env_use_list(Value* head) { env_use_list_ = head; } |
| 846 | 854 |
| 847 // Replace uses of this definition with uses of other definition or value. | 855 // Replace uses of this definition with uses of other definition or value. |
| 848 // Precondition: use lists must be properly calculated. | 856 // Precondition: use lists must be properly calculated. |
| 849 // Postcondition: use lists and use values are still valid. | 857 // Postcondition: use lists and use values are still valid. |
| 850 void ReplaceUsesWith(Definition* other); | 858 void ReplaceUsesWith(Definition* other); |
| 851 | 859 |
| 860 // Insert this definition before 'next'. |
| 861 void InsertBefore(Instruction* next); |
| 862 |
| 863 // Insert this definition after 'prev'. |
| 864 void InsertAfter(Instruction* prev); |
| 865 |
| 852 private: | 866 private: |
| 853 intptr_t temp_index_; | 867 intptr_t temp_index_; |
| 854 intptr_t ssa_temp_index_; | 868 intptr_t ssa_temp_index_; |
| 855 // TODO(regis): GrowableArray<const AbstractType*> propagated_types_; | 869 // TODO(regis): GrowableArray<const AbstractType*> propagated_types_; |
| 856 // For now: | 870 // For now: |
| 857 AbstractType& propagated_type_; | 871 AbstractType& propagated_type_; |
| 858 intptr_t propagated_cid_; | 872 intptr_t propagated_cid_; |
| 859 Value* input_use_list_; | 873 Value* input_use_list_; |
| 860 Value* env_use_list_; | 874 Value* env_use_list_; |
| 875 UseKind use_kind_; |
| 861 | 876 |
| 862 DISALLOW_COPY_AND_ASSIGN(Definition); | 877 DISALLOW_COPY_AND_ASSIGN(Definition); |
| 863 }; | 878 }; |
| 864 | 879 |
| 865 | 880 |
| 866 class BindInstr : public Definition { | 881 class BindInstr : public Definition { |
| 867 public: | 882 public: |
| 868 enum UseKind { kUnused, kUsed }; | |
| 869 | |
| 870 BindInstr(UseKind used, Computation* computation) | 883 BindInstr(UseKind used, Computation* computation) |
| 871 : computation_(computation), is_used_(used != kUnused) { | 884 : computation_(computation) { |
| 872 ASSERT(computation != NULL); | 885 ASSERT(computation != NULL); |
| 886 set_use_kind(used); |
| 873 } | 887 } |
| 874 | 888 |
| 875 DECLARE_INSTRUCTION(Bind) | 889 DECLARE_INSTRUCTION(Bind) |
| 876 | 890 |
| 891 // Overridden functions from class Instruction. |
| 877 virtual intptr_t ArgumentCount() const; | 892 virtual intptr_t ArgumentCount() const; |
| 878 intptr_t InputCount() const; | 893 intptr_t InputCount() const; |
| 879 Value* InputAt(intptr_t i) const; | 894 Value* InputAt(intptr_t i) const; |
| 880 void SetInputAt(intptr_t i, Value* value); | 895 void SetInputAt(intptr_t i, Value* value); |
| 881 virtual bool CanDeoptimize() const; | 896 virtual bool CanDeoptimize() const; |
| 882 | |
| 883 Computation* computation() const { return computation_; } | |
| 884 void set_computation(Computation* value) { computation_ = value; } | |
| 885 bool is_used() const { return is_used_; } | |
| 886 | |
| 887 virtual RawAbstractType* CompileType() const; | |
| 888 virtual intptr_t GetPropagatedCid(); | |
| 889 | |
| 890 virtual void RecordAssignedVars(BitVector* assigned_vars, | 897 virtual void RecordAssignedVars(BitVector* assigned_vars, |
| 891 intptr_t fixed_parameter_count); | 898 intptr_t fixed_parameter_count); |
| 892 | |
| 893 intptr_t Hashcode() const; | |
| 894 bool Equals(BindInstr* other) const; | |
| 895 virtual LocationSummary* locs(); | 899 virtual LocationSummary* locs(); |
| 896 virtual void EmitNativeCode(FlowGraphCompiler* compiler); | 900 virtual void EmitNativeCode(FlowGraphCompiler* compiler); |
| 897 | |
| 898 // Insert this instruction before 'next'. | |
| 899 void InsertBefore(Instruction* next); | |
| 900 | |
| 901 // Insert this instruction after 'prev'. | |
| 902 void InsertAfter(Instruction* prev); | |
| 903 | |
| 904 virtual Representation RequiredInputRepresentation(intptr_t i) const; | 901 virtual Representation RequiredInputRepresentation(intptr_t i) const; |
| 905 virtual Representation representation() const; | 902 virtual Representation representation() const; |
| 906 virtual intptr_t DeoptimizationTarget() const; | 903 virtual intptr_t DeoptimizationTarget() const; |
| 907 | 904 |
| 905 Computation* computation() const { return computation_; } |
| 906 void set_computation(Computation* value) { computation_ = value; } |
| 907 |
| 908 // Overridden functions from class Definition. |
| 909 virtual RawAbstractType* CompileType() const; |
| 910 virtual intptr_t GetPropagatedCid(); |
| 911 |
| 912 // Other functions that forward to the computation. |
| 913 intptr_t Hashcode() const; |
| 914 bool Equals(BindInstr* other) const; |
| 915 |
| 908 private: | 916 private: |
| 909 Computation* computation_; | 917 Computation* computation_; |
| 910 const bool is_used_; | |
| 911 | 918 |
| 912 DISALLOW_COPY_AND_ASSIGN(BindInstr); | 919 DISALLOW_COPY_AND_ASSIGN(BindInstr); |
| 913 }; | 920 }; |
| 914 | 921 |
| 915 | 922 |
| 916 class PhiInstr : public Definition { | 923 class PhiInstr : public Definition { |
| 917 public: | 924 public: |
| 918 explicit PhiInstr(JoinEntryInstr* block, intptr_t num_inputs) | 925 explicit PhiInstr(JoinEntryInstr* block, intptr_t num_inputs) |
| 919 : block_(block), | 926 : block_(block), |
| 920 inputs_(num_inputs), | 927 inputs_(num_inputs), |
| (...skipping 246 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1167 // Parallel move that will be used by linear scan register allocator to | 1174 // Parallel move that will be used by linear scan register allocator to |
| 1168 // connect live ranges at the end of the block and resolve phis. | 1175 // connect live ranges at the end of the block and resolve phis. |
| 1169 ParallelMoveInstr* parallel_move_; | 1176 ParallelMoveInstr* parallel_move_; |
| 1170 }; | 1177 }; |
| 1171 | 1178 |
| 1172 | 1179 |
| 1173 class ControlInstruction : public Instruction { | 1180 class ControlInstruction : public Instruction { |
| 1174 public: | 1181 public: |
| 1175 ControlInstruction() : true_successor_(NULL), false_successor_(NULL) { } | 1182 ControlInstruction() : true_successor_(NULL), false_successor_(NULL) { } |
| 1176 | 1183 |
| 1177 virtual bool IsControl() const { return true; } | 1184 virtual ControlInstruction* AsControl() { return this; } |
| 1178 | 1185 |
| 1179 TargetEntryInstr* true_successor() const { return true_successor_; } | 1186 TargetEntryInstr* true_successor() const { return true_successor_; } |
| 1180 TargetEntryInstr* false_successor() const { return false_successor_; } | 1187 TargetEntryInstr* false_successor() const { return false_successor_; } |
| 1181 | 1188 |
| 1182 TargetEntryInstr** true_successor_address() { return &true_successor_; } | 1189 TargetEntryInstr** true_successor_address() { return &true_successor_; } |
| 1183 TargetEntryInstr** false_successor_address() { return &false_successor_; } | 1190 TargetEntryInstr** false_successor_address() { return &false_successor_; } |
| 1184 | 1191 |
| 1185 virtual intptr_t SuccessorCount() const; | 1192 virtual intptr_t SuccessorCount() const; |
| 1186 virtual BlockEntryInstr* SuccessorAt(intptr_t index) const; | 1193 virtual BlockEntryInstr* SuccessorAt(intptr_t index) const; |
| 1187 | 1194 |
| (...skipping 2223 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3411 ForwardInstructionIterator* current_iterator_; | 3418 ForwardInstructionIterator* current_iterator_; |
| 3412 | 3419 |
| 3413 private: | 3420 private: |
| 3414 DISALLOW_COPY_AND_ASSIGN(FlowGraphVisitor); | 3421 DISALLOW_COPY_AND_ASSIGN(FlowGraphVisitor); |
| 3415 }; | 3422 }; |
| 3416 | 3423 |
| 3417 | 3424 |
| 3418 } // namespace dart | 3425 } // namespace dart |
| 3419 | 3426 |
| 3420 #endif // VM_INTERMEDIATE_LANGUAGE_H_ | 3427 #endif // VM_INTERMEDIATE_LANGUAGE_H_ |
| OLD | NEW |