Compare commits

..

3 Commits

Author SHA1 Message Date
Quentin Carbonneaux
adab20908f .PHONY: check-amd64_win 2026-05-05 16:00:50 +02:00
Quentin Carbonneaux
2ccbf477c7 bump max parallel move size 2026-05-05 15:28:38 +02:00
Quentin Carbonneaux
e01207f772 fix exponential behavior of defwidthle() 2026-05-05 15:22:12 +02:00
5 changed files with 63 additions and 33 deletions

View File

@ -100,4 +100,4 @@ src:
wc:
@wc -l $(SRCALL)
.PHONY: clean clean-gen check check-arm64 check-rv64 src 80 wc install uninstall
.PHONY: clean clean-gen check check-arm64 check-rv64 check-amd64_win src 80 wc install uninstall

6
all.h
View File

@ -240,11 +240,11 @@ struct Ins {
struct Phi {
Ref to;
short cls;
int visit;
uint narg;
Ref *arg;
Blk **blk;
uint narg;
short cls;
uint visit:1;
Phi *link;
};

59
copy.c
View File

@ -41,6 +41,20 @@ bitwidth(uint64_t v)
return n+v;
}
static int
visit(Fn *fn, Ref r, int w, int f(Fn *, Ref, int))
{
Blk *b;
Phi *p;
int ret;
ret = f(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
uwl(Fn *fn, Ref r, int w)
{
@ -107,15 +121,7 @@ uwl(Fn *fn, Ref r, int w)
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;
return visit(fn, r, w, uwl);
}
static int
@ -124,9 +130,8 @@ min(int v1, int v2)
return v1 < v2 ? v1 : v2;
}
/* is the ref narrower than w bits */
static int
defwidthle(Fn *fn, Ref r, int w)
dwl(Fn *fn, Ref r, int w)
{
Ext e;
Tmp *t;
@ -139,6 +144,8 @@ defwidthle(Fn *fn, Ref r, int w)
if (isconbits(fn, r, &v)
&& bitwidth(v) <= w)
return 1;
if (w <= 0)
return 0;
if (rtype(r) != RTmp)
return 0;
t = &fn->tmp[r.val];
@ -151,21 +158,18 @@ defwidthle(Fn *fn, Ref r, int w)
if (req(p->to, r))
break;
assert(p);
if (p->visit)
if (p->visit && p->visit <= w)
return 1;
p->visit = 1;
p->visit = w;
for (n=0; n<p->narg; n++)
if (!defwidthle(fn, p->arg[n], w)) {
p->visit = 0;
if (!dwl(fn, p->arg[n], w))
return 0;
}
p->visit = 0;
return 1;
}
i = t->def;
if (i->op == Ocopy)
return defwidthle(fn, i->arg[0], w);
return dwl(fn, i->arg[0], w);
if (i->op == Oshr || i->op == Osar) {
if (isconbits(fn, i->arg[1], &v))
if (0 < v && v <= 32) {
@ -178,19 +182,19 @@ defwidthle(Fn *fn, Ref r, int w)
w = min(32, w+v);
}
}
return defwidthle(fn, i->arg[0], w);
return dwl(fn, i->arg[0], w);
}
if (iscmp(i->op, &x, &x))
return w >= 1;
if (i->op == Oand) {
if (defwidthle(fn, i->arg[0], w)
|| defwidthle(fn, i->arg[1], w))
if (dwl(fn, i->arg[0], w)
|| dwl(fn, i->arg[1], w))
return 1;
return 0;
}
if (i->op == Oor || i->op == Oxor) {
if (defwidthle(fn, i->arg[0], w)
&& defwidthle(fn, i->arg[1], w))
if (dwl(fn, i->arg[0], w)
&& dwl(fn, i->arg[1], w))
return 1;
return 0;
}
@ -198,12 +202,19 @@ defwidthle(Fn *fn, Ref r, int w)
if (e.zext && e.usew <= w)
return 1;
w = min(w, e.nopw);
return defwidthle(fn, i->arg[0], w);
return dwl(fn, i->arg[0], w);
}
return 0;
}
/* is the ref narrower than w bits */
static int
defwidthle(Fn *fn, Ref r, int w)
{
return visit(fn, r, w, dwl);
}
static int
isw1(Fn *fn, Ref r)
{

10
rega.c
View File

@ -15,13 +15,17 @@ struct RMap {
int n;
};
enum {
NPm = 128, /* max copies in a parallel move */
};
static bits regu; /* registers used */
static Tmp *tmp; /* function temporaries */
static Mem *mem; /* function mem references */
static struct {
Ref src, dst;
int cls;
} pm[Tmp0]; /* parallel move constructed */
} pm[NPm]; /* parallel move constructed */
static int npm; /* size of pm */
static int loop; /* current loop level */
@ -190,8 +194,8 @@ mdump(RMap *m)
static void
pmadd(Ref src, Ref dst, int k)
{
if (npm == Tmp0)
die("cannot have more moves than registers");
if (npm == NPm)
die("no more pm slots");
pm[npm].src = src;
pm[npm].dst = dst;
pm[npm].cls = k;

View File

@ -8,8 +8,23 @@ export function w $f() {
ret %c
}
export function w $g(w %arg) {
@start
%a0 =w extuh %arg # 1
%a1 =w or 65536, %a0 # 65537
@loop
%a2 =w phi @loop %a2, @start %a1 # 65537
jnz %arg, @end, @loop
@end
%a3 =w shr %a2, 1 # 32768
%a4 =w or %a2, 1 # 65537
%a5 =w or %a3, %a4 # 98305
%ret =w extuh %a5 # 32769
ret %ret
}
# >>> driver
# char a = -1;
# extern int f();
# int main() { return !(f() == 1); }
# extern int f(), g(int);
# int main() { return !(f() == 1 && g(1) == 32769); }
# <<<