Commit 03975bef authored by jarin's avatar jarin Committed by Commit bot

[turbofan] Remove some clever-but-wrong bits from select lowering.

BUG=chromium:600593
LOG=n
R=bmeurer@chromium.org

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

Cr-Commit-Position: refs/heads/master@{#35347}
parent d7211216
......@@ -15,10 +15,7 @@ namespace internal {
namespace compiler {
SelectLowering::SelectLowering(Graph* graph, CommonOperatorBuilder* common)
: common_(common),
graph_(graph),
merges_(Merges::key_compare(), Merges::allocator_type(graph->zone())) {}
: common_(common), graph_(graph) {}
SelectLowering::~SelectLowering() {}
......@@ -30,58 +27,16 @@ Reduction SelectLowering::Reduce(Node* node) {
Node* cond = node->InputAt(0);
Node* vthen = node->InputAt(1);
Node* velse = node->InputAt(2);
Node* merge = nullptr;
// Check if we already have a diamond for this condition.
auto range = merges_.equal_range(cond);
for (auto i = range.first;; ++i) {
if (i == range.second) {
// Create a new diamond for this condition and remember its merge node.
// Create a diamond and a phi.
Diamond d(graph(), common(), cond, p.hint());
merges_.insert(std::make_pair(cond, d.merge));
merge = d.merge;
break;
}
// If the diamond is reachable from the Select, merging them would result in
// an unschedulable graph, so we cannot reuse the diamond in that case.
merge = i->second;
if (!ReachableFrom(merge, node)) {
break;
}
}
// Create a Phi hanging off the previously determined merge.
node->ReplaceInput(0, vthen);
node->ReplaceInput(1, velse);
node->ReplaceInput(2, merge);
node->ReplaceInput(2, d.merge);
NodeProperties::ChangeOp(node, common()->Phi(p.representation(), 2));
return Changed(node);
}
bool SelectLowering::ReachableFrom(Node* const sink, Node* const source) {
// TODO(turbofan): This is probably horribly expensive, and it should be moved
// into node.h or somewhere else?!
Zone zone(graph()->zone()->allocator());
std::queue<Node*, NodeDeque> queue((NodeDeque(&zone)));
BoolVector visited(graph()->NodeCount(), false, &zone);
queue.push(source);
visited[source->id()] = true;
while (!queue.empty()) {
Node* current = queue.front();
if (current == sink) return true;
queue.pop();
for (auto input : current->inputs()) {
if (!visited[input->id()]) {
queue.push(input);
visited[input->id()] = true;
}
}
}
return false;
}
} // namespace compiler
} // namespace internal
} // namespace v8
......@@ -5,10 +5,7 @@
#ifndef V8_COMPILER_SELECT_LOWERING_H_
#define V8_COMPILER_SELECT_LOWERING_H_
#include <map>
#include "src/compiler/graph-reducer.h"
#include "src/zone-allocator.h"
namespace v8 {
namespace internal {
......@@ -28,17 +25,11 @@ class SelectLowering final : public Reducer {
Reduction Reduce(Node* node) override;
private:
typedef std::multimap<Node*, Node*, std::less<Node*>,
zone_allocator<std::pair<Node* const, Node*>>> Merges;
bool ReachableFrom(Node* const sink, Node* const source);
CommonOperatorBuilder* common() const { return common_; }
Graph* graph() const { return graph_; }
CommonOperatorBuilder* common_;
Graph* graph_;
Merges merges_;
};
} // namespace compiler
......
// Copyright 2016 the V8 project authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
// Flags: --allow-natives-syntax
"use strict"
function f(c) {
if (c) { throw new Error(); }
throw new Error();
};
function Error() {
return arguments.length;
}
assertThrows(function() { f(true); });
assertThrows(function() { f(false); });
%OptimizeFunctionOnNextCall(f);
assertThrows(function() { f(true); });
// Copyright 2014 the V8 project authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "src/compiler/select-lowering.h"
#include "test/unittests/compiler/graph-unittest.h"
#include "test/unittests/compiler/node-test-utils.h"
#include "testing/gmock-support.h"
using testing::AllOf;
using testing::Capture;
using testing::CaptureEq;
using testing::Not;
namespace v8 {
namespace internal {
namespace compiler {
class SelectLoweringTest : public GraphTest {
public:
SelectLoweringTest() : GraphTest(5), lowering_(graph(), common()) {}
protected:
Reduction Reduce(Node* node) { return lowering_.Reduce(node); }
private:
SelectLowering lowering_;
};
TEST_F(SelectLoweringTest, SelectWithSameConditions) {
Node* const p0 = Parameter(0);
Node* const p1 = Parameter(1);
Node* const p2 = Parameter(2);
Node* const p3 = Parameter(3);
Node* const p4 = Parameter(4);
Node* const s0 = graph()->NewNode(
common()->Select(MachineRepresentation::kWord32), p0, p1, p2);
Capture<Node*> branch;
Capture<Node*> merge;
{
Reduction const r = Reduce(s0);
ASSERT_TRUE(r.Changed());
EXPECT_THAT(
r.replacement(),
IsPhi(
MachineRepresentation::kWord32, p1, p2,
AllOf(CaptureEq(&merge),
IsMerge(IsIfTrue(CaptureEq(&branch)),
IsIfFalse(AllOf(CaptureEq(&branch),
IsBranch(p0, graph()->start())))))));
}
{
Reduction const r = Reduce(graph()->NewNode(
common()->Select(MachineRepresentation::kWord32), p0, p3, p4));
ASSERT_TRUE(r.Changed());
EXPECT_THAT(r.replacement(), IsPhi(MachineRepresentation::kWord32, p3, p4,
CaptureEq(&merge)));
}
{
// We must not reuse the diamond if it is reachable from either else/then
// values of the Select, because the resulting graph can not be scheduled.
Reduction const r = Reduce(graph()->NewNode(
common()->Select(MachineRepresentation::kWord32), p0, s0, p0));
ASSERT_TRUE(r.Changed());
EXPECT_THAT(r.replacement(), IsPhi(MachineRepresentation::kWord32, s0, p0,
Not(CaptureEq(&merge))));
}
}
} // namespace compiler
} // namespace internal
} // namespace v8
......@@ -83,7 +83,6 @@
'compiler/opcodes-unittest.cc',
'compiler/register-allocator-unittest.cc',
'compiler/schedule-unittest.cc',
'compiler/select-lowering-unittest.cc',
'compiler/scheduler-unittest.cc',
'compiler/scheduler-rpo-unittest.cc',
'compiler/simplified-operator-reducer-unittest.cc',
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment