[qfcc] Use ex_list_t for multivec components

This fixes the motor test :) It turns out that every lead I had
previously was due to the disabling of that feature "breaking" dags
(such that expressions wouldn't be found) and it was the dagged
multi-vector components getting linked by expr->next that made a mess of
things.
This commit is contained in:
Bill Currie 2023-09-27 17:42:44 +09:00
parent cf4916e4de
commit 026533d56b
5 changed files with 48 additions and 23 deletions

View file

@ -109,6 +109,8 @@ bool is_mono_grade (const struct type_s *type) __attribute__((pure));
int algebra_get_grade (const struct type_s *type) __attribute__((pure)); int algebra_get_grade (const struct type_s *type) __attribute__((pure));
int algebra_blade_grade (basis_blade_t blade) __attribute__((const)); int algebra_blade_grade (basis_blade_t blade) __attribute__((const));
pr_uint_t get_group_mask (const struct type_s *type, algebra_t *algebra) __attribute__((pure));
const struct expr_s *algebra_binary_expr (int op, const struct expr_s *e1, const struct expr_s *algebra_binary_expr (int op, const struct expr_s *e1,
const struct expr_s *e2); const struct expr_s *e2);
const struct expr_s *algebra_negate (const struct expr_s *e); const struct expr_s *algebra_negate (const struct expr_s *e);

View file

@ -299,8 +299,7 @@ typedef struct {
typedef struct { typedef struct {
struct type_s *type; ///< overall type of multivector struct type_s *type; ///< overall type of multivector
struct algebra_s *algebra; ///< owning algebra struct algebra_s *algebra; ///< owning algebra
int count; ///< number of component expressions ex_list_t components; ///< multivector components
const struct expr_s *components;///< multivector components
} ex_multivec_t; } ex_multivec_t;
#define POINTER_VAL(p) (((p).def ? (p).def->offset : 0) + (p).val) #define POINTER_VAL(p) (((p).def ? (p).def->offset : 0) + (p).val)

View file

@ -47,6 +47,7 @@
#include "qfalloca.h" #include "qfalloca.h"
#include "tools/qfcc/include/algebra.h"
#include "tools/qfcc/include/expr.h" #include "tools/qfcc/include/expr.h"
#include "tools/qfcc/include/method.h" #include "tools/qfcc/include/method.h"
#include "tools/qfcc/include/strpool.h" #include "tools/qfcc/include/strpool.h"
@ -672,18 +673,41 @@ print_multivec (dstring_t *dstr, const expr_t *e, int level, int id,
const expr_t *next) const expr_t *next)
{ {
int indent = level * 2 + 2; int indent = level * 2 + 2;
ex_multivec_t multivec = e->multivec; auto algebra = e->multivec.algebra;
int count = list_count (&e->multivec.components);
const expr_t *components[count];
list_scatter (&e->multivec.components, components);
for (auto c = multivec.components; c; c = c->next) { for (int i = 0; i < count; i++) {
_print_expr (dstr, c, level, id, next); _print_expr (dstr, components[i], level, id, 0);
dasprintf (dstr, "%*se_%p -> \"e_%p\";\n", indent, "", e, c); dasprintf (dstr, "%*se_%p:m%d -> e_%p;\n", indent, "", e, i,
components[i]);
} }
int colspan = count ? count : 1;
dasprintf (dstr, "%*se_%p [shape=none,label=<\n", indent, "", e);
dasprintf (dstr, "%*s<table border=\"0\" cellborder=\"1\" "
"cellspacing=\"0\">\n", indent + 2, "");
dasprintf (dstr, "%*s<tr><td colspan=\"%d\">&lt;multivec&gt;(%d)</td>"
"</tr>\n", indent + 4, "", colspan, e->line);
dstring_t *typestr = dstring_newstr(); dstring_t *typestr = dstring_newstr();
print_type_str (typestr, e->multivec.type); print_type_str (typestr, e->multivec.type);
dasprintf (dstr, "%*se_%p [label=\"multivec %s\\n%d\"];\n", indent, "", e, dasprintf (dstr, "%*s<tr><td colspan=\"%d\">%s</td></tr>\n",
typestr->str, e->line); indent + 4, "", colspan, typestr->str);
dstring_delete (typestr); dstring_delete (typestr);
if (count) {
dasprintf (dstr, "%*s<tr>\n", indent + 4, "");
for (int i = 0; i < count; i++) {
auto mask = get_group_mask (get_type (components[i]), algebra);
dasprintf (dstr, "%*s<td port=\"m%d\">%04x</td>\n", indent + 8, "",
i, mask);
}
dasprintf (dstr, "%*s</tr>\n", indent + 4, "");
}
dasprintf (dstr, "%*s</table>\n", indent + 2, "");
dasprintf (dstr, "%*s>];\n", indent, "");
} }
static void static void

View file

@ -1680,8 +1680,8 @@ has_function_call (const expr_t *e)
case ex_args: case ex_args:
return 0; return 0;
case ex_multivec: case ex_multivec:
for (auto c = e->multivec.components; c; c = c->next) { for (auto c = e->multivec.components.head; c; c = c->next) {
if (has_function_call (c)) { if (has_function_call (c->expr)) {
return 1; return 1;
} }
} }

View file

@ -59,8 +59,8 @@ get_group (type_t *type, algebra_t *algebra)
return BITOP_LOG2 (group_mask); return BITOP_LOG2 (group_mask);
} }
static pr_uint_t pr_uint_t
get_group_mask (type_t *type, algebra_t *algebra) get_group_mask (const type_t *type, algebra_t *algebra)
{ {
auto layout = &algebra->layout; auto layout = &algebra->layout;
if (!is_algebra (type)) { if (!is_algebra (type)) {
@ -288,14 +288,13 @@ mvec_expr (const expr_t *expr, algebra_t *algebra)
.type = algebra_mvec_type (algebra, group_mask), .type = algebra_mvec_type (algebra, group_mask),
.algebra = algebra, .algebra = algebra,
}; };
expr_t *components = 0; const expr_t *components[layout->count];
expr_t **c = &components; int count = 0;
for (auto sym = get_mvec_sym (mvtype); sym; sym = sym->next) { for (auto sym = get_mvec_sym (mvtype); sym; sym = sym->next) {
*c = (expr_t *) new_offset_alias_expr (sym->type, expr, sym->s.offset); auto c = &components[count++];
c = &(*c)->next; *c = new_offset_alias_expr (sym->type, expr, sym->s.offset);
mvec->multivec.count++;
} }
mvec->multivec.components = components; list_gather (&mvec->multivec.components, components, count);
return mvec; return mvec;
} }
@ -323,11 +322,11 @@ mvec_scatter (const expr_t **components, const expr_t *mvec, algebra_t *algebra)
components[group] = edag_add_expr (mvec); components[group] = edag_add_expr (mvec);
return; return;
} }
for (auto c = mvec->multivec.components; c; c = c->next) { for (auto li = mvec->multivec.components.head; li; li = li->next) {
auto c = li->expr;
auto ct = get_type (c); auto ct = get_type (c);
if (!is_algebra (ct)) { if (!is_algebra (ct)) {
group = layout->group_map[layout->mask_map[0]][0]; group = layout->group_map[layout->mask_map[0]][0];
components[group] = edag_add_expr (mvec);
} else if (ct->meta == ty_algebra && ct->type != ev_invalid) { } else if (ct->meta == ty_algebra && ct->type != ev_invalid) {
pr_uint_t mask = ct->t.multivec->group_mask; pr_uint_t mask = ct->t.multivec->group_mask;
if (mask & (mask - 1)) { if (mask & (mask - 1)) {
@ -337,6 +336,9 @@ mvec_scatter (const expr_t **components, const expr_t *mvec, algebra_t *algebra)
} else { } else {
internal_error (mvec, "invalid type in multivec expression"); internal_error (mvec, "invalid type in multivec expression");
} }
if (components[group]) {
internal_error (mvec, "duplicate group in multivec expression");
}
components[group] = edag_add_expr (c); components[group] = edag_add_expr (c);
} }
} }
@ -371,9 +373,7 @@ mvec_gather (const expr_t **components, algebra_t *algebra)
}; };
for (int i = layout->count; i-- > 0; ) { for (int i = layout->count; i-- > 0; ) {
if (components[i]) { if (components[i]) {
((expr_t *) components[i])->next = (expr_t *) mvec->multivec.components;//FIXME list_append (&mvec->multivec.components, components[i]);
mvec->multivec.components = components[i];
mvec->multivec.count++;
} }
} }
return mvec; return mvec;