diff options
author | Quentin Carbonneaux <quentin@c9x.me> | 2022-12-18 17:35:19 +0100 |
---|---|---|
committer | Quentin Carbonneaux <quentin@c9x.me> | 2022-12-25 16:37:33 +0100 |
commit | 5e9726946dcb9248dbd34ded1bdd4f7af8dc2d31 (patch) | |
tree | 9842f9837784911e386357af18b08a2ca1b69896 /mem.c | |
parent | c5cd65261e05029889450ca27050785504164853 (diff) | |
download | roux-5e9726946dcb9248dbd34ded1bdd4f7af8dc2d31.tar.gz |
new UNDEF Ref
Crashing loads of uninitialized memory proved to be a problem when implementing unions using qbe. This patch introduces a new UNDEF Ref to represent data that is known to be uninitialized. Optimization passes can make use of it to eliminate some code. In the last compilation stages, UNDEF is treated as the constant 0xdeaddead.
Diffstat (limited to 'mem.c')
-rw-r--r-- | mem.c | 25 |
1 files changed, 15 insertions, 10 deletions
diff --git a/mem.c b/mem.c index 5d59b96..1db632f 100644 --- a/mem.c +++ b/mem.c @@ -201,7 +201,7 @@ coalesce(Fn *fn) Ref *arg; bits x; int64_t off0, off1; - int n, m, sz, nsl, nbl, ip, *stk; + int n, m, ip, sz, nsl, nbl, *stk; uint total, freed, fused; /* minimize the stack usage @@ -317,26 +317,31 @@ coalesce(Fn *fn) while (n--) { t = &fn->tmp[stk[n]]; assert(t->ndef == 1 && t->def); - *t->def = (Ins){.op = Onop}; + i = t->def; + if (isload(i->op)) { + i->op = Ocopy; + i->arg[0] = UNDEF; + continue; + } + *i = (Ins){.op = Onop}; for (u=t->use; u<&t->use[t->nuse]; u++) { if (u->type == UJmp) { b = fn->rpo[u->bid]; - b->jmp.arg = CON_Z; + assert(isret(b->jmp.type)); + b->jmp.type = Jret0; + b->jmp.arg = R; continue; } assert(u->type == UIns); i = u->u.ins; - /* make loads crash */ - if (isload(i->op)) - i->arg[0] = CON_Z; - else if (i->op == Oargc) - i->arg[1] = CON_Z; - else if (!req(i->to, R)) { + if (!req(i->to, R)) { assert(rtype(i->to) == RTmp); vgrow(&stk, ++n); stk[n-1] = i->to.val; + } else if (isarg(i->op)) { + assert(i->op == Oargc); + i->arg[1] = CON_Z; /* crash */ } else { - assert(!isarg(i->op)); if (i->op == Oblit0) *(i+1) = (Ins){.op = Onop}; *i = (Ins){.op = Onop}; |