| 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 240 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 251 | 251 |
| 252 void ThrowInstr::SetInputAt(intptr_t i, Value* value) { | 252 void ThrowInstr::SetInputAt(intptr_t i, Value* value) { |
| 253 if (i == 0) { | 253 if (i == 0) { |
| 254 exception_ = value; | 254 exception_ = value; |
| 255 return; | 255 return; |
| 256 } | 256 } |
| 257 UNREACHABLE(); | 257 UNREACHABLE(); |
| 258 } | 258 } |
| 259 | 259 |
| 260 | 260 |
| 261 intptr_t GotoInstr::InputCount() const { |
| 262 return 0; |
| 263 } |
| 264 |
| 265 |
| 266 Value* GotoInstr::InputAt(intptr_t i) const { |
| 267 UNREACHABLE(); |
| 268 return NULL; |
| 269 } |
| 270 |
| 271 |
| 272 void GotoInstr::SetInputAt(intptr_t i, Value* value) { |
| 273 UNREACHABLE(); |
| 274 } |
| 275 |
| 276 |
| 261 intptr_t ReturnInstr::InputCount() const { | 277 intptr_t ReturnInstr::InputCount() const { |
| 262 return 1; | 278 return 1; |
| 263 } | 279 } |
| 264 | 280 |
| 265 | 281 |
| 266 Value* ReturnInstr::InputAt(intptr_t i) const { | 282 Value* ReturnInstr::InputAt(intptr_t i) const { |
| 267 if (i == 0) return value(); | 283 if (i == 0) return value(); |
| 268 UNREACHABLE(); | 284 UNREACHABLE(); |
| 269 return NULL; | 285 return NULL; |
| 270 } | 286 } |
| (...skipping 209 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 480 ASSERT(next() != NULL); | 496 ASSERT(next() != NULL); |
| 481 Instruction* next_instr = next(); | 497 Instruction* next_instr = next(); |
| 482 if (next_instr->IsBlockEntry()) { | 498 if (next_instr->IsBlockEntry()) { |
| 483 set_last_instruction(this); | 499 set_last_instruction(this); |
| 484 } else { | 500 } else { |
| 485 while ((next_instr != NULL) && | 501 while ((next_instr != NULL) && |
| 486 !next_instr->IsBlockEntry() && | 502 !next_instr->IsBlockEntry() && |
| 487 !next_instr->IsBranch()) { | 503 !next_instr->IsBranch()) { |
| 488 if (vars != NULL) next_instr->RecordAssignedVars(vars); | 504 if (vars != NULL) next_instr->RecordAssignedVars(vars); |
| 489 set_last_instruction(next_instr); | 505 set_last_instruction(next_instr); |
| 490 next_instr = next_instr->next(); | 506 GotoInstr* goto_instr = next_instr->AsGoto(); |
| 507 next_instr = |
| 508 (goto_instr != NULL) ? goto_instr->successor() : next_instr->next(); |
| 491 } | 509 } |
| 492 } | 510 } |
| 493 if (next_instr != NULL) { | 511 if (next_instr != NULL) { |
| 494 next_instr->DiscoverBlocks(this, preorder, postorder, | 512 next_instr->DiscoverBlocks(this, preorder, postorder, |
| 495 parent, assigned_vars, variable_count); | 513 parent, assigned_vars, variable_count); |
| 496 } | 514 } |
| 497 | 515 |
| 498 // 6. Assign postorder number and add the block entry to the list. | 516 // 6. Assign postorder number and add the block entry to the list. |
| 499 set_postorder_number(postorder->length()); | 517 set_postorder_number(postorder->length()); |
| 500 postorder->Add(this); | 518 postorder->Add(this); |
| (...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 532 phis_->Add(NULL); | 550 phis_->Add(NULL); |
| 533 } | 551 } |
| 534 } | 552 } |
| 535 ASSERT((*phis_)[var_index] == NULL); | 553 ASSERT((*phis_)[var_index] == NULL); |
| 536 (*phis_)[var_index] = new PhiInstr(PredecessorCount()); | 554 (*phis_)[var_index] = new PhiInstr(PredecessorCount()); |
| 537 phi_count_++; | 555 phi_count_++; |
| 538 } | 556 } |
| 539 | 557 |
| 540 | 558 |
| 541 intptr_t Instruction::SuccessorCount() const { | 559 intptr_t Instruction::SuccessorCount() const { |
| 542 ASSERT(next() == NULL || next()->IsBlockEntry()); | 560 return 0; |
| 543 return (next() != NULL) ? 1 : 0; | |
| 544 } | 561 } |
| 545 | 562 |
| 546 | 563 |
| 547 BlockEntryInstr* Instruction::SuccessorAt(intptr_t index) const { | 564 BlockEntryInstr* Instruction::SuccessorAt(intptr_t index) const { |
| 548 return next()->AsBlockEntry(); | 565 // Called only if index is in range. Only control-transfer instructions |
| 566 // can have non-zero successor counts and they override this function. |
| 567 UNREACHABLE(); |
| 568 return NULL; |
| 549 } | 569 } |
| 550 | 570 |
| 551 | 571 |
| 552 intptr_t GraphEntryInstr::SuccessorCount() const { | 572 intptr_t GraphEntryInstr::SuccessorCount() const { |
| 553 return 1 + catch_entries_.length(); | 573 return 1 + catch_entries_.length(); |
| 554 } | 574 } |
| 555 | 575 |
| 556 | 576 |
| 557 BlockEntryInstr* GraphEntryInstr::SuccessorAt(intptr_t index) const { | 577 BlockEntryInstr* GraphEntryInstr::SuccessorAt(intptr_t index) const { |
| 558 if (index == 0) return normal_entry_; | 578 if (index == 0) return normal_entry_; |
| 559 return catch_entries_[index - 1]; | 579 return catch_entries_[index - 1]; |
| 560 } | 580 } |
| 561 | 581 |
| 562 | 582 |
| 563 intptr_t BranchInstr::SuccessorCount() const { | 583 intptr_t BranchInstr::SuccessorCount() const { |
| 564 return 2; | 584 return 2; |
| 565 } | 585 } |
| 566 | 586 |
| 567 | 587 |
| 568 BlockEntryInstr* BranchInstr::SuccessorAt(intptr_t index) const { | 588 BlockEntryInstr* BranchInstr::SuccessorAt(intptr_t index) const { |
| 569 if (index == 0) return true_successor_; | 589 if (index == 0) return true_successor_; |
| 570 if (index == 1) return false_successor_; | 590 if (index == 1) return false_successor_; |
| 571 UNREACHABLE(); | 591 UNREACHABLE(); |
| 572 return NULL; | 592 return NULL; |
| 573 } | 593 } |
| 574 | 594 |
| 575 | 595 |
| 596 intptr_t GotoInstr::SuccessorCount() const { |
| 597 return 1; |
| 598 } |
| 599 |
| 600 |
| 601 BlockEntryInstr* GotoInstr::SuccessorAt(intptr_t index) const { |
| 602 ASSERT(index == 0); |
| 603 return successor(); |
| 604 } |
| 605 |
| 606 |
| 607 void Instruction::Goto(JoinEntryInstr* entry) { |
| 608 set_next(new GotoInstr(entry)); |
| 609 } |
| 610 |
| 611 |
| 576 // ==== Support for propagating static type. | 612 // ==== Support for propagating static type. |
| 577 RawAbstractType* ConstantVal::StaticType() const { | 613 RawAbstractType* ConstantVal::StaticType() const { |
| 578 if (value().IsInstance()) { | 614 if (value().IsInstance()) { |
| 579 return Instance::Cast(value()).GetType(); | 615 return Instance::Cast(value()).GetType(); |
| 580 } else { | 616 } else { |
| 581 UNREACHABLE(); | 617 UNREACHABLE(); |
| 582 return AbstractType::null(); | 618 return AbstractType::null(); |
| 583 } | 619 } |
| 584 } | 620 } |
| 585 | 621 |
| (...skipping 394 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 980 ASSERT(exception()->IsUse()); | 1016 ASSERT(exception()->IsUse()); |
| 981 ASSERT(stack_trace()->IsUse()); | 1017 ASSERT(stack_trace()->IsUse()); |
| 982 compiler->GenerateCallRuntime(cid(), | 1018 compiler->GenerateCallRuntime(cid(), |
| 983 token_pos(), | 1019 token_pos(), |
| 984 try_index(), | 1020 try_index(), |
| 985 kReThrowRuntimeEntry); | 1021 kReThrowRuntimeEntry); |
| 986 __ int3(); | 1022 __ int3(); |
| 987 } | 1023 } |
| 988 | 1024 |
| 989 | 1025 |
| 1026 LocationSummary* GotoInstr::MakeLocationSummary() const { |
| 1027 return new LocationSummary(0, 0); |
| 1028 } |
| 1029 |
| 1030 |
| 1031 void GotoInstr::EmitNativeCode(FlowGraphCompiler* compiler) { |
| 1032 // We can fall through if the successor is the next block in the list. |
| 1033 // Otherwise, we need a jump. |
| 1034 if (!compiler->IsNextBlock(successor())) { |
| 1035 __ jmp(compiler->GetBlockLabel(successor())); |
| 1036 } |
| 1037 } |
| 1038 |
| 1039 |
| 990 LocationSummary* BranchInstr::MakeLocationSummary() const { | 1040 LocationSummary* BranchInstr::MakeLocationSummary() const { |
| 991 if (is_fused_with_comparison()) { | 1041 if (is_fused_with_comparison()) { |
| 992 return fused_with_comparison_->locs(); | 1042 return fused_with_comparison_->locs(); |
| 993 } else { | 1043 } else { |
| 994 const int kNumInputs = 1; | 1044 const int kNumInputs = 1; |
| 995 const int kNumTemps = 0; | 1045 const int kNumTemps = 0; |
| 996 LocationSummary* locs = new LocationSummary(kNumInputs, | 1046 LocationSummary* locs = new LocationSummary(kNumInputs, |
| 997 kNumTemps, | 1047 kNumTemps, |
| 998 LocationSummary::kNoCall); | 1048 LocationSummary::kNoCall); |
| 999 locs->set_in(0, Location::RequiresRegister()); | 1049 locs->set_in(0, Location::RequiresRegister()); |
| (...skipping 308 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1308 const ExternalLabel label(closure_function.ToCString(), stub.EntryPoint()); | 1358 const ExternalLabel label(closure_function.ToCString(), stub.EntryPoint()); |
| 1309 compiler->GenerateCall(token_pos(), try_index(), &label, | 1359 compiler->GenerateCall(token_pos(), try_index(), &label, |
| 1310 PcDescriptors::kOther); | 1360 PcDescriptors::kOther); |
| 1311 __ Drop(2); // Discard type arguments and receiver. | 1361 __ Drop(2); // Discard type arguments and receiver. |
| 1312 } | 1362 } |
| 1313 | 1363 |
| 1314 | 1364 |
| 1315 #undef __ | 1365 #undef __ |
| 1316 | 1366 |
| 1317 } // namespace dart | 1367 } // namespace dart |
| OLD | NEW |