2023-01-20 20:27:03 +00:00
|
|
|
// This file is part of the Luau programming language and is licensed under MIT License; see LICENSE.txt for details
|
|
|
|
#pragma once
|
|
|
|
|
|
|
|
#include <stdint.h>
|
|
|
|
|
|
|
|
#include "ltm.h"
|
|
|
|
|
|
|
|
typedef uint32_t Instruction;
|
|
|
|
|
|
|
|
namespace Luau
|
|
|
|
{
|
|
|
|
namespace CodeGen
|
|
|
|
{
|
|
|
|
|
|
|
|
enum class IrCondition : uint8_t;
|
|
|
|
struct IrOp;
|
|
|
|
struct IrBuilder;
|
2023-02-24 21:49:38 +00:00
|
|
|
enum class IrCmd : uint8_t;
|
2023-01-20 20:27:03 +00:00
|
|
|
|
|
|
|
void translateInstLoadNil(IrBuilder& build, const Instruction* pc);
|
|
|
|
void translateInstLoadB(IrBuilder& build, const Instruction* pc, int pcpos);
|
|
|
|
void translateInstLoadN(IrBuilder& build, const Instruction* pc);
|
|
|
|
void translateInstLoadK(IrBuilder& build, const Instruction* pc);
|
|
|
|
void translateInstLoadKX(IrBuilder& build, const Instruction* pc);
|
|
|
|
void translateInstMove(IrBuilder& build, const Instruction* pc);
|
|
|
|
void translateInstJump(IrBuilder& build, const Instruction* pc, int pcpos);
|
|
|
|
void translateInstJumpBack(IrBuilder& build, const Instruction* pc, int pcpos);
|
|
|
|
void translateInstJumpIf(IrBuilder& build, const Instruction* pc, int pcpos, bool not_);
|
|
|
|
void translateInstJumpIfEq(IrBuilder& build, const Instruction* pc, int pcpos, bool not_);
|
|
|
|
void translateInstJumpIfCond(IrBuilder& build, const Instruction* pc, int pcpos, IrCondition cond);
|
|
|
|
void translateInstJumpX(IrBuilder& build, const Instruction* pc, int pcpos);
|
|
|
|
void translateInstJumpxEqNil(IrBuilder& build, const Instruction* pc, int pcpos);
|
|
|
|
void translateInstJumpxEqB(IrBuilder& build, const Instruction* pc, int pcpos);
|
|
|
|
void translateInstJumpxEqN(IrBuilder& build, const Instruction* pc, int pcpos);
|
|
|
|
void translateInstJumpxEqS(IrBuilder& build, const Instruction* pc, int pcpos);
|
|
|
|
void translateInstBinary(IrBuilder& build, const Instruction* pc, int pcpos, TMS tm);
|
|
|
|
void translateInstBinaryK(IrBuilder& build, const Instruction* pc, int pcpos, TMS tm);
|
Add SUBRK and DIVRK bytecode instructions to bytecode v5 (#1115)
Right now, we can compile R\*K for all arithmetic instructions, but K\*R
gets compiled into two instructions (LOADN/LOADK + arithmetic opcode).
This is problematic since it leads to reduced performance for some code.
However, we'd like to avoid adding reverse variants of ADDK et al for
all opcodes to avoid the increase in I$ footprint for interpreter.
Looking at the arithmetic instructions, % and // don't have interesting
use cases for K\*V; ^ is sometimes used with constant on the left hand
side but this would need to call pow() by necessity in all cases so it
would be slow regardless of the dispatch overhead. This leaves the four
basic arithmetic operations.
For + and \*, we can implement a compiler-side optimization in the
future that transforms K\*R to R\*K automatically. This could either be
done unconditionally at -O2, or conditionally based on the type of the
value (driven by type annotations / inference) -- this technically
changes behavior in presence of metamethods, although it might be
sensible to just always do this because non-commutative +/* are evil.
However, for - and / it is impossible for the compiler to optimize this
in the future, so we need dedicated opcodes. This only increases the
interpreter size by ~300 bytes (~1.5%) on X64.
This makes spectral-norm and math-partial-sums 6% faster; maybe more
importantly, voxelgen gets 1.5% faster (so this change does have
real-world impact).
To avoid the proliferation of bytecode versions this change piggybacks
on the bytecode version bump that was just made in 604 for vector
constants; we would still be able to enable these independently but
we'll consider v5 complete when both are enabled.
Related: #626
---------
Co-authored-by: vegorov-rbx <75688451+vegorov-rbx@users.noreply.github.com>
2023-11-28 15:35:01 +00:00
|
|
|
void translateInstBinaryRK(IrBuilder& build, const Instruction* pc, int pcpos, TMS tm);
|
2023-01-20 20:27:03 +00:00
|
|
|
void translateInstNot(IrBuilder& build, const Instruction* pc);
|
|
|
|
void translateInstMinus(IrBuilder& build, const Instruction* pc, int pcpos);
|
|
|
|
void translateInstLength(IrBuilder& build, const Instruction* pc, int pcpos);
|
|
|
|
void translateInstNewTable(IrBuilder& build, const Instruction* pc, int pcpos);
|
|
|
|
void translateInstDupTable(IrBuilder& build, const Instruction* pc, int pcpos);
|
|
|
|
void translateInstGetUpval(IrBuilder& build, const Instruction* pc, int pcpos);
|
|
|
|
void translateInstSetUpval(IrBuilder& build, const Instruction* pc, int pcpos);
|
|
|
|
void translateInstCloseUpvals(IrBuilder& build, const Instruction* pc);
|
2024-06-21 00:37:55 +01:00
|
|
|
IrOp translateFastCallN(
|
2024-08-02 15:30:04 +01:00
|
|
|
IrBuilder& build,
|
|
|
|
const Instruction* pc,
|
|
|
|
int pcpos,
|
|
|
|
bool customParams,
|
|
|
|
int customParamCount,
|
|
|
|
IrOp customArgs,
|
|
|
|
IrOp customArg3
|
|
|
|
);
|
2023-02-10 19:40:38 +00:00
|
|
|
void translateInstForNPrep(IrBuilder& build, const Instruction* pc, int pcpos);
|
|
|
|
void translateInstForNLoop(IrBuilder& build, const Instruction* pc, int pcpos);
|
|
|
|
void translateInstForGPrepNext(IrBuilder& build, const Instruction* pc, int pcpos);
|
|
|
|
void translateInstForGPrepInext(IrBuilder& build, const Instruction* pc, int pcpos);
|
|
|
|
void translateInstForGLoopIpairs(IrBuilder& build, const Instruction* pc, int pcpos);
|
2023-01-20 20:27:03 +00:00
|
|
|
void translateInstGetTableN(IrBuilder& build, const Instruction* pc, int pcpos);
|
|
|
|
void translateInstSetTableN(IrBuilder& build, const Instruction* pc, int pcpos);
|
|
|
|
void translateInstGetTable(IrBuilder& build, const Instruction* pc, int pcpos);
|
|
|
|
void translateInstSetTable(IrBuilder& build, const Instruction* pc, int pcpos);
|
|
|
|
void translateInstGetImport(IrBuilder& build, const Instruction* pc, int pcpos);
|
|
|
|
void translateInstGetTableKS(IrBuilder& build, const Instruction* pc, int pcpos);
|
|
|
|
void translateInstSetTableKS(IrBuilder& build, const Instruction* pc, int pcpos);
|
|
|
|
void translateInstGetGlobal(IrBuilder& build, const Instruction* pc, int pcpos);
|
|
|
|
void translateInstSetGlobal(IrBuilder& build, const Instruction* pc, int pcpos);
|
|
|
|
void translateInstConcat(IrBuilder& build, const Instruction* pc, int pcpos);
|
|
|
|
void translateInstCapture(IrBuilder& build, const Instruction* pc, int pcpos);
|
2024-05-10 19:21:45 +01:00
|
|
|
bool translateInstNamecall(IrBuilder& build, const Instruction* pc, int pcpos);
|
2023-04-07 22:01:29 +01:00
|
|
|
void translateInstAndX(IrBuilder& build, const Instruction* pc, int pcpos, IrOp c);
|
|
|
|
void translateInstOrX(IrBuilder& build, const Instruction* pc, int pcpos, IrOp c);
|
2023-07-28 16:13:53 +01:00
|
|
|
void translateInstNewClosure(IrBuilder& build, const Instruction* pc, int pcpos);
|
2023-01-20 20:27:03 +00:00
|
|
|
|
2023-12-02 07:46:57 +00:00
|
|
|
void beforeInstForNPrep(IrBuilder& build, const Instruction* pc, int pcpos);
|
2023-10-06 20:02:32 +01:00
|
|
|
void afterInstForNLoop(IrBuilder& build, const Instruction* pc);
|
|
|
|
|
2023-01-20 20:27:03 +00:00
|
|
|
} // namespace CodeGen
|
|
|
|
} // namespace Luau
|