summaryrefslogtreecommitdiffstats
path: root/polly/lib/External/ppcg/print.c
diff options
context:
space:
mode:
Diffstat (limited to 'polly/lib/External/ppcg/print.c')
-rw-r--r--polly/lib/External/ppcg/print.c230
1 files changed, 230 insertions, 0 deletions
diff --git a/polly/lib/External/ppcg/print.c b/polly/lib/External/ppcg/print.c
new file mode 100644
index 00000000000..799da76829c
--- /dev/null
+++ b/polly/lib/External/ppcg/print.c
@@ -0,0 +1,230 @@
+/*
+ * Copyright 2012-2013 Ecole Normale Superieure
+ *
+ * Use of this software is governed by the MIT license
+ *
+ * Written by Sven Verdoolaege,
+ * Ecole Normale Superieure, 45 rue d’Ulm, 75230 Paris, France
+ */
+
+#include <isl/aff.h>
+#include <isl/ast_build.h>
+
+#include "print.h"
+
+__isl_give isl_printer *ppcg_start_block(__isl_take isl_printer *p)
+{
+ p = isl_printer_start_line(p);
+ p = isl_printer_print_str(p, "{");
+ p = isl_printer_end_line(p);
+ p = isl_printer_indent(p, 2);
+ return p;
+}
+
+__isl_give isl_printer *ppcg_end_block(__isl_take isl_printer *p)
+{
+ p = isl_printer_indent(p, -2);
+ p = isl_printer_start_line(p);
+ p = isl_printer_print_str(p, "}");
+ p = isl_printer_end_line(p);
+ return p;
+}
+
+static int print_macro(enum isl_ast_op_type type, void *user)
+{
+ isl_printer **p = user;
+
+ if (type == isl_ast_op_fdiv_q)
+ return 0;
+
+ *p = isl_ast_op_type_print_macro(type, *p);
+
+ return 0;
+}
+
+/* Print the required macros for "node", except one for floord.
+ * The caller is assumed to have printed a macro for floord already
+ * as it may also appear in the declarations and the statements.
+ */
+__isl_give isl_printer *ppcg_print_macros(__isl_take isl_printer *p,
+ __isl_keep isl_ast_node *node)
+{
+ if (isl_ast_node_foreach_ast_op_type(node, &print_macro, &p) < 0)
+ return isl_printer_free(p);
+ return p;
+}
+
+/* Print "extent" as a sequence of
+ *
+ * [1 + maximal_value]
+ *
+ * one for each dimension.
+ * "build" is used to simplify the size expressions, if any.
+ */
+static __isl_give isl_printer *print_extent(__isl_take isl_printer *p,
+ __isl_keep isl_set *extent, __isl_keep isl_ast_build *build)
+{
+ int i, n;
+
+ n = isl_set_dim(extent, isl_dim_set);
+ if (n == 0)
+ return p;
+
+ for (i = 0; i < n; ++i) {
+ isl_set *dom;
+ isl_local_space *ls;
+ isl_aff *one;
+ isl_pw_aff *bound;
+ isl_ast_expr *expr;
+
+ bound = isl_set_dim_max(isl_set_copy(extent), i);
+ dom = isl_pw_aff_domain(isl_pw_aff_copy(bound));
+ ls = isl_local_space_from_space(isl_set_get_space(dom));
+ one = isl_aff_zero_on_domain(ls);
+ one = isl_aff_add_constant_si(one, 1);
+ bound = isl_pw_aff_add(bound, isl_pw_aff_alloc(dom, one));
+
+ p = isl_printer_print_str(p, "[");
+ expr = isl_ast_build_expr_from_pw_aff(build, bound);
+ p = isl_printer_print_ast_expr(p, expr);
+ p = isl_printer_print_str(p, "]");
+
+ isl_ast_expr_free(expr);
+ }
+
+ return p;
+}
+
+/* Print a declaration for array "array" to "p", using "build"
+ * to simplify any size expressions.
+ */
+__isl_give isl_printer *ppcg_print_declaration(__isl_take isl_printer *p,
+ struct pet_array *array, __isl_keep isl_ast_build *build)
+{
+ const char *name;
+
+ if (!array)
+ return isl_printer_free(p);
+
+ name = isl_set_get_tuple_name(array->extent);
+
+ p = isl_printer_start_line(p);
+ p = isl_printer_print_str(p, array->element_type);
+ p = isl_printer_print_str(p, " ");
+ p = isl_printer_print_str(p, name);
+ p = print_extent(p, array->extent, build);
+ p = isl_printer_print_str(p, ";");
+ p = isl_printer_end_line(p);
+
+ return p;
+}
+
+/* Print declarations for the arrays in "scop" that are declared
+ * and that are exposed (if exposed == 1) or not exposed (if exposed == 0).
+ */
+static __isl_give isl_printer *print_declarations(__isl_take isl_printer *p,
+ struct ppcg_scop *scop, int exposed)
+{
+ int i;
+ isl_ast_build *build;
+
+ if (!scop)
+ return isl_printer_free(p);
+
+ build = isl_ast_build_from_context(isl_set_copy(scop->context));
+ for (i = 0; i < scop->pet->n_array; ++i) {
+ struct pet_array *array = scop->pet->arrays[i];
+
+ if (!array->declared)
+ continue;
+ if (array->exposed != exposed)
+ continue;
+
+ p = ppcg_print_declaration(p, array, build);
+ }
+ isl_ast_build_free(build);
+
+ return p;
+}
+
+/* Print declarations for the arrays in "scop" that are declared
+ * and exposed to the code after the scop.
+ */
+__isl_give isl_printer *ppcg_print_exposed_declarations(
+ __isl_take isl_printer *p, struct ppcg_scop *scop)
+{
+ return print_declarations(p, scop, 1);
+}
+
+/* Print declarations for the arrays in "scop" that are declared,
+ * but not exposed to the code after the scop.
+ */
+__isl_give isl_printer *ppcg_print_hidden_declarations(
+ __isl_take isl_printer *p, struct ppcg_scop *scop)
+{
+ return print_declarations(p, scop, 0);
+}
+
+/* Internal data structure for print_guarded_user.
+ *
+ * fn is the function that should be called to print the body.
+ * user is the argument that should be passed to this function.
+ */
+struct ppcg_print_guarded_data {
+ __isl_give isl_printer *(*fn)(__isl_take isl_printer *p, void *user);
+ void *user;
+};
+
+/* Print the body of the if statement expressing the guard passed
+ * to "ppcg_print_guarded" by calling data->fn.
+ */
+static __isl_give isl_printer *print_guarded_user(__isl_take isl_printer *p,
+ __isl_take isl_ast_print_options *options,
+ __isl_keep isl_ast_node *node, void *user)
+{
+ struct ppcg_print_guarded_data *data = user;
+
+ p = data->fn(p, data->user);
+
+ isl_ast_print_options_free(options);
+ return p;
+}
+
+/* Print a condition for the given "guard" within the given "context"
+ * on "p", calling "fn" with "user" to print the body of the if statement.
+ * If the guard is implied by the context, then no if statement is printed
+ * and the body is printed directly to "p".
+ *
+ * Both "guard" and "context" are assumed to be parameter sets.
+ *
+ * We slightly abuse the AST generator to print this guard.
+ * In particular, we create a trivial schedule for an iteration
+ * domain with a single instance, restricted by the guard.
+ */
+__isl_give isl_printer *ppcg_print_guarded(__isl_take isl_printer *p,
+ __isl_take isl_set *guard, __isl_take isl_set *context,
+ __isl_give isl_printer *(*fn)(__isl_take isl_printer *p, void *user),
+ void *user)
+{
+ struct ppcg_print_guarded_data data = { fn, user };
+ isl_ctx *ctx;
+ isl_union_map *schedule;
+ isl_ast_build *build;
+ isl_ast_node *tree;
+ isl_ast_print_options *options;
+
+ ctx = isl_printer_get_ctx(p);
+ guard = isl_set_from_params(guard);
+ schedule = isl_union_map_from_map(isl_map_from_domain(guard));
+ build = isl_ast_build_from_context(context);
+ tree = isl_ast_build_node_from_schedule_map(build, schedule);
+ isl_ast_build_free(build);
+
+ options = isl_ast_print_options_alloc(ctx);
+ options = isl_ast_print_options_set_print_user(options,
+ &print_guarded_user, &data);
+ p = isl_ast_node_print(tree, p, options);
+ isl_ast_node_free(tree);
+
+ return p;
+}
OpenPOWER on IntegriCloud