mie: arith: implement int value cache data structure
This commit is contained in:
139
mie/dialect/arith/int-cache.c
Normal file
139
mie/dialect/arith/int-cache.c
Normal file
@@ -0,0 +1,139 @@
|
||||
#include <blue/core/btree.h>
|
||||
#include <mie/dialect/arith.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
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;
|
||||
}
|
||||
@@ -2,14 +2,52 @@
|
||||
#define MIE_DIALECT_ARITH_H_
|
||||
|
||||
#include <mie/misc.h>
|
||||
#include <mie/value.h>
|
||||
#include <stddef.h>
|
||||
#include <stdint.h>
|
||||
|
||||
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
|
||||
|
||||
Reference in New Issue
Block a user