fold scaled offsets in addresses
This commit is contained in:
parent
8e8f706436
commit
4a809d69b5
5 changed files with 79 additions and 11 deletions
2
all.h
2
all.h
|
@ -484,7 +484,7 @@ void chuse(Ref, int, Fn *);
|
||||||
int symeq(Sym, Sym);
|
int symeq(Sym, Sym);
|
||||||
Ref newcon(Con *, Fn *);
|
Ref newcon(Con *, Fn *);
|
||||||
Ref getcon(int64_t, Fn *);
|
Ref getcon(int64_t, Fn *);
|
||||||
int addcon(Con *, Con *);
|
int addcon(Con *, Con *, int);
|
||||||
void salloc(Ref, Ref, Fn *);
|
void salloc(Ref, Ref, Fn *);
|
||||||
void dumpts(BSet *, Tmp *, FILE *);
|
void dumpts(BSet *, Tmp *, FILE *);
|
||||||
void runmatch(uchar *, Num *, Ref, Ref *);
|
void runmatch(uchar *, Num *, Ref, Ref *);
|
||||||
|
|
|
@ -293,7 +293,7 @@ Next:
|
||||||
if (rtype(m->base) == RSlot) {
|
if (rtype(m->base) == RSlot) {
|
||||||
off.type = CBits;
|
off.type = CBits;
|
||||||
off.bits.i = slot(m->base, fn);
|
off.bits.i = slot(m->base, fn);
|
||||||
addcon(&m->offset, &off);
|
addcon(&m->offset, &off, 1);
|
||||||
m->base = TMP(RBP);
|
m->base = TMP(RBP);
|
||||||
}
|
}
|
||||||
if (m->offset.type != CUndef)
|
if (m->offset.type != CUndef)
|
||||||
|
|
11
amd64/isel.c
11
amd64/isel.c
|
@ -692,7 +692,7 @@ anumber(Num *tn, Blk *b, Con *con)
|
||||||
}
|
}
|
||||||
|
|
||||||
static Ref
|
static Ref
|
||||||
adisp(Con *c, Num *tn, Ref r, Fn *fn)
|
adisp(Con *c, Num *tn, Ref r, Fn *fn, int s)
|
||||||
{
|
{
|
||||||
Ref v[2];
|
Ref v[2];
|
||||||
int n;
|
int n;
|
||||||
|
@ -704,7 +704,7 @@ adisp(Con *c, Num *tn, Ref r, Fn *fn)
|
||||||
break;
|
break;
|
||||||
runmatch(matcher[Pob], tn, r, v);
|
runmatch(matcher[Pob], tn, r, v);
|
||||||
assert(rtype(v[0]) == RCon);
|
assert(rtype(v[0]) == RCon);
|
||||||
addcon(c, &fn->con[v[0].val]);
|
addcon(c, &fn->con[v[0].val], s);
|
||||||
r = v[1];
|
r = v[1];
|
||||||
}
|
}
|
||||||
return r;
|
return r;
|
||||||
|
@ -733,18 +733,18 @@ amatch(Addr *a, Num *tn, Ref r, Fn *fn)
|
||||||
|
|
||||||
memset(&co, 0, sizeof co);
|
memset(&co, 0, sizeof co);
|
||||||
ro = v[0];
|
ro = v[0];
|
||||||
rb = adisp(&co, tn, v[1], fn);
|
rb = adisp(&co, tn, v[1], fn, 1);
|
||||||
ri = v[2];
|
ri = v[2];
|
||||||
rs = v[3];
|
rs = v[3];
|
||||||
s = 1;
|
s = 1;
|
||||||
|
|
||||||
if (*p < 0 && co.type != CUndef)
|
if (*p < 0 && co.type != CUndef)
|
||||||
if (amatch(a, tn, rb, fn))
|
if (amatch(a, tn, rb, fn))
|
||||||
return addcon(&a->offset, &co);
|
return addcon(&a->offset, &co, 1);
|
||||||
if (!req(ro, R)) {
|
if (!req(ro, R)) {
|
||||||
assert(rtype(ro) == RCon);
|
assert(rtype(ro) == RCon);
|
||||||
c = &fn->con[ro.val];
|
c = &fn->con[ro.val];
|
||||||
if (!addcon(&co, c))
|
if (!addcon(&co, c, 1))
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
if (!req(rs, R)) {
|
if (!req(rs, R)) {
|
||||||
|
@ -753,6 +753,7 @@ amatch(Addr *a, Num *tn, Ref r, Fn *fn)
|
||||||
assert(c->type = CBits);
|
assert(c->type = CBits);
|
||||||
s = c->bits.i;
|
s = c->bits.i;
|
||||||
}
|
}
|
||||||
|
ri = adisp(&co, tn, ri, fn, s);
|
||||||
*a = (Addr){co, rb, ri, s};
|
*a = (Addr){co, rb, ri, s};
|
||||||
|
|
||||||
if (rtype(ri) == RTmp)
|
if (rtype(ri) == RTmp)
|
||||||
|
|
64
test/isel4.ssa
Normal file
64
test/isel4.ssa
Normal file
|
@ -0,0 +1,64 @@
|
||||||
|
# amd64 address-folding stress
|
||||||
|
|
||||||
|
export function w $f0(l %a, l %b) {
|
||||||
|
@start
|
||||||
|
%c =l add %b, 2
|
||||||
|
%d =l mul %c, 4
|
||||||
|
%e =l add %a, %d
|
||||||
|
%q =l loadw %e
|
||||||
|
ret %q
|
||||||
|
}
|
||||||
|
|
||||||
|
export function w $f1(l %a, l %b) {
|
||||||
|
@start
|
||||||
|
%c =l add 1, %b
|
||||||
|
%f =l add %c, 1
|
||||||
|
%d =l mul %f, 4
|
||||||
|
%e =l add %d, %a
|
||||||
|
%q =l loadw %e
|
||||||
|
ret %q
|
||||||
|
}
|
||||||
|
|
||||||
|
export function w $f2(l %a, l %b) {
|
||||||
|
@start
|
||||||
|
%l =l mul %b, 4
|
||||||
|
%d =l add 8, %l
|
||||||
|
%e =l add %a, %d
|
||||||
|
%q =l loadw %e
|
||||||
|
ret %q
|
||||||
|
}
|
||||||
|
|
||||||
|
# fixme: folding is not good here
|
||||||
|
export function w $f3(l %a, l %b) {
|
||||||
|
@start
|
||||||
|
%l =l mul %b, 4
|
||||||
|
%d =l add 4, %l
|
||||||
|
%f =l add 4, %d
|
||||||
|
%e =l add %a, %f
|
||||||
|
%q =l loadw %e
|
||||||
|
ret %q
|
||||||
|
}
|
||||||
|
|
||||||
|
export function w $f4(l %a, l %b) {
|
||||||
|
@start
|
||||||
|
%c =l add 1, %b
|
||||||
|
%d =l mul %c, 4
|
||||||
|
%e =l add 4, %d
|
||||||
|
%f =l add %e, %a
|
||||||
|
%q =l loadw %f
|
||||||
|
ret %q
|
||||||
|
}
|
||||||
|
|
||||||
|
# >>> driver
|
||||||
|
# int a[] = {1, 2, 3, 4};
|
||||||
|
# typedef int loadf(int *, long long);
|
||||||
|
# extern loadf f0, f1, f2, f3, f4;
|
||||||
|
# loadf *fns[] = {&f0, &f1, &f2, &f3, &f4, 0};
|
||||||
|
# int main() {
|
||||||
|
# loadf **f;
|
||||||
|
# int n;
|
||||||
|
# for (n=1,f=fns; *f; f++,n++)
|
||||||
|
# if ((*f)(a, 1) != 4) return n;
|
||||||
|
# return 0;
|
||||||
|
# }
|
||||||
|
# <<<
|
11
util.c
11
util.c
|
@ -398,18 +398,21 @@ getcon(int64_t val, Fn *fn)
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
addcon(Con *c0, Con *c1)
|
addcon(Con *c0, Con *c1, int m)
|
||||||
{
|
{
|
||||||
if (c0->type == CUndef)
|
if (m != 1 && c1->type == CAddr)
|
||||||
|
return 0;
|
||||||
|
if (c0->type == CUndef) {
|
||||||
*c0 = *c1;
|
*c0 = *c1;
|
||||||
else {
|
c0->bits.i *= m;
|
||||||
|
} else {
|
||||||
if (c1->type == CAddr) {
|
if (c1->type == CAddr) {
|
||||||
if (c0->type == CAddr)
|
if (c0->type == CAddr)
|
||||||
return 0;
|
return 0;
|
||||||
c0->type = CAddr;
|
c0->type = CAddr;
|
||||||
c0->sym = c1->sym;
|
c0->sym = c1->sym;
|
||||||
}
|
}
|
||||||
c0->bits.i += c1->bits.i;
|
c0->bits.i += c1->bits.i * m;
|
||||||
}
|
}
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Reference in a new issue