diff --git a/Compiler/include/Luau/BytecodeBuilder.h b/Compiler/include/Luau/BytecodeBuilder.h index 88ecd132..620f9e21 100644 --- a/Compiler/include/Luau/BytecodeBuilder.h +++ b/Compiler/include/Luau/BytecodeBuilder.h @@ -54,7 +54,7 @@ public: int32_t addConstantNil(); int32_t addConstantBoolean(bool value); int32_t addConstantNumber(double value); - int32_t addConstantVector(double x, double y, double z); + int32_t addConstantVector(float x, float y, float z); int32_t addConstantString(StringRef value); int32_t addImport(uint32_t iid); int32_t addConstantTable(const TableShape& shape); diff --git a/Compiler/src/BuiltinFolding.cpp b/Compiler/src/BuiltinFolding.cpp index 8fa4b7c7..f5edf4fb 100644 --- a/Compiler/src/BuiltinFolding.cpp +++ b/Compiler/src/BuiltinFolding.cpp @@ -32,6 +32,15 @@ static Constant cnum(double v) return res; } +static Constant cvector(double x, double y, double z) +{ + Constant res = {Constant::Type_Vector}; + res.valueVector[0] = (float)x; + res.valueVector[1] = (float)y; + res.valueVector[2] = (float)z; + return res; +} + static Constant cstring(const char* v) { Constant res = {Constant::Type_String}; @@ -456,6 +465,11 @@ Constant foldBuiltin(int bfid, const Constant* args, size_t count) if (count == 1 && args[0].type == Constant::Type_Number) return cnum(round(args[0].valueNumber)); break; + + case LBF_VECTOR: + if (count == 3 && args[0].type == Constant::Type_Number && args[1].type == Constant::Type_Number && args[2].type == Constant::Type_Number) + return cvector(args[0].valueNumber, args[1].valueNumber, args[2].valueNumber); + break; } return cvar(); diff --git a/Compiler/src/BytecodeBuilder.cpp b/Compiler/src/BytecodeBuilder.cpp index 5ec42181..de5f2658 100644 --- a/Compiler/src/BytecodeBuilder.cpp +++ b/Compiler/src/BytecodeBuilder.cpp @@ -354,22 +354,18 @@ int32_t BytecodeBuilder::addConstantNumber(double value) return addConstant(k, c); } -int32_t BytecodeBuilder::addConstantVector(double x, double y, double z) +int32_t BytecodeBuilder::addConstantVector(float x, float y, float z) { - float fx = (float)x; - float fy = (float)y; - float fz = (float)z; - Constant c = {Constant::Type_Vector}; - c.valueVector[0] = fx; - c.valueVector[1] = fy; - c.valueVector[2] = fz; + c.valueVector[0] = x; + c.valueVector[1] = y; + c.valueVector[2] = z; ConstantKey k = {Constant::Type_Vector}; - static_assert(sizeof(k.value) == sizeof(fx) + sizeof(fy) && sizeof(k.extra) == sizeof(fz), "Expecting vector to have three 32-bit components"); - memcpy(&k.value, &fx, sizeof(fx)); - memcpy((char*)&k.value + sizeof(fx), &fy, sizeof(fy)); - memcpy(&k.extra, &fz, sizeof(fz)); + static_assert(sizeof(k.value) == sizeof(x) + sizeof(y) && sizeof(k.extra) == sizeof(z), "Expecting vector to have three 32-bit components"); + memcpy(&k.value, &x, sizeof(x)); + memcpy((char*)&k.value + sizeof(x), &y, sizeof(y)); + memcpy(&k.extra, &z, sizeof(z)); return addConstant(k, c); } diff --git a/Compiler/src/Compiler.cpp b/Compiler/src/Compiler.cpp index 7859b618..de6d32d3 100644 --- a/Compiler/src/Compiler.cpp +++ b/Compiler/src/Compiler.cpp @@ -816,28 +816,6 @@ struct Compiler } } - // Optimization: replace vector constructor calls with constant loads when all arguments are numbers - if (bfid == LBF_VECTOR && expr->args.size == 3 && targetCount == 1 && isConstant(expr->args.data[0]) && isConstant(expr->args.data[1]) && isConstant(expr->args.data[2])) - { - Constant cx = getConstant(expr->args.data[0]); - Constant cy = getConstant(expr->args.data[1]); - Constant cz = getConstant(expr->args.data[2]); - - if (cx.type == Constant::Type_Number && cy.type == Constant::Type_Number && cz.type == Constant::Type_Number) - { - double x = cx.valueNumber; - double y = cy.valueNumber; - double z = cz.valueNumber; - - int32_t cid = bytecode.addConstantVector(x, y, z); - if (cid < 0) - CompileError::raise(expr->location, "Exceeded constant limit; simplify the code to compile"); - - emitLoadK(target, cid); - return; - } - } - if (expr->self) { AstExprIndexName* fi = expr->func->as(); @@ -2085,6 +2063,13 @@ struct Compiler } break; + case Constant::Type_Vector: + { + int32_t cid = bytecode.addConstantVector(cv->valueVector[0], cv->valueVector[1], cv->valueVector[2]); + emitLoadK(target, cid); + } + break; + case Constant::Type_String: { int32_t cid = bytecode.addConstantString(sref(cv->getString())); diff --git a/Compiler/src/ConstantFolding.h b/Compiler/src/ConstantFolding.h index f0798ea2..02f9eb23 100644 --- a/Compiler/src/ConstantFolding.h +++ b/Compiler/src/ConstantFolding.h @@ -16,6 +16,7 @@ struct Constant Type_Nil, Type_Boolean, Type_Number, + Type_Vector, Type_String, }; @@ -26,6 +27,7 @@ struct Constant { bool valueBoolean; double valueNumber; + float valueVector[3]; const char* valueString = nullptr; // length stored in stringLength };