Commit 7eee1444 authored by epertoso's avatar epertoso Committed by Commit bot

[turbofan] Basic reductions of 64-bit machine operators.

Only basic things for now, but enough, for example, to emit

mov rax, [rax+0xc]

instead of

mov rax, 0x3
mov rdx, [rdx+rax*4]

on x64.

BUG=

Review-Url: https://codereview.chromium.org/2211633003
Cr-Commit-Position: refs/heads/master@{#38338}
parent bb819edf
......@@ -154,10 +154,16 @@ Reduction MachineOperatorReducer::Reduce(Node* node) {
return ReduceWord32Xor(node);
case IrOpcode::kWord32Shl:
return ReduceWord32Shl(node);
case IrOpcode::kWord64Shl:
return ReduceWord64Shl(node);
case IrOpcode::kWord32Shr:
return ReduceWord32Shr(node);
case IrOpcode::kWord64Shr:
return ReduceWord64Shr(node);
case IrOpcode::kWord32Sar:
return ReduceWord32Sar(node);
case IrOpcode::kWord64Sar:
return ReduceWord64Sar(node);
case IrOpcode::kWord32Ror: {
Int32BinopMatcher m(node);
if (m.right().Is(0)) return Replace(m.left().node()); // x ror 0 => x
......@@ -199,8 +205,12 @@ Reduction MachineOperatorReducer::Reduce(Node* node) {
}
case IrOpcode::kInt32Add:
return ReduceInt32Add(node);
case IrOpcode::kInt64Add:
return ReduceInt64Add(node);
case IrOpcode::kInt32Sub:
return ReduceInt32Sub(node);
case IrOpcode::kInt64Sub:
return ReduceInt64Sub(node);
case IrOpcode::kInt32Mul: {
Int32BinopMatcher m(node);
if (m.right().Is(0)) return Replace(m.right().node()); // x * 0 => 0
......@@ -621,6 +631,16 @@ Reduction MachineOperatorReducer::ReduceInt32Add(Node* node) {
return NoChange();
}
Reduction MachineOperatorReducer::ReduceInt64Add(Node* node) {
DCHECK_EQ(IrOpcode::kInt64Add, node->opcode());
Int64BinopMatcher m(node);
if (m.right().Is(0)) return Replace(m.left().node()); // x + 0 => 0
if (m.IsFoldable()) {
return Replace(Uint64Constant(bit_cast<uint64_t>(m.left().Value()) +
bit_cast<uint64_t>(m.right().Value())));
}
return NoChange();
}
Reduction MachineOperatorReducer::ReduceInt32Sub(Node* node) {
DCHECK_EQ(IrOpcode::kInt32Sub, node->opcode());
......@@ -640,6 +660,23 @@ Reduction MachineOperatorReducer::ReduceInt32Sub(Node* node) {
return NoChange();
}
Reduction MachineOperatorReducer::ReduceInt64Sub(Node* node) {
DCHECK_EQ(IrOpcode::kInt64Sub, node->opcode());
Int64BinopMatcher m(node);
if (m.right().Is(0)) return Replace(m.left().node()); // x - 0 => x
if (m.IsFoldable()) { // K - K => K
return Replace(Uint64Constant(bit_cast<uint64_t>(m.left().Value()) -
bit_cast<uint64_t>(m.right().Value())));
}
if (m.LeftEqualsRight()) return Replace(Int64Constant(0)); // x - x => 0
if (m.right().HasValue()) { // x - K => x + -K
node->ReplaceInput(1, Int64Constant(-m.right().Value()));
NodeProperties::ChangeOp(node, machine()->Int64Add());
Reduction const reduction = ReduceInt64Add(node);
return reduction.Changed() ? reduction : Changed(node);
}
return NoChange();
}
Reduction MachineOperatorReducer::ReduceInt32Div(Node* node) {
Int32BinopMatcher m(node);
......@@ -936,6 +973,16 @@ Reduction MachineOperatorReducer::ReduceWord32Shl(Node* node) {
return ReduceWord32Shifts(node);
}
Reduction MachineOperatorReducer::ReduceWord64Shl(Node* node) {
DCHECK_EQ(IrOpcode::kWord64Shl, node->opcode());
Int64BinopMatcher m(node);
if (m.right().Is(0)) return Replace(m.left().node()); // x << 0 => x
if (m.IsFoldable()) { // K << K => K
return ReplaceInt64(m.left().Value() << m.right().Value());
}
return NoChange();
}
Reduction MachineOperatorReducer::ReduceWord32Shr(Node* node) {
Uint32BinopMatcher m(node);
if (m.right().Is(0)) return Replace(m.left().node()); // x >>> 0 => x
......@@ -956,6 +1003,16 @@ Reduction MachineOperatorReducer::ReduceWord32Shr(Node* node) {
return ReduceWord32Shifts(node);
}
Reduction MachineOperatorReducer::ReduceWord64Shr(Node* node) {
DCHECK_EQ(IrOpcode::kWord64Shr, node->opcode());
Uint64BinopMatcher m(node);
if (m.right().Is(0)) return Replace(m.left().node()); // x >>> 0 => x
if (m.IsFoldable()) { // K >> K => K
return ReplaceInt64(m.left().Value() >> m.right().Value());
}
return NoChange();
}
Reduction MachineOperatorReducer::ReduceWord32Sar(Node* node) {
Int32BinopMatcher m(node);
if (m.right().Is(0)) return Replace(m.left().node()); // x >> 0 => x
......@@ -991,6 +1048,14 @@ Reduction MachineOperatorReducer::ReduceWord32Sar(Node* node) {
return ReduceWord32Shifts(node);
}
Reduction MachineOperatorReducer::ReduceWord64Sar(Node* node) {
Int64BinopMatcher m(node);
if (m.right().Is(0)) return Replace(m.left().node()); // x >> 0 => x
if (m.IsFoldable()) {
return ReplaceInt64(m.left().Value() >> m.right().Value());
}
return NoChange();
}
Reduction MachineOperatorReducer::ReduceWord32And(Node* node) {
DCHECK_EQ(IrOpcode::kWord32And, node->opcode());
......
......@@ -32,7 +32,10 @@ class MachineOperatorReducer final : public Reducer {
Node* Int32Constant(int32_t value);
Node* Int64Constant(int64_t value);
Node* Uint32Constant(uint32_t value) {
return Int32Constant(bit_cast<uint32_t>(value));
return Int32Constant(bit_cast<int32_t>(value));
}
Node* Uint64Constant(uint64_t value) {
return Int64Constant(bit_cast<int64_t>(value));
}
Node* Float64Mul(Node* lhs, Node* rhs);
Node* Float64PowHalf(Node* value);
......@@ -67,7 +70,9 @@ class MachineOperatorReducer final : public Reducer {
}
Reduction ReduceInt32Add(Node* node);
Reduction ReduceInt64Add(Node* node);
Reduction ReduceInt32Sub(Node* node);
Reduction ReduceInt64Sub(Node* node);
Reduction ReduceInt32Div(Node* node);
Reduction ReduceUint32Div(Node* node);
Reduction ReduceInt32Mod(Node* node);
......@@ -76,8 +81,11 @@ class MachineOperatorReducer final : public Reducer {
Reduction ReduceProjection(size_t index, Node* node);
Reduction ReduceWord32Shifts(Node* node);
Reduction ReduceWord32Shl(Node* node);
Reduction ReduceWord64Shl(Node* node);
Reduction ReduceWord32Shr(Node* node);
Reduction ReduceWord64Shr(Node* node);
Reduction ReduceWord32Sar(Node* node);
Reduction ReduceWord64Sar(Node* node);
Reduction ReduceWord32And(Node* node);
Reduction TryMatchWord32Ror(Node* node);
Reduction ReduceWord32Or(Node* node);
......
......@@ -25,6 +25,12 @@ const Operator* NewConstantOperator<int32_t>(CommonOperatorBuilder* common,
return common->Int32Constant(value);
}
template <>
const Operator* NewConstantOperator<int64_t>(CommonOperatorBuilder* common,
volatile int64_t value) {
return common->Int64Constant(value);
}
template <>
const Operator* NewConstantOperator<double>(CommonOperatorBuilder* common,
volatile double value) {
......@@ -41,6 +47,12 @@ int32_t ValueOfOperator<int32_t>(const Operator* op) {
return OpParameter<int32_t>(op);
}
template <>
int64_t ValueOfOperator<int64_t>(const Operator* op) {
CHECK_EQ(IrOpcode::kInt64Constant, op->opcode());
return OpParameter<int64_t>(op);
}
template <>
double ValueOfOperator<double>(const Operator* op) {
CHECK_EQ(IrOpcode::kFloat64Constant, op->opcode());
......@@ -315,6 +327,24 @@ TEST(ReduceWord32Shl) {
R.CheckBinop(x, x, zero); // x << 0 => x
}
TEST(ReduceWord64Shl) {
ReducerTester R;
R.binop = R.machine.Word64Shl();
FOR_INT64_INPUTS(i) {
for (int64_t y = 0; y < 64; y++) {
int64_t x = *i;
R.CheckFoldBinop<int64_t>(x << y, x, y);
}
}
R.CheckDontPutConstantOnRight(44);
Node* x = R.Parameter();
Node* zero = R.Constant<int64_t>(0);
R.CheckBinop(x, x, zero); // x << 0 => x
}
TEST(ReduceWord32Shr) {
ReducerTester R;
......@@ -336,6 +366,24 @@ TEST(ReduceWord32Shr) {
R.CheckBinop(x, x, zero); // x >>> 0 => x
}
TEST(ReduceWord64Shr) {
ReducerTester R;
R.binop = R.machine.Word64Shr();
FOR_UINT64_INPUTS(i) {
for (uint64_t y = 0; y < 64; y++) {
uint64_t x = *i;
R.CheckFoldBinop<int64_t>(x >> y, x, y);
}
}
R.CheckDontPutConstantOnRight(44);
Node* x = R.Parameter();
Node* zero = R.Constant<int64_t>(0);
R.CheckBinop(x, x, zero); // x >>> 0 => x
}
TEST(ReduceWord32Sar) {
ReducerTester R;
......@@ -357,6 +405,24 @@ TEST(ReduceWord32Sar) {
R.CheckBinop(x, x, zero); // x >> 0 => x
}
TEST(ReduceWord64Sar) {
ReducerTester R;
R.binop = R.machine.Word64Sar();
FOR_INT64_INPUTS(i) {
for (int64_t y = 0; y < 64; y++) {
int64_t x = *i;
R.CheckFoldBinop<int64_t>(x >> y, x, y);
}
}
R.CheckDontPutConstantOnRight(44);
Node* x = R.Parameter();
Node* zero = R.Constant<int64_t>(0);
R.CheckBinop(x, x, zero); // x >> 0 => x
}
static void CheckJsShift(ReducerTester* R) {
CHECK(R->machine.Word32ShiftIsSafe());
......@@ -433,6 +499,24 @@ TEST(ReduceInt32Add) {
R.CheckBinop(x, zero, x); // 0 + x => x
}
TEST(ReduceInt64Add) {
ReducerTester R;
R.binop = R.machine.Int64Add();
FOR_INT64_INPUTS(pl) {
FOR_INT64_INPUTS(pr) {
int64_t x = *pl, y = *pr;
R.CheckFoldBinop<int64_t>(x + y, x, y);
}
}
R.CheckPutConstantOnRight(41);
Node* x = R.Parameter();
Node* zero = R.Constant<int64_t>(0);
R.CheckBinop(x, x, zero); // x + 0 => x
R.CheckBinop(x, zero, x); // 0 + x => x
}
TEST(ReduceInt32Sub) {
ReducerTester R;
......@@ -453,6 +537,30 @@ TEST(ReduceInt32Sub) {
R.CheckBinop(x, x, zero); // x - 0 => x
}
TEST(ReduceInt64Sub) {
ReducerTester R;
R.binop = R.machine.Int64Sub();
FOR_INT64_INPUTS(pl) {
FOR_INT64_INPUTS(pr) {
int64_t x = *pl, y = *pr;
R.CheckFoldBinop<int64_t>(x - y, x, y);
}
}
R.CheckDontPutConstantOnRight(42);
Node* x = R.Parameter();
Node* zero = R.Constant<int64_t>(0);
R.CheckBinop(x, x, zero); // x - 0 => x
R.CheckFoldBinop<int64_t>(0, x, x); // x - x => 0
Node* k = R.Constant<int64_t>(6);
R.CheckFoldBinop<int64_t>(x, R.machine.Int64Add(), -6, x,
k); // x - K => x + -K
}
TEST(ReduceInt32Mul) {
ReducerTester R;
......@@ -717,13 +825,8 @@ TEST(ReduceLoadStore) {
// TODO(titzer): test MachineOperatorReducer for Word64And
// TODO(titzer): test MachineOperatorReducer for Word64Or
// TODO(titzer): test MachineOperatorReducer for Word64Xor
// TODO(titzer): test MachineOperatorReducer for Word64Shl
// TODO(titzer): test MachineOperatorReducer for Word64Shr
// TODO(titzer): test MachineOperatorReducer for Word64Sar
// TODO(titzer): test MachineOperatorReducer for Word64Equal
// TODO(titzer): test MachineOperatorReducer for Word64Not
// TODO(titzer): test MachineOperatorReducer for Int64Add
// TODO(titzer): test MachineOperatorReducer for Int64Sub
// TODO(titzer): test MachineOperatorReducer for Int64Mul
// TODO(titzer): test MachineOperatorReducer for Int64UMul
// TODO(titzer): test MachineOperatorReducer for Int64Div
......
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