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

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

Issue 415403005: [turbofan] Support for combining branches with <Operation>WithOverflow. (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Created 6 years, 4 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/arm64/instruction-selector-arm64.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 e3c4f9b276a0862add51125b7c25098bc15c1f75..d60eee7a671d0627acc85df79d2a1d5e836d5fb0 100644
--- a/src/compiler/arm/instruction-selector-arm.cc
+++ b/src/compiler/arm/instruction-selector-arm.cc
@@ -249,46 +249,12 @@ static inline bool TryMatchImmediateOrShift(InstructionSelector* selector,
}
-// Shared routine for multiple binary operations.
static void VisitBinop(InstructionSelector* selector, Node* node,
- InstructionCode opcode, InstructionCode reverse_opcode) {
- ArmOperandGenerator g(selector);
- Int32BinopMatcher m(node);
- InstructionOperand* inputs[3];
- size_t input_count = 0;
- InstructionOperand* outputs[1] = {g.DefineAsRegister(node)};
- const size_t output_count = ARRAY_SIZE(outputs);
-
- if (TryMatchImmediateOrShift(selector, &opcode, m.right().node(),
- &input_count, &inputs[1])) {
- inputs[0] = g.UseRegister(m.left().node());
- input_count++;
- } else if (TryMatchImmediateOrShift(selector, &reverse_opcode,
- m.left().node(), &input_count,
- &inputs[1])) {
- inputs[0] = g.UseRegister(m.right().node());
- opcode = reverse_opcode;
- input_count++;
- } else {
- opcode |= AddressingModeField::encode(kMode_Operand2_R);
- inputs[input_count++] = g.UseRegister(m.left().node());
- inputs[input_count++] = g.UseRegister(m.right().node());
- }
-
- ASSERT_NE(0, input_count);
- ASSERT_GE(ARRAY_SIZE(inputs), input_count);
- ASSERT_NE(kMode_None, AddressingModeField::decode(opcode));
-
- selector->Emit(opcode, output_count, outputs, input_count, inputs);
-}
-
-
-static void VisitBinopWithOverflow(InstructionSelector* selector, Node* node,
- InstructionCode opcode,
- InstructionCode reverse_opcode) {
+ InstructionCode opcode, InstructionCode reverse_opcode,
+ FlagsContinuation* cont) {
ArmOperandGenerator g(selector);
Int32BinopMatcher m(node);
- InstructionOperand* inputs[3];
+ InstructionOperand* inputs[5];
size_t input_count = 0;
InstructionOperand* outputs[2];
size_t output_count = 0;
@@ -309,16 +275,14 @@ static void VisitBinopWithOverflow(InstructionSelector* selector, Node* node,
inputs[input_count++] = g.UseRegister(m.right().node());
}
- // Define outputs depending on the projections.
- Node* projections[2];
- node->CollectProjections(ARRAY_SIZE(projections), projections);
- if (projections[0]) {
- outputs[output_count++] = g.DefineAsRegister(projections[0]);
+ if (cont->IsBranch()) {
+ inputs[input_count++] = g.Label(cont->true_block());
+ inputs[input_count++] = g.Label(cont->false_block());
}
- if (projections[1]) {
- opcode |= FlagsModeField::encode(kFlags_set);
- opcode |= FlagsConditionField::encode(kOverflow);
- outputs[output_count++] = g.DefineAsRegister(projections[1]);
+
+ outputs[output_count++] = g.DefineAsRegister(node);
+ if (cont->IsSet()) {
+ outputs[output_count++] = g.DefineAsRegister(cont->result());
}
ASSERT_NE(0, input_count);
@@ -327,7 +291,16 @@ static void VisitBinopWithOverflow(InstructionSelector* selector, Node* node,
ASSERT_GE(ARRAY_SIZE(outputs), output_count);
ASSERT_NE(kMode_None, AddressingModeField::decode(opcode));
- selector->Emit(opcode, output_count, outputs, input_count, inputs);
+ Instruction* instr = selector->Emit(cont->Encode(opcode), output_count,
+ outputs, input_count, inputs);
+ if (cont->IsBranch()) instr->MarkAsControl();
+}
+
+
+static void VisitBinop(InstructionSelector* selector, Node* node,
+ InstructionCode opcode, InstructionCode reverse_opcode) {
+ FlagsContinuation cont;
+ VisitBinop(selector, node, opcode, reverse_opcode, &cont);
}
@@ -597,11 +570,6 @@ void InstructionSelector::VisitInt32Add(Node* node) {
}
-void InstructionSelector::VisitInt32AddWithOverflow(Node* node) {
- VisitBinopWithOverflow(this, node, kArmAdd, kArmAdd);
-}
-
-
void InstructionSelector::VisitInt32Sub(Node* node) {
ArmOperandGenerator g(this);
Int32BinopMatcher m(node);
@@ -616,11 +584,6 @@ void InstructionSelector::VisitInt32Sub(Node* node) {
}
-void InstructionSelector::VisitInt32SubWithOverflow(Node* node) {
- VisitBinopWithOverflow(this, node, kArmSub, kArmRsb);
-}
-
-
void InstructionSelector::VisitInt32Mul(Node* node) {
ArmOperandGenerator g(this);
Int32BinopMatcher m(node);
@@ -867,10 +830,22 @@ void InstructionSelector::VisitCall(Node* call, BasicBlock* continuation,
}
+void InstructionSelector::VisitInt32AddWithOverflow(Node* node,
+ FlagsContinuation* cont) {
+ VisitBinop(this, node, kArmAdd, kArmAdd, cont);
+}
+
+
+void InstructionSelector::VisitInt32SubWithOverflow(Node* node,
+ FlagsContinuation* cont) {
+ VisitBinop(this, node, kArmSub, kArmRsb, cont);
+}
+
+
// Shared routine for multiple compare operations.
static void VisitWordCompare(InstructionSelector* selector, Node* node,
InstructionCode opcode, FlagsContinuation* cont,
- bool commutative, bool requires_output) {
+ bool commutative) {
ArmOperandGenerator g(selector);
Int32BinopMatcher m(node);
InstructionOperand* inputs[5];
@@ -894,9 +869,6 @@ static void VisitWordCompare(InstructionSelector* selector, Node* node,
}
if (cont->IsBranch()) {
- if (requires_output) {
- outputs[output_count++] = g.DefineAsRegister(node);
- }
inputs[input_count++] = g.Label(cont->true_block());
inputs[input_count++] = g.Label(cont->false_block());
} else {
@@ -917,15 +889,15 @@ static void VisitWordCompare(InstructionSelector* selector, Node* node,
void InstructionSelector::VisitWord32Test(Node* node, FlagsContinuation* cont) {
switch (node->opcode()) {
case IrOpcode::kInt32Add:
- return VisitWordCompare(this, node, kArmCmn, cont, true, false);
+ return VisitWordCompare(this, node, kArmCmn, cont, true);
case IrOpcode::kInt32Sub:
- return VisitWordCompare(this, node, kArmCmp, cont, false, false);
+ return VisitWordCompare(this, node, kArmCmp, cont, false);
case IrOpcode::kWord32And:
- return VisitWordCompare(this, node, kArmTst, cont, true, false);
+ return VisitWordCompare(this, node, kArmTst, cont, true);
case IrOpcode::kWord32Or:
- return VisitWordCompare(this, node, kArmOrr, cont, true, true);
+ return VisitBinop(this, node, kArmOrr, kArmOrr, cont);
case IrOpcode::kWord32Xor:
- return VisitWordCompare(this, node, kArmTeq, cont, true, false);
+ return VisitWordCompare(this, node, kArmTeq, cont, true);
default:
break;
}
@@ -946,7 +918,7 @@ void InstructionSelector::VisitWord32Test(Node* node, FlagsContinuation* cont) {
void InstructionSelector::VisitWord32Compare(Node* node,
FlagsContinuation* cont) {
- VisitWordCompare(this, node, kArmCmp, cont, false, false);
+ VisitWordCompare(this, node, kArmCmp, cont, false);
}
« no previous file with comments | « no previous file | src/compiler/arm64/instruction-selector-arm64.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698