| 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/common-operator.h" | 5 #include "src/compiler/common-operator.h" |
| 6 #include "src/compiler/graph.h" | 6 #include "src/compiler/graph.h" |
| 7 #include "src/compiler/instruction.h" | 7 #include "src/compiler/instruction.h" |
| 8 #include "src/compiler/schedule.h" | 8 #include "src/compiler/schedule.h" |
| 9 | 9 |
| 10 namespace v8 { | 10 namespace v8 { |
| (...skipping 108 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 119 DCHECK_IMPLIES(replacement == to_eliminate, replacement == nullptr); | 119 DCHECK_IMPLIES(replacement == to_eliminate, replacement == nullptr); |
| 120 if (replacement != nullptr) move->set_source(replacement->source()); | 120 if (replacement != nullptr) move->set_source(replacement->source()); |
| 121 return to_eliminate; | 121 return to_eliminate; |
| 122 } | 122 } |
| 123 | 123 |
| 124 | 124 |
| 125 Instruction::Instruction(InstructionCode opcode) | 125 Instruction::Instruction(InstructionCode opcode) |
| 126 : opcode_(opcode), | 126 : opcode_(opcode), |
| 127 bit_field_(OutputCountField::encode(0) | InputCountField::encode(0) | | 127 bit_field_(OutputCountField::encode(0) | InputCountField::encode(0) | |
| 128 TempCountField::encode(0) | IsCallField::encode(false)), | 128 TempCountField::encode(0) | IsCallField::encode(false)), |
| 129 pointer_map_(NULL) { | 129 reference_map_(NULL) { |
| 130 parallel_moves_[0] = nullptr; | 130 parallel_moves_[0] = nullptr; |
| 131 parallel_moves_[1] = nullptr; | 131 parallel_moves_[1] = nullptr; |
| 132 } | 132 } |
| 133 | 133 |
| 134 | 134 |
| 135 Instruction::Instruction(InstructionCode opcode, size_t output_count, | 135 Instruction::Instruction(InstructionCode opcode, size_t output_count, |
| 136 InstructionOperand* outputs, size_t input_count, | 136 InstructionOperand* outputs, size_t input_count, |
| 137 InstructionOperand* inputs, size_t temp_count, | 137 InstructionOperand* inputs, size_t temp_count, |
| 138 InstructionOperand* temps) | 138 InstructionOperand* temps) |
| 139 : opcode_(opcode), | 139 : opcode_(opcode), |
| 140 bit_field_(OutputCountField::encode(output_count) | | 140 bit_field_(OutputCountField::encode(output_count) | |
| 141 InputCountField::encode(input_count) | | 141 InputCountField::encode(input_count) | |
| 142 TempCountField::encode(temp_count) | | 142 TempCountField::encode(temp_count) | |
| 143 IsCallField::encode(false)), | 143 IsCallField::encode(false)), |
| 144 pointer_map_(NULL) { | 144 reference_map_(NULL) { |
| 145 parallel_moves_[0] = nullptr; | 145 parallel_moves_[0] = nullptr; |
| 146 parallel_moves_[1] = nullptr; | 146 parallel_moves_[1] = nullptr; |
| 147 size_t offset = 0; | 147 size_t offset = 0; |
| 148 for (size_t i = 0; i < output_count; ++i) { | 148 for (size_t i = 0; i < output_count; ++i) { |
| 149 DCHECK(!outputs[i].IsInvalid()); | 149 DCHECK(!outputs[i].IsInvalid()); |
| 150 operands_[offset++] = outputs[i]; | 150 operands_[offset++] = outputs[i]; |
| 151 } | 151 } |
| 152 for (size_t i = 0; i < input_count; ++i) { | 152 for (size_t i = 0; i < input_count; ++i) { |
| 153 DCHECK(!inputs[i].IsInvalid()); | 153 DCHECK(!inputs[i].IsInvalid()); |
| 154 operands_[offset++] = inputs[i]; | 154 operands_[offset++] = inputs[i]; |
| (...skipping 25 matching lines...) Expand all Loading... |
| 180 if (move->IsEliminated()) continue; | 180 if (move->IsEliminated()) continue; |
| 181 if (!first) os << " "; | 181 if (!first) os << " "; |
| 182 first = false; | 182 first = false; |
| 183 PrintableMoveOperands pmo = {printable.register_configuration_, move}; | 183 PrintableMoveOperands pmo = {printable.register_configuration_, move}; |
| 184 os << pmo; | 184 os << pmo; |
| 185 } | 185 } |
| 186 return os; | 186 return os; |
| 187 } | 187 } |
| 188 | 188 |
| 189 | 189 |
| 190 void PointerMap::RecordPointer(InstructionOperand* op, Zone* zone) { | 190 void ReferenceMap::RecordReference(const InstructionOperand& op) { |
| 191 // Do not record arguments as pointers. | 191 // Do not record arguments as pointers. |
| 192 if (op->IsStackSlot() && StackSlotOperand::cast(op)->index() < 0) return; | 192 if (op.IsStackSlot() && StackSlotOperand::cast(op).index() < 0) return; |
| 193 DCHECK(!op->IsDoubleRegister() && !op->IsDoubleStackSlot()); | 193 DCHECK(!op.IsDoubleRegister() && !op.IsDoubleStackSlot()); |
| 194 pointer_operands_.Add(op, zone); | 194 reference_operands_.push_back(op); |
| 195 } | 195 } |
| 196 | 196 |
| 197 | 197 |
| 198 void PointerMap::RemovePointer(InstructionOperand* op) { | 198 std::ostream& operator<<(std::ostream& os, const ReferenceMap& pm) { |
| 199 // Do not record arguments as pointers. | 199 os << "{"; |
| 200 if (op->IsStackSlot() && StackSlotOperand::cast(op)->index() < 0) return; | 200 bool first = true; |
| 201 DCHECK(!op->IsDoubleRegister() && !op->IsDoubleStackSlot()); | 201 PrintableInstructionOperand poi = {RegisterConfiguration::ArchDefault(), |
| 202 for (int i = 0; i < pointer_operands_.length(); ++i) { | 202 nullptr}; |
| 203 if (pointer_operands_[i]->Equals(op)) { | 203 for (auto& op : pm.reference_operands_) { |
| 204 pointer_operands_.Remove(i); | 204 if (!first) { |
| 205 --i; | 205 os << ";"; |
| 206 } else { |
| 207 first = false; |
| 206 } | 208 } |
| 207 } | 209 poi.op_ = &op; |
| 208 } | 210 os << poi; |
| 209 | |
| 210 | |
| 211 void PointerMap::RecordUntagged(InstructionOperand* op, Zone* zone) { | |
| 212 // Do not record arguments as pointers. | |
| 213 if (op->IsStackSlot() && StackSlotOperand::cast(op)->index() < 0) return; | |
| 214 DCHECK(!op->IsDoubleRegister() && !op->IsDoubleStackSlot()); | |
| 215 untagged_operands_.Add(op, zone); | |
| 216 } | |
| 217 | |
| 218 | |
| 219 std::ostream& operator<<(std::ostream& os, const PointerMap& pm) { | |
| 220 os << "{"; | |
| 221 for (ZoneList<InstructionOperand*>::iterator op = | |
| 222 pm.pointer_operands_.begin(); | |
| 223 op != pm.pointer_operands_.end(); ++op) { | |
| 224 if (op != pm.pointer_operands_.begin()) os << ";"; | |
| 225 os << *op; | |
| 226 } | 211 } |
| 227 return os << "}"; | 212 return os << "}"; |
| 228 } | 213 } |
| 229 | 214 |
| 230 | 215 |
| 231 std::ostream& operator<<(std::ostream& os, const ArchOpcode& ao) { | 216 std::ostream& operator<<(std::ostream& os, const ArchOpcode& ao) { |
| 232 switch (ao) { | 217 switch (ao) { |
| 233 #define CASE(Name) \ | 218 #define CASE(Name) \ |
| 234 case k##Name: \ | 219 case k##Name: \ |
| 235 return os << #Name; | 220 return os << #Name; |
| (...skipping 258 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 494 InstructionBlocks* instruction_blocks) | 479 InstructionBlocks* instruction_blocks) |
| 495 : isolate_(isolate), | 480 : isolate_(isolate), |
| 496 zone_(instruction_zone), | 481 zone_(instruction_zone), |
| 497 instruction_blocks_(instruction_blocks), | 482 instruction_blocks_(instruction_blocks), |
| 498 block_starts_(zone()), | 483 block_starts_(zone()), |
| 499 constants_(ConstantMap::key_compare(), | 484 constants_(ConstantMap::key_compare(), |
| 500 ConstantMap::allocator_type(zone())), | 485 ConstantMap::allocator_type(zone())), |
| 501 immediates_(zone()), | 486 immediates_(zone()), |
| 502 instructions_(zone()), | 487 instructions_(zone()), |
| 503 next_virtual_register_(0), | 488 next_virtual_register_(0), |
| 504 pointer_maps_(zone()), | 489 reference_maps_(zone()), |
| 505 doubles_(std::less<int>(), VirtualRegisterSet::allocator_type(zone())), | 490 doubles_(std::less<int>(), VirtualRegisterSet::allocator_type(zone())), |
| 506 references_(std::less<int>(), VirtualRegisterSet::allocator_type(zone())), | 491 references_(std::less<int>(), VirtualRegisterSet::allocator_type(zone())), |
| 507 deoptimization_entries_(zone()) { | 492 deoptimization_entries_(zone()) { |
| 508 block_starts_.reserve(instruction_blocks_->size()); | 493 block_starts_.reserve(instruction_blocks_->size()); |
| 509 } | 494 } |
| 510 | 495 |
| 511 | 496 |
| 512 int InstructionSequence::NextVirtualRegister() { | 497 int InstructionSequence::NextVirtualRegister() { |
| 513 int virtual_register = next_virtual_register_++; | 498 int virtual_register = next_virtual_register_++; |
| 514 CHECK_NE(virtual_register, InstructionOperand::kInvalidVirtualRegister); | 499 CHECK_NE(virtual_register, InstructionOperand::kInvalidVirtualRegister); |
| (...skipping 24 matching lines...) Expand all Loading... |
| 539 end = static_cast<int>(instructions_.size()); | 524 end = static_cast<int>(instructions_.size()); |
| 540 } | 525 } |
| 541 DCHECK(block->code_start() >= 0 && block->code_start() < end); | 526 DCHECK(block->code_start() >= 0 && block->code_start() < end); |
| 542 block->set_code_end(end); | 527 block->set_code_end(end); |
| 543 } | 528 } |
| 544 | 529 |
| 545 | 530 |
| 546 int InstructionSequence::AddInstruction(Instruction* instr) { | 531 int InstructionSequence::AddInstruction(Instruction* instr) { |
| 547 int index = static_cast<int>(instructions_.size()); | 532 int index = static_cast<int>(instructions_.size()); |
| 548 instructions_.push_back(instr); | 533 instructions_.push_back(instr); |
| 549 if (instr->NeedsPointerMap()) { | 534 if (instr->NeedsReferenceMap()) { |
| 550 DCHECK(instr->pointer_map() == NULL); | 535 DCHECK(instr->reference_map() == NULL); |
| 551 PointerMap* pointer_map = new (zone()) PointerMap(zone()); | 536 ReferenceMap* reference_map = new (zone()) ReferenceMap(zone()); |
| 552 pointer_map->set_instruction_position(index); | 537 reference_map->set_instruction_position(index); |
| 553 instr->set_pointer_map(pointer_map); | 538 instr->set_reference_map(reference_map); |
| 554 pointer_maps_.push_back(pointer_map); | 539 reference_maps_.push_back(reference_map); |
| 555 } | 540 } |
| 556 return index; | 541 return index; |
| 557 } | 542 } |
| 558 | 543 |
| 559 | 544 |
| 560 const InstructionBlock* InstructionSequence::GetInstructionBlock( | 545 const InstructionBlock* InstructionSequence::GetInstructionBlock( |
| 561 int instruction_index) const { | 546 int instruction_index) const { |
| 562 DCHECK(instruction_blocks_->size() == block_starts_.size()); | 547 DCHECK(instruction_blocks_->size() == block_starts_.size()); |
| 563 auto begin = block_starts_.begin(); | 548 auto begin = block_starts_.begin(); |
| 564 auto end = std::lower_bound(begin, block_starts_.end(), instruction_index, | 549 auto end = std::lower_bound(begin, block_starts_.end(), instruction_index, |
| (...skipping 189 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 754 os << " B" << succ.ToInt(); | 739 os << " B" << succ.ToInt(); |
| 755 } | 740 } |
| 756 os << "\n"; | 741 os << "\n"; |
| 757 } | 742 } |
| 758 return os; | 743 return os; |
| 759 } | 744 } |
| 760 | 745 |
| 761 } // namespace compiler | 746 } // namespace compiler |
| 762 } // namespace internal | 747 } // namespace internal |
| 763 } // namespace v8 | 748 } // namespace v8 |
| OLD | NEW |