/*
 * 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"
#include "util.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;
}

/* Names of notes that keep track of whether min/max
 * macro definitions have already been printed.
 */
static const char *ppcg_max_printed = "ppcg_max_printed";
static const char *ppcg_min_printed = "ppcg_min_printed";

/* Has the macro definition corresponding to "note_name" been printed
 * to "p" before?
 * That is, does "p" have an associated "note_name" note?
 */
static isl_bool printed_before(__isl_keep isl_printer *p, const char *note_name)
{
	isl_ctx *ctx;
	isl_id *id;
	isl_bool printed;

	if (!p)
		return isl_bool_error;

	ctx = isl_printer_get_ctx(p);
	id = isl_id_alloc(ctx, note_name, NULL);
	printed = isl_printer_has_note(p, id);
	isl_id_free(id);

	return printed;
}

/* Keep track of the fact that the macro definition corresponding
 * to "note_name" has been printed to "p" by attaching a note with
 * that name.  The value of the note is of no importance, but it
 * has to be a valid isl_id, so the note identifier is reused
 * as the note.
 */
static __isl_give isl_printer *mark_printed(__isl_take isl_printer *p,
	const char *note_name)
{
	isl_ctx *ctx;
	isl_id *id;

	if (!p)
		return NULL;

	ctx = isl_printer_get_ctx(p);
	id = isl_id_alloc(ctx, note_name, NULL);
	return isl_printer_set_note(p, id, isl_id_copy(id));
}

/* Print a macro definition "def" for the macro "name" to "p",
 * unless such a macro definition has been printed to "p" before.
 * "note_name" is used as the name of the note that keeps track
 * of whether this printing has happened.
 */
static __isl_give isl_printer *print_ppcg_macro(__isl_take isl_printer *p,
	const char *name, const char *def, const char *note_name)
{
	isl_bool printed;

	printed = printed_before(p, note_name);
	if (printed < 0)
		return isl_printer_free(p);
	if (printed)
		return p;

	p = isl_printer_start_line(p);
	p = isl_printer_print_str(p, "#define ");
	p = isl_printer_print_str(p, name);
	p = isl_printer_print_str(p, def);
	p = isl_printer_end_line(p);

	p = mark_printed(p, note_name);

	return p;
}

/* Structure for keeping track of definitions of some macros.
 */
struct ppcg_macros {
	const char *min;
	const char *max;
};

/* Free the memory allocated by a struct ppcg_macros.
 */
static void ppcg_macros_free(void *user)
{
	free(user);
}

/* Default macro definitions (when GNU extensions are allowed).
 */
struct ppcg_macros ppcg_macros_default = {
	.min = "(x,y)    "
		"({ __typeof__(x) _x = (x); __typeof__(y) _y = (y); "
		"_x < _y ? _x : _y; })",
	.max = "(x,y)    "
		"({ __typeof__(x) _x = (x); __typeof__(y) _y = (y); "
		"_x > _y ? _x : _y; })",
};

/* Name used for the note that keeps track of macro definitions.
 */
static const char *ppcg_macros = "ppcg_macros";

/* Set the macro definitions for isl_ast_op_min and isl_ast_op_max
 * to "min" and "max" and store them in "p".
 *
 * In particular, create a ppcg_macros object and attach it
 * as a note to the printer.
 */
__isl_give isl_printer *ppcg_set_macros(__isl_take isl_printer *p,
	const char *min, const char *max)
{
	isl_ctx *ctx;
	isl_id *id, *macros_id;
	struct ppcg_macros *macros;

	if (!p)
		return NULL;

	ctx = isl_printer_get_ctx(p);
	macros = isl_alloc_type(ctx, struct ppcg_macros);
	if (!macros)
		return isl_printer_free(p);
	macros->min = min;
	macros->max = max;
	id = isl_id_alloc(ctx, ppcg_macros, NULL);
	macros_id = isl_id_alloc(ctx, NULL, macros);
	if (!macros_id)
		ppcg_macros_free(macros);
	else
		macros_id = isl_id_set_free_user(macros_id, &ppcg_macros_free);

	p = isl_printer_set_note(p, id, macros_id);

	return p;
}

