Reimplement vector literals in built-in folding (requires optimization level 2)

This commit is contained in:
Petri Häkkinen 2023-11-09 12:45:35 +02:00
parent 75afd7747e
commit 83d4de36e0
5 changed files with 32 additions and 35 deletions

View file

@ -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);

View file

@ -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();

View file

@ -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);
}

View file

@ -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<AstExprIndexName>();
@ -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()));

View file

@ -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
};