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.