[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:
parent
3fdfe613f8
commit
de2a225a82
@ -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;
|
||||||
|
@ -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()];
|
||||||
|
@ -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());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user