export isl_map_compute_divs
[platform/upstream/isl.git] / isl_blk.c
1 /*
2  * Copyright 2008-2009 Katholieke Universiteit Leuven
3  *
4  * Use of this software is governed by the GNU LGPLv2.1 license
5  *
6  * Written by Sven Verdoolaege, K.U.Leuven, Departement
7  * Computerwetenschappen, Celestijnenlaan 200A, B-3001 Leuven, Belgium
8  */
9
10 #include "isl_blk.h"
11 #include "isl_ctx.h"
12
13 struct isl_blk isl_blk_empty()
14 {
15         struct isl_blk block;
16         block.size = 0;
17         block.data = NULL;
18         return block;
19 }
20
21 static int isl_blk_is_empty(struct isl_blk block)
22 {
23         return block.size == 0 && block.data == NULL;
24 }
25
26 static struct isl_blk isl_blk_error()
27 {
28         struct isl_blk block;
29         block.size = -1;
30         block.data = NULL;
31         return block;
32 }
33
34 int isl_blk_is_error(struct isl_blk block)
35 {
36         return block.size == -1 && block.data == NULL;
37 }
38
39 struct isl_blk isl_blk_alloc(struct isl_ctx *ctx, size_t n)
40 {
41         int i;
42         struct isl_blk block;
43
44         if (ctx->n_cached) {
45                 int best = 0;
46                 for (i = 1; ctx->cache[best].size != n && i < ctx->n_cached; ++i) {
47                         if (ctx->cache[best].size < n) {
48                                 if (ctx->cache[i].size > ctx->cache[best].size)
49                                         best = i;
50                         } else if (ctx->cache[i].size >= n &&
51                                    ctx->cache[i].size < ctx->cache[best].size)
52                                         best = i;
53                 }
54                 block = ctx->cache[best];
55                 if (--ctx->n_cached != best)
56                         ctx->cache[best] = ctx->cache[ctx->n_cached];
57         } else
58                 block = isl_blk_empty();
59
60         return isl_blk_extend(ctx, block, n);
61 }
62
63 struct isl_blk isl_blk_extend(struct isl_ctx *ctx, struct isl_blk block,
64                                 size_t new_n)
65 {
66         int i;
67         isl_int *p;
68
69         if (block.size >= new_n)
70                 return block;
71
72         p = block.data;
73         block.data = isl_realloc_array(ctx, block.data, isl_int, new_n);
74         if (!block.data) {
75                 free(p);
76                 return isl_blk_error();
77         }
78
79         for (i = block.size; i < new_n; ++i)
80                 isl_int_init(block.data[i]);
81         block.size = new_n;
82
83         return block;
84 }
85
86 static void isl_blk_free_force(struct isl_ctx *ctx, struct isl_blk block)
87 {
88         int i;
89
90         for (i = 0; i < block.size; ++i)
91                 isl_int_clear(block.data[i]);
92         free(block.data);
93 }
94
95 void isl_blk_free(struct isl_ctx *ctx, struct isl_blk block)
96 {
97         if (isl_blk_is_empty(block) || isl_blk_is_error(block))
98                 return;
99
100         if (ctx->n_cached < ISL_BLK_CACHE_SIZE)
101                 ctx->cache[ctx->n_cached++] = block;
102         else
103                 isl_blk_free_force(ctx, block);
104 }
105
106 void isl_blk_clear_cache(struct isl_ctx *ctx)
107 {
108         int i;
109
110         for (i = 0; i < ctx->n_cached; ++i)
111                 isl_blk_free_force(ctx, ctx->cache[i]);
112         ctx->n_cached = 0;
113 }