xref: /llvm-project/polly/lib/External/isl/isl_blk.c (revision 07b209523403d6c0d68c328cb20a8eaf6b51369c)
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