diff options
| author | 2025-10-10 22:34:17 +0200 | |
|---|---|---|
| committer | 2025-10-10 22:34:17 +0200 | |
| commit | 0fb2b5712cc98ea993f37bd86eeed89fddc5d6d9 (patch) | |
| tree | de9fce7ad0212b54c3de3a72dbe67038e8dd7936 | |
| parent | 0cb0dd0d23386a6a6ff4e981bb633b9e34a87c65 (diff) | |
bugfixes
| -rw-r--r-- | amd64/isel.c | 1 | ||||
| -rw-r--r-- | c.c | 5 | ||||
| -rw-r--r-- | regalloc.c | 110 | ||||
| -rw-r--r-- | test/bf.c | 2 |
4 files changed, 59 insertions, 59 deletions
diff --git a/amd64/isel.c b/amd64/isel.c index fefd8ea..44f0ff4 100644 --- a/amd64/isel.c +++ b/amd64/isel.c @@ -271,6 +271,7 @@ sel(struct function *fn, struct instr *ins, struct block *blk, int *curi) case Onop: break; case Oalloca1: case Oalloca2: case Oalloca4: case Oalloca8: case Oalloca16: alignlog2 = ins->op - Oalloca1; + assert(ins->l.i > 0); siz = ins->l.i << alignlog2; fn->stksiz += siz; fn->stksiz = alignup(fn->stksiz, 1 << alignlog2); @@ -3659,8 +3659,7 @@ localdecl(struct comp *cm, struct function *fn, bool forini) goto Err; } EMITS { - /*actual alloca filled in later (for inferred array size decls)*/ - decl.id = addinstr(fn, mkinstr(Oalloca1, KPTR, mkref(RICON, -1))).i; + decl.id = addinstr(fn, mkalloca(typesize(decl.ty), typealign(decl.ty))).i; } Initz: if (st.varini) { @@ -3685,7 +3684,7 @@ localdecl(struct comp *cm, struct function *fn, bool forini) d->ty, ini.ty); } EMITS { - if (ini.t == EINIT || ini.t == ESTRLIT) + if (ini.t == EINIT || (d->ty.t == TYARRAY && ini.t == ESTRLIT)) geninit(fn, d->ty, mkref(RTMP, decl.id), &ini); else if (isagg(d->ty)) structcopy(fn, d->ty, mkref(RTMP, decl.id), exprvalue(fn, &ini)); @@ -439,77 +439,77 @@ intervaloverlap(struct interval *a, struct interval *b) } static void -addrange0(struct interval *it, struct range new) +intervalbegin(struct interval *it, ushort from) { - int dst = it->nrange; - - if (dst == 0) { Push: pushrange(it, new); return; } - /* start from the end, find place by order */ - for (int i = dst - 1; i >= 0; --i) { - struct range range = itrange(it, i); - - /* fully contained? */ - if (range.from <= new.from && new.to <= range.to) - return; - if (range.from > new.from) - dst = i; - } - if (dst == it->nrange) goto Push; - if (rangeoverlap(new, itrange(it, dst)) || rangeadj(new, itrange(it, dst))) { - struct range old = itrange(it, dst), - *merge = &itrange(it, dst); - if (new.from < old.from) merge->from = new.from; - if (new.to > old.to) merge->to = new.to; + if (!it->nrange) { + pushrange(it, (struct range){from,from}); } else { - /* insert at dst */ - pushrange(it, new); - for (int j = it->nrange-1; j > dst; --j) - itrange(it, j) = itrange(it, j-1); - itrange(it, dst) = new; + itrange(it, 0).from = from; } - /* more merges? */ - for (struct range *last = &itrange(it, it->nrange-2); - it->nrange > 1 && (rangeoverlap(last[0], last[1]) || rangeadj(last[0], last[1])); - --last) - { - if (last[1].from < last[0].from) - last[0].from = last[1].from; - if (last[1].to > last[0].to) - last[0].to = last[1].to; - - if (--it->nrange == 2) { - struct range *tmp = it->_dyn; - memcpy(it->_inl, tmp, 2*sizeof*tmp); - xbfree(it->_dyn); - } +} + +static bool +intervaldef(struct intervals *intervals, int t, struct block *blk, int pos, int reghint) +{ + struct interval *it = &intervals->temps[t]; + if (it->nrange) { + assert(itrange(it, 0).from <= pos); + itrange(it, 0).from = pos; + return 1; } + return 0; } static void -addrange(struct intervals *intervals, int t, struct range range, int reghint) +addrange(struct intervals *intervals, int t, struct range new, int reghint) { struct interval *it = &intervals->temps[t]; + struct range *fst; + int n; + if (!it->nrange) { ++intervals->count; it->rhint = reghint; it->fpr = kisflt(insrescls(instrtab[t])); + pushrange(it, new); + return; } - addrange0(it, range); -} -static bool -intervaldef(struct intervals *intervals, int t, struct block *blk, int pos, int reghint) -{ - struct interval *it = &intervals->temps[t]; - if (it->nrange) { - if (itrange(it, 0).from <= pos) /* shorten */ - itrange(it, 0).from = pos; - else - addrange0(it, (struct range){pos, blk->inumstart + blk->ins.n+1}); - if (it->rhint < 0) it->rhint = reghint; - return 1; + fst = &itrange(it, 0); + /* fully covered by first range? */ + if (fst->from <= new.from && fst->to >= new.to) return; + /* overlaps with first range ? */ + if (fst->from <= new.to && new.to < fst->to) { + fst->from = new.from; + } else { + /* put new range at the start */ + pushrange(it, new); + memmove(&itrange(it, 1), &itrange(it, 0), sizeof(struct range) * (it->nrange - 1)); + itrange(it, 0) = new; + } + + /* new range might cover existing ranges (loop header lives), + * check and succesively merge */ + fst = &itrange(it, 0); + n = 0; + for (int i = 1; i < it->nrange; ++i) { + struct range other = itrange(it, i); + if (fst->to >= other.from) { + fst->to = fst->to > other.to ? fst->to : other.to; + ++n; + } else break; + } + + if (n > 0) { + for (int i = 1; i + n < it->nrange; ++i) + itrange(it, i) = itrange(it, i+n); + if (it->nrange > 2 && it->nrange - n <= 2) { + struct range *dyn = it->_dyn; + memcpy(it->_inl, dyn, (it->nrange - n) * sizeof *dyn); + xbfree(dyn); + } + it->nrange -= n; } - return 0; } static void @@ -4,7 +4,7 @@ void bf(const char *p) { extern int putchar(int); extern int getchar(void); - static unsigned char *const Mend = M + sizeof M; + unsigned char *Mend = M + sizeof M; int b; unsigned char *m = M; |