From 3c9506256db66035469b37891304b5f92c181197 Mon Sep 17 00:00:00 2001 From: Max Wash Date: Sun, 4 Jan 2026 18:36:33 +0000 Subject: [PATCH] mie: arith: implement int value cache data structure --- mie/dialect/arith/int-cache.c | 139 ++++++++++++++++++++++++++++++++ mie/include/mie/dialect/arith.h | 38 +++++++++ 2 files changed, 177 insertions(+) create mode 100644 mie/dialect/arith/int-cache.c diff --git a/mie/dialect/arith/int-cache.c b/mie/dialect/arith/int-cache.c new file mode 100644 index 0000000..f174613 --- /dev/null +++ b/mie/dialect/arith/int-cache.c @@ -0,0 +1,139 @@ +#include +#include +#include +#include + +struct int_width_cache_entry { + b_btree_node e_node; + struct mie_int e_value; +}; + +struct int_width_cache { + b_btree_node c_node; + size_t c_width; + b_btree c_ints; +}; + +struct mie_int_cache { + b_btree c_widths; +}; + +static B_BTREE_DEFINE_SIMPLE_INSERT( + struct int_width_cache, c_node, c_width, put_width_cache); +static B_BTREE_DEFINE_SIMPLE_GET( + struct int_width_cache, size_t, c_node, c_width, get_width_cache); + +static B_BTREE_DEFINE_SIMPLE_INSERT( + struct int_width_cache_entry, e_node, e_value.i_val.v_small, put_int); +static B_BTREE_DEFINE_SIMPLE_GET( + struct int_width_cache_entry, uint64_t, e_node, e_value.i_val.v_small, + get_int); + +static struct int_width_cache *int_width_cache_create(size_t width) +{ + struct int_width_cache *out = malloc(sizeof *out); + if (!out) { + return NULL; + } + + memset(out, 0x0, sizeof *out); + + out->c_width = width; + + return out; +} + +static void int_width_cache_destroy(struct int_width_cache *cache) +{ + b_btree_node *cur = b_btree_first(&cache->c_ints); + while (cur) { + b_btree_node *next = b_btree_next(cur); + b_btree_delete(&cache->c_ints, cur); + + struct int_width_cache_entry *entry + = b_unbox(struct int_width_cache_entry, cur, e_node); + free(entry); + + cur = next; + } + + free(cache); +} + +static struct int_width_cache_entry *int_width_cache_entry_create( + struct mie_ctx *ctx, size_t width, size_t value) +{ + struct int_width_cache_entry *out = malloc(sizeof *out); + if (!out) { + return NULL; + } + + memset(out, 0x0, sizeof *out); + + out->e_value.i_val.v_small = value; + out->e_value.i_base.v_type = mie_arith_int_get_type(ctx, width); + if (!out->e_value.i_base.v_type) { + free(out); + return NULL; + } + + return out; +} + +struct mie_int_cache *mie_int_cache_create(void) +{ + struct mie_int_cache *out = malloc(sizeof *out); + if (!out) { + return NULL; + } + + memset(out, 0x0, sizeof *out); + return out; +} + +void mie_int_cache_destroy(struct mie_int_cache *cache) +{ + b_btree_node *cur = b_btree_first(&cache->c_widths); + while (cur) { + b_btree_node *next = b_btree_next(cur); + b_btree_delete(&cache->c_widths, cur); + + struct int_width_cache *width_cache + = b_unbox(struct int_width_cache, cur, c_node); + int_width_cache_destroy(width_cache); + + cur = next; + } + + free(cache); +} + +struct mie_int *mie_int_cache_get( + struct mie_int_cache *cache, struct mie_ctx *ctx, size_t value, + size_t bit_width) +{ + struct int_width_cache *width_cache + = get_width_cache(&cache->c_widths, bit_width); + if (!width_cache) { + width_cache = int_width_cache_create(bit_width); + + if (!width_cache) { + return NULL; + } + + put_width_cache(&cache->c_widths, width_cache); + } + + struct int_width_cache_entry *entry = get_int(&width_cache->c_ints, value); + if (!entry) { + entry = int_width_cache_entry_create(ctx, bit_width, value); + + if (!entry) { + return NULL; + } + + put_int(&width_cache->c_ints, entry); + } + + return &entry->e_value; +} diff --git a/mie/include/mie/dialect/arith.h b/mie/include/mie/dialect/arith.h index f6bb54c..aa98fba 100644 --- a/mie/include/mie/dialect/arith.h +++ b/mie/include/mie/dialect/arith.h @@ -2,14 +2,52 @@ #define MIE_DIALECT_ARITH_H_ #include +#include #include +#include struct mie_ctx; struct mie_dialect; +enum mie_float_width { + MIE_FLOAT_32 = 32, + MIE_FLOAT_64 = 64, +}; + +struct mie_int { + struct mie_value i_base; + union { + int64_t v_small; + + struct { + long *a_parts; + size_t a_nr_parts; + } v_arbitrary; + } i_val; +}; + +struct mie_float { + struct mie_value f_base; + + union { + float v_32; + double v_64; + } f_val; +}; + +struct mie_int_cache; + MIE_API struct mie_dialect *mie_arith_dialect_create(struct mie_ctx *ctx); MIE_API struct mie_type *mie_arith_int_get_type( struct mie_ctx *ctx, size_t bit_width); +MIE_API struct mie_type *mie_arith_float_get_type( + struct mie_ctx *ctx, size_t bit_width); + +MIE_API struct mie_int_cache *mie_int_cache_create(void); +MIE_API void mie_int_cache_destroy(struct mie_int_cache *cache); +MIE_API struct mie_int *mie_int_cache_get( + struct mie_int_cache *cache, struct mie_ctx *ctx, size_t value, + size_t bit_width); #endif