OLD | NEW |
1 // Copyright 2014 the V8 project authors. All rights reserved. | 1 // Copyright 2014 the V8 project authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "src/compiler/instruction.h" | 5 #include "src/compiler/instruction.h" |
6 | 6 |
7 #include "src/compiler/common-operator.h" | 7 #include "src/compiler/common-operator.h" |
8 #include "src/compiler/generic-node-inl.h" | 8 #include "src/compiler/generic-node-inl.h" |
| 9 #include "src/compiler/graph.h" |
9 | 10 |
10 namespace v8 { | 11 namespace v8 { |
11 namespace internal { | 12 namespace internal { |
12 namespace compiler { | 13 namespace compiler { |
13 | 14 |
14 std::ostream& operator<<(std::ostream& os, const InstructionOperand& op) { | 15 std::ostream& operator<<(std::ostream& os, const InstructionOperand& op) { |
15 switch (op.kind()) { | 16 switch (op.kind()) { |
16 case InstructionOperand::INVALID: | 17 case InstructionOperand::INVALID: |
17 return os << "(0)"; | 18 return os << "(0)"; |
18 case InstructionOperand::UNALLOCATED: { | 19 case InstructionOperand::UNALLOCATED: { |
(...skipping 295 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
314 UNREACHABLE(); | 315 UNREACHABLE(); |
315 return os; | 316 return os; |
316 } | 317 } |
317 | 318 |
318 | 319 |
319 InstructionSequence::InstructionSequence(Linkage* linkage, Graph* graph, | 320 InstructionSequence::InstructionSequence(Linkage* linkage, Graph* graph, |
320 Schedule* schedule) | 321 Schedule* schedule) |
321 : zone_(schedule->zone()), | 322 : zone_(schedule->zone()), |
322 node_count_(graph->NodeCount()), | 323 node_count_(graph->NodeCount()), |
323 node_map_(zone()->NewArray<int>(node_count_)), | 324 node_map_(zone()->NewArray<int>(node_count_)), |
| 325 block_data_(schedule->BasicBlockCount(), zone()), |
324 linkage_(linkage), | 326 linkage_(linkage), |
325 schedule_(schedule), | 327 schedule_(schedule), |
326 constants_(ConstantMap::key_compare(), | 328 constants_(ConstantMap::key_compare(), |
327 ConstantMap::allocator_type(zone())), | 329 ConstantMap::allocator_type(zone())), |
328 immediates_(zone()), | 330 immediates_(zone()), |
329 instructions_(zone()), | 331 instructions_(zone()), |
330 next_virtual_register_(0), | 332 next_virtual_register_(0), |
331 pointer_maps_(zone()), | 333 pointer_maps_(zone()), |
332 doubles_(std::less<int>(), VirtualRegisterSet::allocator_type(zone())), | 334 doubles_(std::less<int>(), VirtualRegisterSet::allocator_type(zone())), |
333 references_(std::less<int>(), VirtualRegisterSet::allocator_type(zone())), | 335 references_(std::less<int>(), VirtualRegisterSet::allocator_type(zone())), |
334 deoptimization_entries_(zone()) { | 336 deoptimization_entries_(zone()) { |
335 for (int i = 0; i < node_count_; ++i) { | 337 for (int i = 0; i < node_count_; ++i) { |
336 node_map_[i] = -1; | 338 node_map_[i] = -1; |
337 } | 339 } |
338 } | 340 } |
339 | 341 |
340 | 342 |
341 int InstructionSequence::GetVirtualRegister(const Node* node) { | 343 int InstructionSequence::GetVirtualRegister(const Node* node) { |
342 if (node_map_[node->id()] == -1) { | 344 if (node_map_[node->id()] == -1) { |
343 node_map_[node->id()] = NextVirtualRegister(); | 345 node_map_[node->id()] = NextVirtualRegister(); |
344 } | 346 } |
345 return node_map_[node->id()]; | 347 return node_map_[node->id()]; |
346 } | 348 } |
347 | 349 |
348 | 350 |
349 Label* InstructionSequence::GetLabel(BasicBlock* block) { | 351 Label* InstructionSequence::GetLabel(BasicBlock::RpoNumber rpo) { |
350 return GetBlockStart(block)->label(); | 352 return GetBlockStart(rpo)->label(); |
351 } | 353 } |
352 | 354 |
353 | 355 |
354 BlockStartInstruction* InstructionSequence::GetBlockStart(BasicBlock* block) { | 356 BlockStartInstruction* InstructionSequence::GetBlockStart( |
355 return BlockStartInstruction::cast(InstructionAt(block->code_start())); | 357 BasicBlock::RpoNumber rpo) { |
| 358 BlockStartInstruction* block_start = |
| 359 BlockStartInstruction::cast(InstructionAt(code_start(rpo))); |
| 360 DCHECK_EQ(rpo.ToInt(), block_start->rpo_number().ToInt()); |
| 361 return block_start; |
356 } | 362 } |
357 | 363 |
358 | 364 |
359 void InstructionSequence::StartBlock(BasicBlock* block) { | 365 void InstructionSequence::StartBlock(BasicBlock* block) { |
360 block->set_code_start(static_cast<int>(instructions_.size())); | 366 set_code_start(block, static_cast<int>(instructions_.size())); |
361 BlockStartInstruction* block_start = | 367 BlockStartInstruction* block_start = |
362 BlockStartInstruction::New(zone(), block); | 368 BlockStartInstruction::New(zone(), block); |
363 AddInstruction(block_start, block); | 369 AddInstruction(block_start); |
364 } | 370 } |
365 | 371 |
366 | 372 |
367 void InstructionSequence::EndBlock(BasicBlock* block) { | 373 void InstructionSequence::EndBlock(BasicBlock* block) { |
368 int end = static_cast<int>(instructions_.size()); | 374 int end = static_cast<int>(instructions_.size()); |
369 DCHECK(block->code_start() >= 0 && block->code_start() < end); | 375 DCHECK(code_start(block) >= 0 && code_start(block) < end); |
370 block->set_code_end(end); | 376 set_code_end(block, end); |
371 } | 377 } |
372 | 378 |
373 | 379 |
374 int InstructionSequence::AddInstruction(Instruction* instr, BasicBlock* block) { | 380 int InstructionSequence::AddInstruction(Instruction* instr) { |
375 // TODO(titzer): the order of these gaps is a holdover from Lithium. | 381 // TODO(titzer): the order of these gaps is a holdover from Lithium. |
376 GapInstruction* gap = GapInstruction::New(zone()); | 382 GapInstruction* gap = GapInstruction::New(zone()); |
377 if (instr->IsControl()) instructions_.push_back(gap); | 383 if (instr->IsControl()) instructions_.push_back(gap); |
378 int index = static_cast<int>(instructions_.size()); | 384 int index = static_cast<int>(instructions_.size()); |
379 instructions_.push_back(instr); | 385 instructions_.push_back(instr); |
380 if (!instr->IsControl()) instructions_.push_back(gap); | 386 if (!instr->IsControl()) instructions_.push_back(gap); |
381 if (instr->NeedsPointerMap()) { | 387 if (instr->NeedsPointerMap()) { |
382 DCHECK(instr->pointer_map() == NULL); | 388 DCHECK(instr->pointer_map() == NULL); |
383 PointerMap* pointer_map = new (zone()) PointerMap(zone()); | 389 PointerMap* pointer_map = new (zone()) PointerMap(zone()); |
384 pointer_map->set_instruction_position(index); | 390 pointer_map->set_instruction_position(index); |
385 instr->set_pointer_map(pointer_map); | 391 instr->set_pointer_map(pointer_map); |
386 pointer_maps_.push_back(pointer_map); | 392 pointer_maps_.push_back(pointer_map); |
387 } | 393 } |
388 return index; | 394 return index; |
389 } | 395 } |
390 | 396 |
391 | 397 |
392 BasicBlock* InstructionSequence::GetBasicBlock(int instruction_index) { | 398 BasicBlock* InstructionSequence::GetBasicBlock(int instruction_index) { |
393 // TODO(turbofan): Optimize this. | 399 // TODO(turbofan): Optimize this. |
394 for (;;) { | 400 for (;;) { |
395 DCHECK_LE(0, instruction_index); | 401 DCHECK_LE(0, instruction_index); |
396 Instruction* instruction = InstructionAt(instruction_index--); | 402 Instruction* instruction = InstructionAt(instruction_index--); |
397 if (instruction->IsBlockStart()) { | 403 if (instruction->IsBlockStart()) { |
398 return BlockStartInstruction::cast(instruction)->block(); | 404 return schedule()->rpo_order()->at( |
| 405 BlockStartInstruction::cast(instruction)->rpo_number().ToSize()); |
399 } | 406 } |
400 } | 407 } |
401 } | 408 } |
402 | 409 |
403 | 410 |
404 bool InstructionSequence::IsReference(int virtual_register) const { | 411 bool InstructionSequence::IsReference(int virtual_register) const { |
405 return references_.find(virtual_register) != references_.end(); | 412 return references_.find(virtual_register) != references_.end(); |
406 } | 413 } |
407 | 414 |
408 | 415 |
(...skipping 121 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
530 } | 537 } |
531 for (int i = 0; i < code.BasicBlockCount(); i++) { | 538 for (int i = 0; i < code.BasicBlockCount(); i++) { |
532 BasicBlock* block = code.BlockAt(i); | 539 BasicBlock* block = code.BlockAt(i); |
533 | 540 |
534 os << "RPO#" << block->rpo_number() << ": B" << block->id(); | 541 os << "RPO#" << block->rpo_number() << ": B" << block->id(); |
535 CHECK(block->rpo_number() == i); | 542 CHECK(block->rpo_number() == i); |
536 if (block->IsLoopHeader()) { | 543 if (block->IsLoopHeader()) { |
537 os << " loop blocks: [" << block->rpo_number() << ", " | 544 os << " loop blocks: [" << block->rpo_number() << ", " |
538 << block->loop_end() << ")"; | 545 << block->loop_end() << ")"; |
539 } | 546 } |
540 os << " instructions: [" << block->code_start() << ", " | 547 os << " instructions: [" << code.code_start(block) << ", " |
541 << block->code_end() << ")\n predecessors:"; | 548 << code.code_end(block) << ")\n predecessors:"; |
542 | 549 |
543 for (BasicBlock::Predecessors::iterator iter = block->predecessors_begin(); | 550 for (BasicBlock::Predecessors::iterator iter = block->predecessors_begin(); |
544 iter != block->predecessors_end(); ++iter) { | 551 iter != block->predecessors_end(); ++iter) { |
545 os << " B" << (*iter)->id(); | 552 os << " B" << (*iter)->id(); |
546 } | 553 } |
547 os << "\n"; | 554 os << "\n"; |
548 | 555 |
549 for (BasicBlock::const_iterator j = block->begin(); j != block->end(); | 556 for (BasicBlock::const_iterator j = block->begin(); j != block->end(); |
550 ++j) { | 557 ++j) { |
551 Node* phi = *j; | 558 Node* phi = *j; |
552 if (phi->opcode() != IrOpcode::kPhi) continue; | 559 if (phi->opcode() != IrOpcode::kPhi) continue; |
553 os << " phi: v" << phi->id() << " ="; | 560 os << " phi: v" << phi->id() << " ="; |
554 Node::Inputs inputs = phi->inputs(); | 561 Node::Inputs inputs = phi->inputs(); |
555 for (Node::Inputs::iterator iter(inputs.begin()); iter != inputs.end(); | 562 for (Node::Inputs::iterator iter(inputs.begin()); iter != inputs.end(); |
556 ++iter) { | 563 ++iter) { |
557 os << " v" << (*iter)->id(); | 564 os << " v" << (*iter)->id(); |
558 } | 565 } |
559 os << "\n"; | 566 os << "\n"; |
560 } | 567 } |
561 | 568 |
562 ScopedVector<char> buf(32); | 569 ScopedVector<char> buf(32); |
563 for (int j = block->first_instruction_index(); | 570 for (int j = code.first_instruction_index(block); |
564 j <= block->last_instruction_index(); j++) { | 571 j <= code.last_instruction_index(block); j++) { |
565 // TODO(svenpanne) Add some basic formatting to our streams. | 572 // TODO(svenpanne) Add some basic formatting to our streams. |
566 SNPrintF(buf, "%5d", j); | 573 SNPrintF(buf, "%5d", j); |
567 os << " " << buf.start() << ": " << *code.InstructionAt(j); | 574 os << " " << buf.start() << ": " << *code.InstructionAt(j); |
568 } | 575 } |
569 | 576 |
570 os << " " << block->control(); | 577 os << " " << block->control(); |
571 | 578 |
572 if (block->control_input() != NULL) { | 579 if (block->control_input() != NULL) { |
573 os << " v" << block->control_input()->id(); | 580 os << " v" << block->control_input()->id(); |
574 } | 581 } |
575 | 582 |
576 for (BasicBlock::Successors::iterator iter = block->successors_begin(); | 583 for (BasicBlock::Successors::iterator iter = block->successors_begin(); |
577 iter != block->successors_end(); ++iter) { | 584 iter != block->successors_end(); ++iter) { |
578 os << " B" << (*iter)->id(); | 585 os << " B" << (*iter)->id(); |
579 } | 586 } |
580 os << "\n"; | 587 os << "\n"; |
581 } | 588 } |
582 return os; | 589 return os; |
583 } | 590 } |
584 | 591 |
585 } // namespace compiler | 592 } // namespace compiler |
586 } // namespace internal | 593 } // namespace internal |
587 } // namespace v8 | 594 } // namespace v8 |
OLD | NEW |