mirror of
https://git.code.sf.net/p/quake/quakeforge
synced 2025-02-24 20:51:35 +00:00
[qfcc] Collect like terms into products
That is, `x+x -> 2*x` (and similar for higher counts). Doesn't make much difference for just 2, but it will make collecting scales easier and I remember some testing showing that `2*x` is faster than `x+x` for floating point. Of course, motor-point keeps bouncing around numerically :/
This commit is contained in:
parent
96215ed749
commit
e8521eb4cd
2 changed files with 42 additions and 3 deletions
|
@ -42,6 +42,7 @@
|
||||||
|
|
||||||
#include "tools/qfcc/source/qc-parse.h"
|
#include "tools/qfcc/source/qc-parse.h"
|
||||||
|
|
||||||
|
static const expr_t *optimize_core (const expr_t *expr);
|
||||||
static const expr_t skip;
|
static const expr_t skip;
|
||||||
|
|
||||||
static const expr_t *
|
static const expr_t *
|
||||||
|
@ -158,6 +159,7 @@ optimize_cross (const expr_t *expr, const expr_t **adds, const expr_t **subs)
|
||||||
col = neg_expr (col);
|
col = neg_expr (col);
|
||||||
right = !right;
|
right = !right;
|
||||||
}
|
}
|
||||||
|
col = optimize_core (col);
|
||||||
const expr_t *cross;
|
const expr_t *cross;
|
||||||
if (right) {
|
if (right) {
|
||||||
cross = typed_binary_expr (type, CROSS, col, com);
|
cross = typed_binary_expr (type, CROSS, col, com);
|
||||||
|
@ -180,8 +182,6 @@ clean_skips (const expr_t **expr_list)
|
||||||
*dst = 0;
|
*dst = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static const expr_t *optimize_core (const expr_t *expr);
|
|
||||||
|
|
||||||
static void
|
static void
|
||||||
optimize_extends (const expr_t **expr_list)
|
optimize_extends (const expr_t **expr_list)
|
||||||
{
|
{
|
||||||
|
@ -216,6 +216,42 @@ optimize_cross_products (const expr_t **adds, const expr_t **subs)
|
||||||
clean_skips (subs);
|
clean_skips (subs);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
expr_ptr_cmp (const void *_a, const void *_b)
|
||||||
|
{
|
||||||
|
auto a = *(const expr_t **) _a;
|
||||||
|
auto b = *(const expr_t **) _b;
|
||||||
|
return a - b;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
optimize_adds (const expr_t **expr_list)
|
||||||
|
{
|
||||||
|
int count = 0;
|
||||||
|
for (auto scan = expr_list; *scan; scan++, count++) continue;
|
||||||
|
heapsort (expr_list, count, sizeof (expr_list[0]), expr_ptr_cmp);
|
||||||
|
|
||||||
|
for (auto scan = expr_list; *scan; scan++) {
|
||||||
|
if (*scan == &skip) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
int same = 0;
|
||||||
|
for (auto expr = scan + 1; *expr; expr++) {
|
||||||
|
if (*expr == *scan) {
|
||||||
|
same++;
|
||||||
|
*expr = &skip;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (same++) {
|
||||||
|
auto type = get_type (*scan);
|
||||||
|
auto mult = cast_expr (base_type (type), new_int_expr (same));
|
||||||
|
mult = edag_add_expr (mult);
|
||||||
|
*scan = scale_expr (type, *scan, mult);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
clean_skips (expr_list);
|
||||||
|
}
|
||||||
|
|
||||||
static const expr_t *
|
static const expr_t *
|
||||||
optimize_core (const expr_t *expr)
|
optimize_core (const expr_t *expr)
|
||||||
{
|
{
|
||||||
|
@ -229,6 +265,9 @@ optimize_core (const expr_t *expr)
|
||||||
optimize_extends (adds);
|
optimize_extends (adds);
|
||||||
optimize_extends (subs);
|
optimize_extends (subs);
|
||||||
|
|
||||||
|
optimize_adds (adds);
|
||||||
|
optimize_adds (subs);
|
||||||
|
|
||||||
optimize_cross_products (adds, subs);
|
optimize_cross_products (adds, subs);
|
||||||
|
|
||||||
expr = gather_terms (type, adds, subs);
|
expr = gather_terms (type, adds, subs);
|
||||||
|
|
|
@ -23,7 +23,7 @@ main (void)
|
||||||
point_t p = (point_t)'10 4 -1.5 1'f;
|
point_t p = (point_t)'10 4 -1.5 1'f;
|
||||||
point_t n = apply_motor (m, p);
|
point_t n = apply_motor (m, p);
|
||||||
printf ("n: %.9q\n", n);
|
printf ("n: %.9q\n", n);
|
||||||
if ((vec4)n != '10 -3.99999952 -1.49999988 0.99999994'f) {
|
if ((vec4)n != '9.99999905 -3.99999952 -1.49999988 0.99999994'f) {
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
|
|
Loading…
Reference in a new issue