Index: src/compiler/instruction-selector.cc |
diff --git a/src/compiler/instruction-selector.cc b/src/compiler/instruction-selector.cc |
index ffb8f9fa8d0f7e4a733e7e3894385625323fe578..f987248bead41d33f3acf4146703ed11daa3ebaf 100644 |
--- a/src/compiler/instruction-selector.cc |
+++ b/src/compiler/instruction-selector.cc |
@@ -4,7 +4,6 @@ |
#include "src/compiler/instruction-selector.h" |
-#include "src/compiler/graph.h" |
#include "src/compiler/instruction-selector-impl.h" |
#include "src/compiler/node-matchers.h" |
#include "src/compiler/node-properties-inl.h" |
@@ -14,57 +13,56 @@ namespace v8 { |
namespace internal { |
namespace compiler { |
-InstructionSelector::InstructionSelector(Zone* local_zone, Graph* graph, |
+InstructionSelector::InstructionSelector(Zone* zone, size_t node_count, |
Linkage* linkage, |
InstructionSequence* sequence, |
Schedule* schedule, |
SourcePositionTable* source_positions, |
Features features) |
- : zone_(local_zone), |
+ : zone_(zone), |
linkage_(linkage), |
sequence_(sequence), |
source_positions_(source_positions), |
features_(features), |
schedule_(schedule), |
- node_map_(graph->NodeCount(), kNodeUnmapped, zone()), |
current_block_(NULL), |
- instructions_(zone()), |
- defined_(graph->NodeCount(), false, zone()), |
- used_(graph->NodeCount(), false, zone()) {} |
+ instructions_(zone), |
+ defined_(node_count, false, zone), |
+ used_(node_count, false, zone), |
+ virtual_registers_(node_count, |
+ UnallocatedOperand::kInvalidVirtualRegister, zone) { |
+ instructions_.reserve(node_count); |
+} |
void InstructionSelector::SelectInstructions() { |
// Mark the inputs of all phis in loop headers as used. |
BasicBlockVector* blocks = schedule()->rpo_order(); |
- for (BasicBlockVectorIter i = blocks->begin(); i != blocks->end(); ++i) { |
- BasicBlock* block = *i; |
+ for (auto const block : *blocks) { |
if (!block->IsLoopHeader()) continue; |
- DCHECK_NE(0, static_cast<int>(block->PredecessorCount())); |
- DCHECK_NE(1, static_cast<int>(block->PredecessorCount())); |
- for (BasicBlock::const_iterator j = block->begin(); j != block->end(); |
- ++j) { |
- Node* phi = *j; |
+ DCHECK_LE(2, block->PredecessorCount()); |
+ for (Node* const phi : *block) { |
if (phi->opcode() != IrOpcode::kPhi) continue; |
// Mark all inputs as used. |
- for (Node* const k : phi->inputs()) { |
- MarkAsUsed(k); |
+ for (Node* const input : phi->inputs()) { |
+ MarkAsUsed(input); |
} |
} |
} |
// Visit each basic block in post order. |
- for (BasicBlockVectorRIter i = blocks->rbegin(); i != blocks->rend(); ++i) { |
+ for (auto i = blocks->rbegin(); i != blocks->rend(); ++i) { |
VisitBlock(*i); |
} |
// Schedule the selected instructions. |
- for (BasicBlockVectorIter i = blocks->begin(); i != blocks->end(); ++i) { |
- BasicBlock* block = *i; |
+ for (auto const block : *blocks) { |
InstructionBlock* instruction_block = |
sequence()->InstructionBlockAt(block->GetRpoNumber()); |
size_t end = instruction_block->code_end(); |
size_t start = instruction_block->code_start(); |
+ DCHECK_LE(end, start); |
sequence()->StartBlock(block->GetRpoNumber()); |
while (start-- > end) { |
sequence()->AddInstruction(instructions_[start]); |
@@ -180,58 +178,70 @@ bool InstructionSelector::CanCover(Node* user, Node* node) const { |
int InstructionSelector::GetVirtualRegister(const Node* node) { |
- if (node_map_[node->id()] == kNodeUnmapped) { |
- node_map_[node->id()] = sequence()->NextVirtualRegister(); |
+ DCHECK_NOT_NULL(node); |
+ size_t const id = node->id(); |
+ DCHECK_LT(id, virtual_registers_.size()); |
+ int virtual_register = virtual_registers_[id]; |
+ if (virtual_register == UnallocatedOperand::kInvalidVirtualRegister) { |
+ virtual_register = sequence()->NextVirtualRegister(); |
+ virtual_registers_[id] = virtual_register; |
} |
- return node_map_[node->id()]; |
+ return virtual_register; |
} |
-int InstructionSelector::GetMappedVirtualRegister(const Node* node) const { |
- return node_map_[node->id()]; |
+const std::map<NodeId, int> InstructionSelector::GetVirtualRegistersForTesting() |
+ const { |
+ std::map<NodeId, int> virtual_registers; |
+ for (size_t n = 0; n < virtual_registers_.size(); ++n) { |
+ if (virtual_registers_[n] != UnallocatedOperand::kInvalidVirtualRegister) { |
+ NodeId const id = static_cast<NodeId>(n); |
+ virtual_registers.insert(std::make_pair(id, virtual_registers_[n])); |
+ } |
+ } |
+ return virtual_registers; |
} |
bool InstructionSelector::IsDefined(Node* node) const { |
DCHECK_NOT_NULL(node); |
- NodeId id = node->id(); |
- DCHECK(id >= 0); |
- DCHECK(id < static_cast<NodeId>(defined_.size())); |
+ size_t const id = node->id(); |
+ DCHECK_LT(id, defined_.size()); |
return defined_[id]; |
} |
void InstructionSelector::MarkAsDefined(Node* node) { |
DCHECK_NOT_NULL(node); |
- NodeId id = node->id(); |
- DCHECK(id >= 0); |
- DCHECK(id < static_cast<NodeId>(defined_.size())); |
+ size_t const id = node->id(); |
+ DCHECK_LT(id, defined_.size()); |
defined_[id] = true; |
} |
bool InstructionSelector::IsUsed(Node* node) const { |
+ DCHECK_NOT_NULL(node); |
if (!node->op()->HasProperty(Operator::kEliminatable)) return true; |
- NodeId id = node->id(); |
- DCHECK(id >= 0); |
- DCHECK(id < static_cast<NodeId>(used_.size())); |
+ size_t const id = node->id(); |
+ DCHECK_LT(id, used_.size()); |
return used_[id]; |
} |
void InstructionSelector::MarkAsUsed(Node* node) { |
DCHECK_NOT_NULL(node); |
- NodeId id = node->id(); |
- DCHECK(id >= 0); |
- DCHECK(id < static_cast<NodeId>(used_.size())); |
+ size_t const id = node->id(); |
+ DCHECK_LT(id, used_.size()); |
used_[id] = true; |
} |
bool InstructionSelector::IsDouble(const Node* node) const { |
DCHECK_NOT_NULL(node); |
- int virtual_register = GetMappedVirtualRegister(node); |
- if (virtual_register == kNodeUnmapped) return false; |
+ int const virtual_register = virtual_registers_[node->id()]; |
+ if (virtual_register == UnallocatedOperand::kInvalidVirtualRegister) { |
+ return false; |
+ } |
return sequence()->IsDouble(virtual_register); |
} |
@@ -245,8 +255,10 @@ void InstructionSelector::MarkAsDouble(Node* node) { |
bool InstructionSelector::IsReference(const Node* node) const { |
DCHECK_NOT_NULL(node); |
- int virtual_register = GetMappedVirtualRegister(node); |
- if (virtual_register == kNodeUnmapped) return false; |
+ int const virtual_register = virtual_registers_[node->id()]; |
+ if (virtual_register == UnallocatedOperand::kInvalidVirtualRegister) { |
+ return false; |
+ } |
return sequence()->IsReference(virtual_register); |
} |