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 #include "vm/intermediate_language.h" | 5 #include "vm/intermediate_language.h" |
6 | 6 |
7 #include "vm/bit_vector.h" | 7 #include "vm/bit_vector.h" |
8 #include "vm/dart_entry.h" | 8 #include "vm/dart_entry.h" |
9 #include "vm/flow_graph_builder.h" | 9 #include "vm/flow_graph_builder.h" |
10 #include "vm/flow_graph_compiler.h" | 10 #include "vm/flow_graph_compiler.h" |
(...skipping 78 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
89 prev->set_next(next); | 89 prev->set_next(next); |
90 next->set_previous(prev); | 90 next->set_previous(prev); |
91 // Reset successor and previous instruction to indicate | 91 // Reset successor and previous instruction to indicate |
92 // that the instruction is removed from the graph. | 92 // that the instruction is removed from the graph. |
93 current_->set_previous(NULL); | 93 current_->set_previous(NULL); |
94 current_->set_next(NULL); | 94 current_->set_next(NULL); |
95 current_ = prev; | 95 current_ = prev; |
96 } | 96 } |
97 | 97 |
98 | 98 |
99 // True iff. the v2 is above v1 on stack, or one of them is constant. | |
100 static bool VerifyValues(Value* v1, Value* v2) { | |
101 ASSERT(v1->IsUse() && v2->IsUse()); | |
102 return (v1->AsUse()->definition()->temp_index() + 1) == | |
103 v2->AsUse()->definition()->temp_index(); | |
104 } | |
105 | |
106 | |
107 // Default implementation of visiting basic blocks. Can be overridden. | 99 // Default implementation of visiting basic blocks. Can be overridden. |
108 void FlowGraphVisitor::VisitBlocks() { | 100 void FlowGraphVisitor::VisitBlocks() { |
109 for (intptr_t i = 0; i < block_order_.length(); ++i) { | 101 for (intptr_t i = 0; i < block_order_.length(); ++i) { |
110 BlockEntryInstr* entry = block_order_[i]; | 102 BlockEntryInstr* entry = block_order_[i]; |
111 entry->Accept(this); | 103 entry->Accept(this); |
112 for (ForwardInstructionIterator it(entry); !it.Done(); it.Advance()) { | 104 for (ForwardInstructionIterator it(entry); !it.Done(); it.Advance()) { |
113 it.Current()->Accept(this); | 105 it.Current()->Accept(this); |
114 } | 106 } |
115 } | 107 } |
116 } | 108 } |
(...skipping 268 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
385 | 377 |
386 intptr_t JoinEntryInstr::IndexOfPredecessor(BlockEntryInstr* pred) const { | 378 intptr_t JoinEntryInstr::IndexOfPredecessor(BlockEntryInstr* pred) const { |
387 for (intptr_t i = 0; i < predecessors_.length(); ++i) { | 379 for (intptr_t i = 0; i < predecessors_.length(); ++i) { |
388 if (predecessors_[i] == pred) return i; | 380 if (predecessors_[i] == pred) return i; |
389 } | 381 } |
390 return -1; | 382 return -1; |
391 } | 383 } |
392 | 384 |
393 | 385 |
394 // ==== Recording assigned variables. | 386 // ==== Recording assigned variables. |
395 void Computation::RecordAssignedVars(BitVector* assigned_vars) { | 387 void Computation::RecordAssignedVars(BitVector* assigned_vars, |
388 intptr_t fixed_param_count) { | |
396 // Nothing to do for the base class. | 389 // Nothing to do for the base class. |
397 } | 390 } |
398 | 391 |
399 | 392 |
400 void StoreLocalComp::RecordAssignedVars(BitVector* assigned_vars) { | 393 void StoreLocalComp::RecordAssignedVars(BitVector* assigned_vars, |
394 intptr_t fixed_param_count) { | |
401 if (!local().is_captured()) { | 395 if (!local().is_captured()) { |
402 assigned_vars->Add(local().BitIndexIn(assigned_vars->length())); | 396 assigned_vars->Add(local().BitIndexIn(fixed_param_count)); |
403 } | 397 } |
404 } | 398 } |
405 | 399 |
406 | 400 |
407 void Instruction::RecordAssignedVars(BitVector* assigned_vars) { | 401 void Instruction::RecordAssignedVars(BitVector* assigned_vars, |
402 intptr_t fixed_param_count) { | |
408 // Nothing to do for the base class. | 403 // Nothing to do for the base class. |
409 } | 404 } |
410 | 405 |
411 | 406 |
412 void BindInstr::RecordAssignedVars(BitVector* assigned_vars) { | 407 void BindInstr::RecordAssignedVars(BitVector* assigned_vars, |
413 computation()->RecordAssignedVars(assigned_vars); | 408 intptr_t fixed_param_count) { |
409 computation()->RecordAssignedVars(assigned_vars, fixed_param_count); | |
414 } | 410 } |
415 | 411 |
416 | 412 |
417 // ==== Postorder graph traversal. | 413 // ==== Postorder graph traversal. |
418 void GraphEntryInstr::DiscoverBlocks( | 414 void GraphEntryInstr::DiscoverBlocks( |
419 BlockEntryInstr* current_block, | 415 BlockEntryInstr* current_block, |
420 GrowableArray<BlockEntryInstr*>* preorder, | 416 GrowableArray<BlockEntryInstr*>* preorder, |
421 GrowableArray<BlockEntryInstr*>* postorder, | 417 GrowableArray<BlockEntryInstr*>* postorder, |
422 GrowableArray<intptr_t>* parent, | 418 GrowableArray<intptr_t>* parent, |
423 GrowableArray<BitVector*>* assigned_vars, | 419 GrowableArray<BitVector*>* assigned_vars, |
424 intptr_t variable_count) { | 420 intptr_t variable_count, |
421 intptr_t fixed_param_count) { | |
425 // We only visit this block once, first of all blocks. | 422 // We only visit this block once, first of all blocks. |
426 ASSERT(preorder_number() == -1); | 423 ASSERT(preorder_number() == -1); |
427 ASSERT(current_block == NULL); | 424 ASSERT(current_block == NULL); |
428 ASSERT(preorder->is_empty()); | 425 ASSERT(preorder->is_empty()); |
429 ASSERT(postorder->is_empty()); | 426 ASSERT(postorder->is_empty()); |
430 ASSERT(parent->is_empty()); | 427 ASSERT(parent->is_empty()); |
431 | 428 |
432 // This node has no parent, indicated by -1. The preorder number is 0. | 429 // This node has no parent, indicated by -1. The preorder number is 0. |
433 parent->Add(-1); | 430 parent->Add(-1); |
434 set_preorder_number(0); | 431 set_preorder_number(0); |
435 preorder->Add(this); | 432 preorder->Add(this); |
436 BitVector* vars = | 433 BitVector* vars = |
437 (variable_count == 0) ? NULL : new BitVector(variable_count); | 434 (variable_count == 0) ? NULL : new BitVector(variable_count); |
438 assigned_vars->Add(vars); | 435 assigned_vars->Add(vars); |
439 | 436 |
440 // The graph entry consists of only one instruction. | 437 // The graph entry consists of only one instruction. |
441 set_last_instruction(this); | 438 set_last_instruction(this); |
442 | 439 |
443 // Iteratively traverse all successors. In the unoptimized code, we will | 440 // Iteratively traverse all successors. In the unoptimized code, we will |
444 // enter the function at the first successor in reverse postorder, so we | 441 // enter the function at the first successor in reverse postorder, so we |
445 // must visit the normal entry last. | 442 // must visit the normal entry last. |
446 for (intptr_t i = catch_entries_.length() - 1; i >= 0; --i) { | 443 for (intptr_t i = catch_entries_.length() - 1; i >= 0; --i) { |
447 catch_entries_[i]->DiscoverBlocks(this, preorder, postorder, | 444 catch_entries_[i]->DiscoverBlocks(this, preorder, postorder, |
448 parent, assigned_vars, variable_count); | 445 parent, assigned_vars, |
446 variable_count, fixed_param_count); | |
449 } | 447 } |
450 normal_entry_->DiscoverBlocks(this, preorder, postorder, | 448 normal_entry_->DiscoverBlocks(this, preorder, postorder, |
451 parent, assigned_vars, variable_count); | 449 parent, assigned_vars, |
450 variable_count, fixed_param_count); | |
452 | 451 |
453 // Assign postorder number. | 452 // Assign postorder number. |
454 set_postorder_number(postorder->length()); | 453 set_postorder_number(postorder->length()); |
455 postorder->Add(this); | 454 postorder->Add(this); |
456 } | 455 } |
457 | 456 |
458 | 457 |
459 // Base class implementation used for JoinEntry and TargetEntry. | 458 // Base class implementation used for JoinEntry and TargetEntry. |
460 void BlockEntryInstr::DiscoverBlocks( | 459 void BlockEntryInstr::DiscoverBlocks( |
461 BlockEntryInstr* current_block, | 460 BlockEntryInstr* current_block, |
462 GrowableArray<BlockEntryInstr*>* preorder, | 461 GrowableArray<BlockEntryInstr*>* preorder, |
463 GrowableArray<BlockEntryInstr*>* postorder, | 462 GrowableArray<BlockEntryInstr*>* postorder, |
464 GrowableArray<intptr_t>* parent, | 463 GrowableArray<intptr_t>* parent, |
465 GrowableArray<BitVector*>* assigned_vars, | 464 GrowableArray<BitVector*>* assigned_vars, |
466 intptr_t variable_count) { | 465 intptr_t variable_count, |
466 intptr_t fixed_param_count) { | |
467 // We have already visited the graph entry, so we can assume current_block | 467 // We have already visited the graph entry, so we can assume current_block |
468 // is non-null and preorder array is non-empty. | 468 // is non-null and preorder array is non-empty. |
469 ASSERT(current_block != NULL); | 469 ASSERT(current_block != NULL); |
470 ASSERT(!preorder->is_empty()); | 470 ASSERT(!preorder->is_empty()); |
471 | 471 |
472 // 1. Record control-flow-graph basic-block predecessors. | 472 // 1. Record control-flow-graph basic-block predecessors. |
473 AddPredecessor(current_block); | 473 AddPredecessor(current_block); |
474 | 474 |
475 // 2. If the block has already been reached by the traversal, we are | 475 // 2. If the block has already been reached by the traversal, we are |
476 // done. Blocks with a single predecessor cannot have been reached | 476 // done. Blocks with a single predecessor cannot have been reached |
(...skipping 19 matching lines...) Expand all Loading... | |
496 // 5. Iterate straight-line successors until a branch instruction or | 496 // 5. Iterate straight-line successors until a branch instruction or |
497 // another basic block entry instruction, and visit that instruction. | 497 // another basic block entry instruction, and visit that instruction. |
498 ASSERT(next() != NULL); | 498 ASSERT(next() != NULL); |
499 Instruction* next_instr = next(); | 499 Instruction* next_instr = next(); |
500 if (next_instr->IsBlockEntry()) { | 500 if (next_instr->IsBlockEntry()) { |
501 set_last_instruction(this); | 501 set_last_instruction(this); |
502 } else { | 502 } else { |
503 while ((next_instr != NULL) && | 503 while ((next_instr != NULL) && |
504 !next_instr->IsBlockEntry() && | 504 !next_instr->IsBlockEntry() && |
505 !next_instr->IsBranch()) { | 505 !next_instr->IsBranch()) { |
506 if (vars != NULL) next_instr->RecordAssignedVars(vars); | 506 if (vars != NULL) next_instr->RecordAssignedVars(vars, fixed_param_count); |
507 set_last_instruction(next_instr); | 507 set_last_instruction(next_instr); |
508 GotoInstr* goto_instr = next_instr->AsGoto(); | 508 GotoInstr* goto_instr = next_instr->AsGoto(); |
509 next_instr = | 509 next_instr = |
510 (goto_instr != NULL) ? goto_instr->successor() : next_instr->next(); | 510 (goto_instr != NULL) ? goto_instr->successor() : next_instr->next(); |
511 } | 511 } |
512 } | 512 } |
513 if (next_instr != NULL) { | 513 if (next_instr != NULL) { |
514 next_instr->DiscoverBlocks(this, preorder, postorder, | 514 next_instr->DiscoverBlocks(this, preorder, postorder, |
515 parent, assigned_vars, variable_count); | 515 parent, assigned_vars, |
516 variable_count, fixed_param_count); | |
516 } | 517 } |
517 | 518 |
518 // 6. Assign postorder number and add the block entry to the list. | 519 // 6. Assign postorder number and add the block entry to the list. |
519 set_postorder_number(postorder->length()); | 520 set_postorder_number(postorder->length()); |
520 postorder->Add(this); | 521 postorder->Add(this); |
521 } | 522 } |
522 | 523 |
523 | 524 |
524 void BranchInstr::DiscoverBlocks( | 525 void BranchInstr::DiscoverBlocks( |
525 BlockEntryInstr* current_block, | 526 BlockEntryInstr* current_block, |
526 GrowableArray<BlockEntryInstr*>* preorder, | 527 GrowableArray<BlockEntryInstr*>* preorder, |
527 GrowableArray<BlockEntryInstr*>* postorder, | 528 GrowableArray<BlockEntryInstr*>* postorder, |
528 GrowableArray<intptr_t>* parent, | 529 GrowableArray<intptr_t>* parent, |
529 GrowableArray<BitVector*>* assigned_vars, | 530 GrowableArray<BitVector*>* assigned_vars, |
530 intptr_t variable_count) { | 531 intptr_t variable_count, |
532 intptr_t fixed_param_count) { | |
531 current_block->set_last_instruction(this); | 533 current_block->set_last_instruction(this); |
532 // Visit the false successor before the true successor so they appear in | 534 // Visit the false successor before the true successor so they appear in |
533 // true/false order in reverse postorder used as the block ordering in the | 535 // true/false order in reverse postorder used as the block ordering in the |
534 // nonoptimizing compiler. | 536 // nonoptimizing compiler. |
535 ASSERT(true_successor_ != NULL); | 537 ASSERT(true_successor_ != NULL); |
536 ASSERT(false_successor_ != NULL); | 538 ASSERT(false_successor_ != NULL); |
537 false_successor_->DiscoverBlocks(current_block, preorder, postorder, | 539 false_successor_->DiscoverBlocks(current_block, preorder, postorder, |
538 parent, assigned_vars, variable_count); | 540 parent, assigned_vars, |
541 variable_count, fixed_param_count); | |
539 true_successor_->DiscoverBlocks(current_block, preorder, postorder, | 542 true_successor_->DiscoverBlocks(current_block, preorder, postorder, |
540 parent, assigned_vars, variable_count); | 543 parent, assigned_vars, |
544 variable_count, fixed_param_count); | |
541 } | 545 } |
542 | 546 |
543 | 547 |
544 void JoinEntryInstr::InsertPhi(intptr_t var_index, intptr_t var_count) { | 548 void JoinEntryInstr::InsertPhi(intptr_t var_index, intptr_t var_count) { |
545 // Lazily initialize the array of phis. | 549 // Lazily initialize the array of phis. |
546 // Currently, phis are stored in a sparse array that holds the phi | 550 // Currently, phis are stored in a sparse array that holds the phi |
547 // for variable with index i at position i. | 551 // for variable with index i at position i. |
548 // TODO(fschneider): Store phis in a more compact way. | 552 // TODO(fschneider): Store phis in a more compact way. |
549 if (phis_ == NULL) { | 553 if (phis_ == NULL) { |
550 phis_ = new ZoneGrowableArray<PhiInstr*>(var_count); | 554 phis_ = new ZoneGrowableArray<PhiInstr*>(var_count); |
(...skipping 398 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
949 summary->set_in(0, Location::RequiresRegister()); | 953 summary->set_in(0, Location::RequiresRegister()); |
950 summary->set_in(1, Location::RequiresRegister()); | 954 summary->set_in(1, Location::RequiresRegister()); |
951 if (HasICData()) { | 955 if (HasICData()) { |
952 summary->set_temp(0, Location::RequiresRegister()); | 956 summary->set_temp(0, Location::RequiresRegister()); |
953 } | 957 } |
954 return summary; | 958 return summary; |
955 } | 959 } |
956 | 960 |
957 | 961 |
958 void StoreInstanceFieldComp::EmitNativeCode(FlowGraphCompiler* compiler) { | 962 void StoreInstanceFieldComp::EmitNativeCode(FlowGraphCompiler* compiler) { |
959 ASSERT(VerifyValues(instance(), value())); | |
srdjan
2012/07/26 00:33:56
Why remove this?
Vyacheslav Egorov (Google)
2012/07/26 11:33:53
Because it does not work for SSA form with phis.
| |
960 Register instance_reg = locs()->in(0).reg(); | 963 Register instance_reg = locs()->in(0).reg(); |
961 Register value_reg = locs()->in(1).reg(); | 964 Register value_reg = locs()->in(1).reg(); |
962 | 965 |
963 if (HasICData()) { | 966 if (HasICData()) { |
964 ASSERT(original() != NULL); | 967 ASSERT(original() != NULL); |
965 Label* deopt = compiler->AddDeoptStub(original()->cid(), | 968 Label* deopt = compiler->AddDeoptStub(original()->cid(), |
966 original()->token_pos(), | 969 original()->token_pos(), |
967 original()->try_index(), | 970 original()->try_index(), |
968 kDeoptInstanceGetterSameTarget, | 971 kDeoptInstanceGetterSameTarget, |
969 instance_reg, | 972 instance_reg, |
(...skipping 330 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1300 const ExternalLabel label(closure_function.ToCString(), stub.EntryPoint()); | 1303 const ExternalLabel label(closure_function.ToCString(), stub.EntryPoint()); |
1301 compiler->GenerateCall(token_pos(), try_index(), &label, | 1304 compiler->GenerateCall(token_pos(), try_index(), &label, |
1302 PcDescriptors::kOther); | 1305 PcDescriptors::kOther); |
1303 __ Drop(2); // Discard type arguments and receiver. | 1306 __ Drop(2); // Discard type arguments and receiver. |
1304 } | 1307 } |
1305 | 1308 |
1306 | 1309 |
1307 #undef __ | 1310 #undef __ |
1308 | 1311 |
1309 } // namespace dart | 1312 } // namespace dart |
OLD | NEW |