Commit 46c6fd92 authored by Lu Yahan's avatar Lu Yahan Committed by V8 LUCI CQ

[riscv64] Optimize instr with imm or constant 0

Change-Id: Icfef3e722d8d01f023677090dca6b899c51a46e8
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/2931580Reviewed-by: 's avatarBrice Dobry <brice.dobry@futurewei.com>
Commit-Queue: Brice Dobry <brice.dobry@futurewei.com>
Cr-Commit-Position: refs/heads/master@{#74950}
parent dc3f7f81
...@@ -41,6 +41,10 @@ class RiscvOperandGenerator final : public OperandGenerator { ...@@ -41,6 +41,10 @@ class RiscvOperandGenerator final : public OperandGenerator {
} }
bool IsIntegerConstant(Node* node) { bool IsIntegerConstant(Node* node) {
if (node->opcode() == IrOpcode::kNumberConstant) {
const double value = OpParameter<double>(node->op());
return bit_cast<int64_t>(value) == 0;
}
return (node->opcode() == IrOpcode::kInt32Constant) || return (node->opcode() == IrOpcode::kInt32Constant) ||
(node->opcode() == IrOpcode::kInt64Constant); (node->opcode() == IrOpcode::kInt64Constant);
} }
...@@ -48,9 +52,13 @@ class RiscvOperandGenerator final : public OperandGenerator { ...@@ -48,9 +52,13 @@ class RiscvOperandGenerator final : public OperandGenerator {
int64_t GetIntegerConstantValue(Node* node) { int64_t GetIntegerConstantValue(Node* node) {
if (node->opcode() == IrOpcode::kInt32Constant) { if (node->opcode() == IrOpcode::kInt32Constant) {
return OpParameter<int32_t>(node->op()); return OpParameter<int32_t>(node->op());
} else if (node->opcode() == IrOpcode::kInt64Constant) {
return OpParameter<int64_t>(node->op());
} }
DCHECK_EQ(IrOpcode::kInt64Constant, node->opcode()); DCHECK_EQ(node->opcode(), IrOpcode::kNumberConstant);
return OpParameter<int64_t>(node->op()); const double value = OpParameter<double>(node->op());
DCHECK_EQ(bit_cast<int64_t>(value), 0);
return bit_cast<int64_t>(value);
} }
bool IsFloatConstant(Node* node) { bool IsFloatConstant(Node* node) {
...@@ -296,12 +304,12 @@ static void VisitBinop(InstructionSelector* selector, Node* node, ...@@ -296,12 +304,12 @@ static void VisitBinop(InstructionSelector* selector, Node* node,
if (TryMatchImmediate(selector, &opcode, m.right().node(), &input_count, if (TryMatchImmediate(selector, &opcode, m.right().node(), &input_count,
&inputs[1])) { &inputs[1])) {
inputs[0] = g.UseRegister(m.left().node()); inputs[0] = g.UseRegisterOrImmediateZero(m.left().node());
input_count++; input_count++;
} else if (has_reverse_opcode && } else if (has_reverse_opcode &&
TryMatchImmediate(selector, &reverse_opcode, m.left().node(), TryMatchImmediate(selector, &reverse_opcode, m.left().node(),
&input_count, &inputs[1])) { &input_count, &inputs[1])) {
inputs[0] = g.UseRegister(m.right().node()); inputs[0] = g.UseRegisterOrImmediateZero(m.right().node());
opcode = reverse_opcode; opcode = reverse_opcode;
input_count++; input_count++;
} else { } else {
...@@ -1718,6 +1726,13 @@ static void VisitCompare(InstructionSelector* selector, InstructionCode opcode, ...@@ -1718,6 +1726,13 @@ static void VisitCompare(InstructionSelector* selector, InstructionCode opcode,
selector->EmitWithContinuation(opcode, left, right, cont); selector->EmitWithContinuation(opcode, left, right, cont);
} }
// Shared routine for multiple compare operations.
static void VisitWordCompareZero(InstructionSelector* selector,
InstructionOperand value,
FlagsContinuation* cont) {
selector->EmitWithContinuation(kRiscvCmpZero, value, cont);
}
// Shared routine for multiple float32 compare operations. // Shared routine for multiple float32 compare operations.
void VisitFloat32Compare(InstructionSelector* selector, Node* node, void VisitFloat32Compare(InstructionSelector* selector, Node* node,
FlagsContinuation* cont) { FlagsContinuation* cont) {
...@@ -1753,8 +1768,12 @@ void VisitWordCompare(InstructionSelector* selector, Node* node, ...@@ -1753,8 +1768,12 @@ void VisitWordCompare(InstructionSelector* selector, Node* node,
RiscvOperandGenerator g(selector); RiscvOperandGenerator g(selector);
Node* left = node->InputAt(0); Node* left = node->InputAt(0);
Node* right = node->InputAt(1); Node* right = node->InputAt(1);
// If one of the two inputs is an immediate, make sure it's on the right.
// Match immediates on left or right side of comparison. if (!g.CanBeImmediate(right, opcode) && g.CanBeImmediate(left, opcode)) {
cont->Commute();
std::swap(left, right);
}
// Match immediates on right side of comparison.
if (g.CanBeImmediate(right, opcode)) { if (g.CanBeImmediate(right, opcode)) {
if (opcode == kRiscvTst) { if (opcode == kRiscvTst) {
VisitCompare(selector, opcode, g.UseRegister(left), g.UseImmediate(right), VisitCompare(selector, opcode, g.UseRegister(left), g.UseImmediate(right),
...@@ -1767,49 +1786,36 @@ void VisitWordCompare(InstructionSelector* selector, Node* node, ...@@ -1767,49 +1786,36 @@ void VisitWordCompare(InstructionSelector* selector, Node* node,
VisitCompare(selector, opcode, g.UseRegister(left), VisitCompare(selector, opcode, g.UseRegister(left),
g.UseImmediate(right), cont); g.UseImmediate(right), cont);
} else { } else {
VisitCompare(selector, opcode, g.UseRegister(left), Int32BinopMatcher m(node, true);
g.UseRegister(right), cont); NumberBinopMatcher n(node, true);
if (m.right().Is(0) || n.right().IsZero()) {
VisitWordCompareZero(selector, g.UseRegister(left), cont);
} else {
VisitCompare(selector, opcode, g.UseRegister(left),
g.UseRegister(right), cont);
}
} }
break; break;
case kSignedLessThan: case kSignedLessThan:
case kSignedGreaterThanOrEqual: case kSignedGreaterThanOrEqual:
case kUnsignedLessThan: case kUnsignedLessThan:
case kUnsignedGreaterThanOrEqual: case kUnsignedGreaterThanOrEqual: {
VisitCompare(selector, opcode, g.UseRegister(left), Int32BinopMatcher m(node, true);
g.UseImmediate(right), cont); if (m.right().Is(0)) {
break; VisitWordCompareZero(selector, g.UseRegister(left), cont);
default:
VisitCompare(selector, opcode, g.UseRegister(left),
g.UseRegister(right), cont);
}
}
} else if (g.CanBeImmediate(left, opcode)) {
if (!commutative) cont->Commute();
if (opcode == kRiscvTst) {
VisitCompare(selector, opcode, g.UseRegister(right), g.UseImmediate(left),
cont);
} else {
switch (cont->condition()) {
case kEqual:
case kNotEqual:
if (cont->IsSet()) {
VisitCompare(selector, opcode, g.UseRegister(right),
g.UseImmediate(left), cont);
} else { } else {
VisitCompare(selector, opcode, g.UseRegister(right), VisitCompare(selector, opcode, g.UseRegister(left),
g.UseRegister(left), cont); g.UseImmediate(right), cont);
} }
break; } break;
case kSignedLessThan:
case kSignedGreaterThanOrEqual:
case kUnsignedLessThan:
case kUnsignedGreaterThanOrEqual:
VisitCompare(selector, opcode, g.UseRegister(right),
g.UseImmediate(left), cont);
break;
default: default:
VisitCompare(selector, opcode, g.UseRegister(right), Int32BinopMatcher m(node, true);
g.UseRegister(left), cont); if (m.right().Is(0)) {
VisitWordCompareZero(selector, g.UseRegister(left), cont);
} else {
VisitCompare(selector, opcode, g.UseRegister(left),
g.UseRegister(right), cont);
}
} }
} }
} else { } else {
......
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