152a25237STobias Grosser /*
252a25237STobias Grosser * Copyright 2008-2009 Katholieke Universiteit Leuven
352a25237STobias Grosser *
452a25237STobias Grosser * Use of this software is governed by the MIT license
552a25237STobias Grosser *
652a25237STobias Grosser * Written by Sven Verdoolaege, K.U.Leuven, Departement
752a25237STobias Grosser * Computerwetenschappen, Celestijnenlaan 200A, B-3001 Leuven, Belgium
852a25237STobias Grosser */
952a25237STobias Grosser
1052a25237STobias Grosser #include <isl_blk.h>
1152a25237STobias Grosser #include <isl_ctx_private.h>
1252a25237STobias Grosser
1352a25237STobias Grosser /* The maximal number of cache misses before first element is evicted */
1452a25237STobias Grosser #define ISL_BLK_MAX_MISS 100
1552a25237STobias Grosser
isl_blk_empty()1652a25237STobias Grosser struct isl_blk isl_blk_empty()
1752a25237STobias Grosser {
1852a25237STobias Grosser struct isl_blk block;
1952a25237STobias Grosser block.size = 0;
2052a25237STobias Grosser block.data = NULL;
2152a25237STobias Grosser return block;
2252a25237STobias Grosser }
2352a25237STobias Grosser
isl_blk_is_empty(struct isl_blk block)2452a25237STobias Grosser static int isl_blk_is_empty(struct isl_blk block)
2552a25237STobias Grosser {
2652a25237STobias Grosser return block.size == 0 && block.data == NULL;
2752a25237STobias Grosser }
2852a25237STobias Grosser
isl_blk_error()2952a25237STobias Grosser static struct isl_blk isl_blk_error()
3052a25237STobias Grosser {
3152a25237STobias Grosser struct isl_blk block;
3252a25237STobias Grosser block.size = -1;
3352a25237STobias Grosser block.data = NULL;
3452a25237STobias Grosser return block;
3552a25237STobias Grosser }
3652a25237STobias Grosser
isl_blk_is_error(struct isl_blk block)3752a25237STobias Grosser int isl_blk_is_error(struct isl_blk block)
3852a25237STobias Grosser {
3952a25237STobias Grosser return block.size == -1 && block.data == NULL;
4052a25237STobias Grosser }
4152a25237STobias Grosser
isl_blk_free_force(struct isl_ctx * ctx,struct isl_blk block)42*07b20952STobias Grosser static void isl_blk_free_force(struct isl_ctx *ctx, struct isl_blk block)
43*07b20952STobias Grosser {
44*07b20952STobias Grosser int i;
45*07b20952STobias Grosser
46*07b20952STobias Grosser for (i = 0; i < block.size; ++i)
47*07b20952STobias Grosser isl_int_clear(block.data[i]);
48*07b20952STobias Grosser free(block.data);
49*07b20952STobias Grosser }
50*07b20952STobias Grosser
extend(struct isl_ctx * ctx,struct isl_blk block,size_t new_n)5152a25237STobias Grosser static struct isl_blk extend(struct isl_ctx *ctx, struct isl_blk block,
5252a25237STobias Grosser size_t new_n)
5352a25237STobias Grosser {
5452a25237STobias Grosser int i;
5552a25237STobias Grosser isl_int *p;
5652a25237STobias Grosser
5752a25237STobias Grosser if (block.size >= new_n)
5852a25237STobias Grosser return block;
5952a25237STobias Grosser
60*07b20952STobias Grosser p = isl_realloc_array(ctx, block.data, isl_int, new_n);
61*07b20952STobias Grosser if (!p) {
62*07b20952STobias Grosser isl_blk_free_force(ctx, block);
6352a25237STobias Grosser return isl_blk_error();
6452a25237STobias Grosser }
65*07b20952STobias Grosser block.data = p;
6652a25237STobias Grosser
6752a25237STobias Grosser for (i = block.size; i < new_n; ++i)
6852a25237STobias Grosser isl_int_init(block.data[i]);
6952a25237STobias Grosser block.size = new_n;
7052a25237STobias Grosser
7152a25237STobias Grosser return block;
7252a25237STobias Grosser }
7352a25237STobias Grosser
isl_blk_alloc(struct isl_ctx * ctx,size_t n)7452a25237STobias Grosser struct isl_blk isl_blk_alloc(struct isl_ctx *ctx, size_t n)
7552a25237STobias Grosser {
7652a25237STobias Grosser int i;
7752a25237STobias Grosser struct isl_blk block;
7852a25237STobias Grosser
7952a25237STobias Grosser block = isl_blk_empty();
8052a25237STobias Grosser if (n && ctx->n_cached) {
8152a25237STobias Grosser int best = 0;
8252a25237STobias Grosser for (i = 1; ctx->cache[best].size != n && i < ctx->n_cached; ++i) {
8352a25237STobias Grosser if (ctx->cache[best].size < n) {
8452a25237STobias Grosser if (ctx->cache[i].size > ctx->cache[best].size)
8552a25237STobias Grosser best = i;
8652a25237STobias Grosser } else if (ctx->cache[i].size >= n &&
8752a25237STobias Grosser ctx->cache[i].size < ctx->cache[best].size)
8852a25237STobias Grosser best = i;
8952a25237STobias Grosser }
9052a25237STobias Grosser if (ctx->cache[best].size < 2 * n + 100) {
9152a25237STobias Grosser block = ctx->cache[best];
9252a25237STobias Grosser if (--ctx->n_cached != best)
9352a25237STobias Grosser ctx->cache[best] = ctx->cache[ctx->n_cached];
9452a25237STobias Grosser if (best == 0)
9552a25237STobias Grosser ctx->n_miss = 0;
9652a25237STobias Grosser } else if (ctx->n_miss++ >= ISL_BLK_MAX_MISS) {
9752a25237STobias Grosser isl_blk_free_force(ctx, ctx->cache[0]);
9852a25237STobias Grosser if (--ctx->n_cached != 0)
9952a25237STobias Grosser ctx->cache[0] = ctx->cache[ctx->n_cached];
10052a25237STobias Grosser ctx->n_miss = 0;
10152a25237STobias Grosser }
10252a25237STobias Grosser }
10352a25237STobias Grosser
10452a25237STobias Grosser return extend(ctx, block, n);
10552a25237STobias Grosser }
10652a25237STobias Grosser
isl_blk_extend(struct isl_ctx * ctx,struct isl_blk block,size_t new_n)10752a25237STobias Grosser struct isl_blk isl_blk_extend(struct isl_ctx *ctx, struct isl_blk block,
10852a25237STobias Grosser size_t new_n)
10952a25237STobias Grosser {
11052a25237STobias Grosser if (isl_blk_is_empty(block))
11152a25237STobias Grosser return isl_blk_alloc(ctx, new_n);
11252a25237STobias Grosser
11352a25237STobias Grosser return extend(ctx, block, new_n);
11452a25237STobias Grosser }
11552a25237STobias Grosser
isl_blk_free(struct isl_ctx * ctx,struct isl_blk block)11652a25237STobias Grosser void isl_blk_free(struct isl_ctx *ctx, struct isl_blk block)
11752a25237STobias Grosser {
11852a25237STobias Grosser if (isl_blk_is_empty(block) || isl_blk_is_error(block))
11952a25237STobias Grosser return;
12052a25237STobias Grosser
12152a25237STobias Grosser if (ctx->n_cached < ISL_BLK_CACHE_SIZE)
12252a25237STobias Grosser ctx->cache[ctx->n_cached++] = block;
12352a25237STobias Grosser else
12452a25237STobias Grosser isl_blk_free_force(ctx, block);
12552a25237STobias Grosser }
12652a25237STobias Grosser
isl_blk_clear_cache(struct isl_ctx * ctx)12752a25237STobias Grosser void isl_blk_clear_cache(struct isl_ctx *ctx)
12852a25237STobias Grosser {
12952a25237STobias Grosser int i;
13052a25237STobias Grosser
13152a25237STobias Grosser for (i = 0; i < ctx->n_cached; ++i)
13252a25237STobias Grosser isl_blk_free_force(ctx, ctx->cache[i]);
13352a25237STobias Grosser ctx->n_cached = 0;
13452a25237STobias Grosser }
135