/* Return the ppcg_macros object that holds the currently active
 * macro definitions in "p".
 * If "p" has a note with macro definitions, then return those.
 * Otherwise, return the default macro definitions.
 */
static struct ppcg_macros *get_macros(__isl_keep isl_printer *p)
{
	isl_id *id;
	isl_bool has_macros;
	struct ppcg_macros *macros;

	id = isl_id_alloc(isl_printer_get_ctx(p), ppcg_macros, NULL);
	has_macros = isl_printer_has_note(p, id);
	if (has_macros < 0 || !has_macros) {
		isl_id_free(id);
		if (has_macros < 0)
			return NULL;
		return &ppcg_macros_default;
	}
	id = isl_printer_get_note(p, id);
	macros = isl_id_get_user(id);
	isl_id_free(id);

	return macros;
}

/* Print the currently active macro definition for ppcg_max.
 */
static __isl_give isl_printer *print_max(__isl_take isl_printer *p)
{
	struct ppcg_macros *macros;

	macros = get_macros(p);
	if (!macros)
		return isl_printer_free(p);
	return print_ppcg_macro(p, ppcg_max, macros->max, ppcg_max_printed);
}

/* Print the currently active macro definition for ppcg_min.
 */
static __isl_give isl_printer *print_min(__isl_take isl_printer *p)
{
	struct ppcg_macros *macros;

	macros = get_macros(p);
	if (!macros)
		return isl_printer_free(p);
	return print_ppcg_macro(p, ppcg_min, macros->min, ppcg_min_printed);
}

/* Print a macro definition for "type" to "p".
 * If GNU extensions are allowed, then print a specialized definition
 * for isl_ast_op_min and isl_ast_op_max.
 * Otherwise, use the default isl definition.
 */
__isl_give isl_printer *ppcg_print_macro(enum isl_ast_op_type type,
	__isl_take isl_printer *p)
{
	isl_ctx *ctx;
	struct ppcg_options *options;

	if (!p)
		return NULL;

	ctx = isl_printer_get_ctx(p);
	options = isl_ctx_peek_options(ctx, &ppcg_options_args);
	if (!options || !options->allow_gnu_extensions)
		return isl_ast_op_type_print_macro(type, p);

	switch (type) {
	case isl_ast_op_max:
		return print_max(p);
	case isl_ast_op_min:
		return print_min(p);
	default:
		return isl_ast_op_type_print_macro(type, p);
	}
}

/* isl_ast_expr_foreach_ast_op_type or isl_ast_node_foreach_ast_op_type
 * callback that prints a macro definition for "type".
 */
static isl_stat print_macro(enum isl_ast_op_type type, void *user)
{
	isl_printer **p = user;

	*p = ppcg_print_macro(type, *p);
	if (!*p)
		return isl_stat_error;

	return isl_stat_ok;
}

/* Print the required macros for "expr".
 */
__isl_give isl_printer *ppcg_ast_expr_print_macros(
	__isl_keep isl_ast_expr *expr, __isl_take isl_printer *p)
{
	if (isl_ast_expr_foreach_ast_op_type(expr, &print_macro, &p) < 0)
		return isl_printer_free(p);
	return p;
}

/* isl_id_to_ast_expr_foreach callback that prints the required
 * macro definitions for "val".
 */
static isl_stat print_expr_macros(__isl_take isl_id *key,
	__isl_take isl_ast_expr *val, void *user)
{
	isl_printer **p = user;

	*p = ppcg_ast_expr_print_macros(val, *p);
	isl_id_free(key);
	isl_ast_expr_free(val);

	if (!*p)
		return isl_stat_error;
	return isl_stat_ok;
}

/* Print the required macro definitions for the body of a statement in which
 * the access expressions are replaced by the isl_ast_expr objects
 * in "ref2expr".
 */
