mirror of
https://git.code.sf.net/p/quake/quakeforge
synced 2025-02-24 20:51:35 +00:00
[qfcc] Convert dot of scales to scaled dot
That is, dot(scale(A,a),scale(B,b)) -> (a*b)*dot(A,B). Does the right thing when only one side is a scale. No change to the instruction count in my fancy zero, but it does open more opportunities when I distribute products.
This commit is contained in:
parent
4bf6ce45d4
commit
2bf855657c
1 changed files with 21 additions and 8 deletions
|
@ -391,18 +391,17 @@ mvec_gather (const expr_t **components, algebra_t *algebra)
|
||||||
}
|
}
|
||||||
return mvec;
|
return mvec;
|
||||||
}
|
}
|
||||||
#if 0
|
|
||||||
static const expr_t *
|
static bool __attribute__((pure))
|
||||||
extract_extended_neg (const expr_t *expr)
|
is_scale (const expr_t *expr)
|
||||||
{
|
{
|
||||||
auto e = expr->extend;
|
return expr && expr->type == ex_expr && expr->expr.op == SCALE;
|
||||||
return neg_expr (ext_expr (neg_expr (e.src), e.type, e.extend, e.reverse));
|
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
static const expr_t * __attribute__((pure))
|
static const expr_t * __attribute__((pure))
|
||||||
traverse_scale (const expr_t *expr)
|
traverse_scale (const expr_t *expr)
|
||||||
{
|
{
|
||||||
while (expr && expr->type == ex_expr && expr->expr.op == SCALE) {
|
while (is_scale (expr)) {
|
||||||
expr = expr->expr.e1;
|
expr = expr->expr.e1;
|
||||||
}
|
}
|
||||||
return expr;
|
return expr;
|
||||||
|
@ -656,7 +655,7 @@ scale_expr (type_t *type, const expr_t *a, const expr_t *b)
|
||||||
b = neg_expr (b);
|
b = neg_expr (b);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (a->type == ex_expr && a->expr.op == SCALE) {
|
if (is_scale (a)) {
|
||||||
// covert scale (scale (X, y), z) to scale (X, y*z)
|
// covert scale (scale (X, y), z) to scale (X, y*z)
|
||||||
b = scale_expr (get_type (b), b, a->expr.e2);
|
b = scale_expr (get_type (b), b, a->expr.e2);
|
||||||
a = a->expr.e1;
|
a = a->expr.e1;
|
||||||
|
@ -739,8 +738,22 @@ dot_expr (type_t *type, const expr_t *a, const expr_t *b)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const expr_t *prod = 0;
|
||||||
|
if (is_scale (a)) {
|
||||||
|
prod = a->expr.e2;
|
||||||
|
a = a->expr.e1;
|
||||||
|
}
|
||||||
|
if (is_scale (b)) {
|
||||||
|
auto s = b->expr.e2;
|
||||||
|
prod = prod ? scale_expr (get_type (prod), prod, s) : s;
|
||||||
|
b = b->expr.e1;
|
||||||
|
}
|
||||||
|
|
||||||
auto dot = typed_binary_expr (type, DOT, a, b);
|
auto dot = typed_binary_expr (type, DOT, a, b);
|
||||||
dot = edag_add_expr (dot);
|
dot = edag_add_expr (dot);
|
||||||
|
if (prod) {
|
||||||
|
dot = scale_expr (type, dot, prod);
|
||||||
|
}
|
||||||
if (neg) {
|
if (neg) {
|
||||||
dot = neg_expr (dot);
|
dot = neg_expr (dot);
|
||||||
dot = edag_add_expr (dot);
|
dot = edag_add_expr (dot);
|
||||||
|
|
Loading…
Reference in a new issue