From e1295555fc6be58317d2843aaa05ee6f60da454d Mon Sep 17 00:00:00 2001 From: Sven Verdoolaege Date: Sun, 25 Jul 2010 21:28:03 +0200 Subject: [PATCH] iscc: support codegen operation if CLooG is available --- Makefile.am | 3 +- configure.in | 24 +++++++++ doc/isl.tex | 8 +++ iscc.c | 173 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 207 insertions(+), 1 deletion(-) diff --git a/Makefile.am b/Makefile.am index a65e739..c06f08d 100644 --- a/Makefile.am +++ b/Makefile.am @@ -367,8 +367,9 @@ iscc_SOURCES = \ isl_obj_list.h \ isl_obj_list.c \ iscc.c +iscc_CPPFLAGS = @CLOOG_CFLAGS@ $(AM_CPPFLAGS) iscc_LDADD = \ - libbarvinok.la @ISL_POLYLIB_LIBS@ @ISL_LIBS@ \ + libbarvinok.la @CLOOG_LIBS@ @CLOOG_LIBS@ @ISL_POLYLIB_LIBS@ @ISL_LIBS@ \ @POLYLIB_LIBS@ @PIPLIB_LIBS@ TESTFILES = $(shell find $(top_srcdir)/tests -type f ! -path '*CVS*') diff --git a/configure.in b/configure.in index b707703..2aed328 100644 --- a/configure.in +++ b/configure.in @@ -468,6 +468,30 @@ if test "$topcom_package" != no; then fi AM_CONDITIONAL(HAVE_TOPCOM, test x$have_topcom = xtrue) +AX_SUBMODULE(cloog,no|build|system,no) + +AC_SUBST(CLOOG_LDFLAGS) +AC_SUBST(CLOOG_CFLAGS) +AC_SUBST(CLOOG_LIBS) +CLOOG_CFLAGS="-DCLOOG_INT_GMP=1" +case "$with_cloog" in +build) + with_cloog_builddir=`echo @abs_builddir@ | $with_cloog_builddir/config.status --file=-` + CLOOG_CFLAGS="$CLOOG_CFLAGS -I$cloog_srcdir/include -I$with_cloog_builddir/include" + CLOOG_LIBS="$with_cloog_builddir/libcloog-isl.la" + AC_DEFINE(HAVE_CLOOG,[],[use CLooG]) + ;; +system) + if test "x$with_cloog_prefix" != "x"; then + CLOOG_CFLAGS="$CLOOG_CFLAGS -I$with_cloog_prefix/include" + fi + if test "x$with_cloog_exec_prefix" != "x"; then + CLOOG_LDFLAGS="-L$with_cloog_exec_prefix/lib" + fi + CLOOG_LIBS="-lcloog-isl" + AC_DEFINE(HAVE_CLOOG,[],[use CLooG]) +esac + AC_SUBST(GIT_HEAD_ID) AC_SUBST(GIT_HEAD) AC_SUBST(GIT_HEAD_VERSION) diff --git a/doc/isl.tex b/doc/isl.tex index 2e1c187..075243e 100644 --- a/doc/isl.tex +++ b/doc/isl.tex @@ -67,6 +67,8 @@ m := [n] -> { [i,j] -> [i+1,j+1] : 1 <= i,j < n; [i,j] -> [i+1,j-1] : 1 <= i < n and 2 <= j <= n }; m^+; (m^+)[0]; + +codegen [N] -> { A[i] -> [i,0] : 0 <= i <= N; B[i] -> [i,1] : 1 <= i <= N }; \end{verbatim} \bottomcaption{{\tt iscc} operations. The variables @@ -82,6 +84,7 @@ $o$: object of any type } \label{t:iscc} \tablehead{ +\hline Syntax & Meaning \\ \hline @@ -122,6 +125,11 @@ simplify the representation of $f_1$ by trying to combine pairs of basic sets in the domain of $f_1$ into a single basic set \\ +\ai[\tt]{codegen} $m$ & +generate code for the given scattering function. +This operation is only available if \ai[\tt]{CLooG} +support was compiled in. +\\ $s_3$ := $s_1$ \ai[\tt]{cross} $s_2$ & Cartesian product of $s_1$ and $s_2$ \\ diff --git a/iscc.c b/iscc.c index e2a0c66..79b1a55 100644 --- a/iscc.c +++ b/iscc.c @@ -9,6 +9,10 @@ #include "config.h" +#ifdef HAVE_CLOOG +#include +#endif + static int isl_bool_false = 0; static int isl_bool_true = 1; static int isl_bool_error = -1; @@ -366,6 +370,172 @@ error: return NULL; } +#ifdef HAVE_CLOOG +struct iscc_codegen_data { + int nr; + int nparam; + int max_iter; + int n_scat; + isl_set *context; + CloogState *state; + CloogLoop **next; + CloogBlockList **nextBL; + CloogScatteringList *scatterings; + CloogScatteringList **nextScat; +}; + +static int add_domain(__isl_take isl_map *map, void *user) +{ + struct iscc_codegen_data *data = (struct iscc_codegen_data *)user; + isl_ctx *ctx = isl_map_get_ctx(map); + isl_dim *dim; + isl_set *domain; + CloogStatement *statement; + CloogLoop *l; + CloogScatteringList *s; + int n_in; + + n_in = isl_map_dim(map, isl_dim_in); + if (data->nr == 0) { + isl_dim *dim = isl_map_get_dim(map); + data->nparam = isl_map_dim(map, isl_dim_param); + data->n_scat = isl_map_dim(map, isl_dim_out); + dim = isl_dim_drop_inputs(dim, 0, n_in); + dim = isl_dim_drop_outputs(dim, 0, data->n_scat); + data->context = isl_set_universe(dim); + } else { + isl_assert(ctx, data->nparam == isl_map_dim(map, isl_dim_param), + goto error); + isl_assert(ctx, data->n_scat == isl_map_dim(map, isl_dim_out), + goto error); + } + if (n_in > data->max_iter) + data->max_iter = n_in; + + l = cloog_loop_malloc(data->state); + if (!l) + goto error; + l->next = NULL; + l->inner = NULL; + domain = isl_map_domain(isl_map_copy(map)); + l->domain = cloog_domain_from_isl_set(domain); + + statement = cloog_statement_alloc(data->state, data->nr); + statement->usr = NULL; + dim = isl_map_get_dim(map); + statement->name = strdup(isl_dim_get_tuple_name(dim, isl_dim_in)); + isl_dim_free(dim); + l->block = cloog_block_alloc(statement, 0, NULL, n_in); + + s = isl_alloc_type(ctx, CloogScatteringList); + s->scatt = cloog_scattering_from_isl_map(map); + s->next = NULL; + + *data->next = l; + *data->nextBL = cloog_block_list_alloc((*data->next)->block); + data->next = &(*data->next)->next; + data->nextBL = &(*data->nextBL)->next; + *data->nextScat = s; + data->nextScat = &(s->next); + + data->nr++; + + return 0; +error: + return -1; +} + +char **generate_names(isl_ctx *ctx, int n, const char *prefix) +{ + int i; + char **names; + + names = isl_alloc_array(ctx, char *, n); + for (i = 0; i < n; i++) { + names[i] = isl_alloc_array(ctx, char, 50); + sprintf(names[i], "%s%d", prefix, i); + } + + return names; +} + +void *codegen(void *arg) +{ + int i; + struct iscc_codegen_data data; + isl_dim *dim; + isl_union_map *umap = (isl_union_map *)arg; + isl_ctx *ctx = isl_union_map_get_ctx(umap); + CloogOptions *options; + CloogProgram *p; + struct clast_stmt *stmt; + + data.state = cloog_isl_state_malloc(ctx); + options = cloog_options_malloc(data.state); + options->language = LANGUAGE_C; + p = cloog_program_malloc(); + + isl_assert(ctx, p, goto error); + p->names = cloog_names_malloc(); + isl_assert(ctx, p->names, goto error2); + p->language = 'c'; + + data.context = NULL; + data.nr = 0; + data.nparam = -1; + data.max_iter = 0; + data.n_scat = -1; + data.next = &p->loop; + data.nextBL = &p->blocklist; + data.scatterings = NULL; + data.nextScat = &data.scatterings; + + if (isl_union_map_foreach_map(umap, &add_domain, &data) < 0) + goto error3; + + if (data.nr == 0) + goto error3; + + p->names->nb_parameters = data.nparam; + p->names->parameters = isl_alloc_array(ctx, char *, data.nparam); + dim = isl_set_get_dim(data.context); + p->context = cloog_domain_from_isl_set(data.context); + for (i = 0; i < data.nparam; ++i) { + const char *s = isl_dim_get_name(dim, isl_dim_param, i); + p->names->parameters[i] = strdup(s); + } + isl_dim_free(dim); + + p->names->nb_iterators = data.max_iter; + p->names->iterators = generate_names(ctx, data.max_iter, "i"); + + p->names->nb_scattering = data.n_scat; + p->names->scattering = generate_names(ctx, data.n_scat, "c"); + p->names->nb_scalars = 0; + p->nb_scattdims = data.n_scat; + p->scaldims = (int *)malloc(p->nb_scattdims*(sizeof(int))); + for (i = 0; i < p->nb_scattdims; i++) + p->scaldims[i] = 0; + + cloog_program_scatter(p, data.scatterings, options); + p = cloog_program_generate(p, options); + + stmt = cloog_clast_create(p, options); + clast_pprint(stdout, stmt, 0, options); + cloog_clast_free(stmt); + +error3: + cloog_scattering_list_free(data.scatterings); +error2: + cloog_program_free(p); +error: + cloog_options_free(options); + cloog_state_free(data.state); + isl_union_map_free(umap); + return NULL; +} +#endif + typedef void *(*isc_un_op_fn)(void *arg); struct isc_un_op { enum isl_token_type op; @@ -398,6 +568,9 @@ struct isc_named_un_op named_un_ops[] = { {"coalesce", { -1, isl_obj_union_pw_qpolynomial_fold, isl_obj_union_pw_qpolynomial_fold, (isc_un_op_fn) &isl_union_pw_qpolynomial_fold_coalesce } }, +#ifdef HAVE_CLOOG + {"codegen", { -1, isl_obj_union_map, isl_obj_none, &codegen } }, +#endif {"deltas", { -1, isl_obj_union_map, isl_obj_union_set, (isc_un_op_fn) &isl_union_map_deltas } }, {"dom", { -1, isl_obj_union_map, isl_obj_union_set, -- 2.11.4.GIT