Skip to content

Commit

Permalink
CodeGen: Preserve known tags for LOAD_TVALUE synthesized from LOADK (#…
Browse files Browse the repository at this point in the history
…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).
  • Loading branch information
zeux authored Mar 15, 2024
1 parent d2ed215 commit a768311
Show file tree
Hide file tree
Showing 3 changed files with 14 additions and 1 deletion.
3 changes: 2 additions & 1 deletion CodeGen/include/Luau/IrData.h
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
8 changes: 8 additions & 0 deletions CodeGen/src/IrTranslation.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@

LUAU_FASTFLAGVARIABLE(LuauCodegenVectorTag2, false)
LUAU_FASTFLAGVARIABLE(LuauCodegenVectorTag, false)
LUAU_FASTFLAGVARIABLE(LuauCodegenLoadTVTag, false)

namespace Luau
{
Expand Down Expand Up @@ -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
Expand Down
4 changes: 4 additions & 0 deletions CodeGen/src/OptimizeConstProp.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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
{
Expand Down Expand Up @@ -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);
}
}

Expand Down

0 comments on commit a768311

Please sign in to comment.