| 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 RUNTIME_VM_FLOW_GRAPH_BUILDER_H_ | 5 #ifndef RUNTIME_VM_FLOW_GRAPH_BUILDER_H_ |
| 6 #define RUNTIME_VM_FLOW_GRAPH_BUILDER_H_ | 6 #define RUNTIME_VM_FLOW_GRAPH_BUILDER_H_ |
| 7 | 7 |
| 8 #include "platform/assert.h" | 8 #include "platform/assert.h" |
| 9 #include "platform/globals.h" | 9 #include "platform/globals.h" |
| 10 #include "vm/allocation.h" | 10 #include "vm/allocation.h" |
| (...skipping 12 matching lines...) Expand all Loading... |
| 23 class LocalVariable; | 23 class LocalVariable; |
| 24 class ParsedFunction; | 24 class ParsedFunction; |
| 25 class String; | 25 class String; |
| 26 class TypeArguments; | 26 class TypeArguments; |
| 27 | 27 |
| 28 class NestedStatement; | 28 class NestedStatement; |
| 29 class TestGraphVisitor; | 29 class TestGraphVisitor; |
| 30 | 30 |
| 31 // A class to collect the exits from an inlined function during graph | 31 // A class to collect the exits from an inlined function during graph |
| 32 // construction so they can be plugged into the caller's flow graph. | 32 // construction so they can be plugged into the caller's flow graph. |
| 33 class InlineExitCollector: public ZoneAllocated { | 33 class InlineExitCollector : public ZoneAllocated { |
| 34 public: | 34 public: |
| 35 InlineExitCollector(FlowGraph* caller_graph, Definition* call) | 35 InlineExitCollector(FlowGraph* caller_graph, Definition* call) |
| 36 : caller_graph_(caller_graph), call_(call), exits_(4) { } | 36 : caller_graph_(caller_graph), call_(call), exits_(4) {} |
| 37 | 37 |
| 38 void AddExit(ReturnInstr* exit); | 38 void AddExit(ReturnInstr* exit); |
| 39 | 39 |
| 40 void Union(const InlineExitCollector* other); | 40 void Union(const InlineExitCollector* other); |
| 41 | 41 |
| 42 // Before replacing a call with a graph, the outer environment needs to be | 42 // Before replacing a call with a graph, the outer environment needs to be |
| 43 // attached to each instruction in the callee graph and the caller graph | 43 // attached to each instruction in the callee graph and the caller graph |
| 44 // needs to have its block and instruction ID state updated. | 44 // needs to have its block and instruction ID state updated. |
| 45 // Additionally we need to remove all unreachable exits from the list of | 45 // Additionally we need to remove all unreachable exits from the list of |
| 46 // collected exits. | 46 // collected exits. |
| (...skipping 16 matching lines...) Expand all Loading... |
| 63 | 63 |
| 64 BlockEntryInstr* ExitBlockAt(intptr_t i) const { | 64 BlockEntryInstr* ExitBlockAt(intptr_t i) const { |
| 65 ASSERT(exits_[i].exit_block != NULL); | 65 ASSERT(exits_[i].exit_block != NULL); |
| 66 return exits_[i].exit_block; | 66 return exits_[i].exit_block; |
| 67 } | 67 } |
| 68 | 68 |
| 69 Instruction* LastInstructionAt(intptr_t i) const { | 69 Instruction* LastInstructionAt(intptr_t i) const { |
| 70 return ReturnAt(i)->previous(); | 70 return ReturnAt(i)->previous(); |
| 71 } | 71 } |
| 72 | 72 |
| 73 Value* ValueAt(intptr_t i) const { | 73 Value* ValueAt(intptr_t i) const { return ReturnAt(i)->value(); } |
| 74 return ReturnAt(i)->value(); | |
| 75 } | |
| 76 | 74 |
| 77 ReturnInstr* ReturnAt(intptr_t i) const { | 75 ReturnInstr* ReturnAt(intptr_t i) const { return exits_[i].exit_return; } |
| 78 return exits_[i].exit_return; | |
| 79 } | |
| 80 | 76 |
| 81 static int LowestBlockIdFirst(const Data* a, const Data* b); | 77 static int LowestBlockIdFirst(const Data* a, const Data* b); |
| 82 void SortExits(); | 78 void SortExits(); |
| 83 void RemoveUnreachableExits(FlowGraph* callee_graph); | 79 void RemoveUnreachableExits(FlowGraph* callee_graph); |
| 84 | 80 |
| 85 Definition* JoinReturns(BlockEntryInstr** exit_block, | 81 Definition* JoinReturns(BlockEntryInstr** exit_block, |
| 86 Instruction** last_instruction, | 82 Instruction** last_instruction, |
| 87 intptr_t try_index); | 83 intptr_t try_index); |
| 88 | 84 |
| 89 Isolate* isolate() const { return caller_graph_->isolate(); } | 85 Isolate* isolate() const { return caller_graph_->isolate(); } |
| (...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 133 intptr_t catch_try_index() const { return catch_try_index_; } | 129 intptr_t catch_try_index() const { return catch_try_index_; } |
| 134 | 130 |
| 135 intptr_t next_await_counter() { return jump_count_++; } | 131 intptr_t next_await_counter() { return jump_count_++; } |
| 136 | 132 |
| 137 ZoneGrowableArray<JoinEntryInstr*>* await_joins() const { | 133 ZoneGrowableArray<JoinEntryInstr*>* await_joins() const { |
| 138 return await_joins_; | 134 return await_joins_; |
| 139 } | 135 } |
| 140 | 136 |
| 141 void AddCatchEntry(CatchBlockEntryInstr* entry); | 137 void AddCatchEntry(CatchBlockEntryInstr* entry); |
| 142 | 138 |
| 143 GraphEntryInstr* graph_entry() const { | 139 GraphEntryInstr* graph_entry() const { return graph_entry_; } |
| 144 return graph_entry_; | |
| 145 } | |
| 146 | 140 |
| 147 intptr_t num_copied_params() const { | 141 intptr_t num_copied_params() const { return num_copied_params_; } |
| 148 return num_copied_params_; | 142 intptr_t num_non_copied_params() const { return num_non_copied_params_; } |
| 149 } | 143 intptr_t num_stack_locals() const { return num_stack_locals_; } |
| 150 intptr_t num_non_copied_params() const { | |
| 151 return num_non_copied_params_; | |
| 152 } | |
| 153 intptr_t num_stack_locals() const { | |
| 154 return num_stack_locals_; | |
| 155 } | |
| 156 | 144 |
| 157 bool IsInlining() const { return (exit_collector_ != NULL); } | 145 bool IsInlining() const { return (exit_collector_ != NULL); } |
| 158 InlineExitCollector* exit_collector() const { return exit_collector_; } | 146 InlineExitCollector* exit_collector() const { return exit_collector_; } |
| 159 | 147 |
| 160 ZoneGrowableArray<const LibraryPrefix*>* deferred_prefixes() const { | 148 ZoneGrowableArray<const LibraryPrefix*>* deferred_prefixes() const { |
| 161 return parsed_function_.deferred_prefixes(); | 149 return parsed_function_.deferred_prefixes(); |
| 162 } | 150 } |
| 163 | 151 |
| 164 intptr_t temp_count() const { return temp_count_; } | 152 intptr_t temp_count() const { return temp_count_; } |
| 165 intptr_t AllocateTemp() { return temp_count_++; } | 153 intptr_t AllocateTemp() { return temp_count_++; } |
| (...skipping 68 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 234 // function from an AstNode and next temporary index to a graph fragment | 222 // function from an AstNode and next temporary index to a graph fragment |
| 235 // with a single entry and at most one exit. The fragment is represented by | 223 // with a single entry and at most one exit. The fragment is represented by |
| 236 // an (entry, exit) pair of Instruction pointers: | 224 // an (entry, exit) pair of Instruction pointers: |
| 237 // | 225 // |
| 238 // - (NULL, NULL): an empty and open graph fragment | 226 // - (NULL, NULL): an empty and open graph fragment |
| 239 // - (i0, NULL): a closed graph fragment which has only non-local exits | 227 // - (i0, NULL): a closed graph fragment which has only non-local exits |
| 240 // - (i0, i1): an open graph fragment | 228 // - (i0, i1): an open graph fragment |
| 241 class EffectGraphVisitor : public AstNodeVisitor { | 229 class EffectGraphVisitor : public AstNodeVisitor { |
| 242 public: | 230 public: |
| 243 explicit EffectGraphVisitor(FlowGraphBuilder* owner) | 231 explicit EffectGraphVisitor(FlowGraphBuilder* owner) |
| 244 : owner_(owner), | 232 : owner_(owner), entry_(NULL), exit_(NULL) {} |
| 245 entry_(NULL), | |
| 246 exit_(NULL) { } | |
| 247 | 233 |
| 248 #define DECLARE_VISIT(BaseName) \ | 234 #define DECLARE_VISIT(BaseName) \ |
| 249 virtual void Visit##BaseName##Node(BaseName##Node* node); | 235 virtual void Visit##BaseName##Node(BaseName##Node* node); |
| 250 | 236 |
| 251 FOR_EACH_NODE(DECLARE_VISIT) | 237 FOR_EACH_NODE(DECLARE_VISIT) |
| 252 #undef DECLARE_VISIT | 238 #undef DECLARE_VISIT |
| 253 | 239 |
| 254 FlowGraphBuilder* owner() const { return owner_; } | 240 FlowGraphBuilder* owner() const { return owner_; } |
| 255 Instruction* entry() const { return entry_; } | 241 Instruction* entry() const { return entry_; } |
| 256 Instruction* exit() const { return exit_; } | 242 Instruction* exit() const { return exit_; } |
| (...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 302 Value* value, | 288 Value* value, |
| 303 TokenPosition token_pos); | 289 TokenPosition token_pos); |
| 304 Definition* BuildStoreExprTemp(Value* value, TokenPosition token_pos); | 290 Definition* BuildStoreExprTemp(Value* value, TokenPosition token_pos); |
| 305 Definition* BuildLoadExprTemp(TokenPosition token_pos); | 291 Definition* BuildLoadExprTemp(TokenPosition token_pos); |
| 306 | 292 |
| 307 Definition* BuildStoreLocal(const LocalVariable& local, | 293 Definition* BuildStoreLocal(const LocalVariable& local, |
| 308 Value* value, | 294 Value* value, |
| 309 TokenPosition token_pos); | 295 TokenPosition token_pos); |
| 310 Definition* BuildLoadLocal(const LocalVariable& local, | 296 Definition* BuildLoadLocal(const LocalVariable& local, |
| 311 TokenPosition token_pos); | 297 TokenPosition token_pos); |
| 312 LoadLocalInstr* BuildLoadThisVar(LocalScope* scope, | 298 LoadLocalInstr* BuildLoadThisVar(LocalScope* scope, TokenPosition token_pos); |
| 313 TokenPosition token_pos); | 299 LoadFieldInstr* BuildNativeGetter(NativeBodyNode* node, |
| 314 LoadFieldInstr* BuildNativeGetter( | 300 MethodRecognizer::Kind kind, |
| 315 NativeBodyNode* node, | 301 intptr_t offset, |
| 316 MethodRecognizer::Kind kind, | 302 const Type& type, |
| 317 intptr_t offset, | 303 intptr_t class_id); |
| 318 const Type& type, | |
| 319 intptr_t class_id); | |
| 320 // Assumes setter parameter is named 'value'. Returns null constant. | 304 // Assumes setter parameter is named 'value'. Returns null constant. |
| 321 ConstantInstr* DoNativeSetterStoreValue( | 305 ConstantInstr* DoNativeSetterStoreValue(NativeBodyNode* node, |
| 322 NativeBodyNode* node, | 306 intptr_t offset, |
| 323 intptr_t offset, | 307 StoreBarrierType emit_store_barrier); |
| 324 StoreBarrierType emit_store_barrier); | |
| 325 | 308 |
| 326 // Helpers for translating parts of the AST. | 309 // Helpers for translating parts of the AST. |
| 327 void BuildPushArguments(const ArgumentListNode& node, | 310 void BuildPushArguments(const ArgumentListNode& node, |
| 328 ZoneGrowableArray<PushArgumentInstr*>* values); | 311 ZoneGrowableArray<PushArgumentInstr*>* values); |
| 329 | 312 |
| 330 // Creates an instantiated type argument vector used in preparation of an | 313 // Creates an instantiated type argument vector used in preparation of an |
| 331 // allocation call. | 314 // allocation call. |
| 332 // May be called only if allocating an object of a parameterized class. | 315 // May be called only if allocating an object of a parameterized class. |
| 333 Value* BuildInstantiatedTypeArguments( | 316 Value* BuildInstantiatedTypeArguments(TokenPosition token_pos, |
| 334 TokenPosition token_pos, | 317 const TypeArguments& type_arguments); |
| 335 const TypeArguments& type_arguments); | |
| 336 | 318 |
| 337 void BuildTypecheckPushArguments( | 319 void BuildTypecheckPushArguments( |
| 338 TokenPosition token_pos, | 320 TokenPosition token_pos, |
| 339 PushArgumentInstr** push_instantiator_type_arguments); | 321 PushArgumentInstr** push_instantiator_type_arguments); |
| 340 void BuildTypecheckArguments(TokenPosition token_pos, | 322 void BuildTypecheckArguments(TokenPosition token_pos, |
| 341 Value** instantiator_type_arguments); | 323 Value** instantiator_type_arguments); |
| 342 Value* BuildInstantiator(TokenPosition token_pos); | 324 Value* BuildInstantiator(TokenPosition token_pos); |
| 343 Value* BuildInstantiatorTypeArguments(TokenPosition token_pos, | 325 Value* BuildInstantiatorTypeArguments(TokenPosition token_pos, |
| 344 const Class& instantiator_class, | 326 const Class& instantiator_class, |
| 345 Value* instantiator); | 327 Value* instantiator); |
| (...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 387 void CloseFragment() { exit_ = NULL; } | 369 void CloseFragment() { exit_ = NULL; } |
| 388 | 370 |
| 389 // Returns a local variable index for a temporary local that is | 371 // Returns a local variable index for a temporary local that is |
| 390 // on top of the current expression stack. | 372 // on top of the current expression stack. |
| 391 intptr_t GetCurrentTempLocalIndex() const; | 373 intptr_t GetCurrentTempLocalIndex() const; |
| 392 | 374 |
| 393 Value* BuildObjectAllocation(ConstructorCallNode* node); | 375 Value* BuildObjectAllocation(ConstructorCallNode* node); |
| 394 void BuildConstructorCall(ConstructorCallNode* node, | 376 void BuildConstructorCall(ConstructorCallNode* node, |
| 395 PushArgumentInstr* alloc_value); | 377 PushArgumentInstr* alloc_value); |
| 396 | 378 |
| 397 void BuildSaveContext(const LocalVariable& variable, | 379 void BuildSaveContext(const LocalVariable& variable, TokenPosition token_pos); |
| 398 TokenPosition token_pos); | |
| 399 void BuildRestoreContext(const LocalVariable& variable, | 380 void BuildRestoreContext(const LocalVariable& variable, |
| 400 TokenPosition token_pos); | 381 TokenPosition token_pos); |
| 401 | 382 |
| 402 Definition* BuildStoreContext(Value* value, TokenPosition token_pos); | 383 Definition* BuildStoreContext(Value* value, TokenPosition token_pos); |
| 403 Definition* BuildCurrentContext(TokenPosition token_pos); | 384 Definition* BuildCurrentContext(TokenPosition token_pos); |
| 404 | 385 |
| 405 void BuildThrowNode(ThrowNode* node); | 386 void BuildThrowNode(ThrowNode* node); |
| 406 | 387 |
| 407 StaticCallInstr* BuildStaticNoSuchMethodCall( | 388 StaticCallInstr* BuildStaticNoSuchMethodCall( |
| 408 const Class& target_class, | 389 const Class& target_class, |
| (...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 445 void BuildInstanceCallConditional(InstanceCallNode* node); | 426 void BuildInstanceCallConditional(InstanceCallNode* node); |
| 446 | 427 |
| 447 Thread* thread() const { return owner()->thread(); } | 428 Thread* thread() const { return owner()->thread(); } |
| 448 Isolate* isolate() const { return owner()->isolate(); } | 429 Isolate* isolate() const { return owner()->isolate(); } |
| 449 Zone* zone() const { return owner()->zone(); } | 430 Zone* zone() const { return owner()->zone(); } |
| 450 | 431 |
| 451 private: | 432 private: |
| 452 friend class TempLocalScope; // For ReturnDefinition. | 433 friend class TempLocalScope; // For ReturnDefinition. |
| 453 | 434 |
| 454 // Helper to drop the result value. | 435 // Helper to drop the result value. |
| 455 virtual void ReturnValue(Value* value) { | 436 virtual void ReturnValue(Value* value) { Do(new DropTempsInstr(0, value)); } |
| 456 Do(new DropTempsInstr(0, value)); | |
| 457 } | |
| 458 | 437 |
| 459 // Specify a definition of the final result. Adds the definition to | 438 // Specify a definition of the final result. Adds the definition to |
| 460 // the graph, but normally overridden in subclasses. | 439 // the graph, but normally overridden in subclasses. |
| 461 virtual void ReturnDefinition(Definition* definition) { | 440 virtual void ReturnDefinition(Definition* definition) { |
| 462 // Constants have no effect, do not add them to graph otherwise SSA | 441 // Constants have no effect, do not add them to graph otherwise SSA |
| 463 // builder will get confused. | 442 // builder will get confused. |
| 464 if (!definition->IsConstant()) { | 443 if (!definition->IsConstant()) { |
| 465 Do(definition); | 444 Do(definition); |
| 466 } | 445 } |
| 467 } | 446 } |
| 468 | 447 |
| 469 // Shared global state. | 448 // Shared global state. |
| 470 FlowGraphBuilder* owner_; | 449 FlowGraphBuilder* owner_; |
| 471 | 450 |
| 472 // Output parameters. | 451 // Output parameters. |
| 473 Instruction* entry_; | 452 Instruction* entry_; |
| 474 Instruction* exit_; | 453 Instruction* exit_; |
| 475 }; | 454 }; |
| 476 | 455 |
| 477 | 456 |
| 478 // Translate an AstNode to a control-flow graph fragment for both its effects | 457 // Translate an AstNode to a control-flow graph fragment for both its effects |
| 479 // and value (e.g., for an expression in a value context). Implements a | 458 // and value (e.g., for an expression in a value context). Implements a |
| 480 // function from an AstNode and next temporary index to a graph fragment (as | 459 // function from an AstNode and next temporary index to a graph fragment (as |
| 481 // in the EffectGraphVisitor), a next temporary index, and an intermediate | 460 // in the EffectGraphVisitor), a next temporary index, and an intermediate |
| 482 // language Value. | 461 // language Value. |
| 483 class ValueGraphVisitor : public EffectGraphVisitor { | 462 class ValueGraphVisitor : public EffectGraphVisitor { |
| 484 public: | 463 public: |
| 485 explicit ValueGraphVisitor(FlowGraphBuilder* owner) | 464 explicit ValueGraphVisitor(FlowGraphBuilder* owner) |
| 486 : EffectGraphVisitor(owner), value_(NULL) { } | 465 : EffectGraphVisitor(owner), value_(NULL) {} |
| 487 | 466 |
| 488 // Visit functions overridden by this class. | 467 // Visit functions overridden by this class. |
| 489 virtual void VisitAssignableNode(AssignableNode* node); | 468 virtual void VisitAssignableNode(AssignableNode* node); |
| 490 virtual void VisitConstructorCallNode(ConstructorCallNode* node); | 469 virtual void VisitConstructorCallNode(ConstructorCallNode* node); |
| 491 virtual void VisitBinaryOpNode(BinaryOpNode* node); | 470 virtual void VisitBinaryOpNode(BinaryOpNode* node); |
| 492 virtual void VisitConditionalExprNode(ConditionalExprNode* node); | 471 virtual void VisitConditionalExprNode(ConditionalExprNode* node); |
| 493 virtual void VisitLoadLocalNode(LoadLocalNode* node); | 472 virtual void VisitLoadLocalNode(LoadLocalNode* node); |
| 494 virtual void VisitStoreIndexedNode(StoreIndexedNode* node); | 473 virtual void VisitStoreIndexedNode(StoreIndexedNode* node); |
| 495 virtual void VisitInstanceSetterNode(InstanceSetterNode* node); | 474 virtual void VisitInstanceSetterNode(InstanceSetterNode* node); |
| 496 virtual void VisitInstanceGetterNode(InstanceGetterNode* node); | 475 virtual void VisitInstanceGetterNode(InstanceGetterNode* node); |
| (...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 533 // - Both NULL: only non-local exits, truly closed | 512 // - Both NULL: only non-local exits, truly closed |
| 534 // - Neither NULL: true and false successors at the given addresses | 513 // - Neither NULL: true and false successors at the given addresses |
| 535 // | 514 // |
| 536 // We expect that AstNode in test contexts either have only nonlocal exits | 515 // We expect that AstNode in test contexts either have only nonlocal exits |
| 537 // or else control flow has both true and false successors. | 516 // or else control flow has both true and false successors. |
| 538 // | 517 // |
| 539 // The cis and token_pos are used in checked mode to verify that the | 518 // The cis and token_pos are used in checked mode to verify that the |
| 540 // condition of the test is of type bool. | 519 // condition of the test is of type bool. |
| 541 class TestGraphVisitor : public ValueGraphVisitor { | 520 class TestGraphVisitor : public ValueGraphVisitor { |
| 542 public: | 521 public: |
| 543 TestGraphVisitor(FlowGraphBuilder* owner, | 522 TestGraphVisitor(FlowGraphBuilder* owner, TokenPosition condition_token_pos) |
| 544 TokenPosition condition_token_pos) | |
| 545 : ValueGraphVisitor(owner), | 523 : ValueGraphVisitor(owner), |
| 546 true_successor_addresses_(1), | 524 true_successor_addresses_(1), |
| 547 false_successor_addresses_(1), | 525 false_successor_addresses_(1), |
| 548 condition_token_pos_(condition_token_pos) { } | 526 condition_token_pos_(condition_token_pos) {} |
| 549 | 527 |
| 550 void IfFalseGoto(JoinEntryInstr* join) const; | 528 void IfFalseGoto(JoinEntryInstr* join) const; |
| 551 void IfTrueGoto(JoinEntryInstr* join) const; | 529 void IfTrueGoto(JoinEntryInstr* join) const; |
| 552 | 530 |
| 553 BlockEntryInstr* CreateTrueSuccessor() const; | 531 BlockEntryInstr* CreateTrueSuccessor() const; |
| 554 BlockEntryInstr* CreateFalseSuccessor() const; | 532 BlockEntryInstr* CreateFalseSuccessor() const; |
| 555 | 533 |
| 556 virtual void VisitBinaryOpNode(BinaryOpNode* node); | 534 virtual void VisitBinaryOpNode(BinaryOpNode* node); |
| 557 | 535 |
| 558 TokenPosition condition_token_pos() const { return condition_token_pos_; } | 536 TokenPosition condition_token_pos() const { return condition_token_pos_; } |
| 559 | 537 |
| 560 private: | 538 private: |
| 561 // Construct and concatenate a Branch instruction to this graph fragment. | 539 // Construct and concatenate a Branch instruction to this graph fragment. |
| 562 // Closes the fragment and sets the output parameters. | 540 // Closes the fragment and sets the output parameters. |
| 563 virtual void ReturnValue(Value* value); | 541 virtual void ReturnValue(Value* value); |
| 564 | 542 |
| 565 // Either merges the definition into a BranchInstr (Comparison, BooleanNegate) | 543 // Either merges the definition into a BranchInstr (Comparison, BooleanNegate) |
| 566 // or adds the definition to the graph and returns a use of its value. | 544 // or adds the definition to the graph and returns a use of its value. |
| 567 virtual void ReturnDefinition(Definition* definition); | 545 virtual void ReturnDefinition(Definition* definition); |
| 568 | 546 |
| 569 void MergeBranchWithComparison(ComparisonInstr* comp); | 547 void MergeBranchWithComparison(ComparisonInstr* comp); |
| 570 void MergeBranchWithNegate(BooleanNegateInstr* comp); | 548 void MergeBranchWithNegate(BooleanNegateInstr* comp); |
| 571 | 549 |
| 572 BlockEntryInstr* CreateSuccessorFor( | 550 BlockEntryInstr* CreateSuccessorFor( |
| 573 const GrowableArray<TargetEntryInstr**>& branches) const; | 551 const GrowableArray<TargetEntryInstr**>& branches) const; |
| 574 | 552 |
| 575 void ConnectBranchesTo( | 553 void ConnectBranchesTo(const GrowableArray<TargetEntryInstr**>& branches, |
| 576 const GrowableArray<TargetEntryInstr**>& branches, | 554 JoinEntryInstr* join) const; |
| 577 JoinEntryInstr* join) const; | |
| 578 | 555 |
| 579 // Output parameters. | 556 // Output parameters. |
| 580 GrowableArray<TargetEntryInstr**> true_successor_addresses_; | 557 GrowableArray<TargetEntryInstr**> true_successor_addresses_; |
| 581 GrowableArray<TargetEntryInstr**> false_successor_addresses_; | 558 GrowableArray<TargetEntryInstr**> false_successor_addresses_; |
| 582 | 559 |
| 583 TokenPosition condition_token_pos_; | 560 TokenPosition condition_token_pos_; |
| 584 }; | 561 }; |
| 585 | 562 |
| 586 } // namespace dart | 563 } // namespace dart |
| 587 | 564 |
| 588 #endif // RUNTIME_VM_FLOW_GRAPH_BUILDER_H_ | 565 #endif // RUNTIME_VM_FLOW_GRAPH_BUILDER_H_ |
| OLD | NEW |