mirror of
https://github.com/luau-lang/luau.git
synced 2024-11-15 14:25:44 +08:00
CodeGen: Preserve known tags for LOAD_TVALUE synthesized from LOADK (#1201)
When lowering LOADK for booleans/numbers/nils, we deconstruct the operation using STORE_TAG which informs the rest of the optimization pipeline about the tag of the value. This is helpful to remove various tag checks. When the constant is a string or a vector, we just use LOAD_TVALUE/STORE_TVALUE. For strings, this could be replaced by pointer load/store, but for vectors there's no great alternative using current IR ops; in either case, the optimization needs to be carefully examined for profitability as simply copying constants into registers for function calls could become more expensive. However, there are cases where it's still valuable to preserve the tag. For vectors, doing any math with vector constants contains tag checks that could be removed. For both strings and vectors, storing them into a table has a barrier that for vectors could be elided, and for strings could be simplified as there's no need to confirm the tag. With this change we now carry the optional tag of the value with LOAD_TVALUE. This has no performance effect on existing benchmarks but does reduce the generated code for benchmarks by ~0.1%, and it makes vector code more efficient (~5% lift on X64 log1p approximation).
This commit is contained in:
parent
d2ed2150ca
commit
a7683110d7
@ -59,7 +59,8 @@ enum class IrCmd : uint8_t
|
||||
|
||||
// Load a TValue from memory
|
||||
// A: Rn or Kn or pointer (TValue)
|
||||
// B: int (optional 'A' pointer offset)
|
||||
// B: int/none (optional 'A' pointer offset)
|
||||
// C: tag/none (tag of the value being loaded)
|
||||
LOAD_TVALUE,
|
||||
|
||||
// Load current environment table
|
||||
|
@ -14,6 +14,7 @@
|
||||
|
||||
LUAU_FASTFLAGVARIABLE(LuauCodegenVectorTag2, false)
|
||||
LUAU_FASTFLAGVARIABLE(LuauCodegenVectorTag, false)
|
||||
LUAU_FASTFLAGVARIABLE(LuauCodegenLoadTVTag, false)
|
||||
|
||||
namespace Luau
|
||||
{
|
||||
@ -111,6 +112,13 @@ static void translateInstLoadConstant(IrBuilder& build, int ra, int k)
|
||||
build.inst(IrCmd::STORE_DOUBLE, build.vmReg(ra), build.constDouble(protok.value.n));
|
||||
build.inst(IrCmd::STORE_TAG, build.vmReg(ra), build.constTag(LUA_TNUMBER));
|
||||
}
|
||||
else if (FFlag::LuauCodegenLoadTVTag)
|
||||
{
|
||||
// Tag could be LUA_TSTRING or LUA_TVECTOR; for TSTRING we could generate LOAD_POINTER/STORE_POINTER/STORE_TAG, but it's not profitable;
|
||||
// however, it's still valuable to preserve the tag throughout the optimization pipeline to eliminate tag checks.
|
||||
IrOp load = build.inst(IrCmd::LOAD_TVALUE, build.vmConst(k), build.constInt(0), build.constTag(protok.tt));
|
||||
build.inst(IrCmd::STORE_TVALUE, build.vmReg(ra), load);
|
||||
}
|
||||
else
|
||||
{
|
||||
// Remaining tag here right now is LUA_TSTRING, while it can be transformed to LOAD_POINTER/STORE_POINTER/STORE_TAG, it's not profitable right
|
||||
|
@ -19,6 +19,7 @@ LUAU_FASTINTVARIABLE(LuauCodeGenReuseSlotLimit, 64)
|
||||
LUAU_FASTFLAGVARIABLE(DebugLuauAbortingChecks, false)
|
||||
LUAU_FASTFLAG(LuauCodegenVectorTag2)
|
||||
LUAU_DYNAMIC_FASTFLAGVARIABLE(LuauCodeGenCoverForgprepEffect, false)
|
||||
LUAU_FASTFLAG(LuauCodegenLoadTVTag)
|
||||
|
||||
namespace Luau
|
||||
{
|
||||
@ -726,6 +727,9 @@ static void constPropInInst(ConstPropState& state, IrBuilder& build, IrFunction&
|
||||
arg->cmd == IrCmd::UNM_VEC)
|
||||
tag = LUA_TVECTOR;
|
||||
}
|
||||
|
||||
if (FFlag::LuauCodegenLoadTVTag && arg->cmd == IrCmd::LOAD_TVALUE && arg->c.kind != IrOpKind::None)
|
||||
tag = function.tagOp(arg->c);
|
||||
}
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user