mirror of
https://git.code.sf.net/p/quake/quakeforge
synced 2024-11-29 15:41:59 +00:00
[qfcc] Merge extend expressions through sums
This takes care of chained sums of extend expressions. Now `l p ~l` has only four extend instructions which is expected for the code not detecting the cross product that always produces 0.
This commit is contained in:
parent
924c13f925
commit
c2472e99fa
1 changed files with 45 additions and 15 deletions
|
@ -306,6 +306,14 @@ promote_scalar (type_t *dst_type, expr_t *scalar)
|
||||||
return scalar;
|
return scalar;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static bool __attribute__((const))
|
||||||
|
ext_compat (const expr_t *a, const expr_t *b)
|
||||||
|
{
|
||||||
|
return (a->e.extend.extend == b->e.extend.extend
|
||||||
|
&& a->e.extend.reverse == b->e.extend.reverse
|
||||||
|
&& a->e.extend.type == b->e.extend.type);
|
||||||
|
}
|
||||||
|
|
||||||
static expr_t *
|
static expr_t *
|
||||||
sum_expr (type_t *type, expr_t *a, expr_t *b)
|
sum_expr (type_t *type, expr_t *a, expr_t *b)
|
||||||
{
|
{
|
||||||
|
@ -315,24 +323,46 @@ sum_expr (type_t *type, expr_t *a, expr_t *b)
|
||||||
if (!b) {
|
if (!b) {
|
||||||
return a;
|
return a;
|
||||||
}
|
}
|
||||||
expr_t *ext = 0;
|
if (a->type != ex_extend && b->type == ex_extend) {
|
||||||
if (a->type == ex_extend && b->type == ex_extend) {
|
// ensure always ext + something
|
||||||
if (a->e.extend.extend == b->e.extend.extend
|
return sum_expr (type, b, a);
|
||||||
&& a->e.extend.reverse == b->e.extend.reverse
|
}
|
||||||
&& a->e.extend.type == b->e.extend.type) {
|
if (a->type == ex_extend) {
|
||||||
ext = a; // for copying extend info;
|
if (b->type == ex_extend) {
|
||||||
a = a->e.extend.src;
|
if (ext_compat (a, b)) {
|
||||||
b = b->e.extend.src;
|
auto ext = a->e.extend;
|
||||||
|
a = a->e.extend.src;
|
||||||
|
b = b->e.extend.src;
|
||||||
|
auto sum = sum_expr (get_type (a), a, b);
|
||||||
|
return ext_expr (sum, type, ext.extend, ext.reverse);
|
||||||
|
}
|
||||||
|
} else if (b->type == ex_expr && b->e.expr.op == '+') {
|
||||||
|
auto c = b->e.expr.e1;
|
||||||
|
auto d = b->e.expr.e2;
|
||||||
|
if (ext_compat (a, c)) {
|
||||||
|
// d should not be compatible with a because it should have
|
||||||
|
// already been merged
|
||||||
|
auto ext = a->e.extend;
|
||||||
|
a = a->e.extend.src;
|
||||||
|
c = c->e.extend.src;
|
||||||
|
auto sum = sum_expr (get_type (a), a, c);
|
||||||
|
sum = ext_expr (sum, type, ext.extend, ext.reverse);
|
||||||
|
return sum_expr (type, sum, d);
|
||||||
|
}
|
||||||
|
if (ext_compat (a, d)) {
|
||||||
|
// c should not be compatible with a because it should have
|
||||||
|
// already been merged
|
||||||
|
auto ext = a->e.extend;
|
||||||
|
a = a->e.extend.src;
|
||||||
|
d = d->e.extend.src;
|
||||||
|
auto sum = sum_expr (get_type (a), a, d);
|
||||||
|
sum = ext_expr (sum, type, ext.extend, ext.reverse);
|
||||||
|
return sum_expr (type, sum, c);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
auto sum = new_binary_expr ('+', a, b);
|
auto sum = new_binary_expr ('+', a, b);
|
||||||
if (ext) {
|
sum->e.expr.type = type;
|
||||||
sum->e.expr.type = get_type (a);
|
|
||||||
auto extend = ext->e.extend;
|
|
||||||
sum = ext_expr (sum, type, extend.extend, extend.reverse);
|
|
||||||
} else {
|
|
||||||
sum->e.expr.type = type;
|
|
||||||
}
|
|
||||||
return sum;
|
return sum;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue