Reviewers: Benedikt Meurer,

Message:
PTAL

Description:
[turbofan] Use cbz/cbnz when possible on arm64.

[email protected]

Please review this at https://codereview.chromium.org/715433004/

Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge

Affected files (+62, -12 lines):
  M src/compiler/arm64/code-generator-arm64.cc
  M src/compiler/arm64/instruction-codes-arm64.h
  M src/compiler/arm64/instruction-selector-arm64.cc
  M test/unittests/compiler/arm64/instruction-selector-arm64-unittest.cc


Index: src/compiler/arm64/code-generator-arm64.cc
diff --git a/src/compiler/arm64/code-generator-arm64.cc b/src/compiler/arm64/code-generator-arm64.cc index 41d4c5458d2bcb0c622e51ae931d9c5ddd8c92bc..f48a7239e0f8085de3a5b39bddc204e11d2395a0 100644
--- a/src/compiler/arm64/code-generator-arm64.cc
+++ b/src/compiler/arm64/code-generator-arm64.cc
@@ -172,12 +172,10 @@ class Arm64OperandConverter FINAL : public InstructionOperandConverter {
   } while (0)


-#define ASSEMBLE_TEST_AND_BRANCH(asm_instr, width)           \
-  do {                                                       \
-    bool fallthrough = IsNextInAssemblyOrder(i.InputRpo(3)); \
-    __ asm_instr(i.InputRegister##width(0), i.InputInt6(1),  \
-                 GetLabel(i.InputRpo(2)));                   \
-    if (!fallthrough) __ B(GetLabel(i.InputRpo(3)));         \
+#define ASSEMBLE_BRANCH_TO(target)                    \
+  do {                                                \
+    bool fallthrough = IsNextInAssemblyOrder(target); \
+    if (!fallthrough) __ B(GetLabel(target));         \
   } while (0)


@@ -430,16 +428,28 @@ void CodeGenerator::AssembleArchInstruction(Instruction* instr) {
               i.InputInt8(2));
       break;
     case kArm64Tbz:
-      ASSEMBLE_TEST_AND_BRANCH(Tbz, 64);
+ __ Tbz(i.InputRegister64(0), i.InputInt6(1), GetLabel(i.InputRpo(2)));
+      ASSEMBLE_BRANCH_TO(i.InputRpo(3));
       break;
     case kArm64Tbz32:
-      ASSEMBLE_TEST_AND_BRANCH(Tbz, 32);
+ __ Tbz(i.InputRegister32(0), i.InputInt5(1), GetLabel(i.InputRpo(2)));
+      ASSEMBLE_BRANCH_TO(i.InputRpo(3));
       break;
     case kArm64Tbnz:
-      ASSEMBLE_TEST_AND_BRANCH(Tbnz, 64);
+ __ Tbnz(i.InputRegister64(0), i.InputInt6(1), GetLabel(i.InputRpo(2)));
+      ASSEMBLE_BRANCH_TO(i.InputRpo(3));
       break;
     case kArm64Tbnz32:
-      ASSEMBLE_TEST_AND_BRANCH(Tbnz, 32);
+ __ Tbnz(i.InputRegister32(0), i.InputInt5(1), GetLabel(i.InputRpo(2)));
+      ASSEMBLE_BRANCH_TO(i.InputRpo(3));
+      break;
+    case kArm64Cbz32:
+      __ Cbz(i.InputRegister32(0), GetLabel(i.InputRpo(1)));
+      ASSEMBLE_BRANCH_TO(i.InputRpo(2));
+      break;
+    case kArm64Cbnz32:
+      __ Cbnz(i.InputRegister32(0), GetLabel(i.InputRpo(1)));
+      ASSEMBLE_BRANCH_TO(i.InputRpo(2));
       break;
     case kArm64Claim: {
       int words = MiscField::decode(instr->opcode());
Index: src/compiler/arm64/instruction-codes-arm64.h
diff --git a/src/compiler/arm64/instruction-codes-arm64.h b/src/compiler/arm64/instruction-codes-arm64.h index f7af844267ade0a6f35f48d71d91dca333889eb2..a529ebfd69d5712474cbfd3414d5d92074a10fe7 100644
--- a/src/compiler/arm64/instruction-codes-arm64.h
+++ b/src/compiler/arm64/instruction-codes-arm64.h
@@ -72,6 +72,8 @@ namespace compiler {
   V(Arm64Tbz32)                    \
   V(Arm64Tbnz)                     \
   V(Arm64Tbnz32)                   \
+  V(Arm64Cbz32)                    \
+  V(Arm64Cbnz32)                   \
   V(Arm64Claim)                    \
   V(Arm64Poke)                     \
   V(Arm64PokePairZero)             \
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 151d1aa8b7eac05d1612c657a833c2e0695d0133..aba7eb0189e1bb960624f8f7a4e2ba47a505b222 100644
--- a/src/compiler/arm64/instruction-selector-arm64.cc
+++ b/src/compiler/arm64/instruction-selector-arm64.cc
@@ -1270,8 +1270,11 @@ void InstructionSelector::VisitBranch(Node* branch, BasicBlock* tbranch,
     }
   }

-  // Branch could not be combined with a compare, emit compare against 0.
-  VisitWord32Test(this, value, &cont);
+ // Branch could not be combined with a compare, compare against 0 and branch.
+  DCHECK((cont.condition() == kEqual) || (cont.condition() == kNotEqual));
+ ArchOpcode opcode = (cont.condition() == kEqual) ? kArm64Cbz32 : kArm64Cbnz32;
+  Emit(opcode, NULL, g.UseRegister(value), g.Label(cont.true_block()),
+       g.Label(cont.false_block()))->MarkAsControl();
 }


Index: test/unittests/compiler/arm64/instruction-selector-arm64-unittest.cc
diff --git a/test/unittests/compiler/arm64/instruction-selector-arm64-unittest.cc b/test/unittests/compiler/arm64/instruction-selector-arm64-unittest.cc index eee9c58b127ddac04e6439708f3af73c6d0c910d..2d127c448fbf223ce6eca98f3ee8be25e31d2438 100644
--- a/test/unittests/compiler/arm64/instruction-selector-arm64-unittest.cc
+++ b/test/unittests/compiler/arm64/instruction-selector-arm64-unittest.cc
@@ -952,6 +952,41 @@ TEST_F(InstructionSelectorTest, Word64AndBranchWithOneBitMaskOnLeft) {
 }


+TEST_F(InstructionSelectorTest, CompareAgainstZeroAndBranch) {
+  {
+    StreamBuilder m(this, kMachInt32, kMachInt32);
+    MLabel a, b;
+    Node* p0 = m.Parameter(0);
+    m.Branch(p0, &a, &b);
+    m.Bind(&a);
+    m.Return(m.Int32Constant(1));
+    m.Bind(&b);
+    m.Return(m.Int32Constant(0));
+    Stream s = m.Build();
+    ASSERT_EQ(1U, s.size());
+    EXPECT_EQ(kArm64Cbnz32, s[0]->arch_opcode());
+    EXPECT_EQ(3U, s[0]->InputCount());
+    EXPECT_EQ(s.ToVreg(p0), s.ToVreg(s[0]->InputAt(0)));
+  }
+
+  {
+    StreamBuilder m(this, kMachInt32, kMachInt32);
+    MLabel a, b;
+    Node* p0 = m.Parameter(0);
+    m.Branch(m.Word32BinaryNot(p0), &a, &b);
+    m.Bind(&a);
+    m.Return(m.Int32Constant(1));
+    m.Bind(&b);
+    m.Return(m.Int32Constant(0));
+    Stream s = m.Build();
+    ASSERT_EQ(1U, s.size());
+    EXPECT_EQ(kArm64Cbz32, s[0]->arch_opcode());
+    EXPECT_EQ(3U, s[0]->InputCount());
+    EXPECT_EQ(s.ToVreg(p0), s.ToVreg(s[0]->InputAt(0)));
+  }
+}
+
+
// -----------------------------------------------------------------------------
 // Add and subtract instructions with overflow.



--
--
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