diff options
| author | 2023-06-13 12:02:28 +0200 | |
|---|---|---|
| committer | 2023-06-13 12:02:28 +0200 | |
| commit | de5aa052f234693698fa27564d12958df3fa433e (patch) | |
| tree | 837ed316bc13fe8063dde85e3b075c9357202297 /ir.c | |
| parent | 3e5c11563f8cb7c843c71a0f761e5b644f39db46 (diff) | |
use a hashtable for addr refs
Diffstat (limited to 'ir.c')
| -rw-r--r-- | ir.c | 28 |
1 files changed, 25 insertions, 3 deletions
@@ -10,7 +10,7 @@ static int instrfreelist; struct calltab calltab; struct phitab phitab; struct dattab dattab; -struct addrtab addrtab; +struct addr addrht[1 << 12]; void irinit(struct function *fn) @@ -18,14 +18,13 @@ irinit(struct function *fn) static struct call callsbuf[64]; static struct phi phisbuf[64]; static struct irdat datsbuf[64]; - static struct addr addrsbuf[64]; ninstr = 0; instrfreelist = -1; vinit(&calltab, callsbuf, arraylength(callsbuf)); vinit(&phitab, phisbuf, arraylength(phisbuf)); vinit(&dattab, datsbuf, arraylength(datsbuf)); - vinit(&addrtab, addrsbuf, arraylength(addrsbuf)); + memset(addrht, 0, sizeof addrht); if (!type2cls[TYINT]) { for (int i = TYBOOL; i <= TYUVLONG; ++i) { int siz = targ_primsizes[i]; @@ -44,6 +43,23 @@ irinit(struct function *fn) fn->entry->lprev = fn->entry->lnext = fn->entry; } +static int +addaddr(const struct addr *addr) +{ + uint h = hashb(0, addr, sizeof *addr); + uint i = h, n = arraylength(addrht); + for (;; ++i) { + i &= arraylength(addrht) - 1; + if (!addrht[i].base.t && !addrht[i].index.t) { + addrht[i] = *addr; + return i; + } else if (!memcmp(&addrht[i], addr, sizeof *addr)) { + return i; + } + assert(--n > 0 && "addrht full"); + } +} + struct xcon conht[1 << 12]; static int @@ -191,6 +207,12 @@ mkcallarg(union irtype ret, uint narg, int vararg) return mkref(RMORE, calltab.n-1); } +union ref +mkaddr(struct addr addr) +{ + return mkref(RMORE, addaddr(&addr)); +} + static inline int newinstr(void) { |