/*
 * Copyright 2012,2014 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
 */

/* This program prints an AST that scans the domain elements of
 * the domain of a given schedule in the order specified by
 * the schedule tree or by their image(s) in the schedule map.
 *
 * The input consists of either a schedule tree or
 * a sequence of three sets/relations.
 * - a schedule map
 * - a context
 * - a relation describing AST generation options
 */

#include <assert.h>
#include <stdlib.h>
#include <isl/ast.h>
#include <isl/ast_build.h>
#include <isl/options.h>
#include <isl/space.h>
#include <isl/set.h>
#include <isl/union_set.h>
#include <isl/union_map.h>
#include <isl/stream.h>
#include <isl/schedule_node.h>

struct options {
	struct isl_options	*isl;
	unsigned		 atomic;
	unsigned		 separate;
};

ISL_ARGS_START(struct options, options_args)
ISL_ARG_CHILD(struct options, isl, "isl", &isl_options_args, "isl options")
ISL_ARG_BOOL(struct options, atomic, 0, "atomic", 0,
	"globally set the atomic option")
ISL_ARG_BOOL(struct options, separate, 0, "separate", 0,
	"globally set the separate option")
ISL_ARGS_END

ISL_ARG_DEF(cg_options, struct options, options_args)
ISL_ARG_CTX_DEF(cg_options, struct options, options_args)

/* Return a universal, 1-dimensional set with the given name.
 */
static __isl_give isl_union_set *universe(isl_ctx *ctx, const char *name)
{
	isl_space *space;

	space = isl_space_set_alloc(ctx, 0, 1);
	space = isl_space_set_tuple_name(space, isl_dim_set, name);
	return isl_union_set_from_set(isl_set_universe(space));
}

/* Set the "name" option for the entire schedule domain.
 */
static __isl_give isl_union_map *set_universe(__isl_take isl_union_map *opt,
	__isl_keep isl_union_map *schedule, const char *name)
{
	isl_ctx *ctx;
	isl_union_set *domain, *target;
	isl_union_map *option;

	ctx = isl_union_map_get_ctx(opt);

	domain = isl_union_map_range(isl_union_map_copy(schedule));
	domain = isl_union_set_universe(domain);
	target = universe(ctx, name);
	option = isl_union_map_from_domain_and_range(domain, target);
	opt = isl_union_map_union(opt, option);

	return opt;
}

/* Update the build options based on the user-specified options.
 *
 * If the --separate or --atomic options were specified, then
 * we clear any separate or atomic options that may already exist in "opt".
 */
static __isl_give isl_ast_build *set_options(__isl_take isl_ast_build *build,
	__isl_take isl_union_map *opt, struct options *options,
	__isl_keep isl_union_map *schedule)
{
	if (options->separate || options->atomic) {
		isl_ctx *ctx;
		isl_union_set *target;

		ctx = isl_union_map_get_ctx(schedule);

		target = universe(ctx, "separate");
		opt = isl_union_map_subtract_range(opt, target);
		target = universe(ctx, "atomic");
		opt = isl_union_map_subtract_range(opt, target);
	}

	if (options->separate)
		opt = set_universe(opt, schedule, "separate");
	if (options->atomic)
		opt = set_universe(opt, schedule, "atomic");

	build = isl_ast_build_set_options(build, opt);

	return build;
}

/* Construct an AST in case the schedule is specified by a union map.
 *
 * We read the context and the options from "s" and construct the AST.
 */
static __isl_give isl_ast_node *construct_ast_from_union_map(
	__isl_take isl_union_map *schedule, __isl_keep isl_stream *s)
{
	isl_set *context;
	isl_union_map *options_map;
	isl_ast_build *build;
	isl_ast_node *tree;
	struct options *options;

	options = isl_ctx_peek_cg_options(isl_stream_get_ctx(s));

	context = isl_stream_read_set(s);
	options_map = isl_stream_read_union_map(s);

	build = isl_ast_build_from_context(context);
	build = set_options(build, options_map, options, schedule);
	tree = isl_ast_build_node_from_schedule_map(build, schedule);
	isl_ast_build_free(build);

	return tree;
}

