aboutsummaryrefslogtreecommitdiffhomepage
path: root/ir.c
diff options
context:
space:
mode:
Diffstat (limited to 'ir.c')
-rw-r--r--ir.c28
1 files changed, 25 insertions, 3 deletions
diff --git a/ir.c b/ir.c
index d887fab..5b54d70 100644
--- a/ir.c
+++ b/ir.c
@@ -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)
{