[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:
parent
7e43e0bee3
commit
422090017f
@ -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))
|
||||
|
@ -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);
|
||||
|
||||
|
@ -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) {
|
||||
|
Loading…
Reference in New Issue
Block a user