[turbofan] Fix GVN of projections and add verification for projection uniqueness.

R=bmeurer@chromium.org
BUG=

Review URL: https://codereview.chromium.org/1020873002

Cr-Commit-Position: refs/heads/master@{#27304}
This commit is contained in:
titzer 2015-03-19 06:03:51 -07:00 committed by Commit bot
parent 3fdfe613f8
commit de2a225a82
3 changed files with 27 additions and 7 deletions

View File

@ -292,12 +292,12 @@ struct CommonOperatorGlobalCache FINAL {
template <size_t kIndex> template <size_t kIndex>
struct ProjectionOperator FINAL : public Operator1<size_t> { struct ProjectionOperator FINAL : public Operator1<size_t> {
ProjectionOperator() ProjectionOperator()
: Operator1<size_t>( // -- : Operator1<size_t>( // --
IrOpcode::kProjection, // opcode IrOpcode::kProjection, // opcode
Operator::kFoldable | Operator::kNoThrow, // flags Operator::kPure, // flags
"Projection", // name "Projection", // name
1, 0, 0, 1, 0, 0, // counts, 1, 0, 0, 1, 0, 0, // counts,
kIndex) {} // parameter kIndex) {} // parameter
}; };
#define CACHED_PROJECTION(index) \ #define CACHED_PROJECTION(index) \
ProjectionOperator<index> kProjection##index##Operator; ProjectionOperator<index> kProjection##index##Operator;

View File

@ -1401,6 +1401,8 @@ class ScheduleLateNodeVisitor {
BasicBlock* SplitNode(BasicBlock* block, Node* node) { BasicBlock* SplitNode(BasicBlock* block, Node* node) {
// For now, we limit splitting to pure nodes. // For now, we limit splitting to pure nodes.
if (!node->op()->HasProperty(Operator::kPure)) return block; if (!node->op()->HasProperty(Operator::kPure)) return block;
// TODO(titzer): fix the special case of splitting of projections.
if (node->opcode() == IrOpcode::kProjection) return block;
// The {block} is common dominator of all uses of {node}, so we cannot // The {block} is common dominator of all uses of {node}, so we cannot
// split anything unless the {block} has at least two successors. // split anything unless the {block} has at least two successors.
@ -1573,6 +1575,8 @@ class ScheduleLateNodeVisitor {
inputs[index] = input; inputs[index] = input;
} }
Node* copy = scheduler_->graph_->NewNode(node->op(), input_count, inputs); Node* copy = scheduler_->graph_->NewNode(node->op(), input_count, inputs);
TRACE(("clone #%d:%s -> #%d\n"), node->id(), node->op()->mnemonic(),
copy->id());
scheduler_->node_data_.resize(copy->id() + 1, scheduler_->node_data_.resize(copy->id() + 1,
scheduler_->DefaultSchedulerData()); scheduler_->DefaultSchedulerData());
scheduler_->node_data_[copy->id()] = scheduler_->node_data_[node->id()]; scheduler_->node_data_[copy->id()] = scheduler_->node_data_[node->id()];

View File

@ -825,7 +825,23 @@ void Verifier::Run(Graph* graph, Typing typing) {
CHECK_NOT_NULL(graph->end()); CHECK_NOT_NULL(graph->end());
Zone zone; Zone zone;
Visitor visitor(&zone, typing); Visitor visitor(&zone, typing);
for (Node* node : AllNodes(&zone, graph).live) visitor.Check(node); AllNodes all(&zone, graph);
for (Node* node : all.live) visitor.Check(node);
// Check the uniqueness of projections.
for (Node* proj : all.live) {
if (proj->opcode() != IrOpcode::kProjection) continue;
Node* node = proj->InputAt(0);
for (Node* other : node->uses()) {
if (all.IsLive(other) && other != proj &&
other->opcode() == IrOpcode::kProjection &&
ProjectionIndexOf(other->op()) == ProjectionIndexOf(proj->op())) {
V8_Fatal(__FILE__, __LINE__,
"Node #%d:%s has duplicate projections #%d and #%d",
node->id(), node->op()->mnemonic(), proj->id(), other->id());
}
}
}
} }