Home | History | Annotate | Download | only in isl
      1 /*
      2  * Copyright 2008-2009 Katholieke Universiteit Leuven
      3  *
      4  * Use of this software is governed by the MIT license
      5  *
      6  * Written by Sven Verdoolaege, K.U.Leuven, Departement
      7  * Computerwetenschappen, Celestijnenlaan 200A, B-3001 Leuven, Belgium
      8  */
      9 
     10 #ifndef ISL_CTX_H
     11 #define ISL_CTX_H
     12 
     13 #include <stdio.h>
     14 #include <stdlib.h>
     15 
     16 #include <isl/int.h>
     17 #include <isl/blk.h>
     18 #include <isl/arg.h>
     19 #include <isl/hash.h>
     20 #include <isl/config.h>
     21 
     22 #ifndef __isl_give
     23 #define __isl_give
     24 #endif
     25 #ifndef __isl_take
     26 #define __isl_take
     27 #endif
     28 #ifndef __isl_keep
     29 #define __isl_keep
     30 #endif
     31 #ifndef __isl_export
     32 #define __isl_export
     33 #endif
     34 #ifndef __isl_constructor
     35 #define __isl_constructor
     36 #endif
     37 #ifndef __isl_subclass
     38 #define __isl_subclass(super)
     39 #endif
     40 
     41 #ifdef GCC_WARN_UNUSED_RESULT
     42 #define	WARN_UNUSED	GCC_WARN_UNUSED_RESULT
     43 #else
     44 #define WARN_UNUSED
     45 #endif
     46 
     47 #if defined(__cplusplus)
     48 extern "C" {
     49 #endif
     50 
     51 /* Nearly all isa functions require a struct isl_ctx allocated using
     52  * isl_ctx_alloc.  This ctx contains (or will contain) options that
     53  * control the behavior of the library and some caches.
     54  *
     55  * An object allocated within a given ctx should never be used inside
     56  * another ctx.  Functions for moving objects from one ctx to another
     57  * will be added as the need arises.
     58  *
     59  * A given context should only be used inside a single thread.
     60  * A global context for synchronization between different threads
     61  * as well as functions for moving a context to a different thread
     62  * will be added as the need arises.
     63  *
     64  * If anything goes wrong (out of memory, failed assertion), then
     65  * the library will currently simply abort.  This will be made
     66  * configurable in the future.
     67  * Users of the library should expect functions that return
     68  * a pointer to a structure, to return NULL, indicating failure.
     69  * Any function accepting a pointer to a structure will treat
     70  * a NULL argument as a failure, resulting in the function freeing
     71  * the remaining structures (if any) and returning NULL itself
     72  * (in case of pointer return type).
     73  * The only exception is the isl_ctx argument, which should never be NULL.
     74  */
     75 struct isl_stats {
     76 	long	gbr_solved_lps;
     77 };
     78 enum isl_error {
     79 	isl_error_none = 0,
     80 	isl_error_abort,
     81 	isl_error_unknown,
     82 	isl_error_internal,
     83 	isl_error_invalid,
     84 	isl_error_unsupported
     85 };
     86 struct isl_ctx;
     87 typedef struct isl_ctx isl_ctx;
     88 
     89 /* Some helper macros */
     90 
     91 #define ISL_FL_INIT(l, f)   (l) = (f)               /* Specific flags location. */
     92 #define ISL_FL_SET(l, f)    ((l) |= (f))
     93 #define ISL_FL_CLR(l, f)    ((l) &= ~(f))
     94 #define ISL_FL_ISSET(l, f)  (!!((l) & (f)))
     95 
     96 #define ISL_F_INIT(p, f)    ISL_FL_INIT((p)->flags, f)  /* Structure element flags. */
     97 #define ISL_F_SET(p, f)     ISL_FL_SET((p)->flags, f)
     98 #define ISL_F_CLR(p, f)     ISL_FL_CLR((p)->flags, f)
     99 #define ISL_F_ISSET(p, f)   ISL_FL_ISSET((p)->flags, f)
    100 
    101 /* isl_check_ctx() checks at compile time if 'ctx' is of type 'isl_ctx *' and
    102  * returns the value of 'expr'. It is used to ensure, that always an isl_ctx is
    103  * passed to the following macros, even if they currently do not use it.
    104  */
    105 #define isl_check_ctx(ctx, expr)	((ctx != (isl_ctx *) 0) ? expr : expr)
    106 
    107 #define isl_alloc(ctx,type,size)	((type *)isl_check_ctx(ctx,\
    108 							malloc(size)))
    109 #define isl_calloc(ctx,type,size)	((type *)isl_check_ctx(ctx,\
    110 							calloc(1, size)))
    111 #define isl_realloc(ctx,ptr,type,size)	((type *)isl_check_ctx(ctx,\
    112 							realloc(ptr,size)))
    113 #define isl_alloc_type(ctx,type)	isl_alloc(ctx,type,sizeof(type))
    114 #define isl_calloc_type(ctx,type)	isl_calloc(ctx,type,sizeof(type))
    115 #define isl_realloc_type(ctx,ptr,type)	isl_realloc(ctx,ptr,type,sizeof(type))
    116 #define isl_alloc_array(ctx,type,n)	isl_alloc(ctx,type,(n)*sizeof(type))
    117 #define isl_calloc_array(ctx,type,n)	((type *)isl_check_ctx(ctx,\
    118 						calloc(n, sizeof(type))))
    119 #define isl_realloc_array(ctx,ptr,type,n) \
    120 				    isl_realloc(ctx,ptr,type,(n)*sizeof(type))
    121 
    122 #define isl_die(ctx,errno,msg,code)					\
    123 	do {								\
    124 		isl_handle_error(ctx, errno, msg, __FILE__, __LINE__);	\
    125 		code;							\
    126 	} while (0)
    127 
    128 void isl_handle_error(isl_ctx *ctx, enum isl_error error, const char *msg,
    129 	const char *file, int line);
    130 
    131 #define isl_assert4(ctx,test,code,errno)				\
    132 	do {								\
    133 		if (test)						\
    134 			break;						\
    135 		isl_die(ctx, errno, "Assertion \"" #test "\" failed", code);	\
    136 	} while (0)
    137 #define isl_assert(ctx,test,code)					\
    138 	isl_assert4(ctx,test,code,isl_error_unknown)
    139 
    140 #define isl_min(a,b)			((a < b) ? (a) : (b))
    141 
    142 /* struct isl_ctx functions */
    143 
    144 struct isl_options *isl_ctx_options(isl_ctx *ctx);
    145 
    146 isl_ctx *isl_ctx_alloc_with_options(struct isl_args *args,
    147 	__isl_take void *opt);
    148 isl_ctx *isl_ctx_alloc(void);
    149 void *isl_ctx_peek_options(isl_ctx *ctx, struct isl_args *args);
    150 int isl_ctx_parse_options(isl_ctx *ctx, int argc, char **argv, unsigned flags);
    151 void isl_ctx_ref(struct isl_ctx *ctx);
    152 void isl_ctx_deref(struct isl_ctx *ctx);
    153 void isl_ctx_free(isl_ctx *ctx);
    154 
    155 void isl_ctx_abort(isl_ctx *ctx);
    156 void isl_ctx_resume(isl_ctx *ctx);
    157 int isl_ctx_aborted(isl_ctx *ctx);
    158 
    159 #define ISL_ARG_CTX_DECL(prefix,st,args)				\
    160 st *isl_ctx_peek_ ## prefix(isl_ctx *ctx);
    161 
    162 #define ISL_ARG_CTX_DEF(prefix,st,args)					\
    163 st *isl_ctx_peek_ ## prefix(isl_ctx *ctx)				\
    164 {									\
    165 	return (st *)isl_ctx_peek_options(ctx, &(args));		\
    166 }
    167 
    168 #define ISL_CTX_GET_INT_DEF(prefix,st,args,field)			\
    169 int prefix ## _get_ ## field(isl_ctx *ctx)				\
    170 {									\
    171 	st *options;							\
    172 	options = isl_ctx_peek_ ## prefix(ctx);				\
    173 	if (!options)							\
    174 		isl_die(ctx, isl_error_invalid,				\
    175 			"isl_ctx does not reference " #prefix,		\
    176 			return -1);					\
    177 	return options->field;						\
    178 }
    179 
    180 #define ISL_CTX_SET_INT_DEF(prefix,st,args,field)			\
    181 int prefix ## _set_ ## field(isl_ctx *ctx, int val)			\
    182 {									\
    183 	st *options;							\
    184 	options = isl_ctx_peek_ ## prefix(ctx);				\
    185 	if (!options)							\
    186 		isl_die(ctx, isl_error_invalid,				\
    187 			"isl_ctx does not reference " #prefix,		\
    188 			return -1);					\
    189 	options->field = val;						\
    190 	return 0;							\
    191 }
    192 
    193 #define ISL_CTX_GET_STR_DEF(prefix,st,args,field)			\
    194 const char *prefix ## _get_ ## field(isl_ctx *ctx)			\
    195 {									\
    196 	st *options;							\
    197 	options = isl_ctx_peek_ ## prefix(ctx);				\
    198 	if (!options)							\
    199 		isl_die(ctx, isl_error_invalid,				\
    200 			"isl_ctx does not reference " #prefix,		\
    201 			return NULL);					\
    202 	return options->field;						\
    203 }
    204 
    205 #define ISL_CTX_SET_STR_DEF(prefix,st,args,field)			\
    206 int prefix ## _set_ ## field(isl_ctx *ctx, const char *val)		\
    207 {									\
    208 	st *options;							\
    209 	options = isl_ctx_peek_ ## prefix(ctx);				\
    210 	if (!options)							\
    211 		isl_die(ctx, isl_error_invalid,				\
    212 			"isl_ctx does not reference " #prefix,		\
    213 			return -1);					\
    214 	if (!val)							\
    215 		return -1;						\
    216 	free(options->field);						\
    217 	options->field = strdup(val);					\
    218 	if (!options->field)						\
    219 		return -1;						\
    220 	return 0;							\
    221 }
    222 
    223 #define ISL_CTX_GET_BOOL_DEF(prefix,st,args,field)			\
    224 	ISL_CTX_GET_INT_DEF(prefix,st,args,field)
    225 
    226 #define ISL_CTX_SET_BOOL_DEF(prefix,st,args,field)			\
    227 	ISL_CTX_SET_INT_DEF(prefix,st,args,field)
    228 
    229 #define ISL_CTX_GET_CHOICE_DEF(prefix,st,args,field)			\
    230 	ISL_CTX_GET_INT_DEF(prefix,st,args,field)
    231 
    232 #define ISL_CTX_SET_CHOICE_DEF(prefix,st,args,field)			\
    233 	ISL_CTX_SET_INT_DEF(prefix,st,args,field)
    234 
    235 enum isl_error isl_ctx_last_error(isl_ctx *ctx);
    236 void isl_ctx_reset_error(isl_ctx *ctx);
    237 void isl_ctx_set_error(isl_ctx *ctx, enum isl_error error);
    238 
    239 #if defined(__cplusplus)
    240 }
    241 #endif
    242 
    243 #endif
    244