write more tests for dopm()

This commit is contained in:
Quentin Carbonneaux 2015-08-21 16:05:50 -04:00
parent 13e04cd1de
commit 60b8b06aab

View file

@ -1,24 +1,31 @@
/*% cc -std=c99 -Wall -DTEST_PMOV -g -o # % /*% cc -O3 -std=c99 -Wall -DTEST_PMOV -o # %
*
* This is a test framwork for the dopm() function
* in rega.c, use it when you want to modify it or
* all the parallel move functions.
*
* You might need to decrease NReg to see it
* terminate, I used NReg == 7 at most.
*/ */
#include <stdio.h> #include <stdio.h>
#include <stdlib.h> #include <stdlib.h>
#include <string.h> #include <string.h>
static void assert_test(char *, int), fail(void); static void assert_test(char *, int), fail(void), iexec(int *);
#include "../rega.c" #include "../rega.c"
static RMap mbeg; static RMap mbeg;
static Ins ins[NReg], *ip; static Ins ins[NReg], *ip;
static Blk dummyb = { .ins = ins };
int int
main() main()
{ {
Blk dummyb;
Ins *i1; Ins *i1;
unsigned long long tm, rm; unsigned long long tm, rm, cnt;
RMap mend; RMap mend;
int reg[NReg]; int reg[NReg], val[NReg+1];
int t, i, r, nr; int t, i, r, nr;
tmp = (Tmp[Tmp0+NReg]){{0}}; tmp = (Tmp[Tmp0+NReg]){{0}};
@ -31,9 +38,7 @@ main()
sprintf(tmp[t].name, "tmp%d", t-Tmp0+1); sprintf(tmp[t].name, "tmp%d", t-Tmp0+1);
} }
dummyb.ins = ins; cnt = 0;
strcpy(dummyb.name, "dummy");
for (tm = 0; tm < 1ull << (2*NReg); tm++) { for (tm = 0; tm < 1ull << (2*NReg); tm++) {
mbeg.n = 0; mbeg.n = 0;
mbeg.b = (Bits){{0}}; mbeg.b = (Bits){{0}};
@ -63,7 +68,7 @@ main()
} }
if (ip == ins) if (ip == ins)
/* cancel is the parallel move /* cancel if the parallel move
* is empty * is empty
*/ */
goto Nxt; goto Nxt;
@ -72,7 +77,6 @@ main()
* in mbeg * in mbeg
*/ */
nr = ip - ins; nr = ip - ins;
dummyb.nins = nr;
rm = (1ull << (nr+1)) - 1; rm = (1ull << (nr+1)) - 1;
for (i=0; i<nr; i++) for (i=0; i<nr; i++)
reg[i] = i+1; reg[i] = i+1;
@ -82,28 +86,51 @@ main()
*/ */
for (i=0, i1=ins; i1<ip; i1++, i++) for (i=0, i1=ins; i1<ip; i1++, i++)
i1->arg[0] = TMP(reg[i]); i1->arg[0] = TMP(reg[i]);
#if 0
for (i=0; i<nr; i++)
printf("%d ", reg[i]);
printf("\n");
#endif
/* compile the parallel move /* compile the parallel move
*/ */
mend = mbeg; mend = mbeg;
dopm(&dummyb, ip-1, &mend); dopm(&dummyb, ip-1, &mend);
cnt++;
// TODO
/* check that mend contain mappings for /* check that mend contain mappings for
* source registers and does not map any * source registers and does not map any
* assigned temporary * assigned temporary, then check that
* all temporaries in mend are mapped in
* mbeg and not used in the copy
*/ */
for (i1=ins; i1<ip; i1++) {
r = i1->arg[0].val;
assert(rfree(&mend, r) == r);
t = i1->to.val;
assert(!BGET(mend.b, t));
}
for (i=0; i<mend.n; i++) {
t = mend.t[i];
assert(BGET(mbeg.b, t));
t -= Tmp0;
assert(((tm >> (2*t)) & 3) == 1);
}
// TODO
/* execute the code generated and check /* execute the code generated and check
* that all assigned temporaries got their * that all assigned temporaries got their
* value * value, and that all live variables's
* content got preserved
*/ */
for (i=1; i<=NReg; i++)
val[i] = i;
iexec(val);
for (i1=ins; i1<ip; i1++) {
t = i1->to.val;
r = rfind(&mbeg, t);
if (r != -1)
assert(val[r] == i1->arg[0].val);
}
for (i=0; i<mend.n; i++) {
t = mend.t[i];
r = mend.r[i];
assert(val[t-Tmp0+1] == r);
}
/* find the next register assignment */ /* find the next register assignment */
i = nr - 1; i = nr - 1;
@ -133,11 +160,59 @@ main()
} }
Nxt: ; Nxt: ;
} }
printf("%llu tests successful!\n", cnt);
exit(0); exit(0);
} }
/* execute what pmgen() wrote (swap, copy) */
#define validr(r) \
rtype(r) == RTmp && \
r.val > 0 && \
r.val <= NReg
static void
iexec(int val[])
{
Ins *i;
int t;
for (i=insb; i<curi; i++)
switch (i->op) {
default:
assert(!"iexec: missing case\n");
exit(1);
case OSwap:
assert(validr(i->arg[0]));
assert(validr(i->arg[1]));
t = val[i->arg[0].val];
val[i->arg[0].val] = val[i->arg[1].val];
val[i->arg[1].val] = t;
break;
case OCopy:
assert(validr(i->to));
assert(validr(i->arg[0]));
val[i->to.val] = val[i->arg[0].val];
break;
}
}
/* failure diagnostics */ /* failure diagnostics */
static int re;
static void
replay()
{
RMap mend;
re = 1;
mend = mbeg;
dopm(&dummyb, ip-1, &mend);
}
static void static void
fail() fail()
{ {
@ -155,6 +230,7 @@ fail()
printf("\t %s <- r%d\n", printf("\t %s <- r%d\n",
tmp[i1->to.val].name, tmp[i1->to.val].name,
i1->arg[0].val); i1->arg[0].val);
replay();
exit(1); exit(1);
} }
@ -163,20 +239,26 @@ assert_test(char *s, int x)
{ {
if (x) if (x)
return; return;
if (re)
exit(1);
printf("!assertion failure: %s\n", s); printf("!assertion failure: %s\n", s);
fail(); fail();
} }
void diag(char *s)
{
if (re)
exit(1);
printf("!diag failure: %s\n", s);
fail();
}
/* symbols required by the linker */ /* symbols required by the linker */
char debug['Z'+1]; char debug['Z'+1];
Ins insb[NIns], *curi; Ins insb[NIns], *curi;
void diag(char *s)
{ printf("!diag failure: %s\n", s); fail(); }
void *alloc(size_t n) void *alloc(size_t n)
{ return malloc(n); } { return calloc(n, 1); }
Blk *blocka() Blk *blocka()
{ printf("!blocka called\n"); exit(1); } { printf("!blocka\n"); exit(1); }