[turbofan] Optimize BooleanNot conditions to Branch nodes.

Also remove the weird work-around for this missing optimization in
CHECK_DATE in macros.py.

R=svenpanne@chromium.org

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

Cr-Commit-Position: refs/heads/master@{#29288}
This commit is contained in:
bmeurer 2015-06-25 04:06:58 -07:00 committed by Commit bot
parent 210be5215d
commit 35eb3a0260
3 changed files with 47 additions and 2 deletions

View File

@ -65,6 +65,29 @@ Reduction CommonOperatorReducer::Reduce(Node* node) {
Reduction CommonOperatorReducer::ReduceBranch(Node* node) {
DCHECK_EQ(IrOpcode::kBranch, node->opcode());
Node* const cond = node->InputAt(0);
// Swap IfTrue/IfFalse on {branch} if {cond} is a BooleanNot and use the input
// to BooleanNot as new condition for {branch}. Note we assume that {cond} was
// already properly optimized before we get here (as guaranteed by the graph
// reduction logic).
if (cond->opcode() == IrOpcode::kBooleanNot) {
for (Node* const use : node->uses()) {
switch (use->opcode()) {
case IrOpcode::kIfTrue:
use->set_op(common()->IfFalse());
break;
case IrOpcode::kIfFalse:
use->set_op(common()->IfTrue());
break;
default:
UNREACHABLE();
}
}
// Update the condition of {branch}. No need to mark the uses for revisit,
// since we tell the graph reducer that the {branch} was changed and the
// graph reduction logic will ensure that the uses are revisited properly.
node->ReplaceInput(0, cond->InputAt(0));
return Changed(node);
}
Decision const decision = DecideCondition(cond);
if (decision == Decision::kUnknown) return NoChange();
Node* const control = node->InputAt(1);

View File

@ -191,7 +191,7 @@ define MAX_TIME_BEFORE_UTC = 8640002592000000;
# Gets the value of a Date object. If arg is not a Date object
# a type error is thrown.
macro CHECK_DATE(arg) = if (%_IsDate(arg)) {} else %_ThrowNotDateError();
macro CHECK_DATE(arg) = if (!%_IsDate(arg)) %_ThrowNotDateError();
macro LOCAL_DATE_VALUE(arg) = (%_DateField(arg, 0) + %_DateField(arg, 21));
macro UTC_DATE_VALUE(arg) = (%_DateField(arg, 0));

View File

@ -7,6 +7,7 @@
#include "src/compiler/machine-operator.h"
#include "src/compiler/machine-type.h"
#include "src/compiler/operator.h"
#include "src/compiler/simplified-operator.h"
#include "test/unittests/compiler/graph-reducer-unittest.h"
#include "test/unittests/compiler/graph-unittest.h"
#include "test/unittests/compiler/node-test-utils.h"
@ -20,7 +21,7 @@ namespace compiler {
class CommonOperatorReducerTest : public GraphTest {
public:
explicit CommonOperatorReducerTest(int num_parameters = 1)
: GraphTest(num_parameters), machine_(zone()) {}
: GraphTest(num_parameters), machine_(zone()), simplified_(zone()) {}
~CommonOperatorReducerTest() override {}
protected:
@ -39,9 +40,11 @@ class CommonOperatorReducerTest : public GraphTest {
}
MachineOperatorBuilder* machine() { return &machine_; }
SimplifiedOperatorBuilder* simplified() { return &simplified_; }
private:
MachineOperatorBuilder machine_;
SimplifiedOperatorBuilder simplified_;
};
@ -169,6 +172,25 @@ TEST_F(CommonOperatorReducerTest, BranchWithTrueConstant) {
}
TEST_F(CommonOperatorReducerTest, BranchWithBooleanNot) {
Node* const value = Parameter(0);
TRACED_FOREACH(BranchHint, hint, kBranchHints) {
Node* const control = graph()->start();
Node* const branch = graph()->NewNode(
common()->Branch(hint),
graph()->NewNode(simplified()->BooleanNot(), value), control);
Node* const if_true = graph()->NewNode(common()->IfTrue(), branch);
Node* const if_false = graph()->NewNode(common()->IfFalse(), branch);
Reduction const r = Reduce(branch);
ASSERT_TRUE(r.Changed());
EXPECT_EQ(branch, r.replacement());
EXPECT_THAT(branch, IsBranch(value, control));
EXPECT_THAT(if_false, IsIfTrue(branch));
EXPECT_THAT(if_true, IsIfFalse(branch));
}
}
// -----------------------------------------------------------------------------
// Merge