[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 <jianxiao.lu@intel.com>
Reviewed-by: Nico Hartmann <nicohartmann@chromium.org>
Cr-Commit-Position: refs/heads/main@{#85675}
This commit is contained in:
JianxiaoLuIntel 2023-02-03 14:50:53 +08:00 committed by V8 LUCI CQ
parent 7e43e0bee3
commit 422090017f
3 changed files with 40 additions and 1 deletions

View File

@ -430,6 +430,7 @@ void CodeGenerator::AssembleCode() {
result_ = kSuccess;
}
#ifndef V8_TARGET_ARCH_X64
void CodeGenerator::AssembleArchBinarySearchSwitchRange(
Register input, RpoNumber def_block, std::pair<int32_t, Label*>* begin,
std::pair<int32_t, Label*>* 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))

View File

@ -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<int32_t, Label*>* begin,
std::pair<int32_t, Label*>* end, base::Optional<int32_t>& last_cmp_value);
#else
void AssembleArchBinarySearchSwitchRange(Register input, RpoNumber def_block,
std::pair<int32_t, Label*>* begin,
std::pair<int32_t, Label*>* end);
#endif // V8_TARGET_ARCH_X64
void AssembleArchBinarySearchSwitch(Instruction* instr);
void AssembleArchTableSwitch(Instruction* instr);

View File

@ -4,6 +4,7 @@
#include <limits>
#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<int32_t, Label*>* begin,
std::pair<int32_t, Label*>* end, base::Optional<int32_t>& 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<int32_t> 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) {