Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(99)

Unified Diff: src/compiler/arm64/instruction-selector-arm64.cc

Issue 1218103005: [turbofan] Support cmp with shift/extend on ARM64. (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: Created 5 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: src/compiler/arm64/instruction-selector-arm64.cc
diff --git a/src/compiler/arm64/instruction-selector-arm64.cc b/src/compiler/arm64/instruction-selector-arm64.cc
index 4be5c8371e70b4416741daae11c3535b2c03c52b..3eb37e1ab87cd93f8b6add3e8f678b85141bd970 100644
--- a/src/compiler/arm64/instruction-selector-arm64.cc
+++ b/src/compiler/arm64/instruction-selector-arm64.cc
@@ -132,13 +132,14 @@ void VisitRRO(InstructionSelector* selector, ArchOpcode opcode, Node* node,
bool TryMatchAnyShift(InstructionSelector* selector, Node* node,
- InstructionCode* opcode, bool try_ror) {
+ Node* input_node, InstructionCode* opcode, bool try_ror) {
Arm64OperandGenerator g(selector);
- if (node->InputCount() != 2) return false;
- if (!g.IsIntegerConstant(node->InputAt(1))) return false;
+ if (!selector->CanCover(node, input_node)) return false;
+ if (input_node->InputCount() != 2) return false;
+ if (!g.IsIntegerConstant(input_node->InputAt(1))) return false;
- switch (node->opcode()) {
+ switch (input_node->opcode()) {
case IrOpcode::kWord32Shl:
case IrOpcode::kWord64Shl:
*opcode |= AddressingModeField::encode(kMode_Operand2_R_LSL_I);
@@ -165,9 +166,11 @@ bool TryMatchAnyShift(InstructionSelector* selector, Node* node,
bool TryMatchAnyExtend(Arm64OperandGenerator* g, InstructionSelector* selector,
- Node* left_node, Node* right_node,
+ Node* node, Node* left_node, Node* right_node,
InstructionOperand* left_op,
InstructionOperand* right_op, InstructionCode* opcode) {
+ if (!selector->CanCover(node, right_node)) return false;
+
NodeMatcher nm(right_node);
if (nm.IsWord32And()) {
@@ -207,15 +210,20 @@ void VisitBinop(InstructionSelector* selector, Node* node,
FlagsContinuation* cont) {
Arm64OperandGenerator g(selector);
Matcher m(node);
- InstructionOperand inputs[4];
+ InstructionOperand inputs[5];
size_t input_count = 0;
InstructionOperand outputs[2];
size_t output_count = 0;
- bool is_add_sub = false;
+ bool is_cmp = opcode == kArm64Cmp32;
- if (m.IsInt32Add() || m.IsInt64Add() || m.IsInt32Sub() || m.IsInt64Sub()) {
- is_add_sub = true;
- }
+ // We can commute cmp by switching the inputs and commuting the flags
+ // continuation.
+ bool can_commute = m.HasProperty(Operator::kCommutative) || is_cmp;
+
+ // The cmp instruction is encoded as sub with zero output register, and
+ // therefore supports the same operand modes.
+ bool is_add_sub = m.IsInt32Add() || m.IsInt64Add() || m.IsInt32Sub() ||
+ m.IsInt64Sub() || is_cmp;
Node* left_node = m.left().node();
Node* right_node = m.right().node();
@@ -223,21 +231,28 @@ void VisitBinop(InstructionSelector* selector, Node* node,
if (g.CanBeImmediate(right_node, operand_mode)) {
inputs[input_count++] = g.UseRegister(left_node);
inputs[input_count++] = g.UseImmediate(right_node);
+ } else if (is_cmp && g.CanBeImmediate(left_node, operand_mode)) {
+ cont->Commute();
+ inputs[input_count++] = g.UseRegister(right_node);
+ inputs[input_count++] = g.UseImmediate(left_node);
} else if (is_add_sub &&
- TryMatchAnyExtend(&g, selector, left_node, right_node, &inputs[0],
- &inputs[1], &opcode)) {
+ TryMatchAnyExtend(&g, selector, node, left_node, right_node,
+ &inputs[0], &inputs[1], &opcode)) {
input_count += 2;
- } else if (is_add_sub && m.HasProperty(Operator::kCommutative) &&
- TryMatchAnyExtend(&g, selector, right_node, left_node, &inputs[0],
- &inputs[1], &opcode)) {
+ } else if (is_add_sub && can_commute &&
+ TryMatchAnyExtend(&g, selector, node, right_node, left_node,
+ &inputs[0], &inputs[1], &opcode)) {
+ if (is_cmp) cont->Commute();
input_count += 2;
- } else if (TryMatchAnyShift(selector, right_node, &opcode, !is_add_sub)) {
+ } else if (TryMatchAnyShift(selector, node, right_node, &opcode,
+ !is_add_sub)) {
Matcher m_shift(right_node);
inputs[input_count++] = g.UseRegister(left_node);
inputs[input_count++] = g.UseRegister(m_shift.left().node());
inputs[input_count++] = g.UseImmediate(m_shift.right().node());
- } else if (m.HasProperty(Operator::kCommutative) &&
- TryMatchAnyShift(selector, left_node, &opcode, !is_add_sub)) {
+ } else if (can_commute && TryMatchAnyShift(selector, node, left_node, &opcode,
+ !is_add_sub)) {
+ if (is_cmp) cont->Commute();
Matcher m_shift(left_node);
inputs[input_count++] = g.UseRegister(right_node);
inputs[input_count++] = g.UseRegister(m_shift.left().node());
@@ -252,13 +267,16 @@ void VisitBinop(InstructionSelector* selector, Node* node,
inputs[input_count++] = g.Label(cont->false_block());
}
- outputs[output_count++] = g.DefineAsRegister(node);
+ if (!is_cmp) {
+ outputs[output_count++] = g.DefineAsRegister(node);
+ }
+
if (cont->IsSet()) {
outputs[output_count++] = g.DefineAsRegister(cont->result());
}
DCHECK_NE(0u, input_count);
- DCHECK_NE(0u, output_count);
+ DCHECK((output_count != 0) || is_cmp);
DCHECK_GE(arraysize(inputs), input_count);
DCHECK_GE(arraysize(outputs), output_count);
@@ -1597,7 +1615,8 @@ void VisitWordCompare(InstructionSelector* selector, Node* node,
void VisitWord32Compare(InstructionSelector* selector, Node* node,
FlagsContinuation* cont) {
- VisitWordCompare(selector, node, kArm64Cmp32, cont, false, kArithmeticImm);
+ VisitBinop<Int32BinopMatcher>(selector, node, kArm64Cmp32, kArithmeticImm,
+ cont);
}
@@ -1756,8 +1775,7 @@ void InstructionSelector::VisitBranch(Node* branch, BasicBlock* tbranch,
return VisitWordCompare(this, value, kArm64Cmn32, &cont, true,
kArithmeticImm);
case IrOpcode::kInt32Sub:
- return VisitWordCompare(this, value, kArm64Cmp32, &cont, false,
- kArithmeticImm);
+ return VisitWord32Compare(this, value, &cont);
case IrOpcode::kWord32And: {
Int32BinopMatcher m(value);
if (m.right().HasValue() &&
« no previous file with comments | « src/compiler/arm64/code-generator-arm64.cc ('k') | test/unittests/compiler/arm64/instruction-selector-arm64-unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698