__isl_give isl_printer *ppcg_print_body_macros(__isl_take isl_printer *p,
	__isl_keep isl_id_to_ast_expr *ref2expr)
{
	if (isl_id_to_ast_expr_foreach(ref2expr, &print_expr_macros, &p) < 0)
		return isl_printer_free(p);
	return p;
}

/* Print the required macros for "node".
 */
__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;
}

/* Names used for the macros that may appear in a printed isl AST.
 */
const char *ppcg_min = "ppcg_min";
const char *ppcg_max = "ppcg_max";
const char *ppcg_fdiv_q = "ppcg_fdiv_q";

/* Set the names of the macros that may appear in a printed isl AST.
 */
__isl_give isl_printer *ppcg_set_macro_names(__isl_take isl_printer *p)
{
	p = isl_ast_op_type_set_print_name(p, isl_ast_op_min, ppcg_min);
	p = isl_ast_op_type_set_print_name(p, isl_ast_op_max, ppcg_max);
	p = isl_ast_op_type_set_print_name(p, isl_ast_op_fdiv_q, ppcg_fdiv_q);

	return p;
}

/* Given a multi affine expression "mpa" without domain, modify it to have
 * the schedule space of "build" as domain.
 *
 * If the schedule space of "build" is a parameter space, then nothing
 * needs to be done.
 * Otherwise, "mpa" is first given a 0D domain and then it is combined
 * with a mapping from the schedule space of "build" to the same 0D domain.
 */
__isl_give isl_multi_pw_aff *ppcg_attach_multi_pw_aff(
	__isl_take isl_multi_pw_aff *mpa, __isl_keep isl_ast_build *build)
{
	isl_bool params;
	isl_space *space;
	isl_multi_aff *ma;

	space = isl_ast_build_get_schedule_space(build);
	params = isl_space_is_params(space);
	if (params < 0 || params) {
		isl_space_free(space);
		if (params < 0)
			return isl_multi_pw_aff_free(mpa);
		return mpa;
	}
	space = isl_space_from_domain(space);
	ma = isl_multi_aff_zero(space);
	mpa = isl_multi_pw_aff_from_range(mpa);
	mpa = isl_multi_pw_aff_pullback_multi_aff(mpa, ma);

	return mpa;
}

/* Build an access AST expression from "size" using "build".
 * "size" does not have a domain, but "build" may have a proper schedule space.
 * First modify "size" to have that schedule space as domain.
 */
__isl_give isl_ast_expr *ppcg_build_size_expr(__isl_take isl_multi_pw_aff *size,
	__isl_keep isl_ast_build *build)
{
	size = ppcg_attach_multi_pw_aff(size, build);
	return isl_ast_build_access_from_multi_pw_aff(build, size);
}

/* Print a declaration for an array with element type "base_type" and
 * size "size" to "p".
 */
__isl_give isl_printer *ppcg_print_declaration_with_size(
	__isl_take isl_printer *p, const char *base_type,
	__isl_keep isl_ast_expr *size)
{
	if (!base_type || !size)
		return isl_printer_free(p);

	p = ppcg_ast_expr_print_macros(size, p);
	p = isl_printer_start_line(p);
	p = isl_printer_print_str(p, base_type);
	p = isl_printer_print_str(p, " ");
	p = isl_printer_print_ast_expr(p, size);
	p = isl_printer_print_str(p, ";");
	p = isl_printer_end_line(p);

	return p;
}

/* Print a declaration for array "array" to "p", using "build"
 * to simplify any size expressions.
 *
 * The size is computed from the extent of the array and is
 * subsequently converted to an "access expression" by "build".
 */
__isl_give isl_printer *ppcg_print_declaration(__isl_take isl_printer *p,
	struct pet_array *array, __isl_keep isl_ast_build *build)
{
	isl_multi_pw_aff *size;
	isl_ast_expr *expr;

	if (!array)
		return isl_printer_free(p);

	size = ppcg_size_from_extent(isl_set_copy(array->extent));
	expr = isl_ast_build_access_from_multi_pw_aff(build, size);
	p = ppcg_print_declaration_with_size(p, array->element_type, expr);
	isl_ast_expr_free(expr);

	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);
}
