-Ovector-components

This commit is contained in:
Wolfgang Bumiller 2012-12-29 15:05:04 +01:00
parent c0eca32b92
commit 73bc4cc3e4
4 changed files with 83 additions and 4 deletions

2
ast.c
View file

@ -2089,7 +2089,7 @@ bool ast_member_codegen(ast_member *self, ast_function *func, bool lvalue, ir_va
}
cgen = self->owner->expression.codegen;
if (!(*cgen)((ast_expression*)(self->owner), func, true, &vec))
if (!(*cgen)((ast_expression*)(self->owner), func, false, &vec))
return false;
if (vec->vtype != TYPE_VECTOR &&

32
ir.c
View file

@ -2310,6 +2310,9 @@ bool ir_function_allocate_locals(ir_function *self)
if (vec_size(v->writes) == 1 && v->writes[0]->opcode == INSTR_CALL0)
{
v->store = store_return;
if (v->members[0]) v->members[0]->store = store_return;
if (v->members[1]) v->members[1]->store = store_return;
if (v->members[2]) v->members[2]->store = store_return;
++opts_optimizationcount[OPTIM_CALL_STORES];
continue;
}
@ -3779,7 +3782,7 @@ void ir_function_dump(ir_function *f, char *ind,
attr = "unique ";
else if (v->locked)
attr = "locked ";
oprintf("%s\t%s: %s@%i ", ind, v->name, attr, (int)v->code.local);
oprintf("%s\t%s: %s %s@%i ", ind, v->name, type_name[v->vtype], attr, (int)v->code.local);
for (l = 0; l < vec_size(v->life); ++l) {
oprintf("[%i,%i] ", v->life[l].start, v->life[l].end);
}
@ -3802,13 +3805,36 @@ void ir_function_dump(ir_function *f, char *ind,
}
}
for (i = 0; i < vec_size(f->values); ++i) {
size_t l;
const char *attr = "";
size_t l, m;
ir_value *v = f->values[i];
oprintf("%s\t%s: @%i ", ind, v->name, (int)v->code.local);
if (v->unique_life && v->locked)
attr = "unique,locked ";
else if (v->unique_life)
attr = "unique ";
else if (v->locked)
attr = "locked ";
oprintf("%s\t%s: %s %s@%i ", ind, v->name, type_name[v->vtype], attr, (int)v->code.local);
for (l = 0; l < vec_size(v->life); ++l) {
oprintf("[%i,%i] ", v->life[l].start, v->life[l].end);
}
oprintf("\n");
for (m = 0; m < 3; ++m) {
ir_value *vm = v->members[m];
if (!vm)
continue;
if (vm->unique_life && vm->locked)
attr = "unique,locked ";
else if (vm->unique_life)
attr = "unique ";
else if (vm->locked)
attr = "locked ";
oprintf("%s\t%s: %s@%i ", ind, vm->name, attr, (int)vm->code.local);
for (l = 0; l < vec_size(vm->life); ++l) {
oprintf("[%i,%i] ", vm->life[l].start, vm->life[l].end);
}
oprintf("\n");
}
}
if (vec_size(f->blocks))
{

View file

@ -95,6 +95,7 @@
GMQCC_DEFINE_FLAG(OVERLAP_STRINGS, 2)
GMQCC_DEFINE_FLAG(CALL_STORES, 1)
GMQCC_DEFINE_FLAG(VOID_RETURN, 1)
GMQCC_DEFINE_FLAG(VECTOR_COMPONENTS, 1)
#endif
/* some cleanup so we don't have to */

View file

@ -800,6 +800,58 @@ static bool parser_sy_apply_operator(parser_t *parser, shunt *sy)
{
if (CanConstFold(exprs[0], exprs[1]))
out = (ast_expression*)parser_const_float(parser, vec3_mulvv(ConstV(0), ConstV(1)));
else if (OPTS_OPTIMIZATION(OPTIM_VECTOR_COMPONENTS) && CanConstFold1(exprs[0])) {
vector vec = ConstV(0);
if (!vec.y && !vec.z) { /* 'n 0 0' * v */
++opts_optimizationcount[OPTIM_VECTOR_COMPONENTS];
out = (ast_expression*)ast_member_new(ctx, exprs[1], 0, NULL);
out->expression.node.keep = false;
if (vec.x != 1)
out = (ast_expression*)ast_binary_new(ctx, INSTR_MUL_F, (ast_expression*)parser_const_float(parser, vec.x), out);
}
else if (!vec.x && !vec.z) { /* '0 n 0' * v */
++opts_optimizationcount[OPTIM_VECTOR_COMPONENTS];
out = (ast_expression*)ast_member_new(ctx, exprs[1], 1, NULL);
out->expression.node.keep = false;
if (vec.y != 1)
out = (ast_expression*)ast_binary_new(ctx, INSTR_MUL_F, (ast_expression*)parser_const_float(parser, vec.y), out);
}
else if (!vec.x && !vec.y) { /* '0 n 0' * v */
++opts_optimizationcount[OPTIM_VECTOR_COMPONENTS];
out = (ast_expression*)ast_member_new(ctx, exprs[1], 2, NULL);
out->expression.node.keep = false;
if (vec.z != 1)
out = (ast_expression*)ast_binary_new(ctx, INSTR_MUL_F, (ast_expression*)parser_const_float(parser, vec.z), out);
}
else
out = (ast_expression*)ast_binary_new(ctx, INSTR_MUL_V, exprs[0], exprs[1]);
}
else if (OPTS_OPTIMIZATION(OPTIM_VECTOR_COMPONENTS) && CanConstFold1(exprs[1])) {
vector vec = ConstV(1);
if (!vec.y && !vec.z) { /* v * 'n 0 0' */
++opts_optimizationcount[OPTIM_VECTOR_COMPONENTS];
out = (ast_expression*)ast_member_new(ctx, exprs[0], 0, NULL);
out->expression.node.keep = false;
if (vec.x != 1)
out = (ast_expression*)ast_binary_new(ctx, INSTR_MUL_F, out, (ast_expression*)parser_const_float(parser, vec.x));
}
else if (!vec.x && !vec.z) { /* v * '0 n 0' */
++opts_optimizationcount[OPTIM_VECTOR_COMPONENTS];
out = (ast_expression*)ast_member_new(ctx, exprs[0], 1, NULL);
out->expression.node.keep = false;
if (vec.y != 1)
out = (ast_expression*)ast_binary_new(ctx, INSTR_MUL_F, out, (ast_expression*)parser_const_float(parser, vec.y));
}
else if (!vec.x && !vec.y) { /* v * '0 n 0' */
++opts_optimizationcount[OPTIM_VECTOR_COMPONENTS];
out = (ast_expression*)ast_member_new(ctx, exprs[0], 2, NULL);
out->expression.node.keep = false;
if (vec.z != 1)
out = (ast_expression*)ast_binary_new(ctx, INSTR_MUL_F, out, (ast_expression*)parser_const_float(parser, vec.z));
}
else
out = (ast_expression*)ast_binary_new(ctx, INSTR_MUL_V, exprs[0], exprs[1]);
}
else
out = (ast_expression*)ast_binary_new(ctx, INSTR_MUL_V, exprs[0], exprs[1]);
}