mirror of
https://github.com/LadybirdBrowser/ladybird.git
synced 2024-08-17 01:10:28 +03:00
LibJS/Bytecode: Rewrite Jump-to-Return-or-End as just Return or End
Instead of wasting time jumping to a shared Return or End instruction, we can also emit a Return or End directly in many cases.
This commit is contained in:
parent
7971cfdd89
commit
044539c60b
Notes:
sideshowbarker
2024-07-17 04:34:25 +09:00
Author: https://github.com/awesomekling Commit: https://github.com/SerenityOS/serenity/commit/044539c60b Pull-request: https://github.com/SerenityOS/serenity/pull/24524
@ -340,9 +340,10 @@ CodeGenerationErrorOr<NonnullGCPtr<Executable>> Generator::compile(VM& vm, ASTNo
|
||||
while (!it.at_end()) {
|
||||
auto& instruction = const_cast<Instruction&>(*it);
|
||||
|
||||
// OPTIMIZATION: Don't emit jumps that just jump to the next block.
|
||||
if (instruction.type() == Instruction::Type::Jump) {
|
||||
auto& jump = static_cast<Bytecode::Op::Jump&>(instruction);
|
||||
|
||||
// OPTIMIZATION: Don't emit jumps that just jump to the next block.
|
||||
if (jump.target().basic_block_index() == block->index() + 1) {
|
||||
if (basic_block_start_offsets.last() == bytecode.size()) {
|
||||
// This block is empty, just skip it.
|
||||
@ -351,6 +352,29 @@ CodeGenerationErrorOr<NonnullGCPtr<Executable>> Generator::compile(VM& vm, ASTNo
|
||||
++it;
|
||||
continue;
|
||||
}
|
||||
|
||||
// OPTIMIZATION: For jumps to a return-or-end-only block, we can emit a `Return` or `End` directly instead.
|
||||
auto& target_block = *generator.m_root_basic_blocks[jump.target().basic_block_index()];
|
||||
if (target_block.is_terminated()) {
|
||||
auto target_instruction_iterator = InstructionStreamIterator { target_block.instruction_stream() };
|
||||
auto& target_instruction = *target_instruction_iterator;
|
||||
|
||||
if (target_instruction.type() == Instruction::Type::Return) {
|
||||
auto& return_instruction = static_cast<Bytecode::Op::Return const&>(target_instruction);
|
||||
Op::Return return_op(return_instruction.value());
|
||||
bytecode.append(reinterpret_cast<u8 const*>(&return_op), return_op.length());
|
||||
++it;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (target_instruction.type() == Instruction::Type::End) {
|
||||
auto& return_instruction = static_cast<Bytecode::Op::End const&>(target_instruction);
|
||||
Op::End end_op(return_instruction.value());
|
||||
bytecode.append(reinterpret_cast<u8 const*>(&end_op), end_op.length());
|
||||
++it;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// OPTIMIZATION: For `JumpIf` where one of the targets is the very next block,
|
||||
|
Loading…
Reference in New Issue
Block a user