mirror of
https://github.com/luau-lang/luau.git
synced 2025-05-04 10:33:46 +01:00
Reimplement vector literals in built-in folding (requires optimization level 2)
This commit is contained in:
parent
75afd7747e
commit
83d4de36e0
5 changed files with 32 additions and 35 deletions
|
@ -54,7 +54,7 @@ public:
|
||||||
int32_t addConstantNil();
|
int32_t addConstantNil();
|
||||||
int32_t addConstantBoolean(bool value);
|
int32_t addConstantBoolean(bool value);
|
||||||
int32_t addConstantNumber(double 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 addConstantString(StringRef value);
|
||||||
int32_t addImport(uint32_t iid);
|
int32_t addImport(uint32_t iid);
|
||||||
int32_t addConstantTable(const TableShape& shape);
|
int32_t addConstantTable(const TableShape& shape);
|
||||||
|
|
|
@ -32,6 +32,15 @@ static Constant cnum(double v)
|
||||||
return res;
|
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)
|
static Constant cstring(const char* v)
|
||||||
{
|
{
|
||||||
Constant res = {Constant::Type_String};
|
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)
|
if (count == 1 && args[0].type == Constant::Type_Number)
|
||||||
return cnum(round(args[0].valueNumber));
|
return cnum(round(args[0].valueNumber));
|
||||||
break;
|
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();
|
return cvar();
|
||||||
|
|
|
@ -354,22 +354,18 @@ int32_t BytecodeBuilder::addConstantNumber(double value)
|
||||||
return addConstant(k, c);
|
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};
|
Constant c = {Constant::Type_Vector};
|
||||||
c.valueVector[0] = fx;
|
c.valueVector[0] = x;
|
||||||
c.valueVector[1] = fy;
|
c.valueVector[1] = y;
|
||||||
c.valueVector[2] = fz;
|
c.valueVector[2] = z;
|
||||||
|
|
||||||
ConstantKey k = {Constant::Type_Vector};
|
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");
|
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, &fx, sizeof(fx));
|
memcpy(&k.value, &x, sizeof(x));
|
||||||
memcpy((char*)&k.value + sizeof(fx), &fy, sizeof(fy));
|
memcpy((char*)&k.value + sizeof(x), &y, sizeof(y));
|
||||||
memcpy(&k.extra, &fz, sizeof(fz));
|
memcpy(&k.extra, &z, sizeof(z));
|
||||||
|
|
||||||
return addConstant(k, c);
|
return addConstant(k, c);
|
||||||
}
|
}
|
||||||
|
|
|
@ -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)
|
if (expr->self)
|
||||||
{
|
{
|
||||||
AstExprIndexName* fi = expr->func->as<AstExprIndexName>();
|
AstExprIndexName* fi = expr->func->as<AstExprIndexName>();
|
||||||
|
@ -2085,6 +2063,13 @@ struct Compiler
|
||||||
}
|
}
|
||||||
break;
|
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:
|
case Constant::Type_String:
|
||||||
{
|
{
|
||||||
int32_t cid = bytecode.addConstantString(sref(cv->getString()));
|
int32_t cid = bytecode.addConstantString(sref(cv->getString()));
|
||||||
|
|
|
@ -16,6 +16,7 @@ struct Constant
|
||||||
Type_Nil,
|
Type_Nil,
|
||||||
Type_Boolean,
|
Type_Boolean,
|
||||||
Type_Number,
|
Type_Number,
|
||||||
|
Type_Vector,
|
||||||
Type_String,
|
Type_String,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -26,6 +27,7 @@ struct Constant
|
||||||
{
|
{
|
||||||
bool valueBoolean;
|
bool valueBoolean;
|
||||||
double valueNumber;
|
double valueNumber;
|
||||||
|
float valueVector[3];
|
||||||
const char* valueString = nullptr; // length stored in stringLength
|
const char* valueString = nullptr; // length stored in stringLength
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
Loading…
Add table
Reference in a new issue