From 9797dcb5defd2bf552a89af947f9c1de73a6d6ab Mon Sep 17 00:00:00 2001 From: Bill Currie Date: Mon, 30 Sep 2024 19:11:40 +0900 Subject: [PATCH] [qfcc] Optimize (a+a)/2 in geometric algebra expressions MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Really, I need to look into getting the optimizations more general, but `a × ⋆a` is now just a single cross product instead off cross, add and divide. --- tools/qfcc/source/expr_algebra.c | 30 ++++++++++++++++++++++++------ 1 file changed, 24 insertions(+), 6 deletions(-) diff --git a/tools/qfcc/source/expr_algebra.c b/tools/qfcc/source/expr_algebra.c index 012c0c59e..9da134435 100644 --- a/tools/qfcc/source/expr_algebra.c +++ b/tools/qfcc/source/expr_algebra.c @@ -2634,6 +2634,18 @@ commutator_product (const expr_t *e1, const expr_t *e2) new_int_expr (2, false)); } +static bool +is_two (const expr_t *e) +{ + if (is_integral_val (e)) { + return expr_integral (e) == 2; + } + if (is_floating_val (e)) { + return expr_floating (e) == 2; + } + return false; +} + static const expr_t * multivector_divide (const expr_t *e1, const expr_t *e2) { @@ -2650,6 +2662,7 @@ multivector_divide (const expr_t *e1, const expr_t *e2) auto layout = &algebra->layout; auto stype = algebra->type; const expr_t *a[layout->count] = {}; + bool is_half = is_two (e2); e1 = mvec_expr (e1, algebra); e2 = promote_scalar (algebra->type, e2); mvec_scatter (a, e1, algebra); @@ -2659,13 +2672,18 @@ multivector_divide (const expr_t *e1, const expr_t *e2) continue; } auto den = e2; - auto ct = get_type (a[i]); - int width = type_width (ct); - if (width > 1) { - den = ext_expr (den, vector_type (stype, width), 2, false); + if (is_half && a[i]->type == ex_expr && a[i]->expr.op == '+' + && a[i]->expr.e1 == a[i]->expr.e2) { + a[i] = a[i]->expr.e1; + } else { + auto ct = get_type (a[i]); + int width = type_width (ct); + if (width > 1) { + den = ext_expr (den, vector_type (stype, width), 2, false); + } + a[i] = typed_binary_expr (ct, '/', a[i], den); + a[i] = edag_add_expr (a[i]); } - a[i] = typed_binary_expr (ct, '/', a[i], den); - a[i] = edag_add_expr (a[i]); } return mvec_gather (a, algebra); }