aboutsummaryrefslogtreecommitdiffhomepage
path: root/common.h
diff options
context:
space:
mode:
authorlemon <lsof@mailbox.org>2023-06-26 00:29:07 +0200
committerlemon <lsof@mailbox.org>2023-06-26 00:29:07 +0200
commitb94fe89c9ddfcb85dcddebfd218fa7f00b8e6608 (patch)
tree153c345c5811343bb0f8f5190ead67f9f70b0d97 /common.h
parentbdb0276b534b817afb0b79f8e63196eed5d8bd7f (diff)
backend: fix mem2reg & regalloc
they were broken, especially for unstructured control flow. most significant fix is to register allocator for temporaries that are used before the first definition in the source order, e.g.: @1: %x = add %y, 1 b @3 @2 %y = ... b @1 it's legal for %x to use %y there (assuming @2 dominates @1) but from the point of view of the register allocator %y is defined and freed and then used again, which broke things. the fix is to introduce phis for this situation: @1: %y.1 = phi @2 %y %x = add %y.1, 1 b @3 @2 %y = ... b @1 then regalloc phi handling code makes it work
Diffstat (limited to 'common.h')
-rw-r--r--common.h9
1 files changed, 9 insertions, 0 deletions
diff --git a/common.h b/common.h
index a47837a..252cfa4 100644
--- a/common.h
+++ b/common.h
@@ -367,6 +367,12 @@ xbgrow_(void **p, size_t n)
#define xbgrow(p, n) xbgrow_((void **)(p), (n) * sizeof**(p))
#define xbpush(p, n, x) (xbgrow(p, (*(n) + 1)), (*(p))[(*(n))++] = (x))
#define xbfree(p) ((p) ? free(&xbcap_(p)) : (void)0)
+#define xbcap(p) ((p) ? xbcap_(p) / sizeof*(p) : 0)
+#define xbgrowz(p, n) do { \
+ size_t tmp = *(p) ? xbcap_(*(p)) : 0; \
+ xbgrow(p, n); \
+ memset((char*)*(p)+tmp, 0, xbcap_(*(p))-tmp); \
+} while (0)
struct arena *newarena(uint chunksiz);
void *alloc(struct arena **, uint siz, uint align);
@@ -431,6 +437,9 @@ int pmap_set_(struct pmapbase *, void **v, uint vsiz, const void *k);
#define pmap_get(m, k) (((m)->tmp = pmap_get_(&(m)->mb, k)) < 0 ? NULL : &(m)->v[(m)->tmp])
#define pmap_set(m, k, x) ((m)->tmp = pmap_set_(&(m)->mb, (void **)&(m)->v, sizeof*(m)->v, k), \
(m)->v[(m)->tmp] = (x))
+#define pmap_each(m,kx,pvx) \
+ for (int _i = 0; _i < (m)->mb.N && ((kx) = (m)->mb.k[_i], (pvx) = &(m)->v[_i], 1); ++_i) \
+ if (kx)
static inline bool
bstest(const struct bitset *bs, uint i)