Skip to content

Commit

Permalink
perf: Optimize tail calls
Browse files Browse the repository at this point in the history
  • Loading branch information
mrunix00 committed Apr 25, 2024
1 parent f509e02 commit 016cfdf
Show file tree
Hide file tree
Showing 4 changed files with 11 additions and 17 deletions.
1 change: 1 addition & 0 deletions src/bytecode/compiler/Instruction.h
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ namespace Bytecode {
Not,
Call,
CallLambda,
TailCall,
CondJumpIfNot,
Jump,
StoreGlobal,
Expand Down
19 changes: 2 additions & 17 deletions src/bytecode/compiler/Optimizer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -11,26 +11,11 @@ void Bytecode::Optimizer::optimize_tail_calls(Segment &segment) {
auto &instructions = segment.instructions;
const size_t number_of_args = instructions[instructions.size() - 2]
->params.ri_params.intermediate.data.reg;
const size_t old_number_of_instructions = instructions.size() - 1;
instructions.pop_back();// Remove the Return instruction
instructions.pop_back();// Remove the Call instruction
for (size_t i = number_of_args - 1; i != -1; i--)
instructions.push_back(new (Instruction) {
Instruction::StoreLocal,
{.r_param = {i}},
});
instructions.push_back(new (Instruction){
Instruction::Jump,
{.r_param = {0}},
Instruction::TailCall,
{.r_param = {number_of_args}},
});
instructions.push_back(new (Instruction){Instruction::Return});

// Update jump locations
for (auto &instruction: instructions) {
if ((instruction->type == Instruction::Jump ||
instruction->type == Instruction::CondJumpIfNot) &&
instruction->params.r_param.reg == old_number_of_instructions) {
instruction->params.r_param.reg = instructions.size() - 1;
}
}
}
5 changes: 5 additions & 0 deletions src/bytecode/vm/Interpreter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -252,6 +252,11 @@ void Bytecode::Interpreter::execute(const Program &program) {
currentInstruction->params.r_param.reg,
&vm.program_stack);
} break;
case Instruction::TailCall: {
for (size_t i = currentInstruction->params.r_param.reg; i != 0; i--)
vm.call_stack.setLocal(i - 1, vm.program_stack.pop());
vm.call_stack.stackTop->current_line = -1;
} break;
case Instruction::Return:
vm.call_stack.popStackFrame();
break;
Expand Down
3 changes: 3 additions & 0 deletions src/utils/dump_bytecode.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -89,6 +89,9 @@ void print_instruction(const Bytecode::Instruction &instruction) {
case Bytecode::Instruction::CallLambda:
std::cout << "CallLambda :" << instruction.params.r_param.reg << '\n';
break;
case Bytecode::Instruction::TailCall:
std::cout << "TailCall " << instruction.params.r_param.reg << '\n';
break;
case Bytecode::Instruction::CondJumpIfNot:
std::cout << "CondJumpIfNot :" << instruction.params.r_param.reg << '\n';
break;
Expand Down

0 comments on commit 016cfdf

Please sign in to comment.