LCOV - code coverage report
Current view: top level - metalib_isl - isl_ast.c (source / functions) Hit Total Coverage
Test: 2018-10-31_point_maint_greina16.lcov Lines: 0 1291 0.0 %
Date: 2018-11-01 11:27:00 Functions: 0 134 0.0 %

          Line data    Source code
       1             : /*
       2             :  * Copyright 2012-2013 Ecole Normale Superieure
       3             :  *
       4             :  * Use of this software is governed by the MIT license
       5             :  *
       6             :  * Written by Sven Verdoolaege,
       7             :  * Ecole Normale Superieure, 45 rue d’Ulm, 75230 Paris, France
       8             :  */
       9             : 
      10             : #include <string.h>
      11             : 
      12             : #include <isl/id.h>
      13             : #include <isl/val.h>
      14             : #include <isl_ast_private.h>
      15             : 
      16             : #undef BASE
      17             : #define BASE ast_expr
      18             : 
      19             : #include <isl_list_templ.c>
      20             : 
      21             : #undef BASE
      22             : #define BASE ast_node
      23             : 
      24             : #include <isl_list_templ.c>
      25             : 
      26           0 : isl_ctx *isl_ast_print_options_get_ctx(
      27             :         __isl_keep isl_ast_print_options *options)
      28             : {
      29           0 :         return options ? options->ctx : NULL;
      30             : }
      31             : 
      32           0 : __isl_give isl_ast_print_options *isl_ast_print_options_alloc(isl_ctx *ctx)
      33             : {
      34             :         isl_ast_print_options *options;
      35             : 
      36           0 :         options = isl_calloc_type(ctx, isl_ast_print_options);
      37           0 :         if (!options)
      38           0 :                 return NULL;
      39             : 
      40           0 :         options->ctx = ctx;
      41           0 :         isl_ctx_ref(ctx);
      42           0 :         options->ref = 1;
      43             : 
      44           0 :         return options;
      45             : }
      46             : 
      47           0 : __isl_give isl_ast_print_options *isl_ast_print_options_dup(
      48             :         __isl_keep isl_ast_print_options *options)
      49             : {
      50             :         isl_ctx *ctx;
      51             :         isl_ast_print_options *dup;
      52             : 
      53           0 :         if (!options)
      54           0 :                 return NULL;
      55             : 
      56           0 :         ctx = isl_ast_print_options_get_ctx(options);
      57           0 :         dup = isl_ast_print_options_alloc(ctx);
      58           0 :         if (!dup)
      59           0 :                 return NULL;
      60             : 
      61           0 :         dup->print_for = options->print_for;
      62           0 :         dup->print_for_user = options->print_for_user;
      63           0 :         dup->print_user = options->print_user;
      64           0 :         dup->print_user_user = options->print_user_user;
      65             : 
      66           0 :         return dup;
      67             : }
      68             : 
      69           0 : __isl_give isl_ast_print_options *isl_ast_print_options_cow(
      70             :         __isl_take isl_ast_print_options *options)
      71             : {
      72           0 :         if (!options)
      73           0 :                 return NULL;
      74             : 
      75           0 :         if (options->ref == 1)
      76           0 :                 return options;
      77           0 :         options->ref--;
      78           0 :         return isl_ast_print_options_dup(options);
      79             : }
      80             : 
      81           0 : __isl_give isl_ast_print_options *isl_ast_print_options_copy(
      82             :         __isl_keep isl_ast_print_options *options)
      83             : {
      84           0 :         if (!options)
      85           0 :                 return NULL;
      86             : 
      87           0 :         options->ref++;
      88           0 :         return options;
      89             : }
      90             : 
      91           0 : __isl_null isl_ast_print_options *isl_ast_print_options_free(
      92             :         __isl_take isl_ast_print_options *options)
      93             : {
      94           0 :         if (!options)
      95           0 :                 return NULL;
      96             : 
      97           0 :         if (--options->ref > 0)
      98           0 :                 return NULL;
      99             : 
     100           0 :         isl_ctx_deref(options->ctx);
     101             : 
     102           0 :         free(options);
     103           0 :         return NULL;
     104             : }
     105             : 
     106             : /* Set the print_user callback of "options" to "print_user".
     107             :  *
     108             :  * If this callback is set, then it used to print user nodes in the AST.
     109             :  * Otherwise, the expression associated to the user node is printed.
     110             :  */
     111           0 : __isl_give isl_ast_print_options *isl_ast_print_options_set_print_user(
     112             :         __isl_take isl_ast_print_options *options,
     113             :         __isl_give isl_printer *(*print_user)(__isl_take isl_printer *p,
     114             :                 __isl_take isl_ast_print_options *options,
     115             :                 __isl_keep isl_ast_node *node, void *user),
     116             :         void *user)
     117             : {
     118           0 :         options = isl_ast_print_options_cow(options);
     119           0 :         if (!options)
     120           0 :                 return NULL;
     121             : 
     122           0 :         options->print_user = print_user;
     123           0 :         options->print_user_user = user;
     124             : 
     125           0 :         return options;
     126             : }
     127             : 
     128             : /* Set the print_for callback of "options" to "print_for".
     129             :  *
     130             :  * If this callback is set, then it used to print for nodes in the AST.
     131             :  */
     132           0 : __isl_give isl_ast_print_options *isl_ast_print_options_set_print_for(
     133             :         __isl_take isl_ast_print_options *options,
     134             :         __isl_give isl_printer *(*print_for)(__isl_take isl_printer *p,
     135             :                 __isl_take isl_ast_print_options *options,
     136             :                 __isl_keep isl_ast_node *node, void *user),
     137             :         void *user)
     138             : {
     139           0 :         options = isl_ast_print_options_cow(options);
     140           0 :         if (!options)
     141           0 :                 return NULL;
     142             : 
     143           0 :         options->print_for = print_for;
     144           0 :         options->print_for_user = user;
     145             : 
     146           0 :         return options;
     147             : }
     148             : 
     149           0 : __isl_give isl_ast_expr *isl_ast_expr_copy(__isl_keep isl_ast_expr *expr)
     150             : {
     151           0 :         if (!expr)
     152           0 :                 return NULL;
     153             : 
     154           0 :         expr->ref++;
     155           0 :         return expr;
     156             : }
     157             : 
     158           0 : __isl_give isl_ast_expr *isl_ast_expr_dup(__isl_keep isl_ast_expr *expr)
     159             : {
     160             :         int i;
     161             :         isl_ctx *ctx;
     162             :         isl_ast_expr *dup;
     163             : 
     164           0 :         if (!expr)
     165           0 :                 return NULL;
     166             : 
     167           0 :         ctx = isl_ast_expr_get_ctx(expr);
     168           0 :         switch (expr->type) {
     169             :         case isl_ast_expr_int:
     170           0 :                 dup = isl_ast_expr_from_val(isl_val_copy(expr->u.v));
     171           0 :                 break;
     172             :         case isl_ast_expr_id:
     173           0 :                 dup = isl_ast_expr_from_id(isl_id_copy(expr->u.id));
     174           0 :                 break;
     175             :         case isl_ast_expr_op:
     176           0 :                 dup = isl_ast_expr_alloc_op(ctx,
     177           0 :                                             expr->u.op.op, expr->u.op.n_arg);
     178           0 :                 if (!dup)
     179           0 :                         return NULL;
     180           0 :                 for (i = 0; i < expr->u.op.n_arg; ++i)
     181           0 :                         dup->u.op.args[i] =
     182           0 :                                 isl_ast_expr_copy(expr->u.op.args[i]);
     183           0 :                 break;
     184             :         case isl_ast_expr_error:
     185           0 :                 dup = NULL;
     186             :         }
     187             : 
     188           0 :         if (!dup)
     189           0 :                 return NULL;
     190             : 
     191           0 :         return dup;
     192             : }
     193             : 
     194           0 : __isl_give isl_ast_expr *isl_ast_expr_cow(__isl_take isl_ast_expr *expr)
     195             : {
     196           0 :         if (!expr)
     197           0 :                 return NULL;
     198             : 
     199           0 :         if (expr->ref == 1)
     200           0 :                 return expr;
     201           0 :         expr->ref--;
     202           0 :         return isl_ast_expr_dup(expr);
     203             : }
     204             : 
     205           0 : __isl_null isl_ast_expr *isl_ast_expr_free(__isl_take isl_ast_expr *expr)
     206             : {
     207             :         int i;
     208             : 
     209           0 :         if (!expr)
     210           0 :                 return NULL;
     211             : 
     212           0 :         if (--expr->ref > 0)
     213           0 :                 return NULL;
     214             : 
     215           0 :         isl_ctx_deref(expr->ctx);
     216             : 
     217           0 :         switch (expr->type) {
     218             :         case isl_ast_expr_int:
     219           0 :                 isl_val_free(expr->u.v);
     220           0 :                 break;
     221             :         case isl_ast_expr_id:
     222           0 :                 isl_id_free(expr->u.id);
     223           0 :                 break;
     224             :         case isl_ast_expr_op:
     225           0 :                 if (expr->u.op.args)
     226           0 :                         for (i = 0; i < expr->u.op.n_arg; ++i)
     227           0 :                                 isl_ast_expr_free(expr->u.op.args[i]);
     228           0 :                 free(expr->u.op.args);
     229           0 :                 break;
     230             :         case isl_ast_expr_error:
     231           0 :                 break;
     232             :         }
     233             : 
     234           0 :         free(expr);
     235           0 :         return NULL;
     236             : }
     237             : 
     238           0 : isl_ctx *isl_ast_expr_get_ctx(__isl_keep isl_ast_expr *expr)
     239             : {
     240           0 :         return expr ? expr->ctx : NULL;
     241             : }
     242             : 
     243           0 : enum isl_ast_expr_type isl_ast_expr_get_type(__isl_keep isl_ast_expr *expr)
     244             : {
     245           0 :         return expr ? expr->type : isl_ast_expr_error;
     246             : }
     247             : 
     248             : /* Return the integer value represented by "expr".
     249             :  */
     250           0 : __isl_give isl_val *isl_ast_expr_get_val(__isl_keep isl_ast_expr *expr)
     251             : {
     252           0 :         if (!expr)
     253           0 :                 return NULL;
     254           0 :         if (expr->type != isl_ast_expr_int)
     255           0 :                 isl_die(isl_ast_expr_get_ctx(expr), isl_error_invalid,
     256             :                         "expression not an int", return NULL);
     257           0 :         return isl_val_copy(expr->u.v);
     258             : }
     259             : 
     260           0 : __isl_give isl_id *isl_ast_expr_get_id(__isl_keep isl_ast_expr *expr)
     261             : {
     262           0 :         if (!expr)
     263           0 :                 return NULL;
     264           0 :         if (expr->type != isl_ast_expr_id)
     265           0 :                 isl_die(isl_ast_expr_get_ctx(expr), isl_error_invalid,
     266             :                         "expression not an identifier", return NULL);
     267             : 
     268           0 :         return isl_id_copy(expr->u.id);
     269             : }
     270             : 
     271           0 : enum isl_ast_op_type isl_ast_expr_get_op_type(__isl_keep isl_ast_expr *expr)
     272             : {
     273           0 :         if (!expr)
     274           0 :                 return isl_ast_op_error;
     275           0 :         if (expr->type != isl_ast_expr_op)
     276           0 :                 isl_die(isl_ast_expr_get_ctx(expr), isl_error_invalid,
     277             :                         "expression not an operation", return isl_ast_op_error);
     278           0 :         return expr->u.op.op;
     279             : }
     280             : 
     281           0 : int isl_ast_expr_get_op_n_arg(__isl_keep isl_ast_expr *expr)
     282             : {
     283           0 :         if (!expr)
     284           0 :                 return -1;
     285           0 :         if (expr->type != isl_ast_expr_op)
     286           0 :                 isl_die(isl_ast_expr_get_ctx(expr), isl_error_invalid,
     287             :                         "expression not an operation", return -1);
     288           0 :         return expr->u.op.n_arg;
     289             : }
     290             : 
     291           0 : __isl_give isl_ast_expr *isl_ast_expr_get_op_arg(__isl_keep isl_ast_expr *expr,
     292             :         int pos)
     293             : {
     294           0 :         if (!expr)
     295           0 :                 return NULL;
     296           0 :         if (expr->type != isl_ast_expr_op)
     297           0 :                 isl_die(isl_ast_expr_get_ctx(expr), isl_error_invalid,
     298             :                         "expression not an operation", return NULL);
     299           0 :         if (pos < 0 || pos >= expr->u.op.n_arg)
     300           0 :                 isl_die(isl_ast_expr_get_ctx(expr), isl_error_invalid,
     301             :                         "index out of bounds", return NULL);
     302             : 
     303           0 :         return isl_ast_expr_copy(expr->u.op.args[pos]);
     304             : }
     305             : 
     306             : /* Replace the argument at position "pos" of "expr" by "arg".
     307             :  */
     308           0 : __isl_give isl_ast_expr *isl_ast_expr_set_op_arg(__isl_take isl_ast_expr *expr,
     309             :         int pos, __isl_take isl_ast_expr *arg)
     310             : {
     311           0 :         expr = isl_ast_expr_cow(expr);
     312           0 :         if (!expr || !arg)
     313             :                 goto error;
     314           0 :         if (expr->type != isl_ast_expr_op)
     315           0 :                 isl_die(isl_ast_expr_get_ctx(expr), isl_error_invalid,
     316             :                         "expression not an operation", goto error);
     317           0 :         if (pos < 0 || pos >= expr->u.op.n_arg)
     318           0 :                 isl_die(isl_ast_expr_get_ctx(expr), isl_error_invalid,
     319             :                         "index out of bounds", goto error);
     320             : 
     321           0 :         isl_ast_expr_free(expr->u.op.args[pos]);
     322           0 :         expr->u.op.args[pos] = arg;
     323             : 
     324           0 :         return expr;
     325             : error:
     326           0 :         isl_ast_expr_free(arg);
     327           0 :         return isl_ast_expr_free(expr);
     328             : }
     329             : 
     330             : /* Is "expr1" equal to "expr2"?
     331             :  */
     332           0 : isl_bool isl_ast_expr_is_equal(__isl_keep isl_ast_expr *expr1,
     333             :         __isl_keep isl_ast_expr *expr2)
     334             : {
     335             :         int i;
     336             : 
     337           0 :         if (!expr1 || !expr2)
     338           0 :                 return isl_bool_error;
     339             : 
     340           0 :         if (expr1 == expr2)
     341           0 :                 return isl_bool_true;
     342           0 :         if (expr1->type != expr2->type)
     343           0 :                 return isl_bool_false;
     344           0 :         switch (expr1->type) {
     345             :         case isl_ast_expr_int:
     346           0 :                 return isl_val_eq(expr1->u.v, expr2->u.v);
     347             :         case isl_ast_expr_id:
     348           0 :                 return expr1->u.id == expr2->u.id;
     349             :         case isl_ast_expr_op:
     350           0 :                 if (expr1->u.op.op != expr2->u.op.op)
     351           0 :                         return isl_bool_false;
     352           0 :                 if (expr1->u.op.n_arg != expr2->u.op.n_arg)
     353           0 :                         return isl_bool_false;
     354           0 :                 for (i = 0; i < expr1->u.op.n_arg; ++i) {
     355             :                         isl_bool equal;
     356           0 :                         equal = isl_ast_expr_is_equal(expr1->u.op.args[i],
     357           0 :                                                         expr2->u.op.args[i]);
     358           0 :                         if (equal < 0 || !equal)
     359           0 :                                 return equal;
     360             :                 }
     361           0 :                 return isl_bool_true;
     362             :         case isl_ast_expr_error:
     363           0 :                 return isl_bool_error;
     364             :         }
     365             : 
     366           0 :         isl_die(isl_ast_expr_get_ctx(expr1), isl_error_internal,
     367             :                 "unhandled case", return isl_bool_error);
     368             : }
     369             : 
     370             : /* Create a new operation expression of operation type "op",
     371             :  * with "n_arg" as yet unspecified arguments.
     372             :  */
     373           0 : __isl_give isl_ast_expr *isl_ast_expr_alloc_op(isl_ctx *ctx,
     374             :         enum isl_ast_op_type op, int n_arg)
     375             : {
     376             :         isl_ast_expr *expr;
     377             : 
     378           0 :         expr = isl_calloc_type(ctx, isl_ast_expr);
     379           0 :         if (!expr)
     380           0 :                 return NULL;
     381             : 
     382           0 :         expr->ctx = ctx;
     383           0 :         isl_ctx_ref(ctx);
     384           0 :         expr->ref = 1;
     385           0 :         expr->type = isl_ast_expr_op;
     386           0 :         expr->u.op.op = op;
     387           0 :         expr->u.op.n_arg = n_arg;
     388           0 :         expr->u.op.args = isl_calloc_array(ctx, isl_ast_expr *, n_arg);
     389             : 
     390           0 :         if (n_arg && !expr->u.op.args)
     391           0 :                 return isl_ast_expr_free(expr);
     392             : 
     393           0 :         return expr;
     394             : }
     395             : 
     396             : /* Create a new id expression representing "id".
     397             :  */
     398           0 : __isl_give isl_ast_expr *isl_ast_expr_from_id(__isl_take isl_id *id)
     399             : {
     400             :         isl_ctx *ctx;
     401             :         isl_ast_expr *expr;
     402             : 
     403           0 :         if (!id)
     404           0 :                 return NULL;
     405             : 
     406           0 :         ctx = isl_id_get_ctx(id);
     407           0 :         expr = isl_calloc_type(ctx, isl_ast_expr);
     408           0 :         if (!expr)
     409           0 :                 goto error;
     410             : 
     411           0 :         expr->ctx = ctx;
     412           0 :         isl_ctx_ref(ctx);
     413           0 :         expr->ref = 1;
     414           0 :         expr->type = isl_ast_expr_id;
     415           0 :         expr->u.id = id;
     416             : 
     417           0 :         return expr;
     418             : error:
     419           0 :         isl_id_free(id);
     420           0 :         return NULL;
     421             : }
     422             : 
     423             : /* Create a new integer expression representing "i".
     424             :  */
     425           0 : __isl_give isl_ast_expr *isl_ast_expr_alloc_int_si(isl_ctx *ctx, int i)
     426             : {
     427             :         isl_ast_expr *expr;
     428             : 
     429           0 :         expr = isl_calloc_type(ctx, isl_ast_expr);
     430           0 :         if (!expr)
     431           0 :                 return NULL;
     432             : 
     433           0 :         expr->ctx = ctx;
     434           0 :         isl_ctx_ref(ctx);
     435           0 :         expr->ref = 1;
     436           0 :         expr->type = isl_ast_expr_int;
     437           0 :         expr->u.v = isl_val_int_from_si(ctx, i);
     438           0 :         if (!expr->u.v)
     439           0 :                 return isl_ast_expr_free(expr);
     440             : 
     441           0 :         return expr;
     442             : }
     443             : 
     444             : /* Create a new integer expression representing "v".
     445             :  */
     446           0 : __isl_give isl_ast_expr *isl_ast_expr_from_val(__isl_take isl_val *v)
     447             : {
     448             :         isl_ctx *ctx;
     449             :         isl_ast_expr *expr;
     450             : 
     451           0 :         if (!v)
     452           0 :                 return NULL;
     453           0 :         if (!isl_val_is_int(v))
     454           0 :                 isl_die(isl_val_get_ctx(v), isl_error_invalid,
     455             :                         "expecting integer value", goto error);
     456             : 
     457           0 :         ctx = isl_val_get_ctx(v);
     458           0 :         expr = isl_calloc_type(ctx, isl_ast_expr);
     459           0 :         if (!expr)
     460           0 :                 goto error;
     461             : 
     462           0 :         expr->ctx = ctx;
     463           0 :         isl_ctx_ref(ctx);
     464           0 :         expr->ref = 1;
     465           0 :         expr->type = isl_ast_expr_int;
     466           0 :         expr->u.v = v;
     467             : 
     468           0 :         return expr;
     469             : error:
     470           0 :         isl_val_free(v);
     471           0 :         return NULL;
     472             : }
     473             : 
     474             : /* Create an expression representing the unary operation "type" applied to
     475             :  * "arg".
     476             :  */
     477           0 : __isl_give isl_ast_expr *isl_ast_expr_alloc_unary(enum isl_ast_op_type type,
     478             :         __isl_take isl_ast_expr *arg)
     479             : {
     480             :         isl_ctx *ctx;
     481           0 :         isl_ast_expr *expr = NULL;
     482             : 
     483           0 :         if (!arg)
     484           0 :                 return NULL;
     485             : 
     486           0 :         ctx = isl_ast_expr_get_ctx(arg);
     487           0 :         expr = isl_ast_expr_alloc_op(ctx, type, 1);
     488           0 :         if (!expr)
     489           0 :                 goto error;
     490             : 
     491           0 :         expr->u.op.args[0] = arg;
     492             : 
     493           0 :         return expr;
     494             : error:
     495           0 :         isl_ast_expr_free(arg);
     496           0 :         return NULL;
     497             : }
     498             : 
     499             : /* Create an expression representing the negation of "arg".
     500             :  */
     501           0 : __isl_give isl_ast_expr *isl_ast_expr_neg(__isl_take isl_ast_expr *arg)
     502             : {
     503           0 :         return isl_ast_expr_alloc_unary(isl_ast_op_minus, arg);
     504             : }
     505             : 
     506             : /* Create an expression representing the address of "expr".
     507             :  */
     508           0 : __isl_give isl_ast_expr *isl_ast_expr_address_of(__isl_take isl_ast_expr *expr)
     509             : {
     510           0 :         if (!expr)
     511           0 :                 return NULL;
     512             : 
     513           0 :         if (isl_ast_expr_get_type(expr) != isl_ast_expr_op ||
     514           0 :             isl_ast_expr_get_op_type(expr) != isl_ast_op_access)
     515           0 :                 isl_die(isl_ast_expr_get_ctx(expr), isl_error_invalid,
     516             :                         "can only take address of access expressions",
     517             :                         return isl_ast_expr_free(expr));
     518             : 
     519           0 :         return isl_ast_expr_alloc_unary(isl_ast_op_address_of, expr);
     520             : }
     521             : 
     522             : /* Create an expression representing the binary operation "type"
     523             :  * applied to "expr1" and "expr2".
     524             :  */
     525           0 : __isl_give isl_ast_expr *isl_ast_expr_alloc_binary(enum isl_ast_op_type type,
     526             :         __isl_take isl_ast_expr *expr1, __isl_take isl_ast_expr *expr2)
     527             : {
     528             :         isl_ctx *ctx;
     529           0 :         isl_ast_expr *expr = NULL;
     530             : 
     531           0 :         if (!expr1 || !expr2)
     532             :                 goto error;
     533             : 
     534           0 :         ctx = isl_ast_expr_get_ctx(expr1);
     535           0 :         expr = isl_ast_expr_alloc_op(ctx, type, 2);
     536           0 :         if (!expr)
     537           0 :                 goto error;
     538             : 
     539           0 :         expr->u.op.args[0] = expr1;
     540           0 :         expr->u.op.args[1] = expr2;
     541             : 
     542           0 :         return expr;
     543             : error:
     544           0 :         isl_ast_expr_free(expr1);
     545           0 :         isl_ast_expr_free(expr2);
     546           0 :         return NULL;
     547             : }
     548             : 
     549             : /* Create an expression representing the sum of "expr1" and "expr2".
     550             :  */
     551           0 : __isl_give isl_ast_expr *isl_ast_expr_add(__isl_take isl_ast_expr *expr1,
     552             :         __isl_take isl_ast_expr *expr2)
     553             : {
     554           0 :         return isl_ast_expr_alloc_binary(isl_ast_op_add, expr1, expr2);
     555             : }
     556             : 
     557             : /* Create an expression representing the difference of "expr1" and "expr2".
     558             :  */
     559           0 : __isl_give isl_ast_expr *isl_ast_expr_sub(__isl_take isl_ast_expr *expr1,
     560             :         __isl_take isl_ast_expr *expr2)
     561             : {
     562           0 :         return isl_ast_expr_alloc_binary(isl_ast_op_sub, expr1, expr2);
     563             : }
     564             : 
     565             : /* Create an expression representing the product of "expr1" and "expr2".
     566             :  */
     567           0 : __isl_give isl_ast_expr *isl_ast_expr_mul(__isl_take isl_ast_expr *expr1,
     568             :         __isl_take isl_ast_expr *expr2)
     569             : {
     570           0 :         return isl_ast_expr_alloc_binary(isl_ast_op_mul, expr1, expr2);
     571             : }
     572             : 
     573             : /* Create an expression representing the quotient of "expr1" and "expr2".
     574             :  */
     575           0 : __isl_give isl_ast_expr *isl_ast_expr_div(__isl_take isl_ast_expr *expr1,
     576             :         __isl_take isl_ast_expr *expr2)
     577             : {
     578           0 :         return isl_ast_expr_alloc_binary(isl_ast_op_div, expr1, expr2);
     579             : }
     580             : 
     581             : /* Create an expression representing the quotient of the integer
     582             :  * division of "expr1" by "expr2", where "expr1" is known to be
     583             :  * non-negative.
     584             :  */
     585           0 : __isl_give isl_ast_expr *isl_ast_expr_pdiv_q(__isl_take isl_ast_expr *expr1,
     586             :         __isl_take isl_ast_expr *expr2)
     587             : {
     588           0 :         return isl_ast_expr_alloc_binary(isl_ast_op_pdiv_q, expr1, expr2);
     589             : }
     590             : 
     591             : /* Create an expression representing the remainder of the integer
     592             :  * division of "expr1" by "expr2", where "expr1" is known to be
     593             :  * non-negative.
     594             :  */
     595           0 : __isl_give isl_ast_expr *isl_ast_expr_pdiv_r(__isl_take isl_ast_expr *expr1,
     596             :         __isl_take isl_ast_expr *expr2)
     597             : {
     598           0 :         return isl_ast_expr_alloc_binary(isl_ast_op_pdiv_r, expr1, expr2);
     599             : }
     600             : 
     601             : /* Create an expression representing the conjunction of "expr1" and "expr2".
     602             :  */
     603           0 : __isl_give isl_ast_expr *isl_ast_expr_and(__isl_take isl_ast_expr *expr1,
     604             :         __isl_take isl_ast_expr *expr2)
     605             : {
     606           0 :         return isl_ast_expr_alloc_binary(isl_ast_op_and, expr1, expr2);
     607             : }
     608             : 
     609             : /* Create an expression representing the conjunction of "expr1" and "expr2",
     610             :  * where "expr2" is evaluated only if "expr1" is evaluated to true.
     611             :  */
     612           0 : __isl_give isl_ast_expr *isl_ast_expr_and_then(__isl_take isl_ast_expr *expr1,
     613             :         __isl_take isl_ast_expr *expr2)
     614             : {
     615           0 :         return isl_ast_expr_alloc_binary(isl_ast_op_and_then, expr1, expr2);
     616             : }
     617             : 
     618             : /* Create an expression representing the disjunction of "expr1" and "expr2".
     619             :  */
     620           0 : __isl_give isl_ast_expr *isl_ast_expr_or(__isl_take isl_ast_expr *expr1,
     621             :         __isl_take isl_ast_expr *expr2)
     622             : {
     623           0 :         return isl_ast_expr_alloc_binary(isl_ast_op_or, expr1, expr2);
     624             : }
     625             : 
     626             : /* Create an expression representing the disjunction of "expr1" and "expr2",
     627             :  * where "expr2" is evaluated only if "expr1" is evaluated to false.
     628             :  */
     629           0 : __isl_give isl_ast_expr *isl_ast_expr_or_else(__isl_take isl_ast_expr *expr1,
     630             :         __isl_take isl_ast_expr *expr2)
     631             : {
     632           0 :         return isl_ast_expr_alloc_binary(isl_ast_op_or_else, expr1, expr2);
     633             : }
     634             : 
     635             : /* Create an expression representing "expr1" less than or equal to "expr2".
     636             :  */
     637           0 : __isl_give isl_ast_expr *isl_ast_expr_le(__isl_take isl_ast_expr *expr1,
     638             :         __isl_take isl_ast_expr *expr2)
     639             : {
     640           0 :         return isl_ast_expr_alloc_binary(isl_ast_op_le, expr1, expr2);
     641             : }
     642             : 
     643             : /* Create an expression representing "expr1" less than "expr2".
     644             :  */
     645           0 : __isl_give isl_ast_expr *isl_ast_expr_lt(__isl_take isl_ast_expr *expr1,
     646             :         __isl_take isl_ast_expr *expr2)
     647             : {
     648           0 :         return isl_ast_expr_alloc_binary(isl_ast_op_lt, expr1, expr2);
     649             : }
     650             : 
     651             : /* Create an expression representing "expr1" greater than or equal to "expr2".
     652             :  */
     653           0 : __isl_give isl_ast_expr *isl_ast_expr_ge(__isl_take isl_ast_expr *expr1,
     654             :         __isl_take isl_ast_expr *expr2)
     655             : {
     656           0 :         return isl_ast_expr_alloc_binary(isl_ast_op_ge, expr1, expr2);
     657             : }
     658             : 
     659             : /* Create an expression representing "expr1" greater than "expr2".
     660             :  */
     661           0 : __isl_give isl_ast_expr *isl_ast_expr_gt(__isl_take isl_ast_expr *expr1,
     662             :         __isl_take isl_ast_expr *expr2)
     663             : {
     664           0 :         return isl_ast_expr_alloc_binary(isl_ast_op_gt, expr1, expr2);
     665             : }
     666             : 
     667             : /* Create an expression representing "expr1" equal to "expr2".
     668             :  */
     669           0 : __isl_give isl_ast_expr *isl_ast_expr_eq(__isl_take isl_ast_expr *expr1,
     670             :         __isl_take isl_ast_expr *expr2)
     671             : {
     672           0 :         return isl_ast_expr_alloc_binary(isl_ast_op_eq, expr1, expr2);
     673             : }
     674             : 
     675             : /* Create an expression of type "type" with as arguments "arg0" followed
     676             :  * by "arguments".
     677             :  */
     678           0 : static __isl_give isl_ast_expr *ast_expr_with_arguments(
     679             :         enum isl_ast_op_type type, __isl_take isl_ast_expr *arg0,
     680             :         __isl_take isl_ast_expr_list *arguments)
     681             : {
     682             :         int i, n;
     683             :         isl_ctx *ctx;
     684           0 :         isl_ast_expr *res = NULL;
     685             : 
     686           0 :         if (!arg0 || !arguments)
     687             :                 goto error;
     688             : 
     689           0 :         ctx = isl_ast_expr_get_ctx(arg0);
     690           0 :         n = isl_ast_expr_list_n_ast_expr(arguments);
     691           0 :         res = isl_ast_expr_alloc_op(ctx, type, 1 + n);
     692           0 :         if (!res)
     693           0 :                 goto error;
     694           0 :         for (i = 0; i < n; ++i) {
     695             :                 isl_ast_expr *arg;
     696           0 :                 arg = isl_ast_expr_list_get_ast_expr(arguments, i);
     697           0 :                 res->u.op.args[1 + i] = arg;
     698           0 :                 if (!arg)
     699           0 :                         goto error;
     700             :         }
     701           0 :         res->u.op.args[0] = arg0;
     702             : 
     703           0 :         isl_ast_expr_list_free(arguments);
     704           0 :         return res;
     705             : error:
     706           0 :         isl_ast_expr_free(arg0);
     707           0 :         isl_ast_expr_list_free(arguments);
     708           0 :         isl_ast_expr_free(res);
     709           0 :         return NULL;
     710             : }
     711             : 
     712             : /* Create an expression representing an access to "array" with index
     713             :  * expressions "indices".
     714             :  */
     715           0 : __isl_give isl_ast_expr *isl_ast_expr_access(__isl_take isl_ast_expr *array,
     716             :         __isl_take isl_ast_expr_list *indices)
     717             : {
     718           0 :         return ast_expr_with_arguments(isl_ast_op_access, array, indices);
     719             : }
     720             : 
     721             : /* Create an expression representing a call to "function" with argument
     722             :  * expressions "arguments".
     723             :  */
     724           0 : __isl_give isl_ast_expr *isl_ast_expr_call(__isl_take isl_ast_expr *function,
     725             :         __isl_take isl_ast_expr_list *arguments)
     726             : {
     727           0 :         return ast_expr_with_arguments(isl_ast_op_call, function, arguments);
     728             : }
     729             : 
     730             : /* For each subexpression of "expr" of type isl_ast_expr_id,
     731             :  * if it appears in "id2expr", then replace it by the corresponding
     732             :  * expression.
     733             :  */
     734           0 : __isl_give isl_ast_expr *isl_ast_expr_substitute_ids(
     735             :         __isl_take isl_ast_expr *expr, __isl_take isl_id_to_ast_expr *id2expr)
     736             : {
     737             :         int i;
     738             :         isl_maybe_isl_ast_expr m;
     739             : 
     740           0 :         if (!expr || !id2expr)
     741             :                 goto error;
     742             : 
     743           0 :         switch (expr->type) {
     744             :         case isl_ast_expr_int:
     745           0 :                 break;
     746             :         case isl_ast_expr_id:
     747           0 :                 m = isl_id_to_ast_expr_try_get(id2expr, expr->u.id);
     748           0 :                 if (m.valid < 0)
     749           0 :                         goto error;
     750           0 :                 if (!m.valid)
     751           0 :                         break;
     752           0 :                 isl_ast_expr_free(expr);
     753           0 :                 expr = m.value;
     754           0 :                 break;
     755             :         case isl_ast_expr_op:
     756           0 :                 for (i = 0; i < expr->u.op.n_arg; ++i) {
     757             :                         isl_ast_expr *arg;
     758           0 :                         arg = isl_ast_expr_copy(expr->u.op.args[i]);
     759           0 :                         arg = isl_ast_expr_substitute_ids(arg,
     760             :                                             isl_id_to_ast_expr_copy(id2expr));
     761           0 :                         if (arg == expr->u.op.args[i]) {
     762           0 :                                 isl_ast_expr_free(arg);
     763           0 :                                 continue;
     764             :                         }
     765           0 :                         if (!arg)
     766           0 :                                 expr = isl_ast_expr_free(expr);
     767           0 :                         expr = isl_ast_expr_cow(expr);
     768           0 :                         if (!expr) {
     769           0 :                                 isl_ast_expr_free(arg);
     770           0 :                                 break;
     771             :                         }
     772           0 :                         isl_ast_expr_free(expr->u.op.args[i]);
     773           0 :                         expr->u.op.args[i] = arg;
     774             :                 }
     775           0 :                 break;
     776             :         case isl_ast_expr_error:
     777           0 :                 expr = isl_ast_expr_free(expr);
     778           0 :                 break;
     779             :         }
     780             : 
     781           0 :         isl_id_to_ast_expr_free(id2expr);
     782           0 :         return expr;
     783             : error:
     784           0 :         isl_ast_expr_free(expr);
     785           0 :         isl_id_to_ast_expr_free(id2expr);
     786           0 :         return NULL;
     787             : }
     788             : 
     789           0 : isl_ctx *isl_ast_node_get_ctx(__isl_keep isl_ast_node *node)
     790             : {
     791           0 :         return node ? node->ctx : NULL;
     792             : }
     793             : 
     794           0 : enum isl_ast_node_type isl_ast_node_get_type(__isl_keep isl_ast_node *node)
     795             : {
     796           0 :         return node ? node->type : isl_ast_node_error;
     797             : }
     798             : 
     799           0 : __isl_give isl_ast_node *isl_ast_node_alloc(isl_ctx *ctx,
     800             :         enum isl_ast_node_type type)
     801             : {
     802             :         isl_ast_node *node;
     803             : 
     804           0 :         node = isl_calloc_type(ctx, isl_ast_node);
     805           0 :         if (!node)
     806           0 :                 return NULL;
     807             : 
     808           0 :         node->ctx = ctx;
     809           0 :         isl_ctx_ref(ctx);
     810           0 :         node->ref = 1;
     811           0 :         node->type = type;
     812             : 
     813           0 :         return node;
     814             : }
     815             : 
     816             : /* Create an if node with the given guard.
     817             :  *
     818             :  * The then body needs to be filled in later.
     819             :  */
     820           0 : __isl_give isl_ast_node *isl_ast_node_alloc_if(__isl_take isl_ast_expr *guard)
     821             : {
     822             :         isl_ast_node *node;
     823             : 
     824           0 :         if (!guard)
     825           0 :                 return NULL;
     826             : 
     827           0 :         node = isl_ast_node_alloc(isl_ast_expr_get_ctx(guard), isl_ast_node_if);
     828           0 :         if (!node)
     829           0 :                 goto error;
     830           0 :         node->u.i.guard = guard;
     831             : 
     832           0 :         return node;
     833             : error:
     834           0 :         isl_ast_expr_free(guard);
     835           0 :         return NULL;
     836             : }
     837             : 
     838             : /* Create a for node with the given iterator.
     839             :  *
     840             :  * The remaining fields need to be filled in later.
     841             :  */
     842           0 : __isl_give isl_ast_node *isl_ast_node_alloc_for(__isl_take isl_id *id)
     843             : {
     844             :         isl_ast_node *node;
     845             :         isl_ctx *ctx;
     846             : 
     847           0 :         if (!id)
     848           0 :                 return NULL;
     849             : 
     850           0 :         ctx = isl_id_get_ctx(id);
     851           0 :         node = isl_ast_node_alloc(ctx, isl_ast_node_for);
     852           0 :         if (!node)
     853           0 :                 goto error;
     854             : 
     855           0 :         node->u.f.iterator = isl_ast_expr_from_id(id);
     856           0 :         if (!node->u.f.iterator)
     857           0 :                 return isl_ast_node_free(node);
     858             : 
     859           0 :         return node;
     860             : error:
     861           0 :         isl_id_free(id);
     862           0 :         return NULL;
     863             : }
     864             : 
     865             : /* Create a mark node, marking "node" with "id".
     866             :  */
     867           0 : __isl_give isl_ast_node *isl_ast_node_alloc_mark(__isl_take isl_id *id,
     868             :         __isl_take isl_ast_node *node)
     869             : {
     870             :         isl_ctx *ctx;
     871             :         isl_ast_node *mark;
     872             : 
     873           0 :         if (!id || !node)
     874             :                 goto error;
     875             : 
     876           0 :         ctx = isl_id_get_ctx(id);
     877           0 :         mark = isl_ast_node_alloc(ctx, isl_ast_node_mark);
     878           0 :         if (!mark)
     879           0 :                 goto error;
     880             : 
     881           0 :         mark->u.m.mark = id;
     882           0 :         mark->u.m.node = node;
     883             : 
     884           0 :         return mark;
     885             : error:
     886           0 :         isl_id_free(id);
     887           0 :         isl_ast_node_free(node);
     888           0 :         return NULL;
     889             : }
     890             : 
     891             : /* Create a user node evaluating "expr".
     892             :  */
     893           0 : __isl_give isl_ast_node *isl_ast_node_alloc_user(__isl_take isl_ast_expr *expr)
     894             : {
     895             :         isl_ctx *ctx;
     896             :         isl_ast_node *node;
     897             : 
     898           0 :         if (!expr)
     899           0 :                 return NULL;
     900             : 
     901           0 :         ctx = isl_ast_expr_get_ctx(expr);
     902           0 :         node = isl_ast_node_alloc(ctx, isl_ast_node_user);
     903           0 :         if (!node)
     904           0 :                 goto error;
     905             : 
     906           0 :         node->u.e.expr = expr;
     907             : 
     908           0 :         return node;
     909             : error:
     910           0 :         isl_ast_expr_free(expr);
     911           0 :         return NULL;
     912             : }
     913             : 
     914             : /* Create a block node with the given children.
     915             :  */
     916           0 : __isl_give isl_ast_node *isl_ast_node_alloc_block(
     917             :         __isl_take isl_ast_node_list *list)
     918             : {
     919             :         isl_ast_node *node;
     920             :         isl_ctx *ctx;
     921             : 
     922           0 :         if (!list)
     923           0 :                 return NULL;
     924             : 
     925           0 :         ctx = isl_ast_node_list_get_ctx(list);
     926           0 :         node = isl_ast_node_alloc(ctx, isl_ast_node_block);
     927           0 :         if (!node)
     928           0 :                 goto error;
     929             : 
     930           0 :         node->u.b.children = list;
     931             : 
     932           0 :         return node;
     933             : error:
     934           0 :         isl_ast_node_list_free(list);
     935           0 :         return NULL;
     936             : }
     937             : 
     938             : /* Represent the given list of nodes as a single node, either by
     939             :  * extract the node from a single element list or by creating
     940             :  * a block node with the list of nodes as children.
     941             :  */
     942           0 : __isl_give isl_ast_node *isl_ast_node_from_ast_node_list(
     943             :         __isl_take isl_ast_node_list *list)
     944             : {
     945             :         isl_ast_node *node;
     946             : 
     947           0 :         if (isl_ast_node_list_n_ast_node(list) != 1)
     948           0 :                 return isl_ast_node_alloc_block(list);
     949             : 
     950           0 :         node = isl_ast_node_list_get_ast_node(list, 0);
     951           0 :         isl_ast_node_list_free(list);
     952             : 
     953           0 :         return node;
     954             : }
     955             : 
     956           0 : __isl_give isl_ast_node *isl_ast_node_copy(__isl_keep isl_ast_node *node)
     957             : {
     958           0 :         if (!node)
     959           0 :                 return NULL;
     960             : 
     961           0 :         node->ref++;
     962           0 :         return node;
     963             : }
     964             : 
     965           0 : __isl_give isl_ast_node *isl_ast_node_dup(__isl_keep isl_ast_node *node)
     966             : {
     967             :         isl_ast_node *dup;
     968             : 
     969           0 :         if (!node)
     970           0 :                 return NULL;
     971             : 
     972           0 :         dup = isl_ast_node_alloc(isl_ast_node_get_ctx(node), node->type);
     973           0 :         if (!dup)
     974           0 :                 return NULL;
     975             : 
     976           0 :         switch (node->type) {
     977             :         case isl_ast_node_if:
     978           0 :                 dup->u.i.guard = isl_ast_expr_copy(node->u.i.guard);
     979           0 :                 dup->u.i.then = isl_ast_node_copy(node->u.i.then);
     980           0 :                 dup->u.i.else_node = isl_ast_node_copy(node->u.i.else_node);
     981           0 :                 if (!dup->u.i.guard  || !dup->u.i.then ||
     982           0 :                     (node->u.i.else_node && !dup->u.i.else_node))
     983           0 :                         return isl_ast_node_free(dup);
     984           0 :                 break;
     985             :         case isl_ast_node_for:
     986           0 :                 dup->u.f.iterator = isl_ast_expr_copy(node->u.f.iterator);
     987           0 :                 dup->u.f.init = isl_ast_expr_copy(node->u.f.init);
     988           0 :                 dup->u.f.cond = isl_ast_expr_copy(node->u.f.cond);
     989           0 :                 dup->u.f.inc = isl_ast_expr_copy(node->u.f.inc);
     990           0 :                 dup->u.f.body = isl_ast_node_copy(node->u.f.body);
     991           0 :                 if (!dup->u.f.iterator || !dup->u.f.init || !dup->u.f.cond ||
     992           0 :                     !dup->u.f.inc || !dup->u.f.body)
     993           0 :                         return isl_ast_node_free(dup);
     994           0 :                 break;
     995             :         case isl_ast_node_block:
     996           0 :                 dup->u.b.children = isl_ast_node_list_copy(node->u.b.children);
     997           0 :                 if (!dup->u.b.children)
     998           0 :                         return isl_ast_node_free(dup);
     999           0 :                 break;
    1000             :         case isl_ast_node_mark:
    1001           0 :                 dup->u.m.mark = isl_id_copy(node->u.m.mark);
    1002           0 :                 dup->u.m.node = isl_ast_node_copy(node->u.m.node);
    1003           0 :                 if (!dup->u.m.mark || !dup->u.m.node)
    1004           0 :                         return isl_ast_node_free(dup);
    1005           0 :                 break;
    1006             :         case isl_ast_node_user:
    1007           0 :                 dup->u.e.expr = isl_ast_expr_copy(node->u.e.expr);
    1008           0 :                 if (!dup->u.e.expr)
    1009           0 :                         return isl_ast_node_free(dup);
    1010           0 :                 break;
    1011             :         case isl_ast_node_error:
    1012           0 :                 break;
    1013             :         }
    1014             : 
    1015           0 :         return dup;
    1016             : }
    1017             : 
    1018           0 : __isl_give isl_ast_node *isl_ast_node_cow(__isl_take isl_ast_node *node)
    1019             : {
    1020           0 :         if (!node)
    1021           0 :                 return NULL;
    1022             : 
    1023           0 :         if (node->ref == 1)
    1024           0 :                 return node;
    1025           0 :         node->ref--;
    1026           0 :         return isl_ast_node_dup(node);
    1027             : }
    1028             : 
    1029           0 : __isl_null isl_ast_node *isl_ast_node_free(__isl_take isl_ast_node *node)
    1030             : {
    1031           0 :         if (!node)
    1032           0 :                 return NULL;
    1033             : 
    1034           0 :         if (--node->ref > 0)
    1035           0 :                 return NULL;
    1036             : 
    1037           0 :         switch (node->type) {
    1038             :         case isl_ast_node_if:
    1039           0 :                 isl_ast_expr_free(node->u.i.guard);
    1040           0 :                 isl_ast_node_free(node->u.i.then);
    1041           0 :                 isl_ast_node_free(node->u.i.else_node);
    1042           0 :                 break;
    1043             :         case isl_ast_node_for:
    1044           0 :                 isl_ast_expr_free(node->u.f.iterator);
    1045           0 :                 isl_ast_expr_free(node->u.f.init);
    1046           0 :                 isl_ast_expr_free(node->u.f.cond);
    1047           0 :                 isl_ast_expr_free(node->u.f.inc);
    1048           0 :                 isl_ast_node_free(node->u.f.body);
    1049           0 :                 break;
    1050             :         case isl_ast_node_block:
    1051           0 :                 isl_ast_node_list_free(node->u.b.children);
    1052           0 :                 break;
    1053             :         case isl_ast_node_mark:
    1054           0 :                 isl_id_free(node->u.m.mark);
    1055           0 :                 isl_ast_node_free(node->u.m.node);
    1056           0 :                 break;
    1057             :         case isl_ast_node_user:
    1058           0 :                 isl_ast_expr_free(node->u.e.expr);
    1059           0 :                 break;
    1060             :         case isl_ast_node_error:
    1061           0 :                 break;
    1062             :         }
    1063             : 
    1064           0 :         isl_id_free(node->annotation);
    1065           0 :         isl_ctx_deref(node->ctx);
    1066           0 :         free(node);
    1067             : 
    1068           0 :         return NULL;
    1069             : }
    1070             : 
    1071             : /* Replace the body of the for node "node" by "body".
    1072             :  */
    1073           0 : __isl_give isl_ast_node *isl_ast_node_for_set_body(
    1074             :         __isl_take isl_ast_node *node, __isl_take isl_ast_node *body)
    1075             : {
    1076           0 :         node = isl_ast_node_cow(node);
    1077           0 :         if (!node || !body)
    1078             :                 goto error;
    1079           0 :         if (node->type != isl_ast_node_for)
    1080           0 :                 isl_die(isl_ast_node_get_ctx(node), isl_error_invalid,
    1081             :                         "not a for node", goto error);
    1082             : 
    1083           0 :         isl_ast_node_free(node->u.f.body);
    1084           0 :         node->u.f.body = body;
    1085             : 
    1086           0 :         return node;
    1087             : error:
    1088           0 :         isl_ast_node_free(node);
    1089           0 :         isl_ast_node_free(body);
    1090           0 :         return NULL;
    1091             : }
    1092             : 
    1093           0 : __isl_give isl_ast_node *isl_ast_node_for_get_body(
    1094             :         __isl_keep isl_ast_node *node)
    1095             : {
    1096           0 :         if (!node)
    1097           0 :                 return NULL;
    1098           0 :         if (node->type != isl_ast_node_for)
    1099           0 :                 isl_die(isl_ast_node_get_ctx(node), isl_error_invalid,
    1100             :                         "not a for node", return NULL);
    1101           0 :         return isl_ast_node_copy(node->u.f.body);
    1102             : }
    1103             : 
    1104             : /* Mark the given for node as being degenerate.
    1105             :  */
    1106           0 : __isl_give isl_ast_node *isl_ast_node_for_mark_degenerate(
    1107             :         __isl_take isl_ast_node *node)
    1108             : {
    1109           0 :         node = isl_ast_node_cow(node);
    1110           0 :         if (!node)
    1111           0 :                 return NULL;
    1112           0 :         node->u.f.degenerate = 1;
    1113           0 :         return node;
    1114             : }
    1115             : 
    1116           0 : isl_bool isl_ast_node_for_is_degenerate(__isl_keep isl_ast_node *node)
    1117             : {
    1118           0 :         if (!node)
    1119           0 :                 return isl_bool_error;
    1120           0 :         if (node->type != isl_ast_node_for)
    1121           0 :                 isl_die(isl_ast_node_get_ctx(node), isl_error_invalid,
    1122             :                         "not a for node", return isl_bool_error);
    1123           0 :         return node->u.f.degenerate;
    1124             : }
    1125             : 
    1126           0 : __isl_give isl_ast_expr *isl_ast_node_for_get_iterator(
    1127             :         __isl_keep isl_ast_node *node)
    1128             : {
    1129           0 :         if (!node)
    1130           0 :                 return NULL;
    1131           0 :         if (node->type != isl_ast_node_for)
    1132           0 :                 isl_die(isl_ast_node_get_ctx(node), isl_error_invalid,
    1133             :                         "not a for node", return NULL);
    1134           0 :         return isl_ast_expr_copy(node->u.f.iterator);
    1135             : }
    1136             : 
    1137           0 : __isl_give isl_ast_expr *isl_ast_node_for_get_init(
    1138             :         __isl_keep isl_ast_node *node)
    1139             : {
    1140           0 :         if (!node)
    1141           0 :                 return NULL;
    1142           0 :         if (node->type != isl_ast_node_for)
    1143           0 :                 isl_die(isl_ast_node_get_ctx(node), isl_error_invalid,
    1144             :                         "not a for node", return NULL);
    1145           0 :         return isl_ast_expr_copy(node->u.f.init);
    1146             : }
    1147             : 
    1148             : /* Return the condition expression of the given for node.
    1149             :  *
    1150             :  * If the for node is degenerate, then the condition is not explicitly
    1151             :  * stored in the node.  Instead, it is constructed as
    1152             :  *
    1153             :  *      iterator <= init
    1154             :  */
    1155           0 : __isl_give isl_ast_expr *isl_ast_node_for_get_cond(
    1156             :         __isl_keep isl_ast_node *node)
    1157             : {
    1158           0 :         if (!node)
    1159           0 :                 return NULL;
    1160           0 :         if (node->type != isl_ast_node_for)
    1161           0 :                 isl_die(isl_ast_node_get_ctx(node), isl_error_invalid,
    1162             :                         "not a for node", return NULL);
    1163           0 :         if (!node->u.f.degenerate)
    1164           0 :                 return isl_ast_expr_copy(node->u.f.cond);
    1165             : 
    1166           0 :         return isl_ast_expr_alloc_binary(isl_ast_op_le,
    1167             :                                 isl_ast_expr_copy(node->u.f.iterator),
    1168             :                                 isl_ast_expr_copy(node->u.f.init));
    1169             : }
    1170             : 
    1171             : /* Return the increment of the given for node.
    1172             :  *
    1173             :  * If the for node is degenerate, then the increment is not explicitly
    1174             :  * stored in the node.  We simply return "1".
    1175             :  */
    1176           0 : __isl_give isl_ast_expr *isl_ast_node_for_get_inc(
    1177             :         __isl_keep isl_ast_node *node)
    1178             : {
    1179           0 :         if (!node)
    1180           0 :                 return NULL;
    1181           0 :         if (node->type != isl_ast_node_for)
    1182           0 :                 isl_die(isl_ast_node_get_ctx(node), isl_error_invalid,
    1183             :                         "not a for node", return NULL);
    1184           0 :         if (!node->u.f.degenerate)
    1185           0 :                 return isl_ast_expr_copy(node->u.f.inc);
    1186           0 :         return isl_ast_expr_alloc_int_si(isl_ast_node_get_ctx(node), 1);
    1187             : }
    1188             : 
    1189             : /* Replace the then branch of the if node "node" by "child".
    1190             :  */
    1191           0 : __isl_give isl_ast_node *isl_ast_node_if_set_then(
    1192             :         __isl_take isl_ast_node *node, __isl_take isl_ast_node *child)
    1193             : {
    1194           0 :         node = isl_ast_node_cow(node);
    1195           0 :         if (!node || !child)
    1196             :                 goto error;
    1197           0 :         if (node->type != isl_ast_node_if)
    1198           0 :                 isl_die(isl_ast_node_get_ctx(node), isl_error_invalid,
    1199             :                         "not an if node", goto error);
    1200             : 
    1201           0 :         isl_ast_node_free(node->u.i.then);
    1202           0 :         node->u.i.then = child;
    1203             : 
    1204           0 :         return node;
    1205             : error:
    1206           0 :         isl_ast_node_free(node);
    1207           0 :         isl_ast_node_free(child);
    1208           0 :         return NULL;
    1209             : }
    1210             : 
    1211           0 : __isl_give isl_ast_node *isl_ast_node_if_get_then(
    1212             :         __isl_keep isl_ast_node *node)
    1213             : {
    1214           0 :         if (!node)
    1215           0 :                 return NULL;
    1216           0 :         if (node->type != isl_ast_node_if)
    1217           0 :                 isl_die(isl_ast_node_get_ctx(node), isl_error_invalid,
    1218             :                         "not an if node", return NULL);
    1219           0 :         return isl_ast_node_copy(node->u.i.then);
    1220             : }
    1221             : 
    1222           0 : isl_bool isl_ast_node_if_has_else(
    1223             :         __isl_keep isl_ast_node *node)
    1224             : {
    1225           0 :         if (!node)
    1226           0 :                 return isl_bool_error;
    1227           0 :         if (node->type != isl_ast_node_if)
    1228           0 :                 isl_die(isl_ast_node_get_ctx(node), isl_error_invalid,
    1229             :                         "not an if node", return isl_bool_error);
    1230           0 :         return node->u.i.else_node != NULL;
    1231             : }
    1232             : 
    1233           0 : __isl_give isl_ast_node *isl_ast_node_if_get_else(
    1234             :         __isl_keep isl_ast_node *node)
    1235             : {
    1236           0 :         if (!node)
    1237           0 :                 return NULL;
    1238           0 :         if (node->type != isl_ast_node_if)
    1239           0 :                 isl_die(isl_ast_node_get_ctx(node), isl_error_invalid,
    1240             :                         "not an if node", return NULL);
    1241           0 :         return isl_ast_node_copy(node->u.i.else_node);
    1242             : }
    1243             : 
    1244           0 : __isl_give isl_ast_expr *isl_ast_node_if_get_cond(
    1245             :         __isl_keep isl_ast_node *node)
    1246             : {
    1247           0 :         if (!node)
    1248           0 :                 return NULL;
    1249           0 :         if (node->type != isl_ast_node_if)
    1250           0 :                 isl_die(isl_ast_node_get_ctx(node), isl_error_invalid,
    1251             :                         "not a guard node", return NULL);
    1252           0 :         return isl_ast_expr_copy(node->u.i.guard);
    1253             : }
    1254             : 
    1255           0 : __isl_give isl_ast_node_list *isl_ast_node_block_get_children(
    1256             :         __isl_keep isl_ast_node *node)
    1257             : {
    1258           0 :         if (!node)
    1259           0 :                 return NULL;
    1260           0 :         if (node->type != isl_ast_node_block)
    1261           0 :                 isl_die(isl_ast_node_get_ctx(node), isl_error_invalid,
    1262             :                         "not a block node", return NULL);
    1263           0 :         return isl_ast_node_list_copy(node->u.b.children);
    1264             : }
    1265             : 
    1266           0 : __isl_give isl_ast_expr *isl_ast_node_user_get_expr(
    1267             :         __isl_keep isl_ast_node *node)
    1268             : {
    1269           0 :         if (!node)
    1270           0 :                 return NULL;
    1271           0 :         if (node->type != isl_ast_node_user)
    1272           0 :                 isl_die(isl_ast_node_get_ctx(node), isl_error_invalid,
    1273             :                         "not a user node", return NULL);
    1274             : 
    1275           0 :         return isl_ast_expr_copy(node->u.e.expr);
    1276             : }
    1277             : 
    1278             : /* Return the mark identifier of the mark node "node".
    1279             :  */
    1280           0 : __isl_give isl_id *isl_ast_node_mark_get_id(__isl_keep isl_ast_node *node)
    1281             : {
    1282           0 :         if (!node)
    1283           0 :                 return NULL;
    1284           0 :         if (node->type != isl_ast_node_mark)
    1285           0 :                 isl_die(isl_ast_node_get_ctx(node), isl_error_invalid,
    1286             :                         "not a mark node", return NULL);
    1287             : 
    1288           0 :         return isl_id_copy(node->u.m.mark);
    1289             : }
    1290             : 
    1291             : /* Return the node marked by mark node "node".
    1292             :  */
    1293           0 : __isl_give isl_ast_node *isl_ast_node_mark_get_node(
    1294             :         __isl_keep isl_ast_node *node)
    1295             : {
    1296           0 :         if (!node)
    1297           0 :                 return NULL;
    1298           0 :         if (node->type != isl_ast_node_mark)
    1299           0 :                 isl_die(isl_ast_node_get_ctx(node), isl_error_invalid,
    1300             :                         "not a mark node", return NULL);
    1301             : 
    1302           0 :         return isl_ast_node_copy(node->u.m.node);
    1303             : }
    1304             : 
    1305           0 : __isl_give isl_id *isl_ast_node_get_annotation(__isl_keep isl_ast_node *node)
    1306             : {
    1307           0 :         return node ? isl_id_copy(node->annotation) : NULL;
    1308             : }
    1309             : 
    1310             : /* Replace node->annotation by "annotation".
    1311             :  */
    1312           0 : __isl_give isl_ast_node *isl_ast_node_set_annotation(
    1313             :         __isl_take isl_ast_node *node, __isl_take isl_id *annotation)
    1314             : {
    1315           0 :         node = isl_ast_node_cow(node);
    1316           0 :         if (!node || !annotation)
    1317             :                 goto error;
    1318             : 
    1319           0 :         isl_id_free(node->annotation);
    1320           0 :         node->annotation = annotation;
    1321             : 
    1322           0 :         return node;
    1323             : error:
    1324           0 :         isl_id_free(annotation);
    1325           0 :         return isl_ast_node_free(node);
    1326             : }
    1327             : 
    1328             : /* Traverse the elements of "list" and all their descendants
    1329             :  * in depth first preorder.
    1330             :  *
    1331             :  * Return isl_stat_ok on success and isl_stat_error on failure.
    1332             :  */
    1333           0 : static isl_stat nodelist_foreach(__isl_keep isl_ast_node_list *list,
    1334             :         isl_bool (*fn)(__isl_keep isl_ast_node *node, void *user), void *user)
    1335             : {
    1336             :         int i;
    1337             : 
    1338           0 :         if (!list)
    1339           0 :                 return isl_stat_error;
    1340             : 
    1341           0 :         for (i = 0; i < list->n; ++i) {
    1342             :                 isl_stat ok;
    1343           0 :                 isl_ast_node *node = list->p[i];
    1344             : 
    1345           0 :                 ok = isl_ast_node_foreach_descendant_top_down(node, fn, user);
    1346           0 :                 if (ok < 0)
    1347           0 :                         return isl_stat_error;
    1348             :         }
    1349             : 
    1350           0 :         return isl_stat_ok;
    1351             : }
    1352             : 
    1353             : /* Traverse the descendants of "node" (including the node itself)
    1354             :  * in depth first preorder.
    1355             :  *
    1356             :  * If "fn" returns isl_bool_error on any of the nodes, then the traversal
    1357             :  * is aborted.
    1358             :  * If "fn" returns isl_bool_false on any of the nodes, then the subtree rooted
    1359             :  * at that node is skipped.
    1360             :  *
    1361             :  * Return isl_stat_ok on success and isl_stat_error on failure.
    1362             :  */
    1363           0 : isl_stat isl_ast_node_foreach_descendant_top_down(
    1364             :         __isl_keep isl_ast_node *node,
    1365             :         isl_bool (*fn)(__isl_keep isl_ast_node *node, void *user), void *user)
    1366             : {
    1367             :         isl_bool more;
    1368             :         isl_stat ok;
    1369             : 
    1370           0 :         if (!node)
    1371           0 :                 return isl_stat_error;
    1372             : 
    1373           0 :         more = fn(node, user);
    1374           0 :         if (more < 0)
    1375           0 :                 return isl_stat_error;
    1376           0 :         if (!more)
    1377           0 :                 return isl_stat_ok;
    1378             : 
    1379           0 :         switch (node->type) {
    1380             :         case isl_ast_node_for:
    1381           0 :                 node = node->u.f.body;
    1382           0 :                 return isl_ast_node_foreach_descendant_top_down(node, fn, user);
    1383             :         case isl_ast_node_if:
    1384           0 :                 ok = isl_ast_node_foreach_descendant_top_down(node->u.i.then,
    1385             :                                                                 fn, user);
    1386           0 :                 if (ok < 0)
    1387           0 :                         return isl_stat_error;
    1388           0 :                 if (!node->u.i.else_node)
    1389           0 :                         return isl_stat_ok;
    1390           0 :                 node = node->u.i.else_node;
    1391           0 :                 return isl_ast_node_foreach_descendant_top_down(node, fn, user);
    1392             :         case isl_ast_node_block:
    1393           0 :                 return nodelist_foreach(node->u.b.children, fn, user);
    1394             :         case isl_ast_node_mark:
    1395           0 :                 node = node->u.m.node;
    1396           0 :                 return isl_ast_node_foreach_descendant_top_down(node, fn, user);
    1397             :         case isl_ast_node_user:
    1398           0 :                 break;
    1399             :         case isl_ast_node_error:
    1400           0 :                 return isl_stat_error;
    1401             :         }
    1402             : 
    1403           0 :         return isl_stat_ok;
    1404             : }
    1405             : 
    1406             : /* Textual C representation of the various operators.
    1407             :  */
    1408             : static char *op_str_c[] = {
    1409             :         [isl_ast_op_and] = "&&",
    1410             :         [isl_ast_op_and_then] = "&&",
    1411             :         [isl_ast_op_or] = "||",
    1412             :         [isl_ast_op_or_else] = "||",
    1413             :         [isl_ast_op_max] = "max",
    1414             :         [isl_ast_op_min] = "min",
    1415             :         [isl_ast_op_minus] = "-",
    1416             :         [isl_ast_op_add] = "+",
    1417             :         [isl_ast_op_sub] = "-",
    1418             :         [isl_ast_op_mul] = "*",
    1419             :         [isl_ast_op_fdiv_q] = "floord",
    1420             :         [isl_ast_op_pdiv_q] = "/",
    1421             :         [isl_ast_op_pdiv_r] = "%",
    1422             :         [isl_ast_op_zdiv_r] = "%",
    1423             :         [isl_ast_op_div] = "/",
    1424             :         [isl_ast_op_eq] = "==",
    1425             :         [isl_ast_op_le] = "<=",
    1426             :         [isl_ast_op_ge] = ">=",
    1427             :         [isl_ast_op_lt] = "<",
    1428             :         [isl_ast_op_gt] = ">",
    1429             :         [isl_ast_op_member] = ".",
    1430             :         [isl_ast_op_address_of] = "&"
    1431             : };
    1432             : 
    1433             : /* Precedence in C of the various operators.
    1434             :  * Based on http://en.wikipedia.org/wiki/Operators_in_C_and_C++
    1435             :  * Lowest value means highest precedence.
    1436             :  */
    1437             : static int op_prec[] = {
    1438             :         [isl_ast_op_and] = 13,
    1439             :         [isl_ast_op_and_then] = 13,
    1440             :         [isl_ast_op_or] = 14,
    1441             :         [isl_ast_op_or_else] = 14,
    1442             :         [isl_ast_op_max] = 2,
    1443             :         [isl_ast_op_min] = 2,
    1444             :         [isl_ast_op_minus] = 3,
    1445             :         [isl_ast_op_add] = 6,
    1446             :         [isl_ast_op_sub] = 6,
    1447             :         [isl_ast_op_mul] = 5,
    1448             :         [isl_ast_op_div] = 5,
    1449             :         [isl_ast_op_fdiv_q] = 2,
    1450             :         [isl_ast_op_pdiv_q] = 5,
    1451             :         [isl_ast_op_pdiv_r] = 5,
    1452             :         [isl_ast_op_zdiv_r] = 5,
    1453             :         [isl_ast_op_cond] = 15,
    1454             :         [isl_ast_op_select] = 15,
    1455             :         [isl_ast_op_eq] = 9,
    1456             :         [isl_ast_op_le] = 8,
    1457             :         [isl_ast_op_ge] = 8,
    1458             :         [isl_ast_op_lt] = 8,
    1459             :         [isl_ast_op_gt] = 8,
    1460             :         [isl_ast_op_call] = 2,
    1461             :         [isl_ast_op_access] = 2,
    1462             :         [isl_ast_op_member] = 2,
    1463             :         [isl_ast_op_address_of] = 3
    1464             : };
    1465             : 
    1466             : /* Is the operator left-to-right associative?
    1467             :  */
    1468             : static int op_left[] = {
    1469             :         [isl_ast_op_and] = 1,
    1470             :         [isl_ast_op_and_then] = 1,
    1471             :         [isl_ast_op_or] = 1,
    1472             :         [isl_ast_op_or_else] = 1,
    1473             :         [isl_ast_op_max] = 1,
    1474             :         [isl_ast_op_min] = 1,
    1475             :         [isl_ast_op_minus] = 0,
    1476             :         [isl_ast_op_add] = 1,
    1477             :         [isl_ast_op_sub] = 1,
    1478             :         [isl_ast_op_mul] = 1,
    1479             :         [isl_ast_op_div] = 1,
    1480             :         [isl_ast_op_fdiv_q] = 1,
    1481             :         [isl_ast_op_pdiv_q] = 1,
    1482             :         [isl_ast_op_pdiv_r] = 1,
    1483             :         [isl_ast_op_zdiv_r] = 1,
    1484             :         [isl_ast_op_cond] = 0,
    1485             :         [isl_ast_op_select] = 0,
    1486             :         [isl_ast_op_eq] = 1,
    1487             :         [isl_ast_op_le] = 1,
    1488             :         [isl_ast_op_ge] = 1,
    1489             :         [isl_ast_op_lt] = 1,
    1490             :         [isl_ast_op_gt] = 1,
    1491             :         [isl_ast_op_call] = 1,
    1492             :         [isl_ast_op_access] = 1,
    1493             :         [isl_ast_op_member] = 1,
    1494             :         [isl_ast_op_address_of] = 0
    1495             : };
    1496             : 
    1497           0 : static int is_and(enum isl_ast_op_type op)
    1498             : {
    1499           0 :         return op == isl_ast_op_and || op == isl_ast_op_and_then;
    1500             : }
    1501             : 
    1502           0 : static int is_or(enum isl_ast_op_type op)
    1503             : {
    1504           0 :         return op == isl_ast_op_or || op == isl_ast_op_or_else;
    1505             : }
    1506             : 
    1507           0 : static int is_add_sub(enum isl_ast_op_type op)
    1508             : {
    1509           0 :         return op == isl_ast_op_add || op == isl_ast_op_sub;
    1510             : }
    1511             : 
    1512           0 : static int is_div_mod(enum isl_ast_op_type op)
    1513             : {
    1514           0 :         return op == isl_ast_op_div ||
    1515           0 :                op == isl_ast_op_pdiv_r ||
    1516             :                op == isl_ast_op_zdiv_r;
    1517             : }
    1518             : 
    1519             : static __isl_give isl_printer *print_ast_expr_c(__isl_take isl_printer *p,
    1520             :         __isl_keep isl_ast_expr *expr);
    1521             : 
    1522             : /* Do we need/want parentheses around "expr" as a subexpression of
    1523             :  * an "op" operation?  If "left" is set, then "expr" is the left-most
    1524             :  * operand.
    1525             :  *
    1526             :  * We only need parentheses if "expr" represents an operation.
    1527             :  *
    1528             :  * If op has a higher precedence than expr->u.op.op, then we need
    1529             :  * parentheses.
    1530             :  * If op and expr->u.op.op have the same precedence, but the operations
    1531             :  * are performed in an order that is different from the associativity,
    1532             :  * then we need parentheses.
    1533             :  *
    1534             :  * An and inside an or technically does not require parentheses,
    1535             :  * but some compilers complain about that, so we add them anyway.
    1536             :  *
    1537             :  * Computations such as "a / b * c" and "a % b + c" can be somewhat
    1538             :  * difficult to read, so we add parentheses for those as well.
    1539             :  */
    1540           0 : static int sub_expr_need_parens(enum isl_ast_op_type op,
    1541             :         __isl_keep isl_ast_expr *expr, int left)
    1542             : {
    1543           0 :         if (expr->type != isl_ast_expr_op)
    1544           0 :                 return 0;
    1545             : 
    1546           0 :         if (op_prec[expr->u.op.op] > op_prec[op])
    1547           0 :                 return 1;
    1548           0 :         if (op_prec[expr->u.op.op] == op_prec[op] && left != op_left[op])
    1549           0 :                 return 1;
    1550             : 
    1551           0 :         if (is_or(op) && is_and(expr->u.op.op))
    1552           0 :                 return 1;
    1553           0 :         if (op == isl_ast_op_mul && expr->u.op.op != isl_ast_op_mul &&
    1554           0 :             op_prec[expr->u.op.op] == op_prec[op])
    1555           0 :                 return 1;
    1556           0 :         if (is_add_sub(op) && is_div_mod(expr->u.op.op))
    1557           0 :                 return 1;
    1558             : 
    1559           0 :         return 0;
    1560             : }
    1561             : 
    1562             : /* Print "expr" as a subexpression of an "op" operation in C format.
    1563             :  * If "left" is set, then "expr" is the left-most operand.
    1564             :  */
    1565           0 : static __isl_give isl_printer *print_sub_expr_c(__isl_take isl_printer *p,
    1566             :         enum isl_ast_op_type op, __isl_keep isl_ast_expr *expr, int left)
    1567             : {
    1568             :         int need_parens;
    1569             : 
    1570           0 :         need_parens = sub_expr_need_parens(op, expr, left);
    1571             : 
    1572           0 :         if (need_parens)
    1573           0 :                 p = isl_printer_print_str(p, "(");
    1574           0 :         p = print_ast_expr_c(p, expr);
    1575           0 :         if (need_parens)
    1576           0 :                 p = isl_printer_print_str(p, ")");
    1577           0 :         return p;
    1578             : }
    1579             : 
    1580             : #define isl_ast_op_last isl_ast_op_address_of
    1581             : 
    1582             : /* Data structure that holds the user-specified textual
    1583             :  * representations for the operators in C format.
    1584             :  * The entries are either NULL or copies of strings.
    1585             :  * A NULL entry means that the default name should be used.
    1586             :  */
    1587             : struct isl_ast_op_names {
    1588             :         char *op_str[isl_ast_op_last + 1];
    1589             : };
    1590             : 
    1591             : /* Create an empty struct isl_ast_op_names.
    1592             :  */
    1593           0 : static void *create_names(isl_ctx *ctx)
    1594             : {
    1595           0 :         return isl_calloc_type(ctx, struct isl_ast_op_names);
    1596             : }
    1597             : 
    1598             : /* Free a struct isl_ast_op_names along with all memory
    1599             :  * owned by the struct.
    1600             :  */
    1601           0 : static void free_names(void *user)
    1602             : {
    1603             :         int i;
    1604           0 :         struct isl_ast_op_names *names = user;
    1605             : 
    1606           0 :         if (!user)
    1607           0 :                 return;
    1608             : 
    1609           0 :         for (i = 0; i <= isl_ast_op_last; ++i)
    1610           0 :                 free(names->op_str[i]);
    1611           0 :         free(user);
    1612             : }
    1613             : 
    1614             : /* Create an identifier that is used to store
    1615             :  * an isl_ast_op_names note.
    1616             :  */
    1617           0 : static __isl_give isl_id *names_id(isl_ctx *ctx)
    1618             : {
    1619           0 :         return isl_id_alloc(ctx, "isl_ast_op_type_names", NULL);
    1620             : }
    1621             : 
    1622             : /* Ensure that "p" has a note identified by "id".
    1623             :  * If there is no such note yet, then it is created by "note_create" and
    1624             :  * scheduled do be freed by "note_free".
    1625             :  */
    1626           0 : static __isl_give isl_printer *alloc_note(__isl_take isl_printer *p,
    1627             :         __isl_keep isl_id *id, void *(*note_create)(isl_ctx *),
    1628             :         void (*note_free)(void *))
    1629             : {
    1630             :         isl_ctx *ctx;
    1631             :         isl_id *note_id;
    1632             :         isl_bool has_note;
    1633             :         void *note;
    1634             : 
    1635           0 :         has_note = isl_printer_has_note(p, id);
    1636           0 :         if (has_note < 0)
    1637           0 :                 return isl_printer_free(p);
    1638           0 :         if (has_note)
    1639           0 :                 return p;
    1640             : 
    1641           0 :         ctx = isl_printer_get_ctx(p);
    1642           0 :         note = note_create(ctx);
    1643           0 :         if (!note)
    1644           0 :                 return isl_printer_free(p);
    1645           0 :         note_id = isl_id_alloc(ctx, NULL, note);
    1646           0 :         if (!note_id)
    1647           0 :                 note_free(note);
    1648             :         else
    1649           0 :                 note_id = isl_id_set_free_user(note_id, note_free);
    1650             : 
    1651           0 :         p = isl_printer_set_note(p, isl_id_copy(id), note_id);
    1652             : 
    1653           0 :         return p;
    1654             : }
    1655             : 
    1656             : /* Ensure that "p" has an isl_ast_op_names note identified by "id".
    1657             :  */
    1658           0 : static __isl_give isl_printer *alloc_names(__isl_take isl_printer *p,
    1659             :         __isl_keep isl_id *id)
    1660             : {
    1661           0 :         return alloc_note(p, id, &create_names, &free_names);
    1662             : }
    1663             : 
    1664             : /* Retrieve the note identified by "id" from "p".
    1665             :  * The note is assumed to exist.
    1666             :  */
    1667           0 : static void *get_note(__isl_keep isl_printer *p, __isl_keep isl_id *id)
    1668             : {
    1669             :         void *note;
    1670             : 
    1671           0 :         id = isl_printer_get_note(p, isl_id_copy(id));
    1672           0 :         note = isl_id_get_user(id);
    1673           0 :         isl_id_free(id);
    1674             : 
    1675           0 :         return note;
    1676             : }
    1677             : 
    1678             : /* Use "name" to print operations of type "type" to "p".
    1679             :  *
    1680             :  * Store the name in an isl_ast_op_names note attached to "p", such that
    1681             :  * it can be retrieved by get_op_str.
    1682             :  */
    1683           0 : __isl_give isl_printer *isl_ast_op_type_set_print_name(
    1684             :         __isl_take isl_printer *p, enum isl_ast_op_type type,
    1685             :         __isl_keep const char *name)
    1686             : {
    1687             :         isl_id *id;
    1688             :         struct isl_ast_op_names *names;
    1689             : 
    1690           0 :         if (!p)
    1691           0 :                 return NULL;
    1692           0 :         if (type > isl_ast_op_last)
    1693           0 :                 isl_die(isl_printer_get_ctx(p), isl_error_invalid,
    1694             :                         "invalid type", return isl_printer_free(p));
    1695             : 
    1696           0 :         id = names_id(isl_printer_get_ctx(p));
    1697           0 :         p = alloc_names(p, id);
    1698           0 :         names = get_note(p, id);
    1699           0 :         isl_id_free(id);
    1700           0 :         if (!names)
    1701           0 :                 return isl_printer_free(p);
    1702           0 :         free(names->op_str[type]);
    1703           0 :         names->op_str[type] = strdup(name);
    1704             : 
    1705           0 :         return p;
    1706             : }
    1707             : 
    1708             : /* Return the textual representation of "type" in C format.
    1709             :  *
    1710             :  * If there is a user-specified name in an isl_ast_op_names note
    1711             :  * associated to "p", then return that.
    1712             :  * Otherwise, return the default name in op_str.
    1713             :  */
    1714           0 : static const char *get_op_str_c(__isl_keep isl_printer *p,
    1715             :         enum isl_ast_op_type type)
    1716             : {
    1717             :         isl_id *id;
    1718             :         isl_bool has_names;
    1719           0 :         struct isl_ast_op_names *names = NULL;
    1720             : 
    1721           0 :         id = names_id(isl_printer_get_ctx(p));
    1722           0 :         has_names = isl_printer_has_note(p, id);
    1723           0 :         if (has_names >= 0 && has_names)
    1724           0 :                 names = get_note(p, id);
    1725           0 :         isl_id_free(id);
    1726           0 :         if (names && names->op_str[type])
    1727           0 :                 return names->op_str[type];
    1728           0 :         return op_str_c[type];
    1729             : }
    1730             : 
    1731             : /* Print a min or max reduction "expr" in C format.
    1732             :  */
    1733           0 : static __isl_give isl_printer *print_min_max_c(__isl_take isl_printer *p,
    1734             :         __isl_keep isl_ast_expr *expr)
    1735             : {
    1736           0 :         int i = 0;
    1737             : 
    1738           0 :         for (i = 1; i < expr->u.op.n_arg; ++i) {
    1739           0 :                 p = isl_printer_print_str(p, get_op_str_c(p, expr->u.op.op));
    1740           0 :                 p = isl_printer_print_str(p, "(");
    1741             :         }
    1742           0 :         p = isl_printer_print_ast_expr(p, expr->u.op.args[0]);
    1743           0 :         for (i = 1; i < expr->u.op.n_arg; ++i) {
    1744           0 :                 p = isl_printer_print_str(p, ", ");
    1745           0 :                 p = print_ast_expr_c(p, expr->u.op.args[i]);
    1746           0 :                 p = isl_printer_print_str(p, ")");
    1747             :         }
    1748             : 
    1749           0 :         return p;
    1750             : }
    1751             : 
    1752             : /* Print a function call "expr" in C format.
    1753             :  *
    1754             :  * The first argument represents the function to be called.
    1755             :  */
    1756           0 : static __isl_give isl_printer *print_call_c(__isl_take isl_printer *p,
    1757             :         __isl_keep isl_ast_expr *expr)
    1758             : {
    1759           0 :         int i = 0;
    1760             : 
    1761           0 :         p = print_ast_expr_c(p, expr->u.op.args[0]);
    1762           0 :         p = isl_printer_print_str(p, "(");
    1763           0 :         for (i = 1; i < expr->u.op.n_arg; ++i) {
    1764           0 :                 if (i != 1)
    1765           0 :                         p = isl_printer_print_str(p, ", ");
    1766           0 :                 p = print_ast_expr_c(p, expr->u.op.args[i]);
    1767             :         }
    1768           0 :         p = isl_printer_print_str(p, ")");
    1769             : 
    1770           0 :         return p;
    1771             : }
    1772             : 
    1773             : /* Print an array access "expr" in C format.
    1774             :  *
    1775             :  * The first argument represents the array being accessed.
    1776             :  */
    1777           0 : static __isl_give isl_printer *print_access_c(__isl_take isl_printer *p,
    1778             :         __isl_keep isl_ast_expr *expr)
    1779             : {
    1780           0 :         int i = 0;
    1781             : 
    1782           0 :         p = print_ast_expr_c(p, expr->u.op.args[0]);
    1783           0 :         for (i = 1; i < expr->u.op.n_arg; ++i) {
    1784           0 :                 p = isl_printer_print_str(p, "[");
    1785           0 :                 p = print_ast_expr_c(p, expr->u.op.args[i]);
    1786           0 :                 p = isl_printer_print_str(p, "]");
    1787             :         }
    1788             : 
    1789           0 :         return p;
    1790             : }
    1791             : 
    1792             : /* Print "expr" to "p" in C format.
    1793             :  */
    1794           0 : static __isl_give isl_printer *print_ast_expr_c(__isl_take isl_printer *p,
    1795             :         __isl_keep isl_ast_expr *expr)
    1796             : {
    1797           0 :         if (!p)
    1798           0 :                 return NULL;
    1799           0 :         if (!expr)
    1800           0 :                 return isl_printer_free(p);
    1801             : 
    1802           0 :         switch (expr->type) {
    1803             :         case isl_ast_expr_op:
    1804           0 :                 if (expr->u.op.op == isl_ast_op_call) {
    1805           0 :                         p = print_call_c(p, expr);
    1806           0 :                         break;
    1807             :                 }
    1808           0 :                 if (expr->u.op.op == isl_ast_op_access) {
    1809           0 :                         p = print_access_c(p, expr);
    1810           0 :                         break;
    1811             :                 }
    1812           0 :                 if (expr->u.op.n_arg == 1) {
    1813           0 :                         p = isl_printer_print_str(p,
    1814             :                                                 get_op_str_c(p, expr->u.op.op));
    1815           0 :                         p = print_sub_expr_c(p, expr->u.op.op,
    1816           0 :                                                 expr->u.op.args[0], 0);
    1817           0 :                         break;
    1818             :                 }
    1819           0 :                 if (expr->u.op.op == isl_ast_op_fdiv_q) {
    1820           0 :                         const char *name = get_op_str_c(p, isl_ast_op_fdiv_q);
    1821           0 :                         p = isl_printer_print_str(p, name);
    1822           0 :                         p = isl_printer_print_str(p, "(");
    1823           0 :                         p = print_ast_expr_c(p, expr->u.op.args[0]);
    1824           0 :                         p = isl_printer_print_str(p, ", ");
    1825           0 :                         p = print_ast_expr_c(p, expr->u.op.args[1]);
    1826           0 :                         p = isl_printer_print_str(p, ")");
    1827           0 :                         break;
    1828             :                 }
    1829           0 :                 if (expr->u.op.op == isl_ast_op_max ||
    1830           0 :                     expr->u.op.op == isl_ast_op_min) {
    1831           0 :                         p = print_min_max_c(p, expr);
    1832           0 :                         break;
    1833             :                 }
    1834           0 :                 if (expr->u.op.op == isl_ast_op_cond ||
    1835           0 :                     expr->u.op.op == isl_ast_op_select) {
    1836           0 :                         p = print_ast_expr_c(p, expr->u.op.args[0]);
    1837           0 :                         p = isl_printer_print_str(p, " ? ");
    1838           0 :                         p = print_ast_expr_c(p, expr->u.op.args[1]);
    1839           0 :                         p = isl_printer_print_str(p, " : ");
    1840           0 :                         p = print_ast_expr_c(p, expr->u.op.args[2]);
    1841           0 :                         break;
    1842             :                 }
    1843           0 :                 if (expr->u.op.n_arg != 2)
    1844           0 :                         isl_die(isl_printer_get_ctx(p), isl_error_internal,
    1845             :                                 "operation should have two arguments",
    1846             :                                 return isl_printer_free(p));
    1847           0 :                 p = print_sub_expr_c(p, expr->u.op.op, expr->u.op.args[0], 1);
    1848           0 :                 if (expr->u.op.op != isl_ast_op_member)
    1849           0 :                         p = isl_printer_print_str(p, " ");
    1850           0 :                 p = isl_printer_print_str(p, get_op_str_c(p, expr->u.op.op));
    1851           0 :                 if (expr->u.op.op != isl_ast_op_member)
    1852           0 :                         p = isl_printer_print_str(p, " ");
    1853           0 :                 p = print_sub_expr_c(p, expr->u.op.op, expr->u.op.args[1], 0);
    1854           0 :                 break;
    1855             :         case isl_ast_expr_id:
    1856           0 :                 p = isl_printer_print_str(p, isl_id_get_name(expr->u.id));
    1857           0 :                 break;
    1858             :         case isl_ast_expr_int:
    1859           0 :                 p = isl_printer_print_val(p, expr->u.v);
    1860           0 :                 break;
    1861             :         case isl_ast_expr_error:
    1862           0 :                 break;
    1863             :         }
    1864             : 
    1865           0 :         return p;
    1866             : }
    1867             : 
    1868             : /* Textual representation of the isl_ast_op_type elements
    1869             :  * for use in a YAML representation of an isl_ast_expr.
    1870             :  */
    1871             : static char *op_str[] = {
    1872             :         [isl_ast_op_and] = "and",
    1873             :         [isl_ast_op_and_then] = "and_then",
    1874             :         [isl_ast_op_or] = "or",
    1875             :         [isl_ast_op_or_else] = "or_else",
    1876             :         [isl_ast_op_max] = "max",
    1877             :         [isl_ast_op_min] = "min",
    1878             :         [isl_ast_op_minus] = "minus",
    1879             :         [isl_ast_op_add] = "add",
    1880             :         [isl_ast_op_sub] = "sub",
    1881             :         [isl_ast_op_mul] = "mul",
    1882             :         [isl_ast_op_div] = "div",
    1883             :         [isl_ast_op_fdiv_q] = "fdiv_q",
    1884             :         [isl_ast_op_pdiv_q] = "pdiv_q",
    1885             :         [isl_ast_op_pdiv_r] = "pdiv_r",
    1886             :         [isl_ast_op_zdiv_r] = "zdiv_r",
    1887             :         [isl_ast_op_cond] = "cond",
    1888             :         [isl_ast_op_select] = "select",
    1889             :         [isl_ast_op_eq] = "eq",
    1890             :         [isl_ast_op_le] = "le",
    1891             :         [isl_ast_op_lt] = "lt",
    1892             :         [isl_ast_op_ge] = "ge",
    1893             :         [isl_ast_op_gt] = "gt",
    1894             :         [isl_ast_op_call] = "call",
    1895             :         [isl_ast_op_access] = "access",
    1896             :         [isl_ast_op_member] = "member",
    1897             :         [isl_ast_op_address_of] = "address_of"
    1898             : };
    1899             : 
    1900             : static __isl_give isl_printer *print_ast_expr_isl(__isl_take isl_printer *p,
    1901             :         __isl_keep isl_ast_expr *expr);
    1902             : 
    1903             : /* Print the arguments of "expr" to "p" in isl format.
    1904             :  *
    1905             :  * If there are no arguments, then nothing needs to be printed.
    1906             :  * Otherwise add an "args" key to the current mapping with as value
    1907             :  * the list of arguments of "expr".
    1908             :  */
    1909           0 : static __isl_give isl_printer *print_arguments(__isl_take isl_printer *p,
    1910             :         __isl_keep isl_ast_expr *expr)
    1911             : {
    1912             :         int i, n;
    1913             : 
    1914           0 :         n = isl_ast_expr_get_op_n_arg(expr);
    1915           0 :         if (n < 0)
    1916           0 :                 return isl_printer_free(p);
    1917           0 :         if (n == 0)
    1918           0 :                 return p;
    1919             : 
    1920           0 :         p = isl_printer_print_str(p, "args");
    1921           0 :         p = isl_printer_yaml_next(p);
    1922           0 :         p = isl_printer_yaml_start_sequence(p);
    1923           0 :         for (i = 0; i < n; ++i) {
    1924             :                 isl_ast_expr *arg;
    1925             : 
    1926           0 :                 arg = isl_ast_expr_get_op_arg(expr, i);
    1927           0 :                 p = print_ast_expr_isl(p, arg);
    1928           0 :                 isl_ast_expr_free(arg);
    1929           0 :                 p = isl_printer_yaml_next(p);
    1930             :         }
    1931           0 :         p = isl_printer_yaml_end_sequence(p);
    1932             : 
    1933           0 :         return p;
    1934             : }
    1935             : 
    1936             : /* Print "expr" to "p" in isl format.
    1937             :  *
    1938             :  * In particular, print the isl_ast_expr as a YAML document.
    1939             :  */
    1940           0 : static __isl_give isl_printer *print_ast_expr_isl(__isl_take isl_printer *p,
    1941             :         __isl_keep isl_ast_expr *expr)
    1942             : {
    1943             :         enum isl_ast_expr_type type;
    1944             :         enum isl_ast_op_type op;
    1945             :         isl_id *id;
    1946             :         isl_val *v;
    1947             : 
    1948           0 :         if (!expr)
    1949           0 :                 return isl_printer_free(p);
    1950             : 
    1951           0 :         p = isl_printer_yaml_start_mapping(p);
    1952           0 :         type = isl_ast_expr_get_type(expr);
    1953           0 :         switch (type) {
    1954             :         case isl_ast_expr_error:
    1955           0 :                 return isl_printer_free(p);
    1956             :         case isl_ast_expr_op:
    1957           0 :                 op = isl_ast_expr_get_op_type(expr);
    1958           0 :                 if (op == isl_ast_op_error)
    1959           0 :                         return isl_printer_free(p);
    1960           0 :                 p = isl_printer_print_str(p, "op");
    1961           0 :                 p = isl_printer_yaml_next(p);
    1962           0 :                 p = isl_printer_print_str(p, op_str[op]);
    1963           0 :                 p = isl_printer_yaml_next(p);
    1964           0 :                 p = print_arguments(p, expr);
    1965           0 :                 break;
    1966             :         case isl_ast_expr_id:
    1967           0 :                 p = isl_printer_print_str(p, "id");
    1968           0 :                 p = isl_printer_yaml_next(p);
    1969           0 :                 id = isl_ast_expr_get_id(expr);
    1970           0 :                 p = isl_printer_print_id(p, id);
    1971           0 :                 isl_id_free(id);
    1972           0 :                 break;
    1973             :         case isl_ast_expr_int:
    1974           0 :                 p = isl_printer_print_str(p, "val");
    1975           0 :                 p = isl_printer_yaml_next(p);
    1976           0 :                 v = isl_ast_expr_get_val(expr);
    1977           0 :                 p = isl_printer_print_val(p, v);
    1978           0 :                 isl_val_free(v);
    1979           0 :                 break;
    1980             :         }
    1981           0 :         p = isl_printer_yaml_end_mapping(p);
    1982             : 
    1983           0 :         return p;
    1984             : }
    1985             : 
    1986             : /* Print "expr" to "p".
    1987             :  *
    1988             :  * Only an isl and a C format are supported.
    1989             :  */
    1990           0 : __isl_give isl_printer *isl_printer_print_ast_expr(__isl_take isl_printer *p,
    1991             :         __isl_keep isl_ast_expr *expr)
    1992             : {
    1993             :         int format;
    1994             : 
    1995           0 :         if (!p)
    1996           0 :                 return NULL;
    1997             : 
    1998           0 :         format = isl_printer_get_output_format(p);
    1999           0 :         switch (format) {
    2000             :         case ISL_FORMAT_ISL:
    2001           0 :                 p = print_ast_expr_isl(p, expr);
    2002           0 :                 break;
    2003             :         case ISL_FORMAT_C:
    2004           0 :                 p = print_ast_expr_c(p, expr);
    2005           0 :                 break;
    2006             :         default:
    2007           0 :                 isl_die(isl_printer_get_ctx(p), isl_error_unsupported,
    2008             :                         "output format not supported for ast_expr",
    2009             :                         return isl_printer_free(p));
    2010             :         }
    2011             : 
    2012           0 :         return p;
    2013             : }
    2014             : 
    2015             : static __isl_give isl_printer *print_ast_node_isl(__isl_take isl_printer *p,
    2016             :         __isl_keep isl_ast_node *node);
    2017             : 
    2018             : /* Print a YAML sequence containing the entries in "list" to "p".
    2019             :  */
    2020           0 : static __isl_give isl_printer *print_ast_node_list(__isl_take isl_printer *p,
    2021             :         __isl_keep isl_ast_node_list *list)
    2022             : {
    2023             :         int i, n;
    2024             : 
    2025           0 :         n = isl_ast_node_list_n_ast_node(list);
    2026           0 :         if (n < 0)
    2027           0 :                 return isl_printer_free(p);
    2028             : 
    2029           0 :         p = isl_printer_yaml_start_sequence(p);
    2030           0 :         for (i = 0; i < n; ++i) {
    2031             :                 isl_ast_node *node;
    2032             : 
    2033           0 :                 node = isl_ast_node_list_get_ast_node(list, i);
    2034           0 :                 p = print_ast_node_isl(p, node);
    2035           0 :                 isl_ast_node_free(node);
    2036           0 :                 p = isl_printer_yaml_next(p);
    2037             :         }
    2038           0 :         p = isl_printer_yaml_end_sequence(p);
    2039             : 
    2040           0 :         return p;
    2041             : }
    2042             : 
    2043             : /* Print "node" to "p" in "isl format".
    2044             :  *
    2045             :  * In particular, print the isl_ast_node as a YAML document.
    2046             :  */
    2047           0 : static __isl_give isl_printer *print_ast_node_isl(__isl_take isl_printer *p,
    2048             :         __isl_keep isl_ast_node *node)
    2049             : {
    2050           0 :         switch (node->type) {
    2051             :         case isl_ast_node_for:
    2052           0 :                 p = isl_printer_yaml_start_mapping(p);
    2053           0 :                 p = isl_printer_print_str(p, "iterator");
    2054           0 :                 p = isl_printer_yaml_next(p);
    2055           0 :                 p = isl_printer_print_ast_expr(p, node->u.f.iterator);
    2056           0 :                 p = isl_printer_yaml_next(p);
    2057           0 :                 if (node->u.f.degenerate) {
    2058           0 :                         p = isl_printer_print_str(p, "value");
    2059           0 :                         p = isl_printer_yaml_next(p);
    2060           0 :                         p = isl_printer_print_ast_expr(p, node->u.f.init);
    2061           0 :                         p = isl_printer_yaml_next(p);
    2062             :                 } else {
    2063           0 :                         p = isl_printer_print_str(p, "init");
    2064           0 :                         p = isl_printer_yaml_next(p);
    2065           0 :                         p = isl_printer_print_ast_expr(p, node->u.f.init);
    2066           0 :                         p = isl_printer_yaml_next(p);
    2067           0 :                         p = isl_printer_print_str(p, "cond");
    2068           0 :                         p = isl_printer_yaml_next(p);
    2069           0 :                         p = isl_printer_print_ast_expr(p, node->u.f.cond);
    2070           0 :                         p = isl_printer_yaml_next(p);
    2071           0 :                         p = isl_printer_print_str(p, "inc");
    2072           0 :                         p = isl_printer_yaml_next(p);
    2073           0 :                         p = isl_printer_print_ast_expr(p, node->u.f.inc);
    2074           0 :                         p = isl_printer_yaml_next(p);
    2075             :                 }
    2076           0 :                 if (node->u.f.body) {
    2077           0 :                         p = isl_printer_print_str(p, "body");
    2078           0 :                         p = isl_printer_yaml_next(p);
    2079           0 :                         p = isl_printer_print_ast_node(p, node->u.f.body);
    2080           0 :                         p = isl_printer_yaml_next(p);
    2081             :                 }
    2082           0 :                 p = isl_printer_yaml_end_mapping(p);
    2083           0 :                 break;
    2084             :         case isl_ast_node_mark:
    2085           0 :                 p = isl_printer_yaml_start_mapping(p);
    2086           0 :                 p = isl_printer_print_str(p, "mark");
    2087           0 :                 p = isl_printer_yaml_next(p);
    2088           0 :                 p = isl_printer_print_id(p, node->u.m.mark);
    2089           0 :                 p = isl_printer_yaml_next(p);
    2090           0 :                 p = isl_printer_print_str(p, "node");
    2091           0 :                 p = isl_printer_yaml_next(p);
    2092           0 :                 p = isl_printer_print_ast_node(p, node->u.m.node);
    2093           0 :                 p = isl_printer_yaml_end_mapping(p);
    2094           0 :                 break;
    2095             :         case isl_ast_node_user:
    2096           0 :                 p = isl_printer_yaml_start_mapping(p);
    2097           0 :                 p = isl_printer_print_str(p, "user");
    2098           0 :                 p = isl_printer_yaml_next(p);
    2099           0 :                 p = isl_printer_print_ast_expr(p, node->u.e.expr);
    2100           0 :                 p = isl_printer_yaml_end_mapping(p);
    2101           0 :                 break;
    2102             :         case isl_ast_node_if:
    2103           0 :                 p = isl_printer_yaml_start_mapping(p);
    2104           0 :                 p = isl_printer_print_str(p, "guard");
    2105           0 :                 p = isl_printer_yaml_next(p);
    2106           0 :                 p = isl_printer_print_ast_expr(p, node->u.i.guard);
    2107           0 :                 p = isl_printer_yaml_next(p);
    2108           0 :                 if (node->u.i.then) {
    2109           0 :                         p = isl_printer_print_str(p, "then");
    2110           0 :                         p = isl_printer_yaml_next(p);
    2111           0 :                         p = isl_printer_print_ast_node(p, node->u.i.then);
    2112           0 :                         p = isl_printer_yaml_next(p);
    2113             :                 }
    2114           0 :                 if (node->u.i.else_node) {
    2115           0 :                         p = isl_printer_print_str(p, "else");
    2116           0 :                         p = isl_printer_yaml_next(p);
    2117           0 :                         p = isl_printer_print_ast_node(p, node->u.i.else_node);
    2118             :                 }
    2119           0 :                 p = isl_printer_yaml_end_mapping(p);
    2120           0 :                 break;
    2121             :         case isl_ast_node_block:
    2122           0 :                 p = print_ast_node_list(p, node->u.b.children);
    2123           0 :                 break;
    2124             :         case isl_ast_node_error:
    2125           0 :                 break;
    2126             :         }
    2127           0 :         return p;
    2128             : }
    2129             : 
    2130             : /* Do we need to print a block around the body "node" of a for or if node?
    2131             :  *
    2132             :  * If the node is a block, then we need to print a block.
    2133             :  * Also if the node is a degenerate for then we will print it as
    2134             :  * an assignment followed by the body of the for loop, so we need a block
    2135             :  * as well.
    2136             :  * If the node is an if node with an else, then we print a block
    2137             :  * to avoid spurious dangling else warnings emitted by some compilers.
    2138             :  * If the node is a mark, then in principle, we would have to check
    2139             :  * the child of the mark node.  However, even if the child would not
    2140             :  * require us to print a block, for readability it is probably best
    2141             :  * to print a block anyway.
    2142             :  * If the ast_always_print_block option has been set, then we print a block.
    2143             :  */
    2144           0 : static int need_block(__isl_keep isl_ast_node *node)
    2145             : {
    2146             :         isl_ctx *ctx;
    2147             : 
    2148           0 :         if (node->type == isl_ast_node_block)
    2149           0 :                 return 1;
    2150           0 :         if (node->type == isl_ast_node_for && node->u.f.degenerate)
    2151           0 :                 return 1;
    2152           0 :         if (node->type == isl_ast_node_if && node->u.i.else_node)
    2153           0 :                 return 1;
    2154           0 :         if (node->type == isl_ast_node_mark)
    2155           0 :                 return 1;
    2156             : 
    2157           0 :         ctx = isl_ast_node_get_ctx(node);
    2158           0 :         return isl_options_get_ast_always_print_block(ctx);
    2159             : }
    2160             : 
    2161             : static __isl_give isl_printer *print_ast_node_c(__isl_take isl_printer *p,
    2162             :         __isl_keep isl_ast_node *node,
    2163             :         __isl_keep isl_ast_print_options *options, int in_block, int in_list);
    2164             : static __isl_give isl_printer *print_if_c(__isl_take isl_printer *p,
    2165             :         __isl_keep isl_ast_node *node,
    2166             :         __isl_keep isl_ast_print_options *options, int new_line,
    2167             :         int force_block);
    2168             : 
    2169             : /* Print the body "node" of a for or if node.
    2170             :  * If "else_node" is set, then it is printed as well.
    2171             :  * If "force_block" is set, then print out the body as a block.
    2172             :  *
    2173             :  * We first check if we need to print out a block.
    2174             :  * We always print out a block if there is an else node to make
    2175             :  * sure that the else node is matched to the correct if node.
    2176             :  * For consistency, the corresponding else node is also printed as a block.
    2177             :  *
    2178             :  * If the else node is itself an if, then we print it as
    2179             :  *
    2180             :  *      } else if (..) {
    2181             :  *      }
    2182             :  *
    2183             :  * Otherwise the else node is printed as
    2184             :  *
    2185             :  *      } else {
    2186             :  *        node
    2187             :  *      }
    2188             :  */
    2189           0 : static __isl_give isl_printer *print_body_c(__isl_take isl_printer *p,
    2190             :         __isl_keep isl_ast_node *node, __isl_keep isl_ast_node *else_node,
    2191             :         __isl_keep isl_ast_print_options *options, int force_block)
    2192             : {
    2193           0 :         if (!node)
    2194           0 :                 return isl_printer_free(p);
    2195             : 
    2196           0 :         if (!force_block && !else_node && !need_block(node)) {
    2197           0 :                 p = isl_printer_end_line(p);
    2198           0 :                 p = isl_printer_indent(p, 2);
    2199           0 :                 p = isl_ast_node_print(node, p,
    2200             :                                         isl_ast_print_options_copy(options));
    2201           0 :                 p = isl_printer_indent(p, -2);
    2202           0 :                 return p;
    2203             :         }
    2204             : 
    2205           0 :         p = isl_printer_print_str(p, " {");
    2206           0 :         p = isl_printer_end_line(p);
    2207           0 :         p = isl_printer_indent(p, 2);
    2208           0 :         p = print_ast_node_c(p, node, options, 1, 0);
    2209           0 :         p = isl_printer_indent(p, -2);
    2210           0 :         p = isl_printer_start_line(p);
    2211           0 :         p = isl_printer_print_str(p, "}");
    2212           0 :         if (else_node) {
    2213           0 :                 if (else_node->type == isl_ast_node_if) {
    2214           0 :                         p = isl_printer_print_str(p, " else ");
    2215           0 :                         p = print_if_c(p, else_node, options, 0, 1);
    2216             :                 } else {
    2217           0 :                         p = isl_printer_print_str(p, " else");
    2218           0 :                         p = print_body_c(p, else_node, NULL, options, 1);
    2219             :                 }
    2220             :         } else
    2221           0 :                 p = isl_printer_end_line(p);
    2222             : 
    2223           0 :         return p;
    2224             : }
    2225             : 
    2226             : /* Print the start of a compound statement.
    2227             :  */
    2228           0 : static __isl_give isl_printer *start_block(__isl_take isl_printer *p)
    2229             : {
    2230           0 :         p = isl_printer_start_line(p);
    2231           0 :         p = isl_printer_print_str(p, "{");
    2232           0 :         p = isl_printer_end_line(p);
    2233           0 :         p = isl_printer_indent(p, 2);
    2234             : 
    2235           0 :         return p;
    2236             : }
    2237             : 
    2238             : /* Print the end of a compound statement.
    2239             :  */
    2240           0 : static __isl_give isl_printer *end_block(__isl_take isl_printer *p)
    2241             : {
    2242           0 :         p = isl_printer_indent(p, -2);
    2243           0 :         p = isl_printer_start_line(p);
    2244           0 :         p = isl_printer_print_str(p, "}");
    2245           0 :         p = isl_printer_end_line(p);
    2246             : 
    2247           0 :         return p;
    2248             : }
    2249             : 
    2250             : /* Print the for node "node".
    2251             :  *
    2252             :  * If the for node is degenerate, it is printed as
    2253             :  *
    2254             :  *      type iterator = init;
    2255             :  *      body
    2256             :  *
    2257             :  * Otherwise, it is printed as
    2258             :  *
    2259             :  *      for (type iterator = init; cond; iterator += inc)
    2260             :  *              body
    2261             :  *
    2262             :  * "in_block" is set if we are currently inside a block.
    2263             :  * "in_list" is set if the current node is not alone in the block.
    2264             :  * If we are not in a block or if the current not is not alone in the block
    2265             :  * then we print a block around a degenerate for loop such that the variable
    2266             :  * declaration will not conflict with any potential other declaration
    2267             :  * of the same variable.
    2268             :  */
    2269           0 : static __isl_give isl_printer *print_for_c(__isl_take isl_printer *p,
    2270             :         __isl_keep isl_ast_node *node,
    2271             :         __isl_keep isl_ast_print_options *options, int in_block, int in_list)
    2272             : {
    2273             :         isl_id *id;
    2274             :         const char *name;
    2275             :         const char *type;
    2276             : 
    2277           0 :         type = isl_options_get_ast_iterator_type(isl_printer_get_ctx(p));
    2278           0 :         if (!node->u.f.degenerate) {
    2279           0 :                 id = isl_ast_expr_get_id(node->u.f.iterator);
    2280           0 :                 name = isl_id_get_name(id);
    2281           0 :                 isl_id_free(id);
    2282           0 :                 p = isl_printer_start_line(p);
    2283           0 :                 p = isl_printer_print_str(p, "for (");
    2284           0 :                 p = isl_printer_print_str(p, type);
    2285           0 :                 p = isl_printer_print_str(p, " ");
    2286           0 :                 p = isl_printer_print_str(p, name);
    2287           0 :                 p = isl_printer_print_str(p, " = ");
    2288           0 :                 p = isl_printer_print_ast_expr(p, node->u.f.init);
    2289           0 :                 p = isl_printer_print_str(p, "; ");
    2290           0 :                 p = isl_printer_print_ast_expr(p, node->u.f.cond);
    2291           0 :                 p = isl_printer_print_str(p, "; ");
    2292           0 :                 p = isl_printer_print_str(p, name);
    2293           0 :                 p = isl_printer_print_str(p, " += ");
    2294           0 :                 p = isl_printer_print_ast_expr(p, node->u.f.inc);
    2295           0 :                 p = isl_printer_print_str(p, ")");
    2296           0 :                 p = print_body_c(p, node->u.f.body, NULL, options, 0);
    2297             :         } else {
    2298           0 :                 id = isl_ast_expr_get_id(node->u.f.iterator);
    2299           0 :                 name = isl_id_get_name(id);
    2300           0 :                 isl_id_free(id);
    2301           0 :                 if (!in_block || in_list)
    2302           0 :                         p = start_block(p);
    2303           0 :                 p = isl_printer_start_line(p);
    2304           0 :                 p = isl_printer_print_str(p, type);
    2305           0 :                 p = isl_printer_print_str(p, " ");
    2306           0 :                 p = isl_printer_print_str(p, name);
    2307           0 :                 p = isl_printer_print_str(p, " = ");
    2308           0 :                 p = isl_printer_print_ast_expr(p, node->u.f.init);
    2309           0 :                 p = isl_printer_print_str(p, ";");
    2310           0 :                 p = isl_printer_end_line(p);
    2311           0 :                 p = print_ast_node_c(p, node->u.f.body, options, 1, 0);
    2312           0 :                 if (!in_block || in_list)
    2313           0 :                         p = end_block(p);
    2314             :         }
    2315             : 
    2316           0 :         return p;
    2317             : }
    2318             : 
    2319             : /* Print the if node "node".
    2320             :  * If "new_line" is set then the if node should be printed on a new line.
    2321             :  * If "force_block" is set, then print out the body as a block.
    2322             :  */
    2323           0 : static __isl_give isl_printer *print_if_c(__isl_take isl_printer *p,
    2324             :         __isl_keep isl_ast_node *node,
    2325             :         __isl_keep isl_ast_print_options *options, int new_line,
    2326             :         int force_block)
    2327             : {
    2328           0 :         if (new_line)
    2329           0 :                 p = isl_printer_start_line(p);
    2330           0 :         p = isl_printer_print_str(p, "if (");
    2331           0 :         p = isl_printer_print_ast_expr(p, node->u.i.guard);
    2332           0 :         p = isl_printer_print_str(p, ")");
    2333           0 :         p = print_body_c(p, node->u.i.then, node->u.i.else_node, options,
    2334             :                         force_block);
    2335             : 
    2336           0 :         return p;
    2337             : }
    2338             : 
    2339             : /* Print the "node" to "p".
    2340             :  *
    2341             :  * "in_block" is set if we are currently inside a block.
    2342             :  * If so, we do not print a block around the children of a block node.
    2343             :  * We do this to avoid an extra block around the body of a degenerate
    2344             :  * for node.
    2345             :  *
    2346             :  * "in_list" is set if the current node is not alone in the block.
    2347             :  */
    2348           0 : static __isl_give isl_printer *print_ast_node_c(__isl_take isl_printer *p,
    2349             :         __isl_keep isl_ast_node *node,
    2350             :         __isl_keep isl_ast_print_options *options, int in_block, int in_list)
    2351             : {
    2352           0 :         switch (node->type) {
    2353             :         case isl_ast_node_for:
    2354           0 :                 if (options->print_for)
    2355           0 :                         return options->print_for(p,
    2356             :                                         isl_ast_print_options_copy(options),
    2357             :                                         node, options->print_for_user);
    2358           0 :                 p = print_for_c(p, node, options, in_block, in_list);
    2359           0 :                 break;
    2360             :         case isl_ast_node_if:
    2361           0 :                 p = print_if_c(p, node, options, 1, 0);
    2362           0 :                 break;
    2363             :         case isl_ast_node_block:
    2364           0 :                 if (!in_block)
    2365           0 :                         p = start_block(p);
    2366           0 :                 p = isl_ast_node_list_print(node->u.b.children, p, options);
    2367           0 :                 if (!in_block)
    2368           0 :                         p = end_block(p);
    2369           0 :                 break;
    2370             :         case isl_ast_node_mark:
    2371           0 :                 p = isl_printer_start_line(p);
    2372           0 :                 p = isl_printer_print_str(p, "// ");
    2373           0 :                 p = isl_printer_print_str(p, isl_id_get_name(node->u.m.mark));
    2374           0 :                 p = isl_printer_end_line(p);
    2375           0 :                 p = print_ast_node_c(p, node->u.m.node, options, 0, in_list);
    2376           0 :                 break;
    2377             :         case isl_ast_node_user:
    2378           0 :                 if (options->print_user)
    2379           0 :                         return options->print_user(p,
    2380             :                                         isl_ast_print_options_copy(options),
    2381             :                                         node, options->print_user_user);
    2382           0 :                 p = isl_printer_start_line(p);
    2383           0 :                 p = isl_printer_print_ast_expr(p, node->u.e.expr);
    2384           0 :                 p = isl_printer_print_str(p, ";");
    2385           0 :                 p = isl_printer_end_line(p);
    2386           0 :                 break;
    2387             :         case isl_ast_node_error:
    2388           0 :                 break;
    2389             :         }
    2390           0 :         return p;
    2391             : }
    2392             : 
    2393             : /* Print the for node "node" to "p".
    2394             :  */
    2395           0 : __isl_give isl_printer *isl_ast_node_for_print(__isl_keep isl_ast_node *node,
    2396             :         __isl_take isl_printer *p, __isl_take isl_ast_print_options *options)
    2397             : {
    2398           0 :         if (!node || !options)
    2399             :                 goto error;
    2400           0 :         if (node->type != isl_ast_node_for)
    2401           0 :                 isl_die(isl_ast_node_get_ctx(node), isl_error_invalid,
    2402             :                         "not a for node", goto error);
    2403           0 :         p = print_for_c(p, node, options, 0, 0);
    2404           0 :         isl_ast_print_options_free(options);
    2405           0 :         return p;
    2406             : error:
    2407           0 :         isl_ast_print_options_free(options);
    2408           0 :         isl_printer_free(p);
    2409           0 :         return NULL;
    2410             : }
    2411             : 
    2412             : /* Print the if node "node" to "p".
    2413             :  */
    2414           0 : __isl_give isl_printer *isl_ast_node_if_print(__isl_keep isl_ast_node *node,
    2415             :         __isl_take isl_printer *p, __isl_take isl_ast_print_options *options)
    2416             : {
    2417           0 :         if (!node || !options)
    2418             :                 goto error;
    2419           0 :         if (node->type != isl_ast_node_if)
    2420           0 :                 isl_die(isl_ast_node_get_ctx(node), isl_error_invalid,
    2421             :                         "not an if node", goto error);
    2422           0 :         p = print_if_c(p, node, options, 1, 0);
    2423           0 :         isl_ast_print_options_free(options);
    2424           0 :         return p;
    2425             : error:
    2426           0 :         isl_ast_print_options_free(options);
    2427           0 :         isl_printer_free(p);
    2428           0 :         return NULL;
    2429             : }
    2430             : 
    2431             : /* Print "node" to "p".
    2432             :  */
    2433           0 : __isl_give isl_printer *isl_ast_node_print(__isl_keep isl_ast_node *node,
    2434             :         __isl_take isl_printer *p, __isl_take isl_ast_print_options *options)
    2435             : {
    2436           0 :         if (!options || !node)
    2437             :                 goto error;
    2438           0 :         p = print_ast_node_c(p, node, options, 0, 0);
    2439           0 :         isl_ast_print_options_free(options);
    2440           0 :         return p;
    2441             : error:
    2442           0 :         isl_ast_print_options_free(options);
    2443           0 :         isl_printer_free(p);
    2444           0 :         return NULL;
    2445             : }
    2446             : 
    2447             : /* Print "node" to "p".
    2448             :  */
    2449           0 : __isl_give isl_printer *isl_printer_print_ast_node(__isl_take isl_printer *p,
    2450             :         __isl_keep isl_ast_node *node)
    2451             : {
    2452             :         int format;
    2453             :         isl_ast_print_options *options;
    2454             : 
    2455           0 :         if (!p)
    2456           0 :                 return NULL;
    2457             : 
    2458           0 :         format = isl_printer_get_output_format(p);
    2459           0 :         switch (format) {
    2460             :         case ISL_FORMAT_ISL:
    2461           0 :                 p = print_ast_node_isl(p, node);
    2462           0 :                 break;
    2463             :         case ISL_FORMAT_C:
    2464           0 :                 options = isl_ast_print_options_alloc(isl_printer_get_ctx(p));
    2465           0 :                 p = isl_ast_node_print(node, p, options);
    2466           0 :                 break;
    2467             :         default:
    2468           0 :                 isl_die(isl_printer_get_ctx(p), isl_error_unsupported,
    2469             :                         "output format not supported for ast_node",
    2470             :                         return isl_printer_free(p));
    2471             :         }
    2472             : 
    2473           0 :         return p;
    2474             : }
    2475             : 
    2476             : /* Print the list of nodes "list" to "p".
    2477             :  */
    2478           0 : __isl_give isl_printer *isl_ast_node_list_print(
    2479             :         __isl_keep isl_ast_node_list *list, __isl_take isl_printer *p,
    2480             :         __isl_keep isl_ast_print_options *options)
    2481             : {
    2482             :         int i;
    2483             : 
    2484           0 :         if (!p || !list || !options)
    2485           0 :                 return isl_printer_free(p);
    2486             : 
    2487           0 :         for (i = 0; i < list->n; ++i)
    2488           0 :                 p = print_ast_node_c(p, list->p[i], options, 1, 1);
    2489             : 
    2490           0 :         return p;
    2491             : }
    2492             : 
    2493             : #define ISL_AST_MACRO_FLOORD    (1 << 0)
    2494             : #define ISL_AST_MACRO_MIN       (1 << 1)
    2495             : #define ISL_AST_MACRO_MAX       (1 << 2)
    2496             : #define ISL_AST_MACRO_ALL       (ISL_AST_MACRO_FLOORD | \
    2497             :                                  ISL_AST_MACRO_MIN | \
    2498             :                                  ISL_AST_MACRO_MAX)
    2499             : 
    2500             : /* If "expr" contains an isl_ast_op_min, isl_ast_op_max or isl_ast_op_fdiv_q
    2501             :  * then set the corresponding bit in "macros".
    2502             :  */
    2503           0 : static int ast_expr_required_macros(__isl_keep isl_ast_expr *expr, int macros)
    2504             : {
    2505             :         int i;
    2506             : 
    2507           0 :         if (macros == ISL_AST_MACRO_ALL)
    2508           0 :                 return macros;
    2509             : 
    2510           0 :         if (expr->type != isl_ast_expr_op)
    2511           0 :                 return macros;
    2512             : 
    2513           0 :         if (expr->u.op.op == isl_ast_op_min)
    2514           0 :                 macros |= ISL_AST_MACRO_MIN;
    2515           0 :         if (expr->u.op.op == isl_ast_op_max)
    2516           0 :                 macros |= ISL_AST_MACRO_MAX;
    2517           0 :         if (expr->u.op.op == isl_ast_op_fdiv_q)
    2518           0 :                 macros |= ISL_AST_MACRO_FLOORD;
    2519             : 
    2520           0 :         for (i = 0; i < expr->u.op.n_arg; ++i)
    2521           0 :                 macros = ast_expr_required_macros(expr->u.op.args[i], macros);
    2522             : 
    2523           0 :         return macros;
    2524             : }
    2525             : 
    2526             : static int ast_node_list_required_macros(__isl_keep isl_ast_node_list *list,
    2527             :         int macros);
    2528             : 
    2529             : /* If "node" contains an isl_ast_op_min, isl_ast_op_max or isl_ast_op_fdiv_q
    2530             :  * then set the corresponding bit in "macros".
    2531             :  */
    2532           0 : static int ast_node_required_macros(__isl_keep isl_ast_node *node, int macros)
    2533             : {
    2534           0 :         if (macros == ISL_AST_MACRO_ALL)
    2535           0 :                 return macros;
    2536             : 
    2537           0 :         switch (node->type) {
    2538             :         case isl_ast_node_for:
    2539           0 :                 macros = ast_expr_required_macros(node->u.f.init, macros);
    2540           0 :                 if (!node->u.f.degenerate) {
    2541           0 :                         macros = ast_expr_required_macros(node->u.f.cond,
    2542             :                                                                 macros);
    2543           0 :                         macros = ast_expr_required_macros(node->u.f.inc,
    2544             :                                                                 macros);
    2545             :                 }
    2546           0 :                 macros = ast_node_required_macros(node->u.f.body, macros);
    2547           0 :                 break;
    2548             :         case isl_ast_node_if:
    2549           0 :                 macros = ast_expr_required_macros(node->u.i.guard, macros);
    2550           0 :                 macros = ast_node_required_macros(node->u.i.then, macros);
    2551           0 :                 if (node->u.i.else_node)
    2552           0 :                         macros = ast_node_required_macros(node->u.i.else_node,
    2553             :                                                                 macros);
    2554           0 :                 break;
    2555             :         case isl_ast_node_block:
    2556           0 :                 macros = ast_node_list_required_macros(node->u.b.children,
    2557             :                                                         macros);
    2558           0 :                 break;
    2559             :         case isl_ast_node_mark:
    2560           0 :                 macros = ast_node_required_macros(node->u.m.node, macros);
    2561           0 :                 break;
    2562             :         case isl_ast_node_user:
    2563           0 :                 macros = ast_expr_required_macros(node->u.e.expr, macros);
    2564           0 :                 break;
    2565             :         case isl_ast_node_error:
    2566           0 :                 break;
    2567             :         }
    2568             : 
    2569           0 :         return macros;
    2570             : }
    2571             : 
    2572             : /* If "list" contains an isl_ast_op_min, isl_ast_op_max or isl_ast_op_fdiv_q
    2573             :  * then set the corresponding bit in "macros".
    2574             :  */
    2575           0 : static int ast_node_list_required_macros(__isl_keep isl_ast_node_list *list,
    2576             :         int macros)
    2577             : {
    2578             :         int i;
    2579             : 
    2580           0 :         for (i = 0; i < list->n; ++i)
    2581           0 :                 macros = ast_node_required_macros(list->p[i], macros);
    2582             : 
    2583           0 :         return macros;
    2584             : }
    2585             : 
    2586             : /* Data structure for keeping track of whether a macro definition
    2587             :  * for a given type has already been printed.
    2588             :  * The value is zero if no definition has been printed and non-zero otherwise.
    2589             :  */
    2590             : struct isl_ast_op_printed {
    2591             :         char printed[isl_ast_op_last + 1];
    2592             : };
    2593             : 
    2594             : /* Create an empty struct isl_ast_op_printed.
    2595             :  */
    2596           0 : static void *create_printed(isl_ctx *ctx)
    2597             : {
    2598           0 :         return isl_calloc_type(ctx, struct isl_ast_op_printed);
    2599             : }
    2600             : 
    2601             : /* Free a struct isl_ast_op_printed.
    2602             :  */
    2603           0 : static void free_printed(void *user)
    2604             : {
    2605           0 :         free(user);
    2606           0 : }
    2607             : 
    2608             : /* Ensure that "p" has an isl_ast_op_printed note identified by "id".
    2609             :  */
    2610           0 : static __isl_give isl_printer *alloc_printed(__isl_take isl_printer *p,
    2611             :         __isl_keep isl_id *id)
    2612             : {
    2613           0 :         return alloc_note(p, id, &create_printed, &free_printed);
    2614             : }
    2615             : 
    2616             : /* Create an identifier that is used to store
    2617             :  * an isl_ast_op_printed note.
    2618             :  */
    2619           0 : static __isl_give isl_id *printed_id(isl_ctx *ctx)
    2620             : {
    2621           0 :         return isl_id_alloc(ctx, "isl_ast_op_type_printed", NULL);
    2622             : }
    2623             : 
    2624             : /* Did the user specify that a macro definition should only be
    2625             :  * printed once and has a macro definition for "type" already
    2626             :  * been printed to "p"?
    2627             :  * If definitions should only be printed once, but a definition
    2628             :  * for "p" has not yet been printed, then mark it as having been
    2629             :  * printed so that it will not printed again.
    2630             :  * The actual printing is taken care of by the caller.
    2631             :  */
    2632           0 : static isl_bool already_printed_once(__isl_keep isl_printer *p,
    2633             :         enum isl_ast_op_type type)
    2634             : {
    2635             :         isl_ctx *ctx;
    2636             :         isl_id *id;
    2637             :         struct isl_ast_op_printed *printed;
    2638             : 
    2639           0 :         if (!p)
    2640           0 :                 return isl_bool_error;
    2641             : 
    2642           0 :         ctx = isl_printer_get_ctx(p);
    2643           0 :         if (!isl_options_get_ast_print_macro_once(ctx))
    2644           0 :                 return isl_bool_false;
    2645             : 
    2646           0 :         if (type > isl_ast_op_last)
    2647           0 :                 isl_die(isl_printer_get_ctx(p), isl_error_invalid,
    2648             :                         "invalid type", return isl_bool_error);
    2649             : 
    2650           0 :         id = printed_id(isl_printer_get_ctx(p));
    2651           0 :         p = alloc_printed(p, id);
    2652           0 :         printed = get_note(p, id);
    2653           0 :         isl_id_free(id);
    2654           0 :         if (!printed)
    2655           0 :                 return isl_bool_error;
    2656             : 
    2657           0 :         if (printed->printed[type])
    2658           0 :                 return isl_bool_true;
    2659             : 
    2660           0 :         printed->printed[type] = 1;
    2661           0 :         return isl_bool_false;
    2662             : }
    2663             : 
    2664             : /* Print a macro definition for the operator "type".
    2665             :  *
    2666             :  * If the user has specified that a macro definition should
    2667             :  * only be printed once to any given printer and if the macro definition
    2668             :  * has already been printed to "p", then do not print the definition.
    2669             :  */
    2670           0 : __isl_give isl_printer *isl_ast_op_type_print_macro(
    2671             :         enum isl_ast_op_type type, __isl_take isl_printer *p)
    2672             : {
    2673             :         isl_bool skip;
    2674             : 
    2675           0 :         skip = already_printed_once(p, type);
    2676           0 :         if (skip < 0)
    2677           0 :                 return isl_printer_free(p);
    2678           0 :         if (skip)
    2679           0 :                 return p;
    2680             : 
    2681           0 :         switch (type) {
    2682             :         case isl_ast_op_min:
    2683           0 :                 p = isl_printer_start_line(p);
    2684           0 :                 p = isl_printer_print_str(p, "#define ");
    2685           0 :                 p = isl_printer_print_str(p, get_op_str_c(p, type));
    2686           0 :                 p = isl_printer_print_str(p,
    2687             :                         "(x,y)    ((x) < (y) ? (x) : (y))");
    2688           0 :                 p = isl_printer_end_line(p);
    2689           0 :                 break;
    2690             :         case isl_ast_op_max:
    2691           0 :                 p = isl_printer_start_line(p);
    2692           0 :                 p = isl_printer_print_str(p, "#define ");
    2693           0 :                 p = isl_printer_print_str(p, get_op_str_c(p, type));
    2694           0 :                 p = isl_printer_print_str(p,
    2695             :                         "(x,y)    ((x) > (y) ? (x) : (y))");
    2696           0 :                 p = isl_printer_end_line(p);
    2697           0 :                 break;
    2698             :         case isl_ast_op_fdiv_q:
    2699           0 :                 p = isl_printer_start_line(p);
    2700           0 :                 p = isl_printer_print_str(p, "#define ");
    2701           0 :                 p = isl_printer_print_str(p, get_op_str_c(p, type));
    2702           0 :                 p = isl_printer_print_str(p,
    2703             :                         "(n,d) "
    2704             :                         "(((n)<0) ? -((-(n)+(d)-1)/(d)) : (n)/(d))");
    2705           0 :                 p = isl_printer_end_line(p);
    2706           0 :                 break;
    2707             :         default:
    2708           0 :                 break;
    2709             :         }
    2710             : 
    2711           0 :         return p;
    2712             : }
    2713             : 
    2714             : /* Call "fn" for each type of operation represented in the "macros"
    2715             :  * bit vector.
    2716             :  */
    2717           0 : static isl_stat foreach_ast_op_type(int macros,
    2718             :         isl_stat (*fn)(enum isl_ast_op_type type, void *user), void *user)
    2719             : {
    2720           0 :         if (macros & ISL_AST_MACRO_MIN && fn(isl_ast_op_min, user) < 0)
    2721           0 :                 return isl_stat_error;
    2722           0 :         if (macros & ISL_AST_MACRO_MAX && fn(isl_ast_op_max, user) < 0)
    2723           0 :                 return isl_stat_error;
    2724           0 :         if (macros & ISL_AST_MACRO_FLOORD && fn(isl_ast_op_fdiv_q, user) < 0)
    2725           0 :                 return isl_stat_error;
    2726             : 
    2727           0 :         return isl_stat_ok;
    2728             : }
    2729             : 
    2730             : /* Call "fn" for each type of operation that appears in "expr"
    2731             :  * and that requires a macro definition.
    2732             :  */
    2733           0 : isl_stat isl_ast_expr_foreach_ast_op_type(__isl_keep isl_ast_expr *expr,
    2734             :         isl_stat (*fn)(enum isl_ast_op_type type, void *user), void *user)
    2735             : {
    2736             :         int macros;
    2737             : 
    2738           0 :         if (!expr)
    2739           0 :                 return isl_stat_error;
    2740             : 
    2741           0 :         macros = ast_expr_required_macros(expr, 0);
    2742           0 :         return foreach_ast_op_type(macros, fn, user);
    2743             : }
    2744             : 
    2745             : /* Call "fn" for each type of operation that appears in "node"
    2746             :  * and that requires a macro definition.
    2747             :  */
    2748           0 : isl_stat isl_ast_node_foreach_ast_op_type(__isl_keep isl_ast_node *node,
    2749             :         isl_stat (*fn)(enum isl_ast_op_type type, void *user), void *user)
    2750             : {
    2751             :         int macros;
    2752             : 
    2753           0 :         if (!node)
    2754           0 :                 return isl_stat_error;
    2755             : 
    2756           0 :         macros = ast_node_required_macros(node, 0);
    2757           0 :         return foreach_ast_op_type(macros, fn, user);
    2758             : }
    2759             : 
    2760           0 : static isl_stat ast_op_type_print_macro(enum isl_ast_op_type type, void *user)
    2761             : {
    2762           0 :         isl_printer **p = user;
    2763             : 
    2764           0 :         *p = isl_ast_op_type_print_macro(type, *p);
    2765             : 
    2766           0 :         return isl_stat_ok;
    2767             : }
    2768             : 
    2769             : /* Print macro definitions for all the macros used in the result
    2770             :  * of printing "expr".
    2771             :  */
    2772           0 : __isl_give isl_printer *isl_ast_expr_print_macros(
    2773             :         __isl_keep isl_ast_expr *expr, __isl_take isl_printer *p)
    2774             : {
    2775           0 :         if (isl_ast_expr_foreach_ast_op_type(expr,
    2776             :                                             &ast_op_type_print_macro, &p) < 0)
    2777           0 :                 return isl_printer_free(p);
    2778           0 :         return p;
    2779             : }
    2780             : 
    2781             : /* Print macro definitions for all the macros used in the result
    2782             :  * of printing "node".
    2783             :  */
    2784           0 : __isl_give isl_printer *isl_ast_node_print_macros(
    2785             :         __isl_keep isl_ast_node *node, __isl_take isl_printer *p)
    2786             : {
    2787           0 :         if (isl_ast_node_foreach_ast_op_type(node,
    2788             :                                             &ast_op_type_print_macro, &p) < 0)
    2789           0 :                 return isl_printer_free(p);
    2790           0 :         return p;
    2791             : }
    2792             : 
    2793             : /* Return a string containing C code representing this isl_ast_expr.
    2794             :  */
    2795           0 : __isl_give char *isl_ast_expr_to_C_str(__isl_keep isl_ast_expr *expr)
    2796             : {
    2797             :         isl_printer *p;
    2798             :         char *str;
    2799             : 
    2800           0 :         if (!expr)
    2801           0 :                 return NULL;
    2802             : 
    2803           0 :         p = isl_printer_to_str(isl_ast_expr_get_ctx(expr));
    2804           0 :         p = isl_printer_set_output_format(p, ISL_FORMAT_C);
    2805           0 :         p = isl_printer_print_ast_expr(p, expr);
    2806             : 
    2807           0 :         str = isl_printer_get_str(p);
    2808             : 
    2809           0 :         isl_printer_free(p);
    2810             : 
    2811           0 :         return str;
    2812             : }
    2813             : 
    2814             : /* Return a string containing C code representing this isl_ast_node.
    2815             :  */
    2816           0 : __isl_give char *isl_ast_node_to_C_str(__isl_keep isl_ast_node *node)
    2817             : {
    2818             :         isl_printer *p;
    2819             :         char *str;
    2820             : 
    2821           0 :         if (!node)
    2822           0 :                 return NULL;
    2823             : 
    2824           0 :         p = isl_printer_to_str(isl_ast_node_get_ctx(node));
    2825           0 :         p = isl_printer_set_output_format(p, ISL_FORMAT_C);
    2826           0 :         p = isl_printer_print_ast_node(p, node);
    2827             : 
    2828           0 :         str = isl_printer_get_str(p);
    2829             : 
    2830           0 :         isl_printer_free(p);
    2831             : 
    2832           0 :         return str;
    2833             : }

Generated by: LCOV version 1.12