[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_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 *e2);
const struct expr_s *algebra_negate (const struct expr_s *e);

View file

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

View file

@ -47,6 +47,7 @@
#include "qfalloca.h"
#include "tools/qfcc/include/algebra.h"
#include "tools/qfcc/include/expr.h"
#include "tools/qfcc/include/method.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)
{
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) {
_print_expr (dstr, c, level, id, next);
dasprintf (dstr, "%*se_%p -> \"e_%p\";\n", indent, "", e, c);
for (int i = 0; i < count; i++) {
_print_expr (dstr, components[i], level, id, 0);
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();
print_type_str (typestr, e->multivec.type);
dasprintf (dstr, "%*se_%p [label=\"multivec %s\\n%d\"];\n", indent, "", e,
typestr->str, e->line);
dasprintf (dstr, "%*s<tr><td colspan=\"%d\">%s</td></tr>\n",
indent + 4, "", colspan, typestr->str);
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

View file

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

View file

@ -59,8 +59,8 @@ get_group (type_t *type, algebra_t *algebra)
return BITOP_LOG2 (group_mask);
}
static pr_uint_t
get_group_mask (type_t *type, algebra_t *algebra)
pr_uint_t
get_group_mask (const type_t *type, algebra_t *algebra)
{
auto layout = &algebra->layout;
if (!is_algebra (type)) {
@ -288,14 +288,13 @@ mvec_expr (const expr_t *expr, algebra_t *algebra)
.type = algebra_mvec_type (algebra, group_mask),
.algebra = algebra,
};
expr_t *components = 0;
expr_t **c = &components;
const expr_t *components[layout->count];
int count = 0;
for (auto sym = get_mvec_sym (mvtype); sym; sym = sym->next) {
*c = (expr_t *) new_offset_alias_expr (sym->type, expr, sym->s.offset);
c = &(*c)->next;
mvec->multivec.count++;
auto c = &components[count++];
*c = new_offset_alias_expr (sym->type, expr, sym->s.offset);
}
mvec->multivec.components = components;
list_gather (&mvec->multivec.components, components, count);
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);
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);
if (!is_algebra (ct)) {
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) {
pr_uint_t mask = ct->t.multivec->group_mask;
if (mask & (mask - 1)) {
@ -337,6 +336,9 @@ mvec_scatter (const expr_t **components, const expr_t *mvec, algebra_t *algebra)
} else {
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);
}
}
@ -371,9 +373,7 @@ mvec_gather (const expr_t **components, algebra_t *algebra)
};
for (int i = layout->count; i-- > 0; ) {
if (components[i]) {
((expr_t *) components[i])->next = (expr_t *) mvec->multivec.components;//FIXME
mvec->multivec.components = components[i];
mvec->multivec.count++;
list_append (&mvec->multivec.components, components[i]);
}
}
return mvec;