Revision: 24571
Author:   [email protected]
Date:     Mon Oct 13 23:31:59 2014 UTC
Log:      MIPS: [turbofan] Make VisitBranch and friends to backend specific.

Port r24546 (c3443cd)

Original commit message:
This is required to fix a tricky branch fusion bug on ARM, which was
caused by the interaction between the architecture-independent and
architecture-specific parts of the InstructionSelector. In the end it
wasn't worth sharing a few common lines of code for the additional
complexity, especially if we also want to properly support architectures
without any dedicated flags register (i.e. MIPS).

TEST=mjsunit,unittests
BUG=
[email protected]

Review URL: https://codereview.chromium.org/644973003

Patch from Balazs Kilvady <[email protected]>.
https://code.google.com/p/v8/source/detail?r=24571

Modified:
 /branches/bleeding_edge/src/compiler/mips/instruction-selector-mips.cc

=======================================
--- /branches/bleeding_edge/src/compiler/mips/instruction-selector-mips.cc Thu Oct 2 15:48:48 2014 UTC +++ /branches/bleeding_edge/src/compiler/mips/instruction-selector-mips.cc Mon Oct 13 23:31:59 2014 UTC
@@ -401,21 +401,21 @@
Emit(kMipsSqrtD, g.DefineAsRegister(node), g.UseRegister(node->InputAt(0)));
 }

