| 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 da27be8626acbc43b653c36b541388a76e5bc5f7..be56d5cc81c37bffafeb04150b75e3636e41cae5 100644
|
| --- a/src/compiler/arm64/instruction-selector-arm64.cc
|
| +++ b/src/compiler/arm64/instruction-selector-arm64.cc
|
| @@ -2152,6 +2152,20 @@ FlagsCondition MapForCbz(FlagsCondition cond) {
|
| }
|
| }
|
|
|
| +void EmitBranchOrDeoptimize(InstructionSelector* selector,
|
| + InstructionCode opcode, InstructionOperand value,
|
| + FlagsContinuation* cont) {
|
| + Arm64OperandGenerator g(selector);
|
| + if (cont->IsBranch()) {
|
| + selector->Emit(cont->Encode(opcode), g.NoOutput(), value,
|
| + g.Label(cont->true_block()), g.Label(cont->false_block()));
|
| + } else {
|
| + DCHECK(cont->IsDeoptimize());
|
| + selector->EmitDeoptimize(cont->Encode(opcode), g.NoOutput(), value,
|
| + cont->reason(), cont->frame_state());
|
| + }
|
| +}
|
| +
|
| // Try to emit TBZ, TBNZ, CBZ or CBNZ for certain comparisons of {node}
|
| // against zero, depending on the condition.
|
| bool TryEmitCbzOrTbz(InstructionSelector* selector, Node* node, Node* user,
|
| @@ -2160,12 +2174,16 @@ bool TryEmitCbzOrTbz(InstructionSelector* selector, Node* node, Node* user,
|
| USE(m_user);
|
| DCHECK(m_user.right().Is(0) || m_user.left().Is(0));
|
|
|
| - // Only handle branches.
|
| - if (!cont->IsBranch()) return false;
|
| + // Only handle branches and deoptimisations.
|
| + if (!cont->IsBranch() && !cont->IsDeoptimize()) return false;
|
|
|
| switch (cond) {
|
| case kSignedLessThan:
|
| case kSignedGreaterThanOrEqual: {
|
| + // We don't generate TBZ/TBNZ for deoptimisations, as they have a
|
| + // shorter range than conditional branches and generating them for
|
| + // deoptimisations results in more veneers.
|
| + if (cont->IsDeoptimize()) return false;
|
| Arm64OperandGenerator g(selector);
|
| cont->Overwrite(MapForTbz(cond));
|
| Int32Matcher m(node);
|
| @@ -2192,9 +2210,8 @@ bool TryEmitCbzOrTbz(InstructionSelector* selector, Node* node, Node* user,
|
| case kUnsignedGreaterThan: {
|
| Arm64OperandGenerator g(selector);
|
| cont->Overwrite(MapForCbz(cond));
|
| - selector->Emit(cont->Encode(kArm64CompareAndBranch32), g.NoOutput(),
|
| - g.UseRegister(node), g.Label(cont->true_block()),
|
| - g.Label(cont->false_block()));
|
| + EmitBranchOrDeoptimize(selector, kArm64CompareAndBranch32,
|
| + g.UseRegister(node), cont);
|
| return true;
|
| }
|
| default:
|
| @@ -2380,10 +2397,10 @@ void VisitWordCompareZero(InstructionSelector* selector, Node* user,
|
| kLogical64Imm);
|
| }
|
| // Merge the Word64Equal(x, 0) comparison into a cbz instruction.
|
| - if (cont->IsBranch()) {
|
| - selector->Emit(cont->Encode(kArm64CompareAndBranch), g.NoOutput(),
|
| - g.UseRegister(left), g.Label(cont->true_block()),
|
| - g.Label(cont->false_block()));
|
| + if (cont->IsBranch() || cont->IsDeoptimize()) {
|
| + EmitBranchOrDeoptimize(selector,
|
| + cont->Encode(kArm64CompareAndBranch),
|
| + g.UseRegister(left), cont);
|
| return;
|
| }
|
| }
|
|
|