From 422090017f3eddb2c33d57c3574920af189e07b0 Mon Sep 17 00:00:00 2001 From: JianxiaoLuIntel Date: Fri, 3 Feb 2023 14:50:53 +0800 Subject: [PATCH] [x64][codegen] Remove redundant cmp in BinarySearchSwitch Before: 1b6 cmpl r15,0xb 1ba jl 0x7f69801dd7d5 <+0x1d5> 1bc cmpl r15,0xb 1c0 jz 0x7f69801dd842 B200,201,202,203,204,205 <+0x242> 1b6 cmpl r15,0xb 1ba jl 0x7fa6a00a8591 <+0x1d1> 1bc jz 0x7fa6a00a85fa B200,201,202,203,204,205 <+0x23a> After: Change-Id: I820c9291638f27750cb77a0dcd5f1108c4ab8115 Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/4219940 Commit-Queue: Jianxiao Lu Reviewed-by: Nico Hartmann Cr-Commit-Position: refs/heads/main@{#85675} --- src/compiler/backend/code-generator.cc | 2 ++ src/compiler/backend/code-generator.h | 6 ++++ .../backend/x64/code-generator-x64.cc | 33 ++++++++++++++++++- 3 files changed, 40 insertions(+), 1 deletion(-) diff --git a/src/compiler/backend/code-generator.cc b/src/compiler/backend/code-generator.cc index 9f1f45b90c..ee75ca27bc 100644 --- a/src/compiler/backend/code-generator.cc +++ b/src/compiler/backend/code-generator.cc @@ -430,6 +430,7 @@ void CodeGenerator::AssembleCode() { result_ = kSuccess; } +#ifndef V8_TARGET_ARCH_X64 void CodeGenerator::AssembleArchBinarySearchSwitchRange( Register input, RpoNumber def_block, std::pair* begin, std::pair* end) { @@ -448,6 +449,7 @@ void CodeGenerator::AssembleArchBinarySearchSwitchRange( masm()->bind(&less_label); AssembleArchBinarySearchSwitchRange(input, def_block, begin, middle); } +#endif // V8_TARGET_ARCH_X64 void CodeGenerator::AssembleArchJump(RpoNumber target) { if (!IsNextInAssemblyOrder(target)) diff --git a/src/compiler/backend/code-generator.h b/src/compiler/backend/code-generator.h index f6feb42378..20cc045b11 100644 --- a/src/compiler/backend/code-generator.h +++ b/src/compiler/backend/code-generator.h @@ -278,9 +278,15 @@ class V8_EXPORT_PRIVATE CodeGenerator final : public GapResolver::Assembler { #if V8_ENABLE_WEBASSEMBLY void AssembleArchTrap(Instruction* instr, FlagsCondition condition); #endif // V8_ENABLE_WEBASSEMBLY +#if V8_TARGET_ARCH_X64 + void AssembleArchBinarySearchSwitchRange( + Register input, RpoNumber def_block, std::pair* begin, + std::pair* end, base::Optional& last_cmp_value); +#else void AssembleArchBinarySearchSwitchRange(Register input, RpoNumber def_block, std::pair* begin, std::pair* end); +#endif // V8_TARGET_ARCH_X64 void AssembleArchBinarySearchSwitch(Instruction* instr); void AssembleArchTableSwitch(Instruction* instr); diff --git a/src/compiler/backend/x64/code-generator-x64.cc b/src/compiler/backend/x64/code-generator-x64.cc index 42d846a97f..7924a6fe60 100644 --- a/src/compiler/backend/x64/code-generator-x64.cc +++ b/src/compiler/backend/x64/code-generator-x64.cc @@ -4,6 +4,7 @@ #include +#include "src/base/optional.h" #include "src/base/overflowing-math.h" #include "src/codegen/assembler.h" #include "src/codegen/cpu-features.h" @@ -4746,6 +4747,34 @@ void CodeGenerator::AssembleArchBoolean(Instruction* instr, __ bind(&done); } +void CodeGenerator::AssembleArchBinarySearchSwitchRange( + Register input, RpoNumber def_block, std::pair* begin, + std::pair* end, base::Optional& last_cmp_value) { + if (end - begin < kBinarySearchSwitchMinimalCases) { + if (last_cmp_value && *last_cmp_value == begin->first) { + // No need to do another repeat cmp. + masm()->j(equal, begin->second); + ++begin; + } + + while (begin != end) { + masm()->JumpIfEqual(input, begin->first, begin->second); + ++begin; + } + AssembleArchJumpRegardlessOfAssemblyOrder(def_block); + return; + } + auto middle = begin + (end - begin) / 2; + Label less_label; + masm()->JumpIfLessThan(input, middle->first, &less_label); + last_cmp_value = middle->first; + AssembleArchBinarySearchSwitchRange(input, def_block, middle, end, + last_cmp_value); + masm()->bind(&less_label); + AssembleArchBinarySearchSwitchRange(input, def_block, begin, middle, + last_cmp_value); +} + void CodeGenerator::AssembleArchBinarySearchSwitch(Instruction* instr) { X64OperandConverter i(this, instr); Register input = i.InputRegister(0); @@ -4753,8 +4782,10 @@ void CodeGenerator::AssembleArchBinarySearchSwitch(Instruction* instr) { for (size_t index = 2; index < instr->InputCount(); index += 2) { cases.push_back({i.InputInt32(index + 0), GetLabel(i.InputRpo(index + 1))}); } + base::Optional last_cmp_value; AssembleArchBinarySearchSwitchRange(input, i.InputRpo(1), cases.data(), - cases.data() + cases.size()); + cases.data() + cases.size(), + last_cmp_value); } void CodeGenerator::AssembleArchTableSwitch(Instruction* instr) {