mirror of
https://git.code.sf.net/p/quake/quakeforge
synced 2025-02-24 12:42:32 +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"
|
||||
|
||||
static const expr_t *optimize_core (const expr_t *expr);
|
||||
static const expr_t skip;
|
||||
|
||||
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);
|
||||
right = !right;
|
||||
}
|
||||
col = optimize_core (col);
|
||||
const expr_t *cross;
|
||||
if (right) {
|
||||
cross = typed_binary_expr (type, CROSS, col, com);
|
||||
|
@ -180,8 +182,6 @@ clean_skips (const expr_t **expr_list)
|
|||
*dst = 0;
|
||||
}
|
||||
|
||||
static const expr_t *optimize_core (const expr_t *expr);
|
||||
|
||||
static void
|
||||
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);
|
||||
}
|
||||
|
||||
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 *
|
||||
optimize_core (const expr_t *expr)
|
||||
{
|
||||
|
@ -229,6 +265,9 @@ optimize_core (const expr_t *expr)
|
|||
optimize_extends (adds);
|
||||
optimize_extends (subs);
|
||||
|
||||
optimize_adds (adds);
|
||||
optimize_adds (subs);
|
||||
|
||||
optimize_cross_products (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 n = apply_motor (m, p);
|
||||
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 0;
|
||||
|
|
Loading…
Reference in a new issue