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