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

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

Issue 669133004: [turbofan] Improve code generation for inline comparisons with zero. (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: REBASE Created 6 years, 2 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
« no previous file with comments | « no previous file | src/compiler/ia32/instruction-selector-ia32.cc » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: src/compiler/arm/instruction-selector-arm.cc
diff --git a/src/compiler/arm/instruction-selector-arm.cc b/src/compiler/arm/instruction-selector-arm.cc
index 267a961a0c25d3f93382c9aad5ed832ce5418700..ec0c5b8acba5a33d04e24002b33dd283e684d99f 100644
--- a/src/compiler/arm/instruction-selector-arm.cc
+++ b/src/compiler/arm/instruction-selector-arm.cc
@@ -900,8 +900,7 @@ void VisitFloat64Compare(InstructionSelector* selector, Node* node,
// Shared routine for multiple word compare operations.
void VisitWordCompare(InstructionSelector* selector, Node* node,
- InstructionCode opcode, FlagsContinuation* cont,
- bool commutative) {
+ InstructionCode opcode, FlagsContinuation* cont) {
ArmOperandGenerator g(selector);
Int32BinopMatcher m(node);
InstructionOperand* inputs[5];
@@ -915,7 +914,7 @@ void VisitWordCompare(InstructionSelector* selector, Node* node,
input_count++;
} else if (TryMatchImmediateOrShift(selector, &opcode, m.left().node(),
&input_count, &inputs[1])) {
- if (!commutative) cont->Commute();
+ if (!node->op()->HasProperty(Operator::kCommutative)) cont->Commute();
inputs[0] = g.UseRegister(m.right().node());
input_count++;
} else {
@@ -944,81 +943,49 @@ void VisitWordCompare(InstructionSelector* selector, Node* node,
void VisitWordCompare(InstructionSelector* selector, Node* node,
FlagsContinuation* cont) {
- VisitWordCompare(selector, node, kArmCmp, cont, false);
+ VisitWordCompare(selector, node, kArmCmp, cont);
}
-void VisitWordTest(InstructionSelector* selector, Node* node,
- FlagsContinuation* cont) {
- ArmOperandGenerator g(selector);
- InstructionCode opcode =
- cont->Encode(kArmTst) | AddressingModeField::encode(kMode_Operand2_R);
- if (cont->IsBranch()) {
- selector->Emit(opcode, nullptr, g.UseRegister(node), g.UseRegister(node),
- g.Label(cont->true_block()),
- g.Label(cont->false_block()))->MarkAsControl();
- } else {
- selector->Emit(opcode, g.DefineAsRegister(cont->result()),
- g.UseRegister(node), g.UseRegister(node));
- }
-}
-
-} // namespace
-
-
-void InstructionSelector::VisitBranch(Node* branch, BasicBlock* tbranch,
- BasicBlock* fbranch) {
- ArmOperandGenerator g(this);
- Node* user = branch;
- Node* value = branch->InputAt(0);
-
- FlagsContinuation cont(kNotEqual, tbranch, fbranch);
-
- // If we can fall through to the true block, invert the branch.
- if (IsNextInAssemblyOrder(tbranch)) {
- cont.Negate();
- cont.SwapBlocks();
- }
-
- // Try to combine with comparisons against 0 by simply inverting the branch.
- while (CanCover(user, value) && value->opcode() == IrOpcode::kWord32Equal) {
- Int32BinopMatcher m(value);
- if (m.right().Is(0)) {
- user = value;
- value = m.left().node();
- cont.Negate();
- } else {
- break;
- }
- }
-
- // Try to combine the branch with a comparison.
- if (CanCover(user, value)) {
+// Shared routine for word comparisons against zero.
+void VisitWordCompareZero(InstructionSelector* selector, Node* user,
+ Node* value, FlagsContinuation* cont) {
+ while (selector->CanCover(user, value)) {
switch (value->opcode()) {
- case IrOpcode::kWord32Equal:
- cont.OverwriteAndNegateIfEqual(kEqual);
- return VisitWordCompare(this, value, &cont);
+ case IrOpcode::kWord32Equal: {
+ // Combine with comparisons against 0 by simply inverting the
+ // continuation.
+ Int32BinopMatcher m(value);
+ if (m.right().Is(0)) {
+ user = value;
+ value = m.left().node();
+ cont->Negate();
+ continue;
+ }
+ cont->OverwriteAndNegateIfEqual(kEqual);
+ return VisitWordCompare(selector, value, cont);
+ }
case IrOpcode::kInt32LessThan:
- cont.OverwriteAndNegateIfEqual(kSignedLessThan);
- return VisitWordCompare(this, value, &cont);
+ cont->OverwriteAndNegateIfEqual(kSignedLessThan);
+ return VisitWordCompare(selector, value, cont);
case IrOpcode::kInt32LessThanOrEqual:
- cont.OverwriteAndNegateIfEqual(kSignedLessThanOrEqual);
- return VisitWordCompare(this, value, &cont);
+ cont->OverwriteAndNegateIfEqual(kSignedLessThanOrEqual);
+ return VisitWordCompare(selector, value, cont);
case IrOpcode::kUint32LessThan:
- cont.OverwriteAndNegateIfEqual(kUnsignedLessThan);
- return VisitWordCompare(this, value, &cont);
+ cont->OverwriteAndNegateIfEqual(kUnsignedLessThan);
+ return VisitWordCompare(selector, value, cont);
case IrOpcode::kUint32LessThanOrEqual:
- cont.OverwriteAndNegateIfEqual(kUnsignedLessThanOrEqual);
- return VisitWordCompare(this, value, &cont);
+ cont->OverwriteAndNegateIfEqual(kUnsignedLessThanOrEqual);
+ return VisitWordCompare(selector, value, cont);
case IrOpcode::kFloat64Equal:
- cont.OverwriteAndNegateIfEqual(kUnorderedEqual);
- return VisitFloat64Compare(this, value, &cont);
+ cont->OverwriteAndNegateIfEqual(kUnorderedEqual);
+ return VisitFloat64Compare(selector, value, cont);
case IrOpcode::kFloat64LessThan:
- cont.OverwriteAndNegateIfEqual(kUnorderedLessThan);
- return VisitFloat64Compare(this, value, &cont);
+ cont->OverwriteAndNegateIfEqual(kUnorderedLessThan);
+ return VisitFloat64Compare(selector, value, cont);
case IrOpcode::kFloat64LessThanOrEqual:
- cont.OverwriteAndNegateIfEqual(kUnorderedLessThanOrEqual);
- return VisitFloat64Compare(this, value, &cont);
+ cont->OverwriteAndNegateIfEqual(kUnorderedLessThanOrEqual);
+ return VisitFloat64Compare(selector, value, cont);
case IrOpcode::kProjection:
// Check if this is the overflow output projection of an
// <Operation>WithOverflow node.
@@ -1028,16 +995,16 @@ void InstructionSelector::VisitBranch(Node* branch, BasicBlock* tbranch,
// <Operation> is either NULL, which means there's no use of the
// actual value, or was already defined, which means it is scheduled
// *AFTER* this branch).
- Node* node = value->InputAt(0);
- Node* result = node->FindProjection(0);
- if (!result || IsDefined(result)) {
+ Node* const node = value->InputAt(0);
+ Node* const result = node->FindProjection(0);
+ if (!result || selector->IsDefined(result)) {
switch (node->opcode()) {
case IrOpcode::kInt32AddWithOverflow:
- cont.OverwriteAndNegateIfEqual(kOverflow);
- return VisitBinop(this, node, kArmAdd, kArmAdd, &cont);
+ cont->OverwriteAndNegateIfEqual(kOverflow);
+ return VisitBinop(selector, node, kArmAdd, kArmAdd, cont);
case IrOpcode::kInt32SubWithOverflow:
- cont.OverwriteAndNegateIfEqual(kOverflow);
- return VisitBinop(this, node, kArmSub, kArmRsb, &cont);
+ cont->OverwriteAndNegateIfEqual(kOverflow);
+ return VisitBinop(selector, node, kArmSub, kArmRsb, cont);
default:
break;
}
@@ -1045,64 +1012,63 @@ void InstructionSelector::VisitBranch(Node* branch, BasicBlock* tbranch,
}
break;
case IrOpcode::kInt32Add:
- return VisitWordCompare(this, value, kArmCmn, &cont, true);
+ return VisitWordCompare(selector, value, kArmCmn, cont);
case IrOpcode::kInt32Sub:
- return VisitWordCompare(this, value, kArmCmp, &cont, false);
+ return VisitWordCompare(selector, value, kArmCmp, cont);
case IrOpcode::kWord32And:
- return VisitWordCompare(this, value, kArmTst, &cont, true);
+ return VisitWordCompare(selector, value, kArmTst, cont);
case IrOpcode::kWord32Or:
- return VisitBinop(this, value, kArmOrr, kArmOrr, &cont);
+ return VisitBinop(selector, value, kArmOrr, kArmOrr, cont);
case IrOpcode::kWord32Xor:
- return VisitWordCompare(this, value, kArmTeq, &cont, true);
+ return VisitWordCompare(selector, value, kArmTeq, cont);
case IrOpcode::kWord32Sar:
- return VisitShift(this, value, TryMatchASR, &cont);
+ return VisitShift(selector, value, TryMatchASR, cont);
case IrOpcode::kWord32Shl:
- return VisitShift(this, value, TryMatchLSL, &cont);
+ return VisitShift(selector, value, TryMatchLSL, cont);
case IrOpcode::kWord32Shr:
- return VisitShift(this, value, TryMatchLSR, &cont);
+ return VisitShift(selector, value, TryMatchLSR, cont);
case IrOpcode::kWord32Ror:
- return VisitShift(this, value, TryMatchROR, &cont);
+ return VisitShift(selector, value, TryMatchROR, cont);
default:
break;
}
+ break;
+ }
+
+ // Continuation could not be combined with a compare, emit compare against 0.
+ ArmOperandGenerator g(selector);
+ InstructionCode const opcode =
+ cont->Encode(kArmTst) | AddressingModeField::encode(kMode_Operand2_R);
+ InstructionOperand* const value_operand = g.UseRegister(value);
+ if (cont->IsBranch()) {
+ selector->Emit(opcode, nullptr, value_operand, value_operand,
+ g.Label(cont->true_block()),
+ g.Label(cont->false_block()))->MarkAsControl();
+ } else {
+ selector->Emit(opcode, g.DefineAsRegister(cont->result()), value_operand,
+ value_operand);
}
+}
- // Branch could not be combined with a compare, emit compare against 0.
- return VisitWordTest(this, value, &cont);
+} // namespace
+
+
+void InstructionSelector::VisitBranch(Node* branch, BasicBlock* tbranch,
+ BasicBlock* fbranch) {
+ FlagsContinuation cont(kNotEqual, tbranch, fbranch);
+ if (IsNextInAssemblyOrder(tbranch)) { // We can fallthru to the true block.
+ cont.Negate();
+ cont.SwapBlocks();
+ }
+ VisitWordCompareZero(this, branch, branch->InputAt(0), &cont);
}
void InstructionSelector::VisitWord32Equal(Node* const node) {
- Node* const user = node;
FlagsContinuation cont(kEqual, node);
- Int32BinopMatcher m(user);
+ Int32BinopMatcher m(node);
if (m.right().Is(0)) {
- Node* const value = m.left().node();
- if (CanCover(user, value)) {
- switch (value->opcode()) {
- case IrOpcode::kInt32Add:
- return VisitWordCompare(this, value, kArmCmn, &cont, true);
- case IrOpcode::kInt32Sub:
- return VisitWordCompare(this, value, kArmCmp, &cont, false);
- case IrOpcode::kWord32And:
- return VisitWordCompare(this, value, kArmTst, &cont, true);
- case IrOpcode::kWord32Or:
- return VisitBinop(this, value, kArmOrr, kArmOrr, &cont);
- case IrOpcode::kWord32Xor:
- return VisitWordCompare(this, value, kArmTeq, &cont, true);
- case IrOpcode::kWord32Sar:
- return VisitShift(this, value, TryMatchASR, &cont);
- case IrOpcode::kWord32Shl:
- return VisitShift(this, value, TryMatchLSL, &cont);
- case IrOpcode::kWord32Shr:
- return VisitShift(this, value, TryMatchLSR, &cont);
- case IrOpcode::kWord32Ror:
- return VisitShift(this, value, TryMatchROR, &cont);
- default:
- break;
- }
- return VisitWordTest(this, value, &cont);
- }
+ return VisitWordCompareZero(this, m.node(), m.left().node(), &cont);
}
VisitWordCompare(this, node, &cont);
}
« no previous file with comments | « no previous file | src/compiler/ia32/instruction-selector-ia32.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698