/* If "node" is a band node, then replace the AST build options
 * by "options".
 */
static __isl_give isl_schedule_node *node_set_options(
	__isl_take isl_schedule_node *node, void *user)
{
	enum isl_ast_loop_type *type = user;
	int i;
	isl_size n;

	if (isl_schedule_node_get_type(node) != isl_schedule_node_band)
		return node;

	n = isl_schedule_node_band_n_member(node);
	if (n < 0)
		return isl_schedule_node_free(node);
	for (i = 0; i < n; ++i)
		node = isl_schedule_node_band_member_set_ast_loop_type(node,
								i, *type);
	return node;
}

/* Replace the AST build options on all band nodes if requested
 * by the user.
 */
static __isl_give isl_schedule *schedule_set_options(
	__isl_take isl_schedule *schedule, struct options *options)
{
	enum isl_ast_loop_type type;

	if (!options->separate && !options->atomic)
		return schedule;

	type = options->separate ? isl_ast_loop_separate : isl_ast_loop_atomic;
	schedule = isl_schedule_map_schedule_node_bottom_up(schedule,
						&node_set_options, &type);

	return schedule;
}

/* Construct an AST in case the schedule is specified by a schedule tree.
 */
static __isl_give isl_ast_node *construct_ast_from_schedule(
	__isl_take isl_schedule *schedule)
{
	isl_ast_build *build;
	isl_ast_node *tree;
	struct options *options;

	options = isl_ctx_peek_cg_options(isl_schedule_get_ctx(schedule));

	build = isl_ast_build_alloc(isl_schedule_get_ctx(schedule));
	schedule = schedule_set_options(schedule, options);
	tree = isl_ast_build_node_from_schedule(build, schedule);
	isl_ast_build_free(build);

	return tree;
}

/* Read an object from stdin.
 * If it is a (union) map, then assume an input specified by
 * schedule map, context and options and construct an AST from
 * those elements
 * If it is a schedule object, then construct the AST from the schedule.
 */
int main(int argc, char **argv)
{
	isl_ctx *ctx;
	isl_stream *s;
	isl_ast_node *tree = NULL;
	struct options *options;
	isl_printer *p;
	struct isl_obj obj;
	int r = EXIT_SUCCESS;

	options = cg_options_new_with_defaults();
	assert(options);
	ctx = isl_ctx_alloc_with_options(&options_args, options);
	isl_options_set_ast_build_detect_min_max(ctx, 1);
	isl_options_set_ast_print_outermost_block(ctx, 0);
	argc = cg_options_parse(options, argc, argv, ISL_ARG_ALL);

	s = isl_stream_new_file(ctx, stdin);
	obj = isl_stream_read_obj(s);
	if (obj.v == NULL) {
		r = EXIT_FAILURE;
	} else if (obj.type == isl_obj_map) {
		isl_union_map *umap;

		umap = isl_union_map_from_map(obj.v);
		tree = construct_ast_from_union_map(umap, s);
	} else if (obj.type == isl_obj_union_map) {
		tree = construct_ast_from_union_map(obj.v, s);
	} else if (obj.type == isl_obj_schedule) {
		tree = construct_ast_from_schedule(obj.v);
	} else {
		obj.type->free(obj.v);
		isl_die(ctx, isl_error_invalid, "unknown input",
			r = EXIT_FAILURE);
	}
	isl_stream_free(s);

	p = isl_printer_to_file(ctx, stdout);
	p = isl_printer_set_output_format(p, ISL_FORMAT_C);
	p = isl_printer_print_ast_node(p, tree);
	isl_printer_free(p);

	isl_ast_node_free(tree);

	isl_ctx_free(ctx);
	return r;
}
