fix exponential complexity in usewidthle()

This commit is contained in:
Quentin Carbonneaux 2026-04-21 13:24:52 +02:00
parent 8ff0651552
commit b58e2e695b

27
copy.c
View File

@ -41,9 +41,8 @@ bitwidth(uint64_t v)
return n+v; return n+v;
} }
/* no more than w bits are used */
static int static int
usewidthle(Fn *fn, Ref r, int w) uwl(Fn *fn, Ref r, int w)
{ {
Ext e; Ext e;
Tmp *t; Tmp *t;
@ -52,7 +51,6 @@ usewidthle(Fn *fn, Ref r, int w)
Ins *i; Ins *i;
Ref rc; Ref rc;
int64_t v; int64_t v;
int b;
assert(rtype(r) == RTmp); assert(rtype(r) == RTmp);
t = &fn->tmp[r.val]; t = &fn->tmp[r.val];
@ -69,21 +67,19 @@ usewidthle(Fn *fn, Ref r, int w)
if (p->visit || req(p->to, R)) if (p->visit || req(p->to, R))
continue; continue;
p->visit = 1; p->visit = 1;
b = usewidthle(fn, p->to, w); if (uwl(fn, p->to, w))
p->visit = 0;
if (b)
continue; continue;
break; break;
case UIns: case UIns:
i = u->u.ins; i = u->u.ins;
assert(i != 0); assert(i != 0);
if (i->op == Ocopy) if (i->op == Ocopy)
if (usewidthle(fn, i->to, w)) if (uwl(fn, i->to, w))
continue; continue;
if (ext(i, &e)) { if (ext(i, &e)) {
if (e.usew <= w) if (e.usew <= w)
continue; continue;
if (usewidthle(fn, i->to, w)) if (uwl(fn, i->to, w))
continue; continue;
} }
if (i->op == Oand) { if (i->op == Oand) {
@ -107,6 +103,21 @@ usewidthle(Fn *fn, Ref r, int w)
return 1; return 1;
} }
/* no more than w bits are used */
static int
usewidthle(Fn *fn, Ref r, int w)
{
Blk *b;
Phi *p;
int ret;
ret = uwl(fn, r, w);
for (b=fn->start; b; b=b->link)
for (p=b->phi; p; p=p->link)
p->visit = 0;
return ret;
}
static int static int
min(int v1, int v2) min(int v1, int v2)
{ {