-void InstructionSelector::VisitCall(Node* call, BasicBlock* continuation,
-                                    BasicBlock* deoptimization) {
+
+void InstructionSelector::VisitCall(Node* node) {
   MipsOperandGenerator g(this);
-  CallDescriptor* descriptor = OpParameter<CallDescriptor*>(call);
+  CallDescriptor* descriptor = OpParameter<CallDescriptor*>(node);

   FrameStateDescriptor* frame_state_descriptor = NULL;
   if (descriptor->NeedsFrameState()) {
     frame_state_descriptor =
-        GetFrameStateDescriptor(call->InputAt(descriptor->InputCount()));
+        GetFrameStateDescriptor(node->InputAt(descriptor->InputCount()));
   }

   CallBuffer buffer(zone(), descriptor, frame_state_descriptor);

   // Compute InstructionOperands for inputs and outputs.
-  InitializeCallBuffer(call, &buffer, true, false);
+  InitializeCallBuffer(node, &buffer, true, false);

   // TODO(dcarney): might be possible to use claim/poke instead
   // Push any stack arguments.
@@ -447,26 +447,11 @@
   Instruction* call_instr =
       Emit(opcode, buffer.outputs.size(), &buffer.outputs.front(),
buffer.instruction_args.size(), &buffer.instruction_args.front());
-
   call_instr->MarkAsCall();
-  if (deoptimization != NULL) {
-    DCHECK(continuation != NULL);
-    call_instr->MarkAsControl();
-  }
 }


-void InstructionSelector::VisitInt32AddWithOverflow(Node* node,
- FlagsContinuation* cont) {
-  VisitBinop(this, node, kMipsAddOvf, cont);
-}
-
-
-void InstructionSelector::VisitInt32SubWithOverflow(Node* node,
- FlagsContinuation* cont) {
-  VisitBinop(this, node, kMipsSubOvf, cont);
-}
-
+namespace {

 // Shared routine for multiple compare operations.
static void VisitCompare(InstructionSelector* selector, InstructionCode opcode,
@@ -483,12 +468,23 @@
selector->Emit(opcode, g.DefineAsRegister(cont->result()), left, right);
   }
 }
+
+
+// Shared routine for multiple float compare operations.
+void VisitFloat64Compare(InstructionSelector* selector, Node* node,
+                         FlagsContinuation* cont) {
+  MipsOperandGenerator g(selector);
+  Node* left = node->InputAt(0);
+  Node* right = node->InputAt(1);
+ VisitCompare(selector, kMipsCmpD, g.UseRegister(left), g.UseRegister(right),
+               cont);
+}


 // Shared routine for multiple word compare operations.
-static void VisitWordCompare(InstructionSelector* selector, Node* node,
- InstructionCode opcode, FlagsContinuation* cont,
-                             bool commutative) {
+void VisitWordCompare(InstructionSelector* selector, Node* node,
+                      InstructionCode opcode, FlagsContinuation* cont,
+                      bool commutative) {
   MipsOperandGenerator g(selector);
   Node* left = node->InputAt(0);
   Node* right = node->InputAt(1);
@@ -508,35 +504,138 @@
 }


-void InstructionSelector::VisitWord32Test(Node* node, FlagsContinuation* cont) {
-  switch (node->opcode()) {
-    case IrOpcode::kWord32And:
-      // TODO(plind): understand the significance of 'IR and' special case.
-      return VisitWordCompare(this, node, kMipsTst, cont, true);
-    default:
+void VisitWordCompare(InstructionSelector* selector, Node* node,
+                      FlagsContinuation* cont) {
+  VisitWordCompare(selector, node, kMipsCmp, cont, false);
+}
+
+
+void VisitWordTest(InstructionSelector* selector, Node* node,
+                   FlagsContinuation* cont) {
+  MipsOperandGenerator g(selector);
+ // kMipsTst is a pseudo-instruction to do logical 'and' and leave the result
+  // in a dedicated tmp register.
+ VisitCompare(selector, kMipsTst, g.UseRegister(node), g.UseRegister(node),
+               cont);
+}
+
+}  // namespace
+
+
+void InstructionSelector::VisitBranch(Node* branch, BasicBlock* tbranch,
+                                      BasicBlock* fbranch) {
+  MipsOperandGenerator 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;
+    }
   }

-  MipsOperandGenerator g(this);
- // kMipsTst is a pseudo-instruction to do logical 'and' and leave the result
-  // in a dedicated tmp register.
- VisitCompare(this, kMipsTst, g.UseRegister(node), g.UseRegister(node), cont);
+  // Try to combine the branch with a comparison.
+  if (CanCover(user, value)) {
+    switch (value->opcode()) {
+      case IrOpcode::kWord32And:
+ // TODO(plind): understand the significance of 'IR and' special case.
+        return VisitWordCompare(this, value, kMipsTst, &cont, true);
+      default:
+        break;
+    }
+  }
+
+  // Branch could not be combined with a compare, emit compare against 0.
+  return VisitWordTest(this, value, &cont);
+}
+
+
+void InstructionSelector::VisitWord32Equal(Node* const node) {
+  Node* const user = node;
+  FlagsContinuation cont(kEqual, node);
+  Int32BinopMatcher m(user);
+  if (m.right().Is(0)) {
+    Node* const value = m.left().node();
+    return VisitWordTest(this, value, &cont);
+  }
+
+  VisitWordCompare(this, node, &cont);
+}
+
+
+void InstructionSelector::VisitInt32LessThan(Node* node) {
+  FlagsContinuation cont(kSignedLessThan, node);
+  VisitWordCompare(this, node, &cont);
+}
+
+
+void InstructionSelector::VisitInt32LessThanOrEqual(Node* node) {
+  FlagsContinuation cont(kSignedLessThanOrEqual, node);
+  VisitWordCompare(this, node, &cont);
+}
+
+
+void InstructionSelector::VisitUint32LessThan(Node* node) {
+  FlagsContinuation cont(kUnsignedLessThan, node);
+  VisitWordCompare(this, node, &cont);
+}
+
+
+void InstructionSelector::VisitUint32LessThanOrEqual(Node* node) {
+  FlagsContinuation cont(kUnsignedLessThanOrEqual, node);
+  VisitWordCompare(this, node, &cont);
+}
+
+
+void InstructionSelector::VisitInt32AddWithOverflow(Node* node) {
+  if (Node* ovf = node->FindProjection(1)) {
+    FlagsContinuation cont(kOverflow, ovf);
+    return VisitBinop(this, node, kMipsAddOvf, &cont);
+  }
+  FlagsContinuation cont;
+  VisitBinop(this, node, kMipsAddOvf, &cont);
+}
+
+
+void InstructionSelector::VisitInt32SubWithOverflow(Node* node) {
+  if (Node* ovf = node->FindProjection(1)) {
+    FlagsContinuation cont(kOverflow, ovf);
+    return VisitBinop(this, node, kMipsSubOvf, &cont);
+  }
+  FlagsContinuation cont;
+  VisitBinop(this, node, kMipsSubOvf, &cont);
+}
+
+
+void InstructionSelector::VisitFloat64Equal(Node* node) {
+  FlagsContinuation cont(kUnorderedEqual, node);
+  VisitFloat64Compare(this, node, &cont);
 }


-void InstructionSelector::VisitWord32Compare(Node* node,
-                                             FlagsContinuation* cont) {
-  VisitWordCompare(this, node, kMipsCmp, cont, false);
+void InstructionSelector::VisitFloat64LessThan(Node* node) {
+  FlagsContinuation cont(kUnorderedLessThan, node);
+  VisitFloat64Compare(this, node, &cont);
 }


-void InstructionSelector::VisitFloat64Compare(Node* node,
-                                              FlagsContinuation* cont) {
-  MipsOperandGenerator g(this);
-  Node* left = node->InputAt(0);
-  Node* right = node->InputAt(1);
-  VisitCompare(this, kMipsCmpD, g.UseRegister(left), g.UseRegister(right),
-               cont);
+void InstructionSelector::VisitFloat64LessThanOrEqual(Node* node) {
+  FlagsContinuation cont(kUnorderedLessThanOrEqual, node);
+  VisitFloat64Compare(this, node, &cont);
 }

 }  // namespace compiler

--
--
v8-dev mailing list
[email protected]
http://groups.google.com/group/v8-dev
--- You received this message because you are subscribed to the Google Groups "v8-dev" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to [email protected].
For more options, visit https://groups.google.com/d/optout.

Reply via email to