[qfcc] Merge extend expressions in sums

This removes another 3 instructions from the fancy zero test.
This commit is contained in:
Bill Currie 2023-09-28 10:58:25 +09:00
parent 026533d56b
commit 83e4b2b7f5

View file

@ -139,6 +139,19 @@ ext_expr (const expr_t *src, type_t *type, int extend, bool reverse)
return ext; return ext;
} }
static bool __attribute__((const))
ext_compat (const ex_extend_t *a, const ex_extend_t *b)
{
return (a->extend == b->extend && a->reverse == b->reverse
&& a->type == b->type);
}
static bool __attribute__((const))
is_ext (const expr_t *e)
{
return e && e->type == ex_extend;
}
static const expr_t * static const expr_t *
alias_expr (type_t *type, const expr_t *e, int offset) alias_expr (type_t *type, const expr_t *e, int offset)
{ {
@ -379,14 +392,6 @@ mvec_gather (const expr_t **components, algebra_t *algebra)
return mvec; return mvec;
} }
#if 0 #if 0
static bool __attribute__((const))
ext_compat (const expr_t *a, const expr_t *b)
{
return (a->extend.extend == b->extend.extend
&& a->extend.reverse == b->extend.reverse
&& a->extend.type == b->extend.type);
}
static const expr_t * static const expr_t *
extract_extended_neg (const expr_t *expr) extract_extended_neg (const expr_t *expr)
{ {
@ -513,6 +518,43 @@ collect_terms (type_t *type, const expr_t **adds, const expr_t **subs)
return sum; return sum;
} }
static const expr_t *
sum_expr (type_t *type, const expr_t *a, const expr_t *b);
static void
merge_extends (const expr_t **adds, const expr_t **subs)
{
for (auto scan = adds; *scan; scan++) {
if (!is_ext (*scan)) {
continue;
}
auto extend = (*scan)->extend;
auto type = get_type (extend.src);
auto dst = scan + 1;
for (auto src = dst; *src; src++) {
if (is_ext (*src) && ext_compat (&extend, &(*src)->extend)) {
extend.src = sum_expr (type, extend.src,
(*src)->extend.src);
} else {
*dst++ = *src;
}
}
*dst = 0;
dst = subs;
for (auto src = dst; *src; src++) {
if (is_ext (*src) && ext_compat (&extend, &(*src)->extend)) {
extend.src = sum_expr (type, extend.src,
neg_expr ((*src)->extend.src));
} else {
*dst++ = *src;
}
}
*scan = ext_expr (extend.src, extend.type,
extend.extend, extend.reverse);
*dst = 0;
}
}
static const expr_t * static const expr_t *
sum_expr (type_t *type, const expr_t *a, const expr_t *b) sum_expr (type_t *type, const expr_t *a, const expr_t *b)
{ {
@ -531,6 +573,8 @@ sum_expr (type_t *type, const expr_t *a, const expr_t *b)
const expr_t **dstadd, **srcadd; const expr_t **dstadd, **srcadd;
const expr_t **dstsub, **srcsub; const expr_t **dstsub, **srcsub;
merge_extends (adds, subs);
for (dstadd = adds, srcadd = adds; *srcadd; srcadd++) { for (dstadd = adds, srcadd = adds; *srcadd; srcadd++) {
for (dstsub = subs, srcsub = subs; *srcsub; srcsub++) { for (dstsub = subs, srcsub = subs; *srcsub; srcsub++) {
if (*srcadd == *srcsub) { if (*srcadd == *srcsub) {
@ -685,6 +729,9 @@ dot_expr (type_t *type, const expr_t *a, const expr_t *b)
} else if (!a_terms && b_terms) { } else if (!a_terms && b_terms) {
b = check_dot (a, b, b_terms); b = check_dot (a, b, b_terms);
} }
if (!a || !b) {
return 0;
}
auto dot = typed_binary_expr (type, DOT, a, b); auto dot = typed_binary_expr (type, DOT, a, b);
dot = edag_add_expr (dot); dot = edag_add_expr (dot);