1 1.1 mrg /* 2 1.1 mrg * Copyright 2012-2013 Ecole Normale Superieure 3 1.1 mrg * Copyright 2022 Cerebras Systems 4 1.1 mrg * 5 1.1 mrg * Use of this software is governed by the MIT license 6 1.1 mrg * 7 1.1 mrg * Written by Sven Verdoolaege, 8 1.1 mrg * Ecole Normale Superieure, 45 rue dUlm, 75230 Paris, France 9 1.1 mrg * and Cerebras Systems, 1237 E Arques Ave, Sunnyvale, CA, USA 10 1.1 mrg */ 11 1.1 mrg 12 1.1 mrg #include <string.h> 13 1.1 mrg 14 1.1 mrg #include <isl/id.h> 15 1.1 mrg #include <isl/stream.h> 16 1.1 mrg #include <isl/val.h> 17 1.1 mrg #include <isl_ast_private.h> 18 1.1 mrg 19 1.1 mrg #undef EL_BASE 20 1.1 mrg #define EL_BASE ast_expr 21 1.1 mrg 22 1.1 mrg #include <isl_list_templ.c> 23 1.1 mrg 24 1.1 mrg #undef EL_BASE 25 1.1 mrg #define EL_BASE ast_node 26 1.1 mrg 27 1.1 mrg #include <isl_list_templ.c> 28 1.1 mrg 29 1.1 mrg isl_ctx *isl_ast_print_options_get_ctx( 30 1.1 mrg __isl_keep isl_ast_print_options *options) 31 1.1 mrg { 32 1.1 mrg return options ? options->ctx : NULL; 33 1.1 mrg } 34 1.1 mrg 35 1.1 mrg __isl_give isl_ast_print_options *isl_ast_print_options_alloc(isl_ctx *ctx) 36 1.1 mrg { 37 1.1 mrg isl_ast_print_options *options; 38 1.1 mrg 39 1.1 mrg options = isl_calloc_type(ctx, isl_ast_print_options); 40 1.1 mrg if (!options) 41 1.1 mrg return NULL; 42 1.1 mrg 43 1.1 mrg options->ctx = ctx; 44 1.1 mrg isl_ctx_ref(ctx); 45 1.1 mrg options->ref = 1; 46 1.1 mrg 47 1.1 mrg return options; 48 1.1 mrg } 49 1.1 mrg 50 1.1 mrg __isl_give isl_ast_print_options *isl_ast_print_options_dup( 51 1.1 mrg __isl_keep isl_ast_print_options *options) 52 1.1 mrg { 53 1.1 mrg isl_ctx *ctx; 54 1.1 mrg isl_ast_print_options *dup; 55 1.1 mrg 56 1.1 mrg if (!options) 57 1.1 mrg return NULL; 58 1.1 mrg 59 1.1 mrg ctx = isl_ast_print_options_get_ctx(options); 60 1.1 mrg dup = isl_ast_print_options_alloc(ctx); 61 1.1 mrg if (!dup) 62 1.1 mrg return NULL; 63 1.1 mrg 64 1.1 mrg dup->print_for = options->print_for; 65 1.1 mrg dup->print_for_user = options->print_for_user; 66 1.1 mrg dup->print_user = options->print_user; 67 1.1 mrg dup->print_user_user = options->print_user_user; 68 1.1 mrg 69 1.1 mrg return dup; 70 1.1 mrg } 71 1.1 mrg 72 1.1 mrg __isl_give isl_ast_print_options *isl_ast_print_options_cow( 73 1.1 mrg __isl_take isl_ast_print_options *options) 74 1.1 mrg { 75 1.1 mrg if (!options) 76 1.1 mrg return NULL; 77 1.1 mrg 78 1.1 mrg if (options->ref == 1) 79 1.1 mrg return options; 80 1.1 mrg options->ref--; 81 1.1 mrg return isl_ast_print_options_dup(options); 82 1.1 mrg } 83 1.1 mrg 84 1.1 mrg __isl_give isl_ast_print_options *isl_ast_print_options_copy( 85 1.1 mrg __isl_keep isl_ast_print_options *options) 86 1.1 mrg { 87 1.1 mrg if (!options) 88 1.1 mrg return NULL; 89 1.1 mrg 90 1.1 mrg options->ref++; 91 1.1 mrg return options; 92 1.1 mrg } 93 1.1 mrg 94 1.1 mrg __isl_null isl_ast_print_options *isl_ast_print_options_free( 95 1.1 mrg __isl_take isl_ast_print_options *options) 96 1.1 mrg { 97 1.1 mrg if (!options) 98 1.1 mrg return NULL; 99 1.1 mrg 100 1.1 mrg if (--options->ref > 0) 101 1.1 mrg return NULL; 102 1.1 mrg 103 1.1 mrg isl_ctx_deref(options->ctx); 104 1.1 mrg 105 1.1 mrg free(options); 106 1.1 mrg return NULL; 107 1.1 mrg } 108 1.1 mrg 109 1.1 mrg /* Set the print_user callback of "options" to "print_user". 110 1.1 mrg * 111 1.1 mrg * If this callback is set, then it is used to print user nodes in the AST. 112 1.1 mrg * Otherwise, the expression associated to the user node is printed. 113 1.1 mrg */ 114 1.1 mrg __isl_give isl_ast_print_options *isl_ast_print_options_set_print_user( 115 1.1 mrg __isl_take isl_ast_print_options *options, 116 1.1 mrg __isl_give isl_printer *(*print_user)(__isl_take isl_printer *p, 117 1.1 mrg __isl_take isl_ast_print_options *options, 118 1.1 mrg __isl_keep isl_ast_node *node, void *user), 119 1.1 mrg void *user) 120 1.1 mrg { 121 1.1 mrg options = isl_ast_print_options_cow(options); 122 1.1 mrg if (!options) 123 1.1 mrg return NULL; 124 1.1 mrg 125 1.1 mrg options->print_user = print_user; 126 1.1 mrg options->print_user_user = user; 127 1.1 mrg 128 1.1 mrg return options; 129 1.1 mrg } 130 1.1 mrg 131 1.1 mrg /* Set the print_for callback of "options" to "print_for". 132 1.1 mrg * 133 1.1 mrg * If this callback is set, then it used to print for nodes in the AST. 134 1.1 mrg */ 135 1.1 mrg __isl_give isl_ast_print_options *isl_ast_print_options_set_print_for( 136 1.1 mrg __isl_take isl_ast_print_options *options, 137 1.1 mrg __isl_give isl_printer *(*print_for)(__isl_take isl_printer *p, 138 1.1 mrg __isl_take isl_ast_print_options *options, 139 1.1 mrg __isl_keep isl_ast_node *node, void *user), 140 1.1 mrg void *user) 141 1.1 mrg { 142 1.1 mrg options = isl_ast_print_options_cow(options); 143 1.1 mrg if (!options) 144 1.1 mrg return NULL; 145 1.1 mrg 146 1.1 mrg options->print_for = print_for; 147 1.1 mrg options->print_for_user = user; 148 1.1 mrg 149 1.1 mrg return options; 150 1.1 mrg } 151 1.1 mrg 152 1.1 mrg /* Create a new operation expression of operation type "op", 153 1.1 mrg * with arguments "args". 154 1.1 mrg */ 155 1.1 mrg static __isl_give isl_ast_expr *alloc_op(enum isl_ast_expr_op_type op, 156 1.1 mrg __isl_take isl_ast_expr_list *args) 157 1.1 mrg { 158 1.1 mrg isl_ctx *ctx; 159 1.1 mrg isl_ast_expr *expr; 160 1.1 mrg 161 1.1 mrg if (!args) 162 1.1 mrg return NULL; 163 1.1 mrg 164 1.1 mrg ctx = isl_ast_expr_list_get_ctx(args); 165 1.1 mrg expr = isl_calloc_type(ctx, isl_ast_expr); 166 1.1 mrg if (!expr) 167 1.1 mrg goto error; 168 1.1 mrg 169 1.1 mrg expr->ctx = ctx; 170 1.1 mrg isl_ctx_ref(ctx); 171 1.1 mrg expr->ref = 1; 172 1.1 mrg expr->type = isl_ast_expr_op; 173 1.1 mrg expr->u.op.op = op; 174 1.1 mrg expr->u.op.args = args; 175 1.1 mrg 176 1.1 mrg return expr; 177 1.1 mrg error: 178 1.1 mrg isl_ast_expr_list_free(args); 179 1.1 mrg return NULL; 180 1.1 mrg } 181 1.1 mrg 182 1.1 mrg /* Create a new operation expression of operation type "op", 183 1.1 mrg * which will end up having "n_arg" arguments. 184 1.1 mrg * The caller still needs to add those arguments. 185 1.1 mrg */ 186 1.1 mrg __isl_give isl_ast_expr *isl_ast_expr_alloc_op(isl_ctx *ctx, 187 1.1 mrg enum isl_ast_expr_op_type op, int n_arg) 188 1.1 mrg { 189 1.1 mrg isl_ast_expr_list *args; 190 1.1 mrg 191 1.1 mrg args = isl_ast_expr_list_alloc(ctx, n_arg); 192 1.1 mrg return alloc_op(op, args); 193 1.1 mrg } 194 1.1 mrg 195 1.1 mrg __isl_give isl_ast_expr *isl_ast_expr_copy(__isl_keep isl_ast_expr *expr) 196 1.1 mrg { 197 1.1 mrg if (!expr) 198 1.1 mrg return NULL; 199 1.1 mrg 200 1.1 mrg expr->ref++; 201 1.1 mrg return expr; 202 1.1 mrg } 203 1.1 mrg 204 1.1 mrg __isl_give isl_ast_expr *isl_ast_expr_dup(__isl_keep isl_ast_expr *expr) 205 1.1 mrg { 206 1.1 mrg isl_ast_expr *dup; 207 1.1 mrg 208 1.1 mrg if (!expr) 209 1.1 mrg return NULL; 210 1.1 mrg 211 1.1 mrg switch (expr->type) { 212 1.1 mrg case isl_ast_expr_int: 213 1.1 mrg dup = isl_ast_expr_from_val(isl_val_copy(expr->u.v)); 214 1.1 mrg break; 215 1.1 mrg case isl_ast_expr_id: 216 1.1 mrg dup = isl_ast_expr_from_id(isl_id_copy(expr->u.id)); 217 1.1 mrg break; 218 1.1 mrg case isl_ast_expr_op: 219 1.1 mrg dup = alloc_op(expr->u.op.op, 220 1.1 mrg isl_ast_expr_list_copy(expr->u.op.args)); 221 1.1 mrg break; 222 1.1 mrg case isl_ast_expr_error: 223 1.1 mrg dup = NULL; 224 1.1 mrg } 225 1.1 mrg 226 1.1 mrg if (!dup) 227 1.1 mrg return NULL; 228 1.1 mrg 229 1.1 mrg return dup; 230 1.1 mrg } 231 1.1 mrg 232 1.1 mrg __isl_give isl_ast_expr *isl_ast_expr_cow(__isl_take isl_ast_expr *expr) 233 1.1 mrg { 234 1.1 mrg if (!expr) 235 1.1 mrg return NULL; 236 1.1 mrg 237 1.1 mrg if (expr->ref == 1) 238 1.1 mrg return expr; 239 1.1 mrg expr->ref--; 240 1.1 mrg return isl_ast_expr_dup(expr); 241 1.1 mrg } 242 1.1 mrg 243 1.1 mrg __isl_null isl_ast_expr *isl_ast_expr_free(__isl_take isl_ast_expr *expr) 244 1.1 mrg { 245 1.1 mrg if (!expr) 246 1.1 mrg return NULL; 247 1.1 mrg 248 1.1 mrg if (--expr->ref > 0) 249 1.1 mrg return NULL; 250 1.1 mrg 251 1.1 mrg isl_ctx_deref(expr->ctx); 252 1.1 mrg 253 1.1 mrg switch (expr->type) { 254 1.1 mrg case isl_ast_expr_int: 255 1.1 mrg isl_val_free(expr->u.v); 256 1.1 mrg break; 257 1.1 mrg case isl_ast_expr_id: 258 1.1 mrg isl_id_free(expr->u.id); 259 1.1 mrg break; 260 1.1 mrg case isl_ast_expr_op: 261 1.1 mrg isl_ast_expr_list_free(expr->u.op.args); 262 1.1 mrg break; 263 1.1 mrg case isl_ast_expr_error: 264 1.1 mrg break; 265 1.1 mrg } 266 1.1 mrg 267 1.1 mrg free(expr); 268 1.1 mrg return NULL; 269 1.1 mrg } 270 1.1 mrg 271 1.1 mrg isl_ctx *isl_ast_expr_get_ctx(__isl_keep isl_ast_expr *expr) 272 1.1 mrg { 273 1.1 mrg return expr ? expr->ctx : NULL; 274 1.1 mrg } 275 1.1 mrg 276 1.1 mrg enum isl_ast_expr_type isl_ast_expr_get_type(__isl_keep isl_ast_expr *expr) 277 1.1 mrg { 278 1.1 mrg return expr ? expr->type : isl_ast_expr_error; 279 1.1 mrg } 280 1.1 mrg 281 1.1 mrg /* Return the integer value represented by "expr". 282 1.1 mrg */ 283 1.1 mrg __isl_give isl_val *isl_ast_expr_int_get_val(__isl_keep isl_ast_expr *expr) 284 1.1 mrg { 285 1.1 mrg if (!expr) 286 1.1 mrg return NULL; 287 1.1 mrg if (expr->type != isl_ast_expr_int) 288 1.1 mrg isl_die(isl_ast_expr_get_ctx(expr), isl_error_invalid, 289 1.1 mrg "expression not an int", return NULL); 290 1.1 mrg return isl_val_copy(expr->u.v); 291 1.1 mrg } 292 1.1 mrg 293 1.1 mrg /* This is an alternative name for the function above. 294 1.1 mrg */ 295 1.1 mrg __isl_give isl_val *isl_ast_expr_get_val(__isl_keep isl_ast_expr *expr) 296 1.1 mrg { 297 1.1 mrg return isl_ast_expr_int_get_val(expr); 298 1.1 mrg } 299 1.1 mrg 300 1.1 mrg __isl_give isl_id *isl_ast_expr_id_get_id(__isl_keep isl_ast_expr *expr) 301 1.1 mrg { 302 1.1 mrg if (!expr) 303 1.1 mrg return NULL; 304 1.1 mrg if (expr->type != isl_ast_expr_id) 305 1.1 mrg isl_die(isl_ast_expr_get_ctx(expr), isl_error_invalid, 306 1.1 mrg "expression not an identifier", return NULL); 307 1.1 mrg 308 1.1 mrg return isl_id_copy(expr->u.id); 309 1.1 mrg } 310 1.1 mrg 311 1.1 mrg /* This is an alternative name for the function above. 312 1.1 mrg */ 313 1.1 mrg __isl_give isl_id *isl_ast_expr_get_id(__isl_keep isl_ast_expr *expr) 314 1.1 mrg { 315 1.1 mrg return isl_ast_expr_id_get_id(expr); 316 1.1 mrg } 317 1.1 mrg 318 1.1 mrg /* Check that "expr" is of type isl_ast_expr_op. 319 1.1 mrg */ 320 1.1 mrg static isl_stat isl_ast_expr_check_op(__isl_keep isl_ast_expr *expr) 321 1.1 mrg { 322 1.1 mrg if (!expr) 323 1.1 mrg return isl_stat_error; 324 1.1 mrg if (expr->type != isl_ast_expr_op) 325 1.1 mrg isl_die(isl_ast_expr_get_ctx(expr), isl_error_invalid, 326 1.1 mrg "expression not an operation", return isl_stat_error); 327 1.1 mrg return isl_stat_ok; 328 1.1 mrg } 329 1.1 mrg 330 1.1 mrg /* Return the type of operation represented by "expr". 331 1.1 mrg */ 332 1.1 mrg enum isl_ast_expr_op_type isl_ast_expr_op_get_type( 333 1.1 mrg __isl_keep isl_ast_expr *expr) 334 1.1 mrg { 335 1.1 mrg if (isl_ast_expr_check_op(expr) < 0) 336 1.1 mrg return isl_ast_expr_op_error; 337 1.1 mrg return expr->u.op.op; 338 1.1 mrg } 339 1.1 mrg 340 1.1 mrg /* This is an alternative name for the function above. 341 1.1 mrg */ 342 1.1 mrg enum isl_ast_expr_op_type isl_ast_expr_get_op_type( 343 1.1 mrg __isl_keep isl_ast_expr *expr) 344 1.1 mrg { 345 1.1 mrg return isl_ast_expr_op_get_type(expr); 346 1.1 mrg } 347 1.1 mrg 348 1.1 mrg /* Return the number of arguments of the operation represented by "expr". 349 1.1 mrg */ 350 1.1 mrg isl_size isl_ast_expr_op_get_n_arg(__isl_keep isl_ast_expr *expr) 351 1.1 mrg { 352 1.1 mrg if (isl_ast_expr_check_op(expr) < 0) 353 1.1 mrg return isl_size_error; 354 1.1 mrg return isl_ast_expr_list_size(expr->u.op.args); 355 1.1 mrg } 356 1.1 mrg 357 1.1 mrg /* This is an alternative name for the function above. 358 1.1 mrg */ 359 1.1 mrg isl_size isl_ast_expr_get_op_n_arg(__isl_keep isl_ast_expr *expr) 360 1.1 mrg { 361 1.1 mrg return isl_ast_expr_op_get_n_arg(expr); 362 1.1 mrg } 363 1.1 mrg 364 1.1 mrg /* Return the argument at position "pos" of the operation represented by "expr". 365 1.1 mrg */ 366 1.1 mrg __isl_give isl_ast_expr *isl_ast_expr_op_get_arg(__isl_keep isl_ast_expr *expr, 367 1.1 mrg int pos) 368 1.1 mrg { 369 1.1 mrg if (isl_ast_expr_check_op(expr) < 0) 370 1.1 mrg return NULL; 371 1.1 mrg 372 1.1 mrg return isl_ast_expr_list_get_at(expr->u.op.args, pos); 373 1.1 mrg } 374 1.1 mrg 375 1.1 mrg /* This is an alternative name for the function above. 376 1.1 mrg */ 377 1.1 mrg __isl_give isl_ast_expr *isl_ast_expr_get_op_arg(__isl_keep isl_ast_expr *expr, 378 1.1 mrg int pos) 379 1.1 mrg { 380 1.1 mrg return isl_ast_expr_op_get_arg(expr, pos); 381 1.1 mrg } 382 1.1 mrg 383 1.1 mrg /* Return a copy of the arguments of the operation represented by "expr". 384 1.1 mrg */ 385 1.1 mrg static __isl_give isl_ast_expr_list *isl_ast_expr_op_get_args( 386 1.1 mrg __isl_keep isl_ast_expr *expr) 387 1.1 mrg { 388 1.1 mrg if (isl_ast_expr_check_op(expr) < 0) 389 1.1 mrg return NULL; 390 1.1 mrg return isl_ast_expr_list_copy(expr->u.op.args); 391 1.1 mrg } 392 1.1 mrg 393 1.1 mrg /* Return the arguments of the operation expression "expr". 394 1.1 mrg * This may be either a copy or the arguments themselves 395 1.1 mrg * if there is only one reference to "expr". 396 1.1 mrg * This allows the arguments to be modified inplace 397 1.1 mrg * if both "expr" and its arguments have only a single reference. 398 1.1 mrg * The caller is not allowed to modify "expr" between this call and 399 1.1 mrg * the subsequent call to isl_ast_expr_op_restore_args. 400 1.1 mrg * The only exception is that isl_ast_expr_free can be called instead. 401 1.1 mrg */ 402 1.1 mrg static __isl_give isl_ast_expr_list *isl_ast_expr_op_take_args( 403 1.1 mrg __isl_keep isl_ast_expr *expr) 404 1.1 mrg { 405 1.1 mrg isl_ast_expr_list *args; 406 1.1 mrg 407 1.1 mrg if (isl_ast_expr_check_op(expr) < 0) 408 1.1 mrg return NULL; 409 1.1 mrg if (expr->ref != 1) 410 1.1 mrg return isl_ast_expr_op_get_args(expr); 411 1.1 mrg args = expr->u.op.args; 412 1.1 mrg expr->u.op.args = NULL; 413 1.1 mrg return args; 414 1.1 mrg } 415 1.1 mrg 416 1.1 mrg /* Set the arguments of the operation expression "expr" to "args", 417 1.1 mrg * where the arguments of "args" may be missing 418 1.1 mrg * due to a preceding call to isl_ast_expr_op_take_args. 419 1.1 mrg * However, in this case, "expr" only has a single reference and 420 1.1 mrg * then the call to isl_ast_expr_cow has no effect. 421 1.1 mrg */ 422 1.1 mrg static __isl_give isl_ast_expr *isl_ast_expr_op_restore_args( 423 1.1 mrg __isl_take isl_ast_expr *expr, __isl_take isl_ast_expr_list *args) 424 1.1 mrg { 425 1.1 mrg if (isl_ast_expr_check_op(expr) < 0 || !args) 426 1.1 mrg goto error; 427 1.1 mrg if (expr->u.op.args == args) { 428 1.1 mrg isl_ast_expr_list_free(args); 429 1.1 mrg return expr; 430 1.1 mrg } 431 1.1 mrg 432 1.1 mrg expr = isl_ast_expr_cow(expr); 433 1.1 mrg if (!expr) 434 1.1 mrg goto error; 435 1.1 mrg 436 1.1 mrg isl_ast_expr_list_free(expr->u.op.args); 437 1.1 mrg expr->u.op.args = args; 438 1.1 mrg 439 1.1 mrg return expr; 440 1.1 mrg error: 441 1.1 mrg isl_ast_expr_free(expr); 442 1.1 mrg isl_ast_expr_list_free(args); 443 1.1 mrg return NULL; 444 1.1 mrg } 445 1.1 mrg 446 1.1 mrg /* Add "arg" to the arguments of the operation expression "expr". 447 1.1 mrg */ 448 1.1 mrg __isl_give isl_ast_expr *isl_ast_expr_op_add_arg(__isl_take isl_ast_expr *expr, 449 1.1 mrg __isl_take isl_ast_expr *arg) 450 1.1 mrg { 451 1.1 mrg isl_ast_expr_list *args; 452 1.1 mrg 453 1.1 mrg args = isl_ast_expr_op_take_args(expr); 454 1.1 mrg args = isl_ast_expr_list_add(args, arg); 455 1.1 mrg expr = isl_ast_expr_op_restore_args(expr, args); 456 1.1 mrg 457 1.1 mrg return expr; 458 1.1 mrg } 459 1.1 mrg 460 1.1 mrg /* Replace the argument at position "pos" of "expr" by "arg". 461 1.1 mrg */ 462 1.1 mrg __isl_give isl_ast_expr *isl_ast_expr_set_op_arg(__isl_take isl_ast_expr *expr, 463 1.1 mrg int pos, __isl_take isl_ast_expr *arg) 464 1.1 mrg { 465 1.1 mrg isl_ast_expr_list *args; 466 1.1 mrg 467 1.1 mrg args = isl_ast_expr_op_take_args(expr); 468 1.1 mrg args = isl_ast_expr_list_set_at(args, pos, arg); 469 1.1 mrg expr = isl_ast_expr_op_restore_args(expr, args); 470 1.1 mrg 471 1.1 mrg return expr; 472 1.1 mrg } 473 1.1 mrg 474 1.1 mrg /* Are the lists of AST expressions "list1" and "list2" the same? 475 1.1 mrg */ 476 1.1 mrg static isl_bool isl_ast_expr_list_is_equal(__isl_keep isl_ast_expr_list *list1, 477 1.1 mrg __isl_keep isl_ast_expr_list *list2) 478 1.1 mrg { 479 1.1 mrg int i; 480 1.1 mrg isl_size n1, n2; 481 1.1 mrg 482 1.1 mrg if (!list1 || !list2) 483 1.1 mrg return isl_bool_error; 484 1.1 mrg if (list1 == list2) 485 1.1 mrg return isl_bool_true; 486 1.1 mrg 487 1.1 mrg n1 = isl_ast_expr_list_size(list1); 488 1.1 mrg n2 = isl_ast_expr_list_size(list2); 489 1.1 mrg if (n1 < 0 || n2 < 0) 490 1.1 mrg return isl_bool_error; 491 1.1 mrg if (n1 != n2) 492 1.1 mrg return isl_bool_false; 493 1.1 mrg for (i = 0; i < n1; ++i) { 494 1.1 mrg isl_ast_expr *expr1, *expr2; 495 1.1 mrg isl_bool equal; 496 1.1 mrg 497 1.1 mrg expr1 = isl_ast_expr_list_get_at(list1, i); 498 1.1 mrg expr2 = isl_ast_expr_list_get_at(list2, i); 499 1.1 mrg equal = isl_ast_expr_is_equal(expr1, expr2); 500 1.1 mrg isl_ast_expr_free(expr1); 501 1.1 mrg isl_ast_expr_free(expr2); 502 1.1 mrg if (equal < 0 || !equal) 503 1.1 mrg return equal; 504 1.1 mrg } 505 1.1 mrg 506 1.1 mrg return isl_bool_true; 507 1.1 mrg } 508 1.1 mrg 509 1.1 mrg /* Is "expr1" equal to "expr2"? 510 1.1 mrg */ 511 1.1 mrg isl_bool isl_ast_expr_is_equal(__isl_keep isl_ast_expr *expr1, 512 1.1 mrg __isl_keep isl_ast_expr *expr2) 513 1.1 mrg { 514 1.1 mrg if (!expr1 || !expr2) 515 1.1 mrg return isl_bool_error; 516 1.1 mrg 517 1.1 mrg if (expr1 == expr2) 518 1.1 mrg return isl_bool_true; 519 1.1 mrg if (expr1->type != expr2->type) 520 1.1 mrg return isl_bool_false; 521 1.1 mrg switch (expr1->type) { 522 1.1 mrg case isl_ast_expr_int: 523 1.1 mrg return isl_val_eq(expr1->u.v, expr2->u.v); 524 1.1 mrg case isl_ast_expr_id: 525 1.1 mrg return isl_bool_ok(expr1->u.id == expr2->u.id); 526 1.1 mrg case isl_ast_expr_op: 527 1.1 mrg if (expr1->u.op.op != expr2->u.op.op) 528 1.1 mrg return isl_bool_false; 529 1.1 mrg return isl_ast_expr_list_is_equal(expr1->u.op.args, 530 1.1 mrg expr2->u.op.args); 531 1.1 mrg case isl_ast_expr_error: 532 1.1 mrg return isl_bool_error; 533 1.1 mrg } 534 1.1 mrg 535 1.1 mrg isl_die(isl_ast_expr_get_ctx(expr1), isl_error_internal, 536 1.1 mrg "unhandled case", return isl_bool_error); 537 1.1 mrg } 538 1.1 mrg 539 1.1 mrg /* Create a new id expression representing "id". 540 1.1 mrg */ 541 1.1 mrg __isl_give isl_ast_expr *isl_ast_expr_from_id(__isl_take isl_id *id) 542 1.1 mrg { 543 1.1 mrg isl_ctx *ctx; 544 1.1 mrg isl_ast_expr *expr; 545 1.1 mrg 546 1.1 mrg if (!id) 547 1.1 mrg return NULL; 548 1.1 mrg 549 1.1 mrg ctx = isl_id_get_ctx(id); 550 1.1 mrg expr = isl_calloc_type(ctx, isl_ast_expr); 551 1.1 mrg if (!expr) 552 1.1 mrg goto error; 553 1.1 mrg 554 1.1 mrg expr->ctx = ctx; 555 1.1 mrg isl_ctx_ref(ctx); 556 1.1 mrg expr->ref = 1; 557 1.1 mrg expr->type = isl_ast_expr_id; 558 1.1 mrg expr->u.id = id; 559 1.1 mrg 560 1.1 mrg return expr; 561 1.1 mrg error: 562 1.1 mrg isl_id_free(id); 563 1.1 mrg return NULL; 564 1.1 mrg } 565 1.1 mrg 566 1.1 mrg /* Create a new integer expression representing "i". 567 1.1 mrg */ 568 1.1 mrg __isl_give isl_ast_expr *isl_ast_expr_alloc_int_si(isl_ctx *ctx, int i) 569 1.1 mrg { 570 1.1 mrg isl_ast_expr *expr; 571 1.1 mrg 572 1.1 mrg expr = isl_calloc_type(ctx, isl_ast_expr); 573 1.1 mrg if (!expr) 574 1.1 mrg return NULL; 575 1.1 mrg 576 1.1 mrg expr->ctx = ctx; 577 1.1 mrg isl_ctx_ref(ctx); 578 1.1 mrg expr->ref = 1; 579 1.1 mrg expr->type = isl_ast_expr_int; 580 1.1 mrg expr->u.v = isl_val_int_from_si(ctx, i); 581 1.1 mrg if (!expr->u.v) 582 1.1 mrg return isl_ast_expr_free(expr); 583 1.1 mrg 584 1.1 mrg return expr; 585 1.1 mrg } 586 1.1 mrg 587 1.1 mrg /* Create a new integer expression representing "v". 588 1.1 mrg */ 589 1.1 mrg __isl_give isl_ast_expr *isl_ast_expr_from_val(__isl_take isl_val *v) 590 1.1 mrg { 591 1.1 mrg isl_ctx *ctx; 592 1.1 mrg isl_ast_expr *expr; 593 1.1 mrg 594 1.1 mrg if (!v) 595 1.1 mrg return NULL; 596 1.1 mrg if (!isl_val_is_int(v)) 597 1.1 mrg isl_die(isl_val_get_ctx(v), isl_error_invalid, 598 1.1 mrg "expecting integer value", goto error); 599 1.1 mrg 600 1.1 mrg ctx = isl_val_get_ctx(v); 601 1.1 mrg expr = isl_calloc_type(ctx, isl_ast_expr); 602 1.1 mrg if (!expr) 603 1.1 mrg goto error; 604 1.1 mrg 605 1.1 mrg expr->ctx = ctx; 606 1.1 mrg isl_ctx_ref(ctx); 607 1.1 mrg expr->ref = 1; 608 1.1 mrg expr->type = isl_ast_expr_int; 609 1.1 mrg expr->u.v = v; 610 1.1 mrg 611 1.1 mrg return expr; 612 1.1 mrg error: 613 1.1 mrg isl_val_free(v); 614 1.1 mrg return NULL; 615 1.1 mrg } 616 1.1 mrg 617 1.1 mrg /* Create an expression representing the unary operation "type" applied to 618 1.1 mrg * "arg". 619 1.1 mrg */ 620 1.1 mrg __isl_give isl_ast_expr *isl_ast_expr_alloc_unary( 621 1.1 mrg enum isl_ast_expr_op_type type, __isl_take isl_ast_expr *arg) 622 1.1 mrg { 623 1.1 mrg isl_ctx *ctx; 624 1.1 mrg isl_ast_expr *expr = NULL; 625 1.1 mrg isl_ast_expr_list *args; 626 1.1 mrg 627 1.1 mrg if (!arg) 628 1.1 mrg return NULL; 629 1.1 mrg 630 1.1 mrg ctx = isl_ast_expr_get_ctx(arg); 631 1.1 mrg expr = isl_ast_expr_alloc_op(ctx, type, 1); 632 1.1 mrg 633 1.1 mrg args = isl_ast_expr_op_take_args(expr); 634 1.1 mrg args = isl_ast_expr_list_add(args, arg); 635 1.1 mrg expr = isl_ast_expr_op_restore_args(expr, args); 636 1.1 mrg 637 1.1 mrg return expr; 638 1.1 mrg } 639 1.1 mrg 640 1.1 mrg /* Create an expression representing the negation of "arg". 641 1.1 mrg */ 642 1.1 mrg __isl_give isl_ast_expr *isl_ast_expr_neg(__isl_take isl_ast_expr *arg) 643 1.1 mrg { 644 1.1 mrg return isl_ast_expr_alloc_unary(isl_ast_expr_op_minus, arg); 645 1.1 mrg } 646 1.1 mrg 647 1.1 mrg /* Create an expression representing the address of "expr". 648 1.1 mrg */ 649 1.1 mrg __isl_give isl_ast_expr *isl_ast_expr_address_of(__isl_take isl_ast_expr *expr) 650 1.1 mrg { 651 1.1 mrg if (!expr) 652 1.1 mrg return NULL; 653 1.1 mrg 654 1.1 mrg if (isl_ast_expr_get_type(expr) != isl_ast_expr_op || 655 1.1 mrg isl_ast_expr_get_op_type(expr) != isl_ast_expr_op_access) 656 1.1 mrg isl_die(isl_ast_expr_get_ctx(expr), isl_error_invalid, 657 1.1 mrg "can only take address of access expressions", 658 1.1 mrg return isl_ast_expr_free(expr)); 659 1.1 mrg 660 1.1 mrg return isl_ast_expr_alloc_unary(isl_ast_expr_op_address_of, expr); 661 1.1 mrg } 662 1.1 mrg 663 1.1 mrg /* Create an expression representing the binary operation "type" 664 1.1 mrg * applied to "expr1" and "expr2". 665 1.1 mrg */ 666 1.1 mrg __isl_give isl_ast_expr *isl_ast_expr_alloc_binary( 667 1.1 mrg enum isl_ast_expr_op_type type, 668 1.1 mrg __isl_take isl_ast_expr *expr1, __isl_take isl_ast_expr *expr2) 669 1.1 mrg { 670 1.1 mrg isl_ctx *ctx; 671 1.1 mrg isl_ast_expr *expr = NULL; 672 1.1 mrg isl_ast_expr_list *args; 673 1.1 mrg 674 1.1 mrg if (!expr1 || !expr2) 675 1.1 mrg goto error; 676 1.1 mrg 677 1.1 mrg ctx = isl_ast_expr_get_ctx(expr1); 678 1.1 mrg expr = isl_ast_expr_alloc_op(ctx, type, 2); 679 1.1 mrg 680 1.1 mrg args = isl_ast_expr_op_take_args(expr); 681 1.1 mrg args = isl_ast_expr_list_add(args, expr1); 682 1.1 mrg args = isl_ast_expr_list_add(args, expr2); 683 1.1 mrg expr = isl_ast_expr_op_restore_args(expr, args); 684 1.1 mrg 685 1.1 mrg return expr; 686 1.1 mrg error: 687 1.1 mrg isl_ast_expr_free(expr1); 688 1.1 mrg isl_ast_expr_free(expr2); 689 1.1 mrg return NULL; 690 1.1 mrg } 691 1.1 mrg 692 1.1 mrg /* Create an expression representing the sum of "expr1" and "expr2". 693 1.1 mrg */ 694 1.1 mrg __isl_give isl_ast_expr *isl_ast_expr_add(__isl_take isl_ast_expr *expr1, 695 1.1 mrg __isl_take isl_ast_expr *expr2) 696 1.1 mrg { 697 1.1 mrg return isl_ast_expr_alloc_binary(isl_ast_expr_op_add, expr1, expr2); 698 1.1 mrg } 699 1.1 mrg 700 1.1 mrg /* Create an expression representing the difference of "expr1" and "expr2". 701 1.1 mrg */ 702 1.1 mrg __isl_give isl_ast_expr *isl_ast_expr_sub(__isl_take isl_ast_expr *expr1, 703 1.1 mrg __isl_take isl_ast_expr *expr2) 704 1.1 mrg { 705 1.1 mrg return isl_ast_expr_alloc_binary(isl_ast_expr_op_sub, expr1, expr2); 706 1.1 mrg } 707 1.1 mrg 708 1.1 mrg /* Create an expression representing the product of "expr1" and "expr2". 709 1.1 mrg */ 710 1.1 mrg __isl_give isl_ast_expr *isl_ast_expr_mul(__isl_take isl_ast_expr *expr1, 711 1.1 mrg __isl_take isl_ast_expr *expr2) 712 1.1 mrg { 713 1.1 mrg return isl_ast_expr_alloc_binary(isl_ast_expr_op_mul, expr1, expr2); 714 1.1 mrg } 715 1.1 mrg 716 1.1 mrg /* Create an expression representing the quotient of "expr1" and "expr2". 717 1.1 mrg */ 718 1.1 mrg __isl_give isl_ast_expr *isl_ast_expr_div(__isl_take isl_ast_expr *expr1, 719 1.1 mrg __isl_take isl_ast_expr *expr2) 720 1.1 mrg { 721 1.1 mrg return isl_ast_expr_alloc_binary(isl_ast_expr_op_div, expr1, expr2); 722 1.1 mrg } 723 1.1 mrg 724 1.1 mrg /* Create an expression representing the quotient of the integer 725 1.1 mrg * division of "expr1" by "expr2", where "expr1" is known to be 726 1.1 mrg * non-negative. 727 1.1 mrg */ 728 1.1 mrg __isl_give isl_ast_expr *isl_ast_expr_pdiv_q(__isl_take isl_ast_expr *expr1, 729 1.1 mrg __isl_take isl_ast_expr *expr2) 730 1.1 mrg { 731 1.1 mrg return isl_ast_expr_alloc_binary(isl_ast_expr_op_pdiv_q, expr1, expr2); 732 1.1 mrg } 733 1.1 mrg 734 1.1 mrg /* Create an expression representing the remainder of the integer 735 1.1 mrg * division of "expr1" by "expr2", where "expr1" is known to be 736 1.1 mrg * non-negative. 737 1.1 mrg */ 738 1.1 mrg __isl_give isl_ast_expr *isl_ast_expr_pdiv_r(__isl_take isl_ast_expr *expr1, 739 1.1 mrg __isl_take isl_ast_expr *expr2) 740 1.1 mrg { 741 1.1 mrg return isl_ast_expr_alloc_binary(isl_ast_expr_op_pdiv_r, expr1, expr2); 742 1.1 mrg } 743 1.1 mrg 744 1.1 mrg /* Create an expression representing the conjunction of "expr1" and "expr2". 745 1.1 mrg */ 746 1.1 mrg __isl_give isl_ast_expr *isl_ast_expr_and(__isl_take isl_ast_expr *expr1, 747 1.1 mrg __isl_take isl_ast_expr *expr2) 748 1.1 mrg { 749 1.1 mrg return isl_ast_expr_alloc_binary(isl_ast_expr_op_and, expr1, expr2); 750 1.1 mrg } 751 1.1 mrg 752 1.1 mrg /* Create an expression representing the conjunction of "expr1" and "expr2", 753 1.1 mrg * where "expr2" is evaluated only if "expr1" is evaluated to true. 754 1.1 mrg */ 755 1.1 mrg __isl_give isl_ast_expr *isl_ast_expr_and_then(__isl_take isl_ast_expr *expr1, 756 1.1 mrg __isl_take isl_ast_expr *expr2) 757 1.1 mrg { 758 1.1 mrg return isl_ast_expr_alloc_binary(isl_ast_expr_op_and_then, expr1, expr2); 759 1.1 mrg } 760 1.1 mrg 761 1.1 mrg /* Create an expression representing the disjunction of "expr1" and "expr2". 762 1.1 mrg */ 763 1.1 mrg __isl_give isl_ast_expr *isl_ast_expr_or(__isl_take isl_ast_expr *expr1, 764 1.1 mrg __isl_take isl_ast_expr *expr2) 765 1.1 mrg { 766 1.1 mrg return isl_ast_expr_alloc_binary(isl_ast_expr_op_or, expr1, expr2); 767 1.1 mrg } 768 1.1 mrg 769 1.1 mrg /* Create an expression representing the disjunction of "expr1" and "expr2", 770 1.1 mrg * where "expr2" is evaluated only if "expr1" is evaluated to false. 771 1.1 mrg */ 772 1.1 mrg __isl_give isl_ast_expr *isl_ast_expr_or_else(__isl_take isl_ast_expr *expr1, 773 1.1 mrg __isl_take isl_ast_expr *expr2) 774 1.1 mrg { 775 1.1 mrg return isl_ast_expr_alloc_binary(isl_ast_expr_op_or_else, expr1, expr2); 776 1.1 mrg } 777 1.1 mrg 778 1.1 mrg /* Create an expression representing "expr1" less than or equal to "expr2". 779 1.1 mrg */ 780 1.1 mrg __isl_give isl_ast_expr *isl_ast_expr_le(__isl_take isl_ast_expr *expr1, 781 1.1 mrg __isl_take isl_ast_expr *expr2) 782 1.1 mrg { 783 1.1 mrg return isl_ast_expr_alloc_binary(isl_ast_expr_op_le, expr1, expr2); 784 1.1 mrg } 785 1.1 mrg 786 1.1 mrg /* Create an expression representing "expr1" less than "expr2". 787 1.1 mrg */ 788 1.1 mrg __isl_give isl_ast_expr *isl_ast_expr_lt(__isl_take isl_ast_expr *expr1, 789 1.1 mrg __isl_take isl_ast_expr *expr2) 790 1.1 mrg { 791 1.1 mrg return isl_ast_expr_alloc_binary(isl_ast_expr_op_lt, expr1, expr2); 792 1.1 mrg } 793 1.1 mrg 794 1.1 mrg /* Create an expression representing "expr1" greater than or equal to "expr2". 795 1.1 mrg */ 796 1.1 mrg __isl_give isl_ast_expr *isl_ast_expr_ge(__isl_take isl_ast_expr *expr1, 797 1.1 mrg __isl_take isl_ast_expr *expr2) 798 1.1 mrg { 799 1.1 mrg return isl_ast_expr_alloc_binary(isl_ast_expr_op_ge, expr1, expr2); 800 1.1 mrg } 801 1.1 mrg 802 1.1 mrg /* Create an expression representing "expr1" greater than "expr2". 803 1.1 mrg */ 804 1.1 mrg __isl_give isl_ast_expr *isl_ast_expr_gt(__isl_take isl_ast_expr *expr1, 805 1.1 mrg __isl_take isl_ast_expr *expr2) 806 1.1 mrg { 807 1.1 mrg return isl_ast_expr_alloc_binary(isl_ast_expr_op_gt, expr1, expr2); 808 1.1 mrg } 809 1.1 mrg 810 1.1 mrg /* Create an expression representing "expr1" equal to "expr2". 811 1.1 mrg */ 812 1.1 mrg __isl_give isl_ast_expr *isl_ast_expr_eq(__isl_take isl_ast_expr *expr1, 813 1.1 mrg __isl_take isl_ast_expr *expr2) 814 1.1 mrg { 815 1.1 mrg return isl_ast_expr_alloc_binary(isl_ast_expr_op_eq, expr1, expr2); 816 1.1 mrg } 817 1.1 mrg 818 1.1 mrg /* Create an expression of type "type" with as arguments "arg0" followed 819 1.1 mrg * by "arguments". 820 1.1 mrg */ 821 1.1 mrg static __isl_give isl_ast_expr *ast_expr_with_arguments( 822 1.1 mrg enum isl_ast_expr_op_type type, __isl_take isl_ast_expr *arg0, 823 1.1 mrg __isl_take isl_ast_expr_list *arguments) 824 1.1 mrg { 825 1.1 mrg arguments = isl_ast_expr_list_insert(arguments, 0, arg0); 826 1.1 mrg return alloc_op(type, arguments); 827 1.1 mrg } 828 1.1 mrg 829 1.1 mrg /* Create an expression representing an access to "array" with index 830 1.1 mrg * expressions "indices". 831 1.1 mrg */ 832 1.1 mrg __isl_give isl_ast_expr *isl_ast_expr_access(__isl_take isl_ast_expr *array, 833 1.1 mrg __isl_take isl_ast_expr_list *indices) 834 1.1 mrg { 835 1.1 mrg return ast_expr_with_arguments(isl_ast_expr_op_access, array, indices); 836 1.1 mrg } 837 1.1 mrg 838 1.1 mrg /* Create an expression representing a call to "function" with argument 839 1.1 mrg * expressions "arguments". 840 1.1 mrg */ 841 1.1 mrg __isl_give isl_ast_expr *isl_ast_expr_call(__isl_take isl_ast_expr *function, 842 1.1 mrg __isl_take isl_ast_expr_list *arguments) 843 1.1 mrg { 844 1.1 mrg return ast_expr_with_arguments(isl_ast_expr_op_call, function, arguments); 845 1.1 mrg } 846 1.1 mrg 847 1.1 mrg /* Wrapper around isl_ast_expr_substitute_ids for use 848 1.1 mrg * as an isl_ast_expr_list_map callback. 849 1.1 mrg */ 850 1.1 mrg static __isl_give isl_ast_expr *substitute_ids(__isl_take isl_ast_expr *expr, 851 1.1 mrg void *user) 852 1.1 mrg { 853 1.1 mrg isl_id_to_ast_expr *id2expr = user; 854 1.1 mrg 855 1.1 mrg return isl_ast_expr_substitute_ids(expr, 856 1.1 mrg isl_id_to_ast_expr_copy(id2expr)); 857 1.1 mrg } 858 1.1 mrg 859 1.1 mrg /* For each subexpression of "expr" of type isl_ast_expr_id, 860 1.1 mrg * if it appears in "id2expr", then replace it by the corresponding 861 1.1 mrg * expression. 862 1.1 mrg */ 863 1.1 mrg __isl_give isl_ast_expr *isl_ast_expr_substitute_ids( 864 1.1 mrg __isl_take isl_ast_expr *expr, __isl_take isl_id_to_ast_expr *id2expr) 865 1.1 mrg { 866 1.1 mrg isl_maybe_isl_ast_expr m; 867 1.1 mrg isl_ast_expr_list *args; 868 1.1 mrg 869 1.1 mrg if (!expr || !id2expr) 870 1.1 mrg goto error; 871 1.1 mrg 872 1.1 mrg switch (expr->type) { 873 1.1 mrg case isl_ast_expr_int: 874 1.1 mrg break; 875 1.1 mrg case isl_ast_expr_id: 876 1.1 mrg m = isl_id_to_ast_expr_try_get(id2expr, expr->u.id); 877 1.1 mrg if (m.valid < 0) 878 1.1 mrg goto error; 879 1.1 mrg if (!m.valid) 880 1.1 mrg break; 881 1.1 mrg isl_ast_expr_free(expr); 882 1.1 mrg expr = m.value; 883 1.1 mrg break; 884 1.1 mrg case isl_ast_expr_op: 885 1.1 mrg args = isl_ast_expr_op_take_args(expr); 886 1.1 mrg args = isl_ast_expr_list_map(args, &substitute_ids, id2expr); 887 1.1 mrg expr = isl_ast_expr_op_restore_args(expr, args); 888 1.1 mrg break; 889 1.1 mrg case isl_ast_expr_error: 890 1.1 mrg expr = isl_ast_expr_free(expr); 891 1.1 mrg break; 892 1.1 mrg } 893 1.1 mrg 894 1.1 mrg isl_id_to_ast_expr_free(id2expr); 895 1.1 mrg return expr; 896 1.1 mrg error: 897 1.1 mrg isl_ast_expr_free(expr); 898 1.1 mrg isl_id_to_ast_expr_free(id2expr); 899 1.1 mrg return NULL; 900 1.1 mrg } 901 1.1 mrg 902 1.1 mrg isl_ctx *isl_ast_node_get_ctx(__isl_keep isl_ast_node *node) 903 1.1 mrg { 904 1.1 mrg return node ? node->ctx : NULL; 905 1.1 mrg } 906 1.1 mrg 907 1.1 mrg enum isl_ast_node_type isl_ast_node_get_type(__isl_keep isl_ast_node *node) 908 1.1 mrg { 909 1.1 mrg return node ? node->type : isl_ast_node_error; 910 1.1 mrg } 911 1.1 mrg 912 1.1 mrg __isl_give isl_ast_node *isl_ast_node_alloc(isl_ctx *ctx, 913 1.1 mrg enum isl_ast_node_type type) 914 1.1 mrg { 915 1.1 mrg isl_ast_node *node; 916 1.1 mrg 917 1.1 mrg node = isl_calloc_type(ctx, isl_ast_node); 918 1.1 mrg if (!node) 919 1.1 mrg return NULL; 920 1.1 mrg 921 1.1 mrg node->ctx = ctx; 922 1.1 mrg isl_ctx_ref(ctx); 923 1.1 mrg node->ref = 1; 924 1.1 mrg node->type = type; 925 1.1 mrg 926 1.1 mrg return node; 927 1.1 mrg } 928 1.1 mrg 929 1.1 mrg /* Create an if node with the given guard. 930 1.1 mrg * 931 1.1 mrg * The then body needs to be filled in later. 932 1.1 mrg */ 933 1.1 mrg __isl_give isl_ast_node *isl_ast_node_alloc_if(__isl_take isl_ast_expr *guard) 934 1.1 mrg { 935 1.1 mrg isl_ast_node *node; 936 1.1 mrg 937 1.1 mrg if (!guard) 938 1.1 mrg return NULL; 939 1.1 mrg 940 1.1 mrg node = isl_ast_node_alloc(isl_ast_expr_get_ctx(guard), isl_ast_node_if); 941 1.1 mrg if (!node) 942 1.1 mrg goto error; 943 1.1 mrg node->u.i.guard = guard; 944 1.1 mrg 945 1.1 mrg return node; 946 1.1 mrg error: 947 1.1 mrg isl_ast_expr_free(guard); 948 1.1 mrg return NULL; 949 1.1 mrg } 950 1.1 mrg 951 1.1 mrg /* Create a for node with the given iterator. 952 1.1 mrg * 953 1.1 mrg * The remaining fields need to be filled in later. 954 1.1 mrg */ 955 1.1 mrg __isl_give isl_ast_node *isl_ast_node_alloc_for(__isl_take isl_id *id) 956 1.1 mrg { 957 1.1 mrg isl_ast_node *node; 958 1.1 mrg isl_ctx *ctx; 959 1.1 mrg 960 1.1 mrg if (!id) 961 1.1 mrg return NULL; 962 1.1 mrg 963 1.1 mrg ctx = isl_id_get_ctx(id); 964 1.1 mrg node = isl_ast_node_alloc(ctx, isl_ast_node_for); 965 1.1 mrg if (!node) 966 1.1 mrg goto error; 967 1.1 mrg 968 1.1 mrg node->u.f.iterator = isl_ast_expr_from_id(id); 969 1.1 mrg if (!node->u.f.iterator) 970 1.1 mrg return isl_ast_node_free(node); 971 1.1 mrg 972 1.1 mrg return node; 973 1.1 mrg error: 974 1.1 mrg isl_id_free(id); 975 1.1 mrg return NULL; 976 1.1 mrg } 977 1.1 mrg 978 1.1 mrg /* Create a mark node, marking "node" with "id". 979 1.1 mrg */ 980 1.1 mrg __isl_give isl_ast_node *isl_ast_node_alloc_mark(__isl_take isl_id *id, 981 1.1 mrg __isl_take isl_ast_node *node) 982 1.1 mrg { 983 1.1 mrg isl_ctx *ctx; 984 1.1 mrg isl_ast_node *mark; 985 1.1 mrg 986 1.1 mrg if (!id || !node) 987 1.1 mrg goto error; 988 1.1 mrg 989 1.1 mrg ctx = isl_id_get_ctx(id); 990 1.1 mrg mark = isl_ast_node_alloc(ctx, isl_ast_node_mark); 991 1.1 mrg if (!mark) 992 1.1 mrg goto error; 993 1.1 mrg 994 1.1 mrg mark->u.m.mark = id; 995 1.1 mrg mark->u.m.node = node; 996 1.1 mrg 997 1.1 mrg return mark; 998 1.1 mrg error: 999 1.1 mrg isl_id_free(id); 1000 1.1 mrg isl_ast_node_free(node); 1001 1.1 mrg return NULL; 1002 1.1 mrg } 1003 1.1 mrg 1004 1.1 mrg /* Create a user node evaluating "expr". 1005 1.1 mrg */ 1006 1.1 mrg __isl_give isl_ast_node *isl_ast_node_user_from_expr( 1007 1.1 mrg __isl_take isl_ast_expr *expr) 1008 1.1 mrg { 1009 1.1 mrg isl_ctx *ctx; 1010 1.1 mrg isl_ast_node *node; 1011 1.1 mrg 1012 1.1 mrg if (!expr) 1013 1.1 mrg return NULL; 1014 1.1 mrg 1015 1.1 mrg ctx = isl_ast_expr_get_ctx(expr); 1016 1.1 mrg node = isl_ast_node_alloc(ctx, isl_ast_node_user); 1017 1.1 mrg if (!node) 1018 1.1 mrg goto error; 1019 1.1 mrg 1020 1.1 mrg node->u.e.expr = expr; 1021 1.1 mrg 1022 1.1 mrg return node; 1023 1.1 mrg error: 1024 1.1 mrg isl_ast_expr_free(expr); 1025 1.1 mrg return NULL; 1026 1.1 mrg } 1027 1.1 mrg 1028 1.1 mrg /* This is an alternative name for the function above. 1029 1.1 mrg */ 1030 1.1 mrg __isl_give isl_ast_node *isl_ast_node_alloc_user(__isl_take isl_ast_expr *expr) 1031 1.1 mrg { 1032 1.1 mrg return isl_ast_node_user_from_expr(expr); 1033 1.1 mrg } 1034 1.1 mrg 1035 1.1 mrg /* Create a block node with the given children. 1036 1.1 mrg */ 1037 1.1 mrg __isl_give isl_ast_node *isl_ast_node_block_from_children( 1038 1.1 mrg __isl_take isl_ast_node_list *list) 1039 1.1 mrg { 1040 1.1 mrg isl_ast_node *node; 1041 1.1 mrg isl_ctx *ctx; 1042 1.1 mrg 1043 1.1 mrg if (!list) 1044 1.1 mrg return NULL; 1045 1.1 mrg 1046 1.1 mrg ctx = isl_ast_node_list_get_ctx(list); 1047 1.1 mrg node = isl_ast_node_alloc(ctx, isl_ast_node_block); 1048 1.1 mrg if (!node) 1049 1.1 mrg goto error; 1050 1.1 mrg 1051 1.1 mrg node->u.b.children = list; 1052 1.1 mrg 1053 1.1 mrg return node; 1054 1.1 mrg error: 1055 1.1 mrg isl_ast_node_list_free(list); 1056 1.1 mrg return NULL; 1057 1.1 mrg } 1058 1.1 mrg 1059 1.1 mrg /* This is an alternative name for the function above. 1060 1.1 mrg */ 1061 1.1 mrg __isl_give isl_ast_node *isl_ast_node_alloc_block( 1062 1.1 mrg __isl_take isl_ast_node_list *list) 1063 1.1 mrg { 1064 1.1 mrg return isl_ast_node_block_from_children(list); 1065 1.1 mrg } 1066 1.1 mrg 1067 1.1 mrg /* Represent the given list of nodes as a single node, either by 1068 1.1 mrg * extract the node from a single element list or by creating 1069 1.1 mrg * a block node with the list of nodes as children. 1070 1.1 mrg */ 1071 1.1 mrg __isl_give isl_ast_node *isl_ast_node_from_ast_node_list( 1072 1.1 mrg __isl_take isl_ast_node_list *list) 1073 1.1 mrg { 1074 1.1 mrg isl_size n; 1075 1.1 mrg isl_ast_node *node; 1076 1.1 mrg 1077 1.1 mrg n = isl_ast_node_list_n_ast_node(list); 1078 1.1 mrg if (n < 0) 1079 1.1 mrg goto error; 1080 1.1 mrg if (n != 1) 1081 1.1 mrg return isl_ast_node_alloc_block(list); 1082 1.1 mrg 1083 1.1 mrg node = isl_ast_node_list_get_ast_node(list, 0); 1084 1.1 mrg isl_ast_node_list_free(list); 1085 1.1 mrg 1086 1.1 mrg return node; 1087 1.1 mrg error: 1088 1.1 mrg isl_ast_node_list_free(list); 1089 1.1 mrg return NULL; 1090 1.1 mrg } 1091 1.1 mrg 1092 1.1 mrg __isl_give isl_ast_node *isl_ast_node_copy(__isl_keep isl_ast_node *node) 1093 1.1 mrg { 1094 1.1 mrg if (!node) 1095 1.1 mrg return NULL; 1096 1.1 mrg 1097 1.1 mrg node->ref++; 1098 1.1 mrg return node; 1099 1.1 mrg } 1100 1.1 mrg 1101 1.1 mrg /* Return a fresh copy of "node". 1102 1.1 mrg * 1103 1.1 mrg * In the case of a degenerate for node, take into account 1104 1.1 mrg * that "cond" and "inc" are NULL. 1105 1.1 mrg */ 1106 1.1 mrg __isl_give isl_ast_node *isl_ast_node_dup(__isl_keep isl_ast_node *node) 1107 1.1 mrg { 1108 1.1 mrg isl_ast_node *dup; 1109 1.1 mrg 1110 1.1 mrg if (!node) 1111 1.1 mrg return NULL; 1112 1.1 mrg 1113 1.1 mrg dup = isl_ast_node_alloc(isl_ast_node_get_ctx(node), node->type); 1114 1.1 mrg if (!dup) 1115 1.1 mrg return NULL; 1116 1.1 mrg 1117 1.1 mrg switch (node->type) { 1118 1.1 mrg case isl_ast_node_if: 1119 1.1 mrg dup->u.i.guard = isl_ast_expr_copy(node->u.i.guard); 1120 1.1 mrg dup->u.i.then = isl_ast_node_copy(node->u.i.then); 1121 1.1 mrg dup->u.i.else_node = isl_ast_node_copy(node->u.i.else_node); 1122 1.1 mrg if (!dup->u.i.guard || !dup->u.i.then || 1123 1.1 mrg (node->u.i.else_node && !dup->u.i.else_node)) 1124 1.1 mrg return isl_ast_node_free(dup); 1125 1.1 mrg break; 1126 1.1 mrg case isl_ast_node_for: 1127 1.1 mrg dup->u.f.degenerate = node->u.f.degenerate; 1128 1.1 mrg dup->u.f.iterator = isl_ast_expr_copy(node->u.f.iterator); 1129 1.1 mrg dup->u.f.init = isl_ast_expr_copy(node->u.f.init); 1130 1.1 mrg dup->u.f.body = isl_ast_node_copy(node->u.f.body); 1131 1.1 mrg if (!dup->u.f.iterator || !dup->u.f.init || !dup->u.f.body) 1132 1.1 mrg return isl_ast_node_free(dup); 1133 1.1 mrg if (node->u.f.degenerate) 1134 1.1 mrg break; 1135 1.1 mrg dup->u.f.cond = isl_ast_expr_copy(node->u.f.cond); 1136 1.1 mrg dup->u.f.inc = isl_ast_expr_copy(node->u.f.inc); 1137 1.1 mrg if (!dup->u.f.cond || !dup->u.f.inc) 1138 1.1 mrg return isl_ast_node_free(dup); 1139 1.1 mrg break; 1140 1.1 mrg case isl_ast_node_block: 1141 1.1 mrg dup->u.b.children = isl_ast_node_list_copy(node->u.b.children); 1142 1.1 mrg if (!dup->u.b.children) 1143 1.1 mrg return isl_ast_node_free(dup); 1144 1.1 mrg break; 1145 1.1 mrg case isl_ast_node_mark: 1146 1.1 mrg dup->u.m.mark = isl_id_copy(node->u.m.mark); 1147 1.1 mrg dup->u.m.node = isl_ast_node_copy(node->u.m.node); 1148 1.1 mrg if (!dup->u.m.mark || !dup->u.m.node) 1149 1.1 mrg return isl_ast_node_free(dup); 1150 1.1 mrg break; 1151 1.1 mrg case isl_ast_node_user: 1152 1.1 mrg dup->u.e.expr = isl_ast_expr_copy(node->u.e.expr); 1153 1.1 mrg if (!dup->u.e.expr) 1154 1.1 mrg return isl_ast_node_free(dup); 1155 1.1 mrg break; 1156 1.1 mrg case isl_ast_node_error: 1157 1.1 mrg break; 1158 1.1 mrg } 1159 1.1 mrg 1160 1.1 mrg if (!node->annotation) 1161 1.1 mrg return dup; 1162 1.1 mrg dup->annotation = isl_id_copy(node->annotation); 1163 1.1 mrg if (!dup->annotation) 1164 1.1 mrg return isl_ast_node_free(dup); 1165 1.1 mrg 1166 1.1 mrg return dup; 1167 1.1 mrg } 1168 1.1 mrg 1169 1.1 mrg __isl_give isl_ast_node *isl_ast_node_cow(__isl_take isl_ast_node *node) 1170 1.1 mrg { 1171 1.1 mrg if (!node) 1172 1.1 mrg return NULL; 1173 1.1 mrg 1174 1.1 mrg if (node->ref == 1) 1175 1.1 mrg return node; 1176 1.1 mrg node->ref--; 1177 1.1 mrg return isl_ast_node_dup(node); 1178 1.1 mrg } 1179 1.1 mrg 1180 1.1 mrg __isl_null isl_ast_node *isl_ast_node_free(__isl_take isl_ast_node *node) 1181 1.1 mrg { 1182 1.1 mrg if (!node) 1183 1.1 mrg return NULL; 1184 1.1 mrg 1185 1.1 mrg if (--node->ref > 0) 1186 1.1 mrg return NULL; 1187 1.1 mrg 1188 1.1 mrg switch (node->type) { 1189 1.1 mrg case isl_ast_node_if: 1190 1.1 mrg isl_ast_expr_free(node->u.i.guard); 1191 1.1 mrg isl_ast_node_free(node->u.i.then); 1192 1.1 mrg isl_ast_node_free(node->u.i.else_node); 1193 1.1 mrg break; 1194 1.1 mrg case isl_ast_node_for: 1195 1.1 mrg isl_ast_expr_free(node->u.f.iterator); 1196 1.1 mrg isl_ast_expr_free(node->u.f.init); 1197 1.1 mrg isl_ast_expr_free(node->u.f.cond); 1198 1.1 mrg isl_ast_expr_free(node->u.f.inc); 1199 1.1 mrg isl_ast_node_free(node->u.f.body); 1200 1.1 mrg break; 1201 1.1 mrg case isl_ast_node_block: 1202 1.1 mrg isl_ast_node_list_free(node->u.b.children); 1203 1.1 mrg break; 1204 1.1 mrg case isl_ast_node_mark: 1205 1.1 mrg isl_id_free(node->u.m.mark); 1206 1.1 mrg isl_ast_node_free(node->u.m.node); 1207 1.1 mrg break; 1208 1.1 mrg case isl_ast_node_user: 1209 1.1 mrg isl_ast_expr_free(node->u.e.expr); 1210 1.1 mrg break; 1211 1.1 mrg case isl_ast_node_error: 1212 1.1 mrg break; 1213 1.1 mrg } 1214 1.1 mrg 1215 1.1 mrg isl_id_free(node->annotation); 1216 1.1 mrg isl_ctx_deref(node->ctx); 1217 1.1 mrg free(node); 1218 1.1 mrg 1219 1.1 mrg return NULL; 1220 1.1 mrg } 1221 1.1 mrg 1222 1.1 mrg /* Check that "node" is of type "type", printing "msg" if not. 1223 1.1 mrg */ 1224 1.1 mrg static isl_stat isl_ast_node_check_type(__isl_keep isl_ast_node *node, 1225 1.1 mrg enum isl_ast_node_type type, const char *msg) 1226 1.1 mrg { 1227 1.1 mrg if (!node) 1228 1.1 mrg return isl_stat_error; 1229 1.1 mrg if (node->type != type) 1230 1.1 mrg isl_die(isl_ast_node_get_ctx(node), isl_error_invalid, msg, 1231 1.1 mrg return isl_stat_error); 1232 1.1 mrg return isl_stat_ok; 1233 1.1 mrg } 1234 1.1 mrg 1235 1.1 mrg /* Check that "node" is of type isl_ast_node_block. 1236 1.1 mrg */ 1237 1.1 mrg static isl_stat isl_ast_node_check_block(__isl_keep isl_ast_node *node) 1238 1.1 mrg { 1239 1.1 mrg return isl_ast_node_check_type(node, isl_ast_node_block, 1240 1.1 mrg "not a block node"); 1241 1.1 mrg } 1242 1.1 mrg 1243 1.1 mrg /* Check that "node" is of type isl_ast_node_if. 1244 1.1 mrg */ 1245 1.1 mrg static isl_stat isl_ast_node_check_if(__isl_keep isl_ast_node *node) 1246 1.1 mrg { 1247 1.1 mrg return isl_ast_node_check_type(node, isl_ast_node_if, "not an if node"); 1248 1.1 mrg } 1249 1.1 mrg 1250 1.1 mrg /* Check that "node" is of type isl_ast_node_for. 1251 1.1 mrg */ 1252 1.1 mrg static isl_stat isl_ast_node_check_for(__isl_keep isl_ast_node *node) 1253 1.1 mrg { 1254 1.1 mrg return isl_ast_node_check_type(node, isl_ast_node_for, 1255 1.1 mrg "not a for node"); 1256 1.1 mrg } 1257 1.1 mrg 1258 1.1 mrg /* Check that "node" is of type isl_ast_node_mark. 1259 1.1 mrg */ 1260 1.1 mrg static isl_stat isl_ast_node_check_mark(__isl_keep isl_ast_node *node) 1261 1.1 mrg { 1262 1.1 mrg return isl_ast_node_check_type(node, isl_ast_node_mark, 1263 1.1 mrg "not a mark node"); 1264 1.1 mrg } 1265 1.1 mrg 1266 1.1 mrg /* Check that "node" is of type isl_ast_node_user. 1267 1.1 mrg */ 1268 1.1 mrg static isl_stat isl_ast_node_check_user(__isl_keep isl_ast_node *node) 1269 1.1 mrg { 1270 1.1 mrg return isl_ast_node_check_type(node, isl_ast_node_user, 1271 1.1 mrg "not a user node"); 1272 1.1 mrg } 1273 1.1 mrg 1274 1.1 mrg #undef NODE_TYPE 1275 1.1 mrg #define NODE_TYPE for 1276 1.1 mrg #undef FIELD_NAME 1277 1.1 mrg #define FIELD_NAME init 1278 1.1 mrg #undef FIELD_TYPE 1279 1.1 mrg #define FIELD_TYPE isl_ast_expr 1280 1.1 mrg #undef FIELD 1281 1.1 mrg #define FIELD u.f.init 1282 1.1 mrg #include "isl_ast_node_set_field_templ.c" 1283 1.1 mrg 1284 1.1 mrg #undef NODE_TYPE 1285 1.1 mrg #define NODE_TYPE for 1286 1.1 mrg #undef FIELD_NAME 1287 1.1 mrg #define FIELD_NAME cond 1288 1.1 mrg #undef FIELD_TYPE 1289 1.1 mrg #define FIELD_TYPE isl_ast_expr 1290 1.1 mrg #undef FIELD 1291 1.1 mrg #define FIELD u.f.cond 1292 1.1 mrg #include "isl_ast_node_set_field_templ.c" 1293 1.1 mrg 1294 1.1 mrg #undef NODE_TYPE 1295 1.1 mrg #define NODE_TYPE for 1296 1.1 mrg #undef FIELD_NAME 1297 1.1 mrg #define FIELD_NAME inc 1298 1.1 mrg #undef FIELD_TYPE 1299 1.1 mrg #define FIELD_TYPE isl_ast_expr 1300 1.1 mrg #undef FIELD 1301 1.1 mrg #define FIELD u.f.inc 1302 1.1 mrg #include "isl_ast_node_set_field_templ.c" 1303 1.1 mrg 1304 1.1 mrg #undef NODE_TYPE 1305 1.1 mrg #define NODE_TYPE for 1306 1.1 mrg #undef FIELD_NAME 1307 1.1 mrg #define FIELD_NAME body 1308 1.1 mrg #undef FIELD_TYPE 1309 1.1 mrg #define FIELD_TYPE isl_ast_node 1310 1.1 mrg #undef FIELD 1311 1.1 mrg #define FIELD u.f.body 1312 1.1 mrg #include "isl_ast_node_set_field_templ.c" 1313 1.1 mrg 1314 1.1 mrg /* Return the body of the for-node "node", 1315 1.1 mrg * This may be either a copy or the body itself 1316 1.1 mrg * if there is only one reference to "node". 1317 1.1 mrg * This allows the body to be modified inplace 1318 1.1 mrg * if both "node" and its body have only a single reference. 1319 1.1 mrg * The caller is not allowed to modify "node" between this call and 1320 1.1 mrg * the subsequent call to isl_ast_node_for_restore_body. 1321 1.1 mrg * The only exception is that isl_ast_node_free can be called instead. 1322 1.1 mrg */ 1323 1.1 mrg static __isl_give isl_ast_node *isl_ast_node_for_take_body( 1324 1.1 mrg __isl_keep isl_ast_node *node) 1325 1.1 mrg { 1326 1.1 mrg isl_ast_node *body; 1327 1.1 mrg 1328 1.1 mrg if (isl_ast_node_check_for(node) < 0) 1329 1.1 mrg return NULL; 1330 1.1 mrg if (node->ref != 1) 1331 1.1 mrg return isl_ast_node_for_get_body(node); 1332 1.1 mrg body = node->u.f.body; 1333 1.1 mrg node->u.f.body = NULL; 1334 1.1 mrg return body; 1335 1.1 mrg } 1336 1.1 mrg 1337 1.1 mrg /* Set the body of the for-node "node" to "body", 1338 1.1 mrg * where the body of "node" may be missing 1339 1.1 mrg * due to a preceding call to isl_ast_node_for_take_body. 1340 1.1 mrg * However, in this case, "node" only has a single reference. 1341 1.1 mrg */ 1342 1.1 mrg static __isl_give isl_ast_node *isl_ast_node_for_restore_body( 1343 1.1 mrg __isl_take isl_ast_node *node, __isl_take isl_ast_node *body) 1344 1.1 mrg { 1345 1.1 mrg return isl_ast_node_for_set_body(node, body); 1346 1.1 mrg } 1347 1.1 mrg 1348 1.1 mrg __isl_give isl_ast_node *isl_ast_node_for_get_body( 1349 1.1 mrg __isl_keep isl_ast_node *node) 1350 1.1 mrg { 1351 1.1 mrg if (isl_ast_node_check_for(node) < 0) 1352 1.1 mrg return NULL; 1353 1.1 mrg return isl_ast_node_copy(node->u.f.body); 1354 1.1 mrg } 1355 1.1 mrg 1356 1.1 mrg /* Mark the given for node as being degenerate. 1357 1.1 mrg */ 1358 1.1 mrg __isl_give isl_ast_node *isl_ast_node_for_mark_degenerate( 1359 1.1 mrg __isl_take isl_ast_node *node) 1360 1.1 mrg { 1361 1.1 mrg node = isl_ast_node_cow(node); 1362 1.1 mrg if (!node) 1363 1.1 mrg return NULL; 1364 1.1 mrg node->u.f.degenerate = 1; 1365 1.1 mrg return node; 1366 1.1 mrg } 1367 1.1 mrg 1368 1.1 mrg isl_bool isl_ast_node_for_is_degenerate(__isl_keep isl_ast_node *node) 1369 1.1 mrg { 1370 1.1 mrg if (isl_ast_node_check_for(node) < 0) 1371 1.1 mrg return isl_bool_error; 1372 1.1 mrg return isl_bool_ok(node->u.f.degenerate); 1373 1.1 mrg } 1374 1.1 mrg 1375 1.1 mrg __isl_give isl_ast_expr *isl_ast_node_for_get_iterator( 1376 1.1 mrg __isl_keep isl_ast_node *node) 1377 1.1 mrg { 1378 1.1 mrg if (isl_ast_node_check_for(node) < 0) 1379 1.1 mrg return NULL; 1380 1.1 mrg return isl_ast_expr_copy(node->u.f.iterator); 1381 1.1 mrg } 1382 1.1 mrg 1383 1.1 mrg __isl_give isl_ast_expr *isl_ast_node_for_get_init( 1384 1.1 mrg __isl_keep isl_ast_node *node) 1385 1.1 mrg { 1386 1.1 mrg if (isl_ast_node_check_for(node) < 0) 1387 1.1 mrg return NULL; 1388 1.1 mrg return isl_ast_expr_copy(node->u.f.init); 1389 1.1 mrg } 1390 1.1 mrg 1391 1.1 mrg /* Return the condition expression of the given for node. 1392 1.1 mrg * 1393 1.1 mrg * If the for node is degenerate, then the condition is not explicitly 1394 1.1 mrg * stored in the node. Instead, it is constructed as 1395 1.1 mrg * 1396 1.1 mrg * iterator <= init 1397 1.1 mrg */ 1398 1.1 mrg __isl_give isl_ast_expr *isl_ast_node_for_get_cond( 1399 1.1 mrg __isl_keep isl_ast_node *node) 1400 1.1 mrg { 1401 1.1 mrg if (isl_ast_node_check_for(node) < 0) 1402 1.1 mrg return NULL; 1403 1.1 mrg if (!node->u.f.degenerate) 1404 1.1 mrg return isl_ast_expr_copy(node->u.f.cond); 1405 1.1 mrg 1406 1.1 mrg return isl_ast_expr_alloc_binary(isl_ast_expr_op_le, 1407 1.1 mrg isl_ast_expr_copy(node->u.f.iterator), 1408 1.1 mrg isl_ast_expr_copy(node->u.f.init)); 1409 1.1 mrg } 1410 1.1 mrg 1411 1.1 mrg /* Return the increment of the given for node. 1412 1.1 mrg * 1413 1.1 mrg * If the for node is degenerate, then the increment is not explicitly 1414 1.1 mrg * stored in the node. We simply return "1". 1415 1.1 mrg */ 1416 1.1 mrg __isl_give isl_ast_expr *isl_ast_node_for_get_inc( 1417 1.1 mrg __isl_keep isl_ast_node *node) 1418 1.1 mrg { 1419 1.1 mrg if (isl_ast_node_check_for(node) < 0) 1420 1.1 mrg return NULL; 1421 1.1 mrg if (!node->u.f.degenerate) 1422 1.1 mrg return isl_ast_expr_copy(node->u.f.inc); 1423 1.1 mrg return isl_ast_expr_alloc_int_si(isl_ast_node_get_ctx(node), 1); 1424 1.1 mrg } 1425 1.1 mrg 1426 1.1 mrg #undef NODE_TYPE 1427 1.1 mrg #define NODE_TYPE if 1428 1.1 mrg #undef FIELD_NAME 1429 1.1 mrg #define FIELD_NAME then 1430 1.1 mrg #undef FIELD_TYPE 1431 1.1 mrg #define FIELD_TYPE isl_ast_node 1432 1.1 mrg #undef FIELD 1433 1.1 mrg #define FIELD u.i.then 1434 1.1 mrg #include "isl_ast_node_set_field_templ.c" 1435 1.1 mrg 1436 1.1 mrg /* Return the then-branch of the if-node "node", 1437 1.1 mrg * This may be either a copy or the branch itself 1438 1.1 mrg * if there is only one reference to "node". 1439 1.1 mrg * This allows the branch to be modified inplace 1440 1.1 mrg * if both "node" and its then-branch have only a single reference. 1441 1.1 mrg * The caller is not allowed to modify "node" between this call and 1442 1.1 mrg * the subsequent call to isl_ast_node_if_restore_then_node. 1443 1.1 mrg * The only exception is that isl_ast_node_free can be called instead. 1444 1.1 mrg */ 1445 1.1 mrg static __isl_give isl_ast_node *isl_ast_node_if_take_then_node( 1446 1.1 mrg __isl_keep isl_ast_node *node) 1447 1.1 mrg { 1448 1.1 mrg isl_ast_node *then_node; 1449 1.1 mrg 1450 1.1 mrg if (isl_ast_node_check_if(node) < 0) 1451 1.1 mrg return NULL; 1452 1.1 mrg if (node->ref != 1) 1453 1.1 mrg return isl_ast_node_if_get_then_node(node); 1454 1.1 mrg then_node = node->u.i.then; 1455 1.1 mrg node->u.i.then = NULL; 1456 1.1 mrg return then_node; 1457 1.1 mrg } 1458 1.1 mrg 1459 1.1 mrg /* Set the then-branch of the if-node "node" to "child", 1460 1.1 mrg * where the then-branch of "node" may be missing 1461 1.1 mrg * due to a preceding call to isl_ast_node_if_take_then_node. 1462 1.1 mrg * However, in this case, "node" only has a single reference. 1463 1.1 mrg */ 1464 1.1 mrg static __isl_give isl_ast_node *isl_ast_node_if_restore_then_node( 1465 1.1 mrg __isl_take isl_ast_node *node, __isl_take isl_ast_node *child) 1466 1.1 mrg { 1467 1.1 mrg return isl_ast_node_if_set_then(node, child); 1468 1.1 mrg } 1469 1.1 mrg 1470 1.1 mrg /* Return the then-node of the given if-node. 1471 1.1 mrg */ 1472 1.1 mrg __isl_give isl_ast_node *isl_ast_node_if_get_then_node( 1473 1.1 mrg __isl_keep isl_ast_node *node) 1474 1.1 mrg { 1475 1.1 mrg if (isl_ast_node_check_if(node) < 0) 1476 1.1 mrg return NULL; 1477 1.1 mrg return isl_ast_node_copy(node->u.i.then); 1478 1.1 mrg } 1479 1.1 mrg 1480 1.1 mrg /* This is an alternative name for the function above. 1481 1.1 mrg */ 1482 1.1 mrg __isl_give isl_ast_node *isl_ast_node_if_get_then( 1483 1.1 mrg __isl_keep isl_ast_node *node) 1484 1.1 mrg { 1485 1.1 mrg return isl_ast_node_if_get_then_node(node); 1486 1.1 mrg } 1487 1.1 mrg 1488 1.1 mrg /* Does the given if-node have an else-node? 1489 1.1 mrg */ 1490 1.1 mrg isl_bool isl_ast_node_if_has_else_node(__isl_keep isl_ast_node *node) 1491 1.1 mrg { 1492 1.1 mrg if (isl_ast_node_check_if(node) < 0) 1493 1.1 mrg return isl_bool_error; 1494 1.1 mrg return isl_bool_ok(node->u.i.else_node != NULL); 1495 1.1 mrg } 1496 1.1 mrg 1497 1.1 mrg /* This is an alternative name for the function above. 1498 1.1 mrg */ 1499 1.1 mrg isl_bool isl_ast_node_if_has_else(__isl_keep isl_ast_node *node) 1500 1.1 mrg { 1501 1.1 mrg return isl_ast_node_if_has_else_node(node); 1502 1.1 mrg } 1503 1.1 mrg 1504 1.1 mrg /* Return the else-node of the given if-node, 1505 1.1 mrg * assuming there is one. 1506 1.1 mrg */ 1507 1.1 mrg __isl_give isl_ast_node *isl_ast_node_if_get_else_node( 1508 1.1 mrg __isl_keep isl_ast_node *node) 1509 1.1 mrg { 1510 1.1 mrg if (isl_ast_node_check_if(node) < 0) 1511 1.1 mrg return NULL; 1512 1.1 mrg return isl_ast_node_copy(node->u.i.else_node); 1513 1.1 mrg } 1514 1.1 mrg 1515 1.1 mrg /* This is an alternative name for the function above. 1516 1.1 mrg */ 1517 1.1 mrg __isl_give isl_ast_node *isl_ast_node_if_get_else( 1518 1.1 mrg __isl_keep isl_ast_node *node) 1519 1.1 mrg { 1520 1.1 mrg return isl_ast_node_if_get_else_node(node); 1521 1.1 mrg } 1522 1.1 mrg 1523 1.1 mrg #undef NODE_TYPE 1524 1.1 mrg #define NODE_TYPE if 1525 1.1 mrg #undef FIELD_NAME 1526 1.1 mrg #define FIELD_NAME else_node 1527 1.1 mrg #undef FIELD_TYPE 1528 1.1 mrg #define FIELD_TYPE isl_ast_node 1529 1.1 mrg #undef FIELD 1530 1.1 mrg #define FIELD u.i.else_node 1531 1.1 mrg static 1532 1.1 mrg #include "isl_ast_node_set_field_templ.c" 1533 1.1 mrg 1534 1.1 mrg /* Return the else-branch of the if-node "node", 1535 1.1 mrg * This may be either a copy or the branch itself 1536 1.1 mrg * if there is only one reference to "node". 1537 1.1 mrg * This allows the branch to be modified inplace 1538 1.1 mrg * if both "node" and its else-branch have only a single reference. 1539 1.1 mrg * The caller is not allowed to modify "node" between this call and 1540 1.1 mrg * the subsequent call to isl_ast_node_if_restore_else_node. 1541 1.1 mrg * The only exception is that isl_ast_node_free can be called instead. 1542 1.1 mrg */ 1543 1.1 mrg static __isl_give isl_ast_node *isl_ast_node_if_take_else_node( 1544 1.1 mrg __isl_keep isl_ast_node *node) 1545 1.1 mrg { 1546 1.1 mrg isl_ast_node *else_node; 1547 1.1 mrg 1548 1.1 mrg if (isl_ast_node_check_if(node) < 0) 1549 1.1 mrg return NULL; 1550 1.1 mrg if (node->ref != 1) 1551 1.1 mrg return isl_ast_node_if_get_else_node(node); 1552 1.1 mrg else_node = node->u.i.else_node; 1553 1.1 mrg node->u.i.else_node = NULL; 1554 1.1 mrg return else_node; 1555 1.1 mrg } 1556 1.1 mrg 1557 1.1 mrg /* Set the else-branch of the if-node "node" to "child", 1558 1.1 mrg * where the else-branch of "node" may be missing 1559 1.1 mrg * due to a preceding call to isl_ast_node_if_take_else_node. 1560 1.1 mrg * However, in this case, "node" only has a single reference. 1561 1.1 mrg */ 1562 1.1 mrg static __isl_give isl_ast_node *isl_ast_node_if_restore_else_node( 1563 1.1 mrg __isl_take isl_ast_node *node, __isl_take isl_ast_node *child) 1564 1.1 mrg { 1565 1.1 mrg return isl_ast_node_if_set_else_node(node, child); 1566 1.1 mrg } 1567 1.1 mrg 1568 1.1 mrg __isl_give isl_ast_expr *isl_ast_node_if_get_cond( 1569 1.1 mrg __isl_keep isl_ast_node *node) 1570 1.1 mrg { 1571 1.1 mrg if (isl_ast_node_check_if(node) < 0) 1572 1.1 mrg return NULL; 1573 1.1 mrg return isl_ast_expr_copy(node->u.i.guard); 1574 1.1 mrg } 1575 1.1 mrg 1576 1.1 mrg __isl_give isl_ast_node_list *isl_ast_node_block_get_children( 1577 1.1 mrg __isl_keep isl_ast_node *node) 1578 1.1 mrg { 1579 1.1 mrg if (isl_ast_node_check_block(node) < 0) 1580 1.1 mrg return NULL; 1581 1.1 mrg return isl_ast_node_list_copy(node->u.b.children); 1582 1.1 mrg } 1583 1.1 mrg 1584 1.1 mrg #undef NODE_TYPE 1585 1.1 mrg #define NODE_TYPE block 1586 1.1 mrg #undef FIELD_NAME 1587 1.1 mrg #define FIELD_NAME children 1588 1.1 mrg #undef FIELD_TYPE 1589 1.1 mrg #define FIELD_TYPE isl_ast_node_list 1590 1.1 mrg #undef FIELD 1591 1.1 mrg #define FIELD u.b.children 1592 1.1 mrg static 1593 1.1 mrg #include "isl_ast_node_set_field_templ.c" 1594 1.1 mrg 1595 1.1 mrg /* Return the children of the block-node "node", 1596 1.1 mrg * This may be either a copy or the children themselves 1597 1.1 mrg * if there is only one reference to "node". 1598 1.1 mrg * This allows the children to be modified inplace 1599 1.1 mrg * if both "node" and its children have only a single reference. 1600 1.1 mrg * The caller is not allowed to modify "node" between this call and 1601 1.1 mrg * the subsequent call to isl_ast_node_block_restore_children. 1602 1.1 mrg * The only exception is that isl_ast_node_free can be called instead. 1603 1.1 mrg */ 1604 1.1 mrg static __isl_give isl_ast_node_list *isl_ast_node_block_take_children( 1605 1.1 mrg __isl_keep isl_ast_node *node) 1606 1.1 mrg { 1607 1.1 mrg isl_ast_node_list *children; 1608 1.1 mrg 1609 1.1 mrg if (isl_ast_node_check_block(node) < 0) 1610 1.1 mrg return NULL; 1611 1.1 mrg if (node->ref != 1) 1612 1.1 mrg return isl_ast_node_block_get_children(node); 1613 1.1 mrg children = node->u.b.children; 1614 1.1 mrg node->u.b.children = NULL; 1615 1.1 mrg return children; 1616 1.1 mrg } 1617 1.1 mrg 1618 1.1 mrg /* Set the children of the block-node "node" to "children", 1619 1.1 mrg * where the children of "node" may be missing 1620 1.1 mrg * due to a preceding call to isl_ast_node_block_take_children. 1621 1.1 mrg * However, in this case, "node" only has a single reference. 1622 1.1 mrg */ 1623 1.1 mrg static __isl_give isl_ast_node *isl_ast_node_block_restore_children( 1624 1.1 mrg __isl_take isl_ast_node *node, __isl_take isl_ast_node_list *children) 1625 1.1 mrg { 1626 1.1 mrg return isl_ast_node_block_set_children(node, children); 1627 1.1 mrg } 1628 1.1 mrg 1629 1.1 mrg __isl_give isl_ast_expr *isl_ast_node_user_get_expr( 1630 1.1 mrg __isl_keep isl_ast_node *node) 1631 1.1 mrg { 1632 1.1 mrg if (isl_ast_node_check_user(node) < 0) 1633 1.1 mrg return NULL; 1634 1.1 mrg 1635 1.1 mrg return isl_ast_expr_copy(node->u.e.expr); 1636 1.1 mrg } 1637 1.1 mrg 1638 1.1 mrg /* Return the mark identifier of the mark node "node". 1639 1.1 mrg */ 1640 1.1 mrg __isl_give isl_id *isl_ast_node_mark_get_id(__isl_keep isl_ast_node *node) 1641 1.1 mrg { 1642 1.1 mrg if (isl_ast_node_check_mark(node) < 0) 1643 1.1 mrg return NULL; 1644 1.1 mrg 1645 1.1 mrg return isl_id_copy(node->u.m.mark); 1646 1.1 mrg } 1647 1.1 mrg 1648 1.1 mrg /* Return the node marked by mark node "node". 1649 1.1 mrg */ 1650 1.1 mrg __isl_give isl_ast_node *isl_ast_node_mark_get_node( 1651 1.1 mrg __isl_keep isl_ast_node *node) 1652 1.1 mrg { 1653 1.1 mrg if (isl_ast_node_check_mark(node) < 0) 1654 1.1 mrg return NULL; 1655 1.1 mrg 1656 1.1 mrg return isl_ast_node_copy(node->u.m.node); 1657 1.1 mrg } 1658 1.1 mrg 1659 1.1 mrg #undef NODE_TYPE 1660 1.1 mrg #define NODE_TYPE mark 1661 1.1 mrg #undef FIELD_NAME 1662 1.1 mrg #define FIELD_NAME node 1663 1.1 mrg #undef FIELD_TYPE 1664 1.1 mrg #define FIELD_TYPE isl_ast_node 1665 1.1 mrg #undef FIELD 1666 1.1 mrg #define FIELD u.m.node 1667 1.1 mrg static 1668 1.1 mrg #include "isl_ast_node_set_field_templ.c" 1669 1.1 mrg 1670 1.1 mrg /* Return the child of the mark-node "node", 1671 1.1 mrg * This may be either a copy or the child itself 1672 1.1 mrg * if there is only one reference to "node". 1673 1.1 mrg * This allows the child to be modified inplace 1674 1.1 mrg * if both "node" and its child have only a single reference. 1675 1.1 mrg * The caller is not allowed to modify "node" between this call and 1676 1.1 mrg * the subsequent call to isl_ast_node_mark_restore_node. 1677 1.1 mrg * The only exception is that isl_ast_node_free can be called instead. 1678 1.1 mrg */ 1679 1.1 mrg static __isl_give isl_ast_node *isl_ast_node_mark_take_node( 1680 1.1 mrg __isl_keep isl_ast_node *node) 1681 1.1 mrg { 1682 1.1 mrg isl_ast_node *child; 1683 1.1 mrg 1684 1.1 mrg if (isl_ast_node_check_mark(node) < 0) 1685 1.1 mrg return NULL; 1686 1.1 mrg if (node->ref != 1) 1687 1.1 mrg return isl_ast_node_mark_get_node(node); 1688 1.1 mrg child = node->u.m.node; 1689 1.1 mrg node->u.m.node = NULL; 1690 1.1 mrg return child; 1691 1.1 mrg } 1692 1.1 mrg 1693 1.1 mrg /* Set the child of the mark-node "node" to "child", 1694 1.1 mrg * where the child of "node" may be missing 1695 1.1 mrg * due to a preceding call to isl_ast_node_mark_take_node. 1696 1.1 mrg * However, in this case, "node" only has a single reference. 1697 1.1 mrg */ 1698 1.1 mrg static __isl_give isl_ast_node *isl_ast_node_mark_restore_node( 1699 1.1 mrg __isl_take isl_ast_node *node, __isl_take isl_ast_node *child) 1700 1.1 mrg { 1701 1.1 mrg return isl_ast_node_mark_set_node(node, child); 1702 1.1 mrg } 1703 1.1 mrg 1704 1.1 mrg __isl_give isl_id *isl_ast_node_get_annotation(__isl_keep isl_ast_node *node) 1705 1.1 mrg { 1706 1.1 mrg return node ? isl_id_copy(node->annotation) : NULL; 1707 1.1 mrg } 1708 1.1 mrg 1709 1.1 mrg /* Check that "node" is of any type. 1710 1.1 mrg * That is, simply check that it is a valid node. 1711 1.1 mrg */ 1712 1.1 mrg static isl_stat isl_ast_node_check_any(__isl_keep isl_ast_node *node) 1713 1.1 mrg { 1714 1.1 mrg return isl_stat_non_null(node); 1715 1.1 mrg } 1716 1.1 mrg 1717 1.1 mrg #undef NODE_TYPE 1718 1.1 mrg #define NODE_TYPE any 1719 1.1 mrg #undef FIELD_NAME 1720 1.1 mrg #define FIELD_NAME annotation 1721 1.1 mrg #undef FIELD_TYPE 1722 1.1 mrg #define FIELD_TYPE isl_id 1723 1.1 mrg #undef FIELD 1724 1.1 mrg #define FIELD annotation 1725 1.1 mrg static 1726 1.1 mrg #include "isl_ast_node_set_field_templ.c" 1727 1.1 mrg 1728 1.1 mrg /* Replace node->annotation by "annotation". 1729 1.1 mrg */ 1730 1.1 mrg __isl_give isl_ast_node *isl_ast_node_set_annotation( 1731 1.1 mrg __isl_take isl_ast_node *node, __isl_take isl_id *annotation) 1732 1.1 mrg { 1733 1.1 mrg return isl_ast_node_any_set_annotation(node, annotation); 1734 1.1 mrg } 1735 1.1 mrg 1736 1.1 mrg static __isl_give isl_ast_node *traverse(__isl_take isl_ast_node *node, 1737 1.1 mrg __isl_give isl_ast_node *(*enter)(__isl_take isl_ast_node *node, 1738 1.1 mrg int *more, void *user), 1739 1.1 mrg __isl_give isl_ast_node *(*leave)(__isl_take isl_ast_node *node, 1740 1.1 mrg void *user), 1741 1.1 mrg void *user); 1742 1.1 mrg 1743 1.1 mrg /* Traverse the elements of "list" and all their descendants 1744 1.1 mrg * in depth first preorder. Call "enter" whenever a node is entered and "leave" 1745 1.1 mrg * whenever a node is left. 1746 1.1 mrg * 1747 1.1 mrg * Return the updated node. 1748 1.1 mrg */ 1749 1.1 mrg static __isl_give isl_ast_node_list *traverse_list( 1750 1.1 mrg __isl_take isl_ast_node_list *list, 1751 1.1 mrg __isl_give isl_ast_node *(*enter)(__isl_take isl_ast_node *node, 1752 1.1 mrg int *more, void *user), 1753 1.1 mrg __isl_give isl_ast_node *(*leave)(__isl_take isl_ast_node *node, 1754 1.1 mrg void *user), 1755 1.1 mrg void *user) 1756 1.1 mrg { 1757 1.1 mrg int i; 1758 1.1 mrg isl_size n; 1759 1.1 mrg 1760 1.1 mrg n = isl_ast_node_list_size(list); 1761 1.1 mrg if (n < 0) 1762 1.1 mrg return isl_ast_node_list_free(list); 1763 1.1 mrg 1764 1.1 mrg for (i = 0; i < n; ++i) { 1765 1.1 mrg isl_ast_node *node; 1766 1.1 mrg 1767 1.1 mrg node = isl_ast_node_list_get_at(list, i); 1768 1.1 mrg node = traverse(node, enter, leave, user); 1769 1.1 mrg list = isl_ast_node_list_set_at(list, i, node); 1770 1.1 mrg } 1771 1.1 mrg 1772 1.1 mrg return list; 1773 1.1 mrg } 1774 1.1 mrg 1775 1.1 mrg /* Traverse the descendants of "node" (including the node itself) 1776 1.1 mrg * in depth first preorder. Call "enter" whenever a node is entered and "leave" 1777 1.1 mrg * whenever a node is left. 1778 1.1 mrg * 1779 1.1 mrg * If "enter" sets the "more" argument to zero, then the subtree rooted 1780 1.1 mrg * at the given node is skipped. 1781 1.1 mrg * 1782 1.1 mrg * Return the updated node. 1783 1.1 mrg */ 1784 1.1 mrg static __isl_give isl_ast_node *traverse(__isl_take isl_ast_node *node, 1785 1.1 mrg __isl_give isl_ast_node *(*enter)(__isl_take isl_ast_node *node, 1786 1.1 mrg int *more, void *user), 1787 1.1 mrg __isl_give isl_ast_node *(*leave)(__isl_take isl_ast_node *node, 1788 1.1 mrg void *user), 1789 1.1 mrg void *user) 1790 1.1 mrg { 1791 1.1 mrg int more; 1792 1.1 mrg isl_bool has_else; 1793 1.1 mrg isl_ast_node *child; 1794 1.1 mrg isl_ast_node_list *children; 1795 1.1 mrg 1796 1.1 mrg node = enter(node, &more, user); 1797 1.1 mrg if (!node) 1798 1.1 mrg return NULL; 1799 1.1 mrg if (!more) 1800 1.1 mrg return node; 1801 1.1 mrg 1802 1.1 mrg switch (node->type) { 1803 1.1 mrg case isl_ast_node_for: 1804 1.1 mrg child = isl_ast_node_for_take_body(node); 1805 1.1 mrg child = traverse(child, enter, leave, user); 1806 1.1 mrg node = isl_ast_node_for_restore_body(node, child); 1807 1.1 mrg return leave(node, user); 1808 1.1 mrg case isl_ast_node_if: 1809 1.1 mrg child = isl_ast_node_if_take_then_node(node); 1810 1.1 mrg child = traverse(child, enter, leave, user); 1811 1.1 mrg node = isl_ast_node_if_restore_then_node(node, child); 1812 1.1 mrg has_else = isl_ast_node_if_has_else_node(node); 1813 1.1 mrg if (has_else < 0) 1814 1.1 mrg return isl_ast_node_free(node); 1815 1.1 mrg if (!has_else) 1816 1.1 mrg return leave(node, user); 1817 1.1 mrg child = isl_ast_node_if_take_else_node(node); 1818 1.1 mrg child = traverse(child, enter, leave, user); 1819 1.1 mrg node = isl_ast_node_if_restore_else_node(node, child); 1820 1.1 mrg return leave(node, user); 1821 1.1 mrg case isl_ast_node_block: 1822 1.1 mrg children = isl_ast_node_block_take_children(node); 1823 1.1 mrg children = traverse_list(children, enter, leave, user); 1824 1.1 mrg node = isl_ast_node_block_restore_children(node, children); 1825 1.1 mrg return leave(node, user); 1826 1.1 mrg case isl_ast_node_mark: 1827 1.1 mrg child = isl_ast_node_mark_take_node(node); 1828 1.1 mrg child = traverse(child, enter, leave, user); 1829 1.1 mrg node = isl_ast_node_mark_restore_node(node, child); 1830 1.1 mrg return leave(node, user); 1831 1.1 mrg case isl_ast_node_user: 1832 1.1 mrg return leave(node, user); 1833 1.1 mrg case isl_ast_node_error: 1834 1.1 mrg return isl_ast_node_free(node); 1835 1.1 mrg } 1836 1.1 mrg 1837 1.1 mrg return node; 1838 1.1 mrg } 1839 1.1 mrg 1840 1.1 mrg /* Internal data structure storing the arguments of 1841 1.1 mrg * isl_ast_node_foreach_descendant_top_down. 1842 1.1 mrg */ 1843 1.1 mrg struct isl_ast_node_preorder_data { 1844 1.1 mrg isl_bool (*fn)(__isl_keep isl_ast_node *node, void *user); 1845 1.1 mrg void *user; 1846 1.1 mrg }; 1847 1.1 mrg 1848 1.1 mrg /* Enter "node" and set *more to continue traversing its descendants. 1849 1.1 mrg * 1850 1.1 mrg * In the case of a depth first preorder traversal, call data->fn and 1851 1.1 mrg * let it decide whether to continue. 1852 1.1 mrg */ 1853 1.1 mrg static __isl_give isl_ast_node *preorder_enter(__isl_take isl_ast_node *node, 1854 1.1 mrg int *more, void *user) 1855 1.1 mrg { 1856 1.1 mrg struct isl_ast_node_preorder_data *data = user; 1857 1.1 mrg isl_bool m; 1858 1.1 mrg 1859 1.1 mrg if (!node) 1860 1.1 mrg return NULL; 1861 1.1 mrg m = data->fn(node, data->user); 1862 1.1 mrg if (m < 0) 1863 1.1 mrg return isl_ast_node_free(node); 1864 1.1 mrg *more = m; 1865 1.1 mrg return node; 1866 1.1 mrg } 1867 1.1 mrg 1868 1.1 mrg /* Leave "node". 1869 1.1 mrg * 1870 1.1 mrg * In the case of a depth first preorder traversal, nothing needs to be done. 1871 1.1 mrg */ 1872 1.1 mrg static __isl_give isl_ast_node *preorder_leave(__isl_take isl_ast_node *node, 1873 1.1 mrg void *user) 1874 1.1 mrg { 1875 1.1 mrg return node; 1876 1.1 mrg } 1877 1.1 mrg 1878 1.1 mrg /* Traverse the descendants of "node" (including the node itself) 1879 1.1 mrg * in depth first preorder. 1880 1.1 mrg * 1881 1.1 mrg * If "fn" returns isl_bool_error on any of the nodes, then the traversal 1882 1.1 mrg * is aborted. 1883 1.1 mrg * If "fn" returns isl_bool_false on any of the nodes, then the subtree rooted 1884 1.1 mrg * at that node is skipped. 1885 1.1 mrg * 1886 1.1 mrg * Return isl_stat_ok on success and isl_stat_error on failure. 1887 1.1 mrg */ 1888 1.1 mrg isl_stat isl_ast_node_foreach_descendant_top_down( 1889 1.1 mrg __isl_keep isl_ast_node *node, 1890 1.1 mrg isl_bool (*fn)(__isl_keep isl_ast_node *node, void *user), void *user) 1891 1.1 mrg { 1892 1.1 mrg struct isl_ast_node_preorder_data data = { fn, user }; 1893 1.1 mrg 1894 1.1 mrg node = isl_ast_node_copy(node); 1895 1.1 mrg node = traverse(node, &preorder_enter, &preorder_leave, &data); 1896 1.1 mrg isl_ast_node_free(node); 1897 1.1 mrg 1898 1.1 mrg return isl_stat_non_null(node); 1899 1.1 mrg } 1900 1.1 mrg 1901 1.1 mrg /* Internal data structure storing the arguments of 1902 1.1 mrg * isl_ast_node_map_descendant_bottom_up. 1903 1.1 mrg */ 1904 1.1 mrg struct isl_ast_node_postorder_data { 1905 1.1 mrg __isl_give isl_ast_node *(*fn)(__isl_take isl_ast_node *node, 1906 1.1 mrg void *user); 1907 1.1 mrg void *user; 1908 1.1 mrg }; 1909 1.1 mrg 1910 1.1 mrg /* Enter "node" and set *more to continue traversing its descendants. 1911 1.1 mrg * 1912 1.1 mrg * In the case of a depth-first post-order traversal, 1913 1.1 mrg * nothing needs to be done and traversal always continues. 1914 1.1 mrg */ 1915 1.1 mrg static __isl_give isl_ast_node *postorder_enter(__isl_take isl_ast_node *node, 1916 1.1 mrg int *more, void *user) 1917 1.1 mrg { 1918 1.1 mrg *more = 1; 1919 1.1 mrg return node; 1920 1.1 mrg } 1921 1.1 mrg 1922 1.1 mrg /* Leave "node". 1923 1.1 mrg * 1924 1.1 mrg * In the case of a depth-first post-order traversal, call data->fn. 1925 1.1 mrg */ 1926 1.1 mrg static __isl_give isl_ast_node *postorder_leave(__isl_take isl_ast_node *node, 1927 1.1 mrg void *user) 1928 1.1 mrg { 1929 1.1 mrg struct isl_ast_node_postorder_data *data = user; 1930 1.1 mrg 1931 1.1 mrg if (!node) 1932 1.1 mrg return NULL; 1933 1.1 mrg 1934 1.1 mrg node = data->fn(node, data->user); 1935 1.1 mrg return node; 1936 1.1 mrg } 1937 1.1 mrg 1938 1.1 mrg /* Traverse the descendants of "node" (including the node itself) 1939 1.1 mrg * in depth-first post-order, where the user callback is allowed to modify the 1940 1.1 mrg * visited node. 1941 1.1 mrg * 1942 1.1 mrg * Return the updated node. 1943 1.1 mrg */ 1944 1.1 mrg __isl_give isl_ast_node *isl_ast_node_map_descendant_bottom_up( 1945 1.1 mrg __isl_take isl_ast_node *node, 1946 1.1 mrg __isl_give isl_ast_node *(*fn)(__isl_take isl_ast_node *node, 1947 1.1 mrg void *user), void *user) 1948 1.1 mrg { 1949 1.1 mrg struct isl_ast_node_postorder_data data = { fn, user }; 1950 1.1 mrg 1951 1.1 mrg return traverse(node, &postorder_enter, &postorder_leave, &data); 1952 1.1 mrg } 1953 1.1 mrg 1954 1.1 mrg /* Textual C representation of the various operators. 1955 1.1 mrg */ 1956 1.1 mrg static char *op_str_c[] = { 1957 1.1 mrg [isl_ast_expr_op_and] = "&&", 1958 1.1 mrg [isl_ast_expr_op_and_then] = "&&", 1959 1.1 mrg [isl_ast_expr_op_or] = "||", 1960 1.1 mrg [isl_ast_expr_op_or_else] = "||", 1961 1.1 mrg [isl_ast_expr_op_max] = "max", 1962 1.1 mrg [isl_ast_expr_op_min] = "min", 1963 1.1 mrg [isl_ast_expr_op_minus] = "-", 1964 1.1 mrg [isl_ast_expr_op_add] = "+", 1965 1.1 mrg [isl_ast_expr_op_sub] = "-", 1966 1.1 mrg [isl_ast_expr_op_mul] = "*", 1967 1.1 mrg [isl_ast_expr_op_fdiv_q] = "floord", 1968 1.1 mrg [isl_ast_expr_op_pdiv_q] = "/", 1969 1.1 mrg [isl_ast_expr_op_pdiv_r] = "%", 1970 1.1 mrg [isl_ast_expr_op_zdiv_r] = "%", 1971 1.1 mrg [isl_ast_expr_op_div] = "/", 1972 1.1 mrg [isl_ast_expr_op_eq] = "==", 1973 1.1 mrg [isl_ast_expr_op_le] = "<=", 1974 1.1 mrg [isl_ast_expr_op_ge] = ">=", 1975 1.1 mrg [isl_ast_expr_op_lt] = "<", 1976 1.1 mrg [isl_ast_expr_op_gt] = ">", 1977 1.1 mrg [isl_ast_expr_op_member] = ".", 1978 1.1 mrg [isl_ast_expr_op_address_of] = "&" 1979 1.1 mrg }; 1980 1.1 mrg 1981 1.1 mrg /* Precedence in C of the various operators. 1982 1.1 mrg * Based on http://en.wikipedia.org/wiki/Operators_in_C_and_C++ 1983 1.1 mrg * Lowest value means highest precedence. 1984 1.1 mrg */ 1985 1.1 mrg static int op_prec[] = { 1986 1.1 mrg [isl_ast_expr_op_and] = 13, 1987 1.1 mrg [isl_ast_expr_op_and_then] = 13, 1988 1.1 mrg [isl_ast_expr_op_or] = 14, 1989 1.1 mrg [isl_ast_expr_op_or_else] = 14, 1990 1.1 mrg [isl_ast_expr_op_max] = 2, 1991 1.1 mrg [isl_ast_expr_op_min] = 2, 1992 1.1 mrg [isl_ast_expr_op_minus] = 3, 1993 1.1 mrg [isl_ast_expr_op_add] = 6, 1994 1.1 mrg [isl_ast_expr_op_sub] = 6, 1995 1.1 mrg [isl_ast_expr_op_mul] = 5, 1996 1.1 mrg [isl_ast_expr_op_div] = 5, 1997 1.1 mrg [isl_ast_expr_op_fdiv_q] = 2, 1998 1.1 mrg [isl_ast_expr_op_pdiv_q] = 5, 1999 1.1 mrg [isl_ast_expr_op_pdiv_r] = 5, 2000 1.1 mrg [isl_ast_expr_op_zdiv_r] = 5, 2001 1.1 mrg [isl_ast_expr_op_cond] = 15, 2002 1.1 mrg [isl_ast_expr_op_select] = 15, 2003 1.1 mrg [isl_ast_expr_op_eq] = 9, 2004 1.1 mrg [isl_ast_expr_op_le] = 8, 2005 1.1 mrg [isl_ast_expr_op_ge] = 8, 2006 1.1 mrg [isl_ast_expr_op_lt] = 8, 2007 1.1 mrg [isl_ast_expr_op_gt] = 8, 2008 1.1 mrg [isl_ast_expr_op_call] = 2, 2009 1.1 mrg [isl_ast_expr_op_access] = 2, 2010 1.1 mrg [isl_ast_expr_op_member] = 2, 2011 1.1 mrg [isl_ast_expr_op_address_of] = 3 2012 1.1 mrg }; 2013 1.1 mrg 2014 1.1 mrg /* Is the operator left-to-right associative? 2015 1.1 mrg */ 2016 1.1 mrg static int op_left[] = { 2017 1.1 mrg [isl_ast_expr_op_and] = 1, 2018 1.1 mrg [isl_ast_expr_op_and_then] = 1, 2019 1.1 mrg [isl_ast_expr_op_or] = 1, 2020 1.1 mrg [isl_ast_expr_op_or_else] = 1, 2021 1.1 mrg [isl_ast_expr_op_max] = 1, 2022 1.1 mrg [isl_ast_expr_op_min] = 1, 2023 1.1 mrg [isl_ast_expr_op_minus] = 0, 2024 1.1 mrg [isl_ast_expr_op_add] = 1, 2025 1.1 mrg [isl_ast_expr_op_sub] = 1, 2026 1.1 mrg [isl_ast_expr_op_mul] = 1, 2027 1.1 mrg [isl_ast_expr_op_div] = 1, 2028 1.1 mrg [isl_ast_expr_op_fdiv_q] = 1, 2029 1.1 mrg [isl_ast_expr_op_pdiv_q] = 1, 2030 1.1 mrg [isl_ast_expr_op_pdiv_r] = 1, 2031 1.1 mrg [isl_ast_expr_op_zdiv_r] = 1, 2032 1.1 mrg [isl_ast_expr_op_cond] = 0, 2033 1.1 mrg [isl_ast_expr_op_select] = 0, 2034 1.1 mrg [isl_ast_expr_op_eq] = 1, 2035 1.1 mrg [isl_ast_expr_op_le] = 1, 2036 1.1 mrg [isl_ast_expr_op_ge] = 1, 2037 1.1 mrg [isl_ast_expr_op_lt] = 1, 2038 1.1 mrg [isl_ast_expr_op_gt] = 1, 2039 1.1 mrg [isl_ast_expr_op_call] = 1, 2040 1.1 mrg [isl_ast_expr_op_access] = 1, 2041 1.1 mrg [isl_ast_expr_op_member] = 1, 2042 1.1 mrg [isl_ast_expr_op_address_of] = 0 2043 1.1 mrg }; 2044 1.1 mrg 2045 1.1 mrg static int is_and(enum isl_ast_expr_op_type op) 2046 1.1 mrg { 2047 1.1 mrg return op == isl_ast_expr_op_and || op == isl_ast_expr_op_and_then; 2048 1.1 mrg } 2049 1.1 mrg 2050 1.1 mrg static int is_or(enum isl_ast_expr_op_type op) 2051 1.1 mrg { 2052 1.1 mrg return op == isl_ast_expr_op_or || op == isl_ast_expr_op_or_else; 2053 1.1 mrg } 2054 1.1 mrg 2055 1.1 mrg static int is_add_sub(enum isl_ast_expr_op_type op) 2056 1.1 mrg { 2057 1.1 mrg return op == isl_ast_expr_op_add || op == isl_ast_expr_op_sub; 2058 1.1 mrg } 2059 1.1 mrg 2060 1.1 mrg static int is_div_mod(enum isl_ast_expr_op_type op) 2061 1.1 mrg { 2062 1.1 mrg return op == isl_ast_expr_op_div || 2063 1.1 mrg op == isl_ast_expr_op_pdiv_r || 2064 1.1 mrg op == isl_ast_expr_op_zdiv_r; 2065 1.1 mrg } 2066 1.1 mrg 2067 1.1 mrg static __isl_give isl_printer *print_ast_expr_c(__isl_take isl_printer *p, 2068 1.1 mrg __isl_keep isl_ast_expr *expr); 2069 1.1 mrg 2070 1.1 mrg /* Do we need/want parentheses around "expr" as a subexpression of 2071 1.1 mrg * an "op" operation? If "left" is set, then "expr" is the left-most 2072 1.1 mrg * operand. 2073 1.1 mrg * 2074 1.1 mrg * We only need parentheses if "expr" represents an operation. 2075 1.1 mrg * 2076 1.1 mrg * If op has a higher precedence than expr->u.op.op, then we need 2077 1.1 mrg * parentheses. 2078 1.1 mrg * If op and expr->u.op.op have the same precedence, but the operations 2079 1.1 mrg * are performed in an order that is different from the associativity, 2080 1.1 mrg * then we need parentheses. 2081 1.1 mrg * 2082 1.1 mrg * An and inside an or technically does not require parentheses, 2083 1.1 mrg * but some compilers complain about that, so we add them anyway. 2084 1.1 mrg * 2085 1.1 mrg * Computations such as "a / b * c" and "a % b + c" can be somewhat 2086 1.1 mrg * difficult to read, so we add parentheses for those as well. 2087 1.1 mrg */ 2088 1.1 mrg static int sub_expr_need_parens(enum isl_ast_expr_op_type op, 2089 1.1 mrg __isl_keep isl_ast_expr *expr, int left) 2090 1.1 mrg { 2091 1.1 mrg if (expr->type != isl_ast_expr_op) 2092 1.1 mrg return 0; 2093 1.1 mrg 2094 1.1 mrg if (op_prec[expr->u.op.op] > op_prec[op]) 2095 1.1 mrg return 1; 2096 1.1 mrg if (op_prec[expr->u.op.op] == op_prec[op] && left != op_left[op]) 2097 1.1 mrg return 1; 2098 1.1 mrg 2099 1.1 mrg if (is_or(op) && is_and(expr->u.op.op)) 2100 1.1 mrg return 1; 2101 1.1 mrg if (op == isl_ast_expr_op_mul && expr->u.op.op != isl_ast_expr_op_mul && 2102 1.1 mrg op_prec[expr->u.op.op] == op_prec[op]) 2103 1.1 mrg return 1; 2104 1.1 mrg if (is_add_sub(op) && is_div_mod(expr->u.op.op)) 2105 1.1 mrg return 1; 2106 1.1 mrg 2107 1.1 mrg return 0; 2108 1.1 mrg } 2109 1.1 mrg 2110 1.1 mrg /* Print the subexpression at position "pos" of operation expression "expr" 2111 1.1 mrg * in C format. 2112 1.1 mrg * If "left" is set, then "expr" is the left-most operand. 2113 1.1 mrg */ 2114 1.1 mrg static __isl_give isl_printer *print_sub_expr_c(__isl_take isl_printer *p, 2115 1.1 mrg __isl_keep isl_ast_expr *expr, int pos, int left) 2116 1.1 mrg { 2117 1.1 mrg int need_parens; 2118 1.1 mrg isl_ast_expr *arg; 2119 1.1 mrg 2120 1.1 mrg if (!expr) 2121 1.1 mrg return isl_printer_free(p); 2122 1.1 mrg 2123 1.1 mrg arg = isl_ast_expr_list_get_at(expr->u.op.args, pos); 2124 1.1 mrg need_parens = sub_expr_need_parens(expr->u.op.op, arg, left); 2125 1.1 mrg 2126 1.1 mrg if (need_parens) 2127 1.1 mrg p = isl_printer_print_str(p, "("); 2128 1.1 mrg p = print_ast_expr_c(p, arg); 2129 1.1 mrg if (need_parens) 2130 1.1 mrg p = isl_printer_print_str(p, ")"); 2131 1.1 mrg 2132 1.1 mrg isl_ast_expr_free(arg); 2133 1.1 mrg 2134 1.1 mrg return p; 2135 1.1 mrg } 2136 1.1 mrg 2137 1.1 mrg #define isl_ast_expr_op_last isl_ast_expr_op_address_of 2138 1.1 mrg 2139 1.1 mrg /* Data structure that holds the user-specified textual 2140 1.1 mrg * representations for the operators in C format. 2141 1.1 mrg * The entries are either NULL or copies of strings. 2142 1.1 mrg * A NULL entry means that the default name should be used. 2143 1.1 mrg */ 2144 1.1 mrg struct isl_ast_expr_op_names { 2145 1.1 mrg char *op_str[isl_ast_expr_op_last + 1]; 2146 1.1 mrg }; 2147 1.1 mrg 2148 1.1 mrg /* Create an empty struct isl_ast_expr_op_names. 2149 1.1 mrg */ 2150 1.1 mrg static void *create_names(isl_ctx *ctx) 2151 1.1 mrg { 2152 1.1 mrg return isl_calloc_type(ctx, struct isl_ast_expr_op_names); 2153 1.1 mrg } 2154 1.1 mrg 2155 1.1 mrg /* Free a struct isl_ast_expr_op_names along with all memory 2156 1.1 mrg * owned by the struct. 2157 1.1 mrg */ 2158 1.1 mrg static void free_names(void *user) 2159 1.1 mrg { 2160 1.1 mrg int i; 2161 1.1 mrg struct isl_ast_expr_op_names *names = user; 2162 1.1 mrg 2163 1.1 mrg if (!user) 2164 1.1 mrg return; 2165 1.1 mrg 2166 1.1 mrg for (i = 0; i <= isl_ast_expr_op_last; ++i) 2167 1.1 mrg free(names->op_str[i]); 2168 1.1 mrg free(user); 2169 1.1 mrg } 2170 1.1 mrg 2171 1.1 mrg /* Create an identifier that is used to store 2172 1.1 mrg * an isl_ast_expr_op_names note. 2173 1.1 mrg */ 2174 1.1 mrg static __isl_give isl_id *names_id(isl_ctx *ctx) 2175 1.1 mrg { 2176 1.1 mrg return isl_id_alloc(ctx, "isl_ast_expr_op_type_names", NULL); 2177 1.1 mrg } 2178 1.1 mrg 2179 1.1 mrg /* Ensure that "p" has a note identified by "id". 2180 1.1 mrg * If there is no such note yet, then it is created by "note_create" and 2181 1.1 mrg * scheduled do be freed by "note_free". 2182 1.1 mrg */ 2183 1.1 mrg static __isl_give isl_printer *alloc_note(__isl_take isl_printer *p, 2184 1.1 mrg __isl_keep isl_id *id, void *(*note_create)(isl_ctx *), 2185 1.1 mrg void (*note_free)(void *)) 2186 1.1 mrg { 2187 1.1 mrg isl_ctx *ctx; 2188 1.1 mrg isl_id *note_id; 2189 1.1 mrg isl_bool has_note; 2190 1.1 mrg void *note; 2191 1.1 mrg 2192 1.1 mrg has_note = isl_printer_has_note(p, id); 2193 1.1 mrg if (has_note < 0) 2194 1.1 mrg return isl_printer_free(p); 2195 1.1 mrg if (has_note) 2196 1.1 mrg return p; 2197 1.1 mrg 2198 1.1 mrg ctx = isl_printer_get_ctx(p); 2199 1.1 mrg note = note_create(ctx); 2200 1.1 mrg if (!note) 2201 1.1 mrg return isl_printer_free(p); 2202 1.1 mrg note_id = isl_id_alloc(ctx, NULL, note); 2203 1.1 mrg if (!note_id) 2204 1.1 mrg note_free(note); 2205 1.1 mrg else 2206 1.1 mrg note_id = isl_id_set_free_user(note_id, note_free); 2207 1.1 mrg 2208 1.1 mrg p = isl_printer_set_note(p, isl_id_copy(id), note_id); 2209 1.1 mrg 2210 1.1 mrg return p; 2211 1.1 mrg } 2212 1.1 mrg 2213 1.1 mrg /* Ensure that "p" has an isl_ast_expr_op_names note identified by "id". 2214 1.1 mrg */ 2215 1.1 mrg static __isl_give isl_printer *alloc_names(__isl_take isl_printer *p, 2216 1.1 mrg __isl_keep isl_id *id) 2217 1.1 mrg { 2218 1.1 mrg return alloc_note(p, id, &create_names, &free_names); 2219 1.1 mrg } 2220 1.1 mrg 2221 1.1 mrg /* Retrieve the note identified by "id" from "p". 2222 1.1 mrg * The note is assumed to exist. 2223 1.1 mrg */ 2224 1.1 mrg static void *get_note(__isl_keep isl_printer *p, __isl_keep isl_id *id) 2225 1.1 mrg { 2226 1.1 mrg void *note; 2227 1.1 mrg 2228 1.1 mrg id = isl_printer_get_note(p, isl_id_copy(id)); 2229 1.1 mrg note = isl_id_get_user(id); 2230 1.1 mrg isl_id_free(id); 2231 1.1 mrg 2232 1.1 mrg return note; 2233 1.1 mrg } 2234 1.1 mrg 2235 1.1 mrg /* Use "name" to print operations of type "type" to "p". 2236 1.1 mrg * 2237 1.1 mrg * Store the name in an isl_ast_expr_op_names note attached to "p", such that 2238 1.1 mrg * it can be retrieved by get_op_str. 2239 1.1 mrg */ 2240 1.1 mrg __isl_give isl_printer *isl_ast_expr_op_type_set_print_name( 2241 1.1 mrg __isl_take isl_printer *p, enum isl_ast_expr_op_type type, 2242 1.1 mrg __isl_keep const char *name) 2243 1.1 mrg { 2244 1.1 mrg isl_id *id; 2245 1.1 mrg struct isl_ast_expr_op_names *names; 2246 1.1 mrg 2247 1.1 mrg if (!p) 2248 1.1 mrg return NULL; 2249 1.1 mrg if (type > isl_ast_expr_op_last) 2250 1.1 mrg isl_die(isl_printer_get_ctx(p), isl_error_invalid, 2251 1.1 mrg "invalid type", return isl_printer_free(p)); 2252 1.1 mrg 2253 1.1 mrg id = names_id(isl_printer_get_ctx(p)); 2254 1.1 mrg p = alloc_names(p, id); 2255 1.1 mrg names = get_note(p, id); 2256 1.1 mrg isl_id_free(id); 2257 1.1 mrg if (!names) 2258 1.1 mrg return isl_printer_free(p); 2259 1.1 mrg free(names->op_str[type]); 2260 1.1 mrg names->op_str[type] = strdup(name); 2261 1.1 mrg 2262 1.1 mrg return p; 2263 1.1 mrg } 2264 1.1 mrg 2265 1.1 mrg /* This is an alternative name for the function above. 2266 1.1 mrg */ 2267 1.1 mrg __isl_give isl_printer *isl_ast_op_type_set_print_name( 2268 1.1 mrg __isl_take isl_printer *p, enum isl_ast_expr_op_type type, 2269 1.1 mrg __isl_keep const char *name) 2270 1.1 mrg { 2271 1.1 mrg return isl_ast_expr_op_type_set_print_name(p, type, name); 2272 1.1 mrg } 2273 1.1 mrg 2274 1.1 mrg /* Return the textual representation of "type" in C format. 2275 1.1 mrg * 2276 1.1 mrg * If there is a user-specified name in an isl_ast_expr_op_names note 2277 1.1 mrg * associated to "p", then return that. 2278 1.1 mrg * Otherwise, return the default name in op_str_c. 2279 1.1 mrg */ 2280 1.1 mrg static const char *get_op_str_c(__isl_keep isl_printer *p, 2281 1.1 mrg enum isl_ast_expr_op_type type) 2282 1.1 mrg { 2283 1.1 mrg isl_id *id; 2284 1.1 mrg isl_bool has_names; 2285 1.1 mrg struct isl_ast_expr_op_names *names = NULL; 2286 1.1 mrg 2287 1.1 mrg id = names_id(isl_printer_get_ctx(p)); 2288 1.1 mrg has_names = isl_printer_has_note(p, id); 2289 1.1 mrg if (has_names >= 0 && has_names) 2290 1.1 mrg names = get_note(p, id); 2291 1.1 mrg isl_id_free(id); 2292 1.1 mrg if (names && names->op_str[type]) 2293 1.1 mrg return names->op_str[type]; 2294 1.1 mrg return op_str_c[type]; 2295 1.1 mrg } 2296 1.1 mrg 2297 1.1 mrg /* Print the expression at position "pos" in "list" in C format. 2298 1.1 mrg */ 2299 1.1 mrg static __isl_give isl_printer *print_at_c(__isl_take isl_printer *p, 2300 1.1 mrg __isl_keep isl_ast_expr_list *list, int pos) 2301 1.1 mrg { 2302 1.1 mrg isl_ast_expr *expr; 2303 1.1 mrg 2304 1.1 mrg expr = isl_ast_expr_list_get_at(list, pos); 2305 1.1 mrg p = print_ast_expr_c(p, expr); 2306 1.1 mrg isl_ast_expr_free(expr); 2307 1.1 mrg 2308 1.1 mrg return p; 2309 1.1 mrg } 2310 1.1 mrg 2311 1.1 mrg /* Print a min or max reduction "expr" in C format. 2312 1.1 mrg */ 2313 1.1 mrg static __isl_give isl_printer *print_min_max_c(__isl_take isl_printer *p, 2314 1.1 mrg __isl_keep isl_ast_expr *expr) 2315 1.1 mrg { 2316 1.1 mrg int i = 0; 2317 1.1 mrg isl_size n; 2318 1.1 mrg 2319 1.1 mrg n = isl_ast_expr_list_size(expr->u.op.args); 2320 1.1 mrg if (n < 0) 2321 1.1 mrg return isl_printer_free(p); 2322 1.1 mrg 2323 1.1 mrg for (i = 1; i < n; ++i) { 2324 1.1 mrg p = isl_printer_print_str(p, get_op_str_c(p, expr->u.op.op)); 2325 1.1 mrg p = isl_printer_print_str(p, "("); 2326 1.1 mrg } 2327 1.1 mrg p = print_at_c(p, expr->u.op.args, 0); 2328 1.1 mrg for (i = 1; i < n; ++i) { 2329 1.1 mrg p = isl_printer_print_str(p, ", "); 2330 1.1 mrg p = print_at_c(p, expr->u.op.args, i); 2331 1.1 mrg p = isl_printer_print_str(p, ")"); 2332 1.1 mrg } 2333 1.1 mrg 2334 1.1 mrg return p; 2335 1.1 mrg } 2336 1.1 mrg 2337 1.1 mrg /* Print a function call "expr" in C format. 2338 1.1 mrg * 2339 1.1 mrg * The first argument represents the function to be called. 2340 1.1 mrg */ 2341 1.1 mrg static __isl_give isl_printer *print_call_c(__isl_take isl_printer *p, 2342 1.1 mrg __isl_keep isl_ast_expr *expr) 2343 1.1 mrg { 2344 1.1 mrg int i = 0; 2345 1.1 mrg isl_size n; 2346 1.1 mrg 2347 1.1 mrg n = isl_ast_expr_list_size(expr->u.op.args); 2348 1.1 mrg if (n < 0) 2349 1.1 mrg return isl_printer_free(p); 2350 1.1 mrg 2351 1.1 mrg p = print_at_c(p, expr->u.op.args, 0); 2352 1.1 mrg p = isl_printer_print_str(p, "("); 2353 1.1 mrg for (i = 1; i < n; ++i) { 2354 1.1 mrg if (i != 1) 2355 1.1 mrg p = isl_printer_print_str(p, ", "); 2356 1.1 mrg p = print_at_c(p, expr->u.op.args, i); 2357 1.1 mrg } 2358 1.1 mrg p = isl_printer_print_str(p, ")"); 2359 1.1 mrg 2360 1.1 mrg return p; 2361 1.1 mrg } 2362 1.1 mrg 2363 1.1 mrg /* Print an array access "expr" in C format. 2364 1.1 mrg * 2365 1.1 mrg * The first argument represents the array being accessed. 2366 1.1 mrg */ 2367 1.1 mrg static __isl_give isl_printer *print_access_c(__isl_take isl_printer *p, 2368 1.1 mrg __isl_keep isl_ast_expr *expr) 2369 1.1 mrg { 2370 1.1 mrg int i = 0; 2371 1.1 mrg isl_size n; 2372 1.1 mrg 2373 1.1 mrg n = isl_ast_expr_list_size(expr->u.op.args); 2374 1.1 mrg if (n < 0) 2375 1.1 mrg return isl_printer_free(p); 2376 1.1 mrg 2377 1.1 mrg p = print_at_c(p, expr->u.op.args, 0); 2378 1.1 mrg for (i = 1; i < n; ++i) { 2379 1.1 mrg p = isl_printer_print_str(p, "["); 2380 1.1 mrg p = print_at_c(p, expr->u.op.args, i); 2381 1.1 mrg p = isl_printer_print_str(p, "]"); 2382 1.1 mrg } 2383 1.1 mrg 2384 1.1 mrg return p; 2385 1.1 mrg } 2386 1.1 mrg 2387 1.1 mrg /* Print "expr" to "p" in C format. 2388 1.1 mrg */ 2389 1.1 mrg static __isl_give isl_printer *print_ast_expr_c(__isl_take isl_printer *p, 2390 1.1 mrg __isl_keep isl_ast_expr *expr) 2391 1.1 mrg { 2392 1.1 mrg isl_size n; 2393 1.1 mrg 2394 1.1 mrg if (!p) 2395 1.1 mrg return NULL; 2396 1.1 mrg if (!expr) 2397 1.1 mrg return isl_printer_free(p); 2398 1.1 mrg 2399 1.1 mrg switch (expr->type) { 2400 1.1 mrg case isl_ast_expr_op: 2401 1.1 mrg if (expr->u.op.op == isl_ast_expr_op_call) { 2402 1.1 mrg p = print_call_c(p, expr); 2403 1.1 mrg break; 2404 1.1 mrg } 2405 1.1 mrg if (expr->u.op.op == isl_ast_expr_op_access) { 2406 1.1 mrg p = print_access_c(p, expr); 2407 1.1 mrg break; 2408 1.1 mrg } 2409 1.1 mrg n = isl_ast_expr_list_size(expr->u.op.args); 2410 1.1 mrg if (n < 0) 2411 1.1 mrg return isl_printer_free(p); 2412 1.1 mrg if (n == 1) { 2413 1.1 mrg p = isl_printer_print_str(p, 2414 1.1 mrg get_op_str_c(p, expr->u.op.op)); 2415 1.1 mrg p = print_sub_expr_c(p, expr, 0, 0); 2416 1.1 mrg break; 2417 1.1 mrg } 2418 1.1 mrg if (expr->u.op.op == isl_ast_expr_op_fdiv_q) { 2419 1.1 mrg const char *name; 2420 1.1 mrg 2421 1.1 mrg name = get_op_str_c(p, isl_ast_expr_op_fdiv_q); 2422 1.1 mrg p = isl_printer_print_str(p, name); 2423 1.1 mrg p = isl_printer_print_str(p, "("); 2424 1.1 mrg p = print_at_c(p, expr->u.op.args, 0); 2425 1.1 mrg p = isl_printer_print_str(p, ", "); 2426 1.1 mrg p = print_at_c(p, expr->u.op.args, 1); 2427 1.1 mrg p = isl_printer_print_str(p, ")"); 2428 1.1 mrg break; 2429 1.1 mrg } 2430 1.1 mrg if (expr->u.op.op == isl_ast_expr_op_max || 2431 1.1 mrg expr->u.op.op == isl_ast_expr_op_min) { 2432 1.1 mrg p = print_min_max_c(p, expr); 2433 1.1 mrg break; 2434 1.1 mrg } 2435 1.1 mrg if (expr->u.op.op == isl_ast_expr_op_cond || 2436 1.1 mrg expr->u.op.op == isl_ast_expr_op_select) { 2437 1.1 mrg p = print_at_c(p, expr->u.op.args, 0); 2438 1.1 mrg p = isl_printer_print_str(p, " ? "); 2439 1.1 mrg p = print_at_c(p, expr->u.op.args, 1); 2440 1.1 mrg p = isl_printer_print_str(p, " : "); 2441 1.1 mrg p = print_at_c(p, expr->u.op.args, 2); 2442 1.1 mrg break; 2443 1.1 mrg } 2444 1.1 mrg if (n != 2) 2445 1.1 mrg isl_die(isl_printer_get_ctx(p), isl_error_internal, 2446 1.1 mrg "operation should have two arguments", 2447 1.1 mrg return isl_printer_free(p)); 2448 1.1 mrg p = print_sub_expr_c(p, expr, 0, 1); 2449 1.1 mrg if (expr->u.op.op != isl_ast_expr_op_member) 2450 1.1 mrg p = isl_printer_print_str(p, " "); 2451 1.1 mrg p = isl_printer_print_str(p, get_op_str_c(p, expr->u.op.op)); 2452 1.1 mrg if (expr->u.op.op != isl_ast_expr_op_member) 2453 1.1 mrg p = isl_printer_print_str(p, " "); 2454 1.1 mrg p = print_sub_expr_c(p, expr, 1, 0); 2455 1.1 mrg break; 2456 1.1 mrg case isl_ast_expr_id: 2457 1.1 mrg p = isl_printer_print_str(p, isl_id_get_name(expr->u.id)); 2458 1.1 mrg break; 2459 1.1 mrg case isl_ast_expr_int: 2460 1.1 mrg p = isl_printer_print_val(p, expr->u.v); 2461 1.1 mrg break; 2462 1.1 mrg case isl_ast_expr_error: 2463 1.1 mrg break; 2464 1.1 mrg } 2465 1.1 mrg 2466 1.1 mrg return p; 2467 1.1 mrg } 2468 1.1 mrg 2469 1.1 mrg /* Textual representation of the isl_ast_expr_op_type elements 2470 1.1 mrg * for use in a YAML representation of an isl_ast_expr. 2471 1.1 mrg */ 2472 1.1 mrg static char *op_str[] = { 2473 1.1 mrg [isl_ast_expr_op_and] = "and", 2474 1.1 mrg [isl_ast_expr_op_and_then] = "and_then", 2475 1.1 mrg [isl_ast_expr_op_or] = "or", 2476 1.1 mrg [isl_ast_expr_op_or_else] = "or_else", 2477 1.1 mrg [isl_ast_expr_op_max] = "max", 2478 1.1 mrg [isl_ast_expr_op_min] = "min", 2479 1.1 mrg [isl_ast_expr_op_minus] = "minus", 2480 1.1 mrg [isl_ast_expr_op_add] = "add", 2481 1.1 mrg [isl_ast_expr_op_sub] = "sub", 2482 1.1 mrg [isl_ast_expr_op_mul] = "mul", 2483 1.1 mrg [isl_ast_expr_op_div] = "div", 2484 1.1 mrg [isl_ast_expr_op_fdiv_q] = "fdiv_q", 2485 1.1 mrg [isl_ast_expr_op_pdiv_q] = "pdiv_q", 2486 1.1 mrg [isl_ast_expr_op_pdiv_r] = "pdiv_r", 2487 1.1 mrg [isl_ast_expr_op_zdiv_r] = "zdiv_r", 2488 1.1 mrg [isl_ast_expr_op_cond] = "cond", 2489 1.1 mrg [isl_ast_expr_op_select] = "select", 2490 1.1 mrg [isl_ast_expr_op_eq] = "eq", 2491 1.1 mrg [isl_ast_expr_op_le] = "le", 2492 1.1 mrg [isl_ast_expr_op_lt] = "lt", 2493 1.1 mrg [isl_ast_expr_op_ge] = "ge", 2494 1.1 mrg [isl_ast_expr_op_gt] = "gt", 2495 1.1 mrg [isl_ast_expr_op_call] = "call", 2496 1.1 mrg [isl_ast_expr_op_access] = "access", 2497 1.1 mrg [isl_ast_expr_op_member] = "member", 2498 1.1 mrg [isl_ast_expr_op_address_of] = "address_of" 2499 1.1 mrg }; 2500 1.1 mrg 2501 1.1 mrg static __isl_give isl_printer *print_ast_expr_isl(__isl_take isl_printer *p, 2502 1.1 mrg __isl_keep isl_ast_expr *expr); 2503 1.1 mrg 2504 1.1 mrg /* Print the arguments of "expr" to "p" in isl format. 2505 1.1 mrg * 2506 1.1 mrg * If there are no arguments, then nothing needs to be printed. 2507 1.1 mrg * Otherwise add an "args" key to the current mapping with as value 2508 1.1 mrg * the list of arguments of "expr". 2509 1.1 mrg */ 2510 1.1 mrg static __isl_give isl_printer *print_arguments(__isl_take isl_printer *p, 2511 1.1 mrg __isl_keep isl_ast_expr *expr) 2512 1.1 mrg { 2513 1.1 mrg int i; 2514 1.1 mrg isl_size n; 2515 1.1 mrg 2516 1.1 mrg n = isl_ast_expr_get_op_n_arg(expr); 2517 1.1 mrg if (n < 0) 2518 1.1 mrg return isl_printer_free(p); 2519 1.1 mrg if (n == 0) 2520 1.1 mrg return p; 2521 1.1 mrg 2522 1.1 mrg p = isl_printer_print_str(p, "args"); 2523 1.1 mrg p = isl_printer_yaml_next(p); 2524 1.1 mrg p = isl_printer_yaml_start_sequence(p); 2525 1.1 mrg for (i = 0; i < n; ++i) { 2526 1.1 mrg isl_ast_expr *arg; 2527 1.1 mrg 2528 1.1 mrg arg = isl_ast_expr_get_op_arg(expr, i); 2529 1.1 mrg p = print_ast_expr_isl(p, arg); 2530 1.1 mrg isl_ast_expr_free(arg); 2531 1.1 mrg p = isl_printer_yaml_next(p); 2532 1.1 mrg } 2533 1.1 mrg p = isl_printer_yaml_end_sequence(p); 2534 1.1 mrg 2535 1.1 mrg return p; 2536 1.1 mrg } 2537 1.1 mrg 2538 1.1 mrg /* Textual representations of the YAML keys for an isl_ast_expr object. 2539 1.1 mrg */ 2540 1.1 mrg static char *expr_str[] = { 2541 1.1 mrg [isl_ast_expr_op] = "op", 2542 1.1 mrg [isl_ast_expr_id] = "id", 2543 1.1 mrg [isl_ast_expr_int] = "val", 2544 1.1 mrg }; 2545 1.1 mrg 2546 1.1 mrg /* Print "expr" to "p" in isl format. 2547 1.1 mrg * 2548 1.1 mrg * In particular, print the isl_ast_expr as a YAML document. 2549 1.1 mrg */ 2550 1.1 mrg static __isl_give isl_printer *print_ast_expr_isl(__isl_take isl_printer *p, 2551 1.1 mrg __isl_keep isl_ast_expr *expr) 2552 1.1 mrg { 2553 1.1 mrg enum isl_ast_expr_type type; 2554 1.1 mrg enum isl_ast_expr_op_type op; 2555 1.1 mrg isl_id *id; 2556 1.1 mrg isl_val *v; 2557 1.1 mrg 2558 1.1 mrg if (!expr) 2559 1.1 mrg return isl_printer_free(p); 2560 1.1 mrg 2561 1.1 mrg p = isl_printer_yaml_start_mapping(p); 2562 1.1 mrg type = isl_ast_expr_get_type(expr); 2563 1.1 mrg switch (type) { 2564 1.1 mrg case isl_ast_expr_error: 2565 1.1 mrg return isl_printer_free(p); 2566 1.1 mrg case isl_ast_expr_op: 2567 1.1 mrg op = isl_ast_expr_get_op_type(expr); 2568 1.1 mrg if (op == isl_ast_expr_op_error) 2569 1.1 mrg return isl_printer_free(p); 2570 1.1 mrg p = isl_printer_print_str(p, expr_str[type]); 2571 1.1 mrg p = isl_printer_yaml_next(p); 2572 1.1 mrg p = isl_printer_print_str(p, op_str[op]); 2573 1.1 mrg p = isl_printer_yaml_next(p); 2574 1.1 mrg p = print_arguments(p, expr); 2575 1.1 mrg break; 2576 1.1 mrg case isl_ast_expr_id: 2577 1.1 mrg p = isl_printer_print_str(p, expr_str[type]); 2578 1.1 mrg p = isl_printer_yaml_next(p); 2579 1.1 mrg id = isl_ast_expr_get_id(expr); 2580 1.1 mrg p = isl_printer_print_id(p, id); 2581 1.1 mrg isl_id_free(id); 2582 1.1 mrg break; 2583 1.1 mrg case isl_ast_expr_int: 2584 1.1 mrg p = isl_printer_print_str(p, expr_str[type]); 2585 1.1 mrg p = isl_printer_yaml_next(p); 2586 1.1 mrg v = isl_ast_expr_get_val(expr); 2587 1.1 mrg p = isl_printer_print_val(p, v); 2588 1.1 mrg isl_val_free(v); 2589 1.1 mrg break; 2590 1.1 mrg } 2591 1.1 mrg p = isl_printer_yaml_end_mapping(p); 2592 1.1 mrg 2593 1.1 mrg return p; 2594 1.1 mrg } 2595 1.1 mrg 2596 1.1 mrg /* Print "expr" to "p". 2597 1.1 mrg * 2598 1.1 mrg * Only an isl and a C format are supported. 2599 1.1 mrg */ 2600 1.1 mrg __isl_give isl_printer *isl_printer_print_ast_expr(__isl_take isl_printer *p, 2601 1.1 mrg __isl_keep isl_ast_expr *expr) 2602 1.1 mrg { 2603 1.1 mrg int format; 2604 1.1 mrg 2605 1.1 mrg if (!p) 2606 1.1 mrg return NULL; 2607 1.1 mrg 2608 1.1 mrg format = isl_printer_get_output_format(p); 2609 1.1 mrg switch (format) { 2610 1.1 mrg case ISL_FORMAT_ISL: 2611 1.1 mrg p = print_ast_expr_isl(p, expr); 2612 1.1 mrg break; 2613 1.1 mrg case ISL_FORMAT_C: 2614 1.1 mrg p = print_ast_expr_c(p, expr); 2615 1.1 mrg break; 2616 1.1 mrg default: 2617 1.1 mrg isl_die(isl_printer_get_ctx(p), isl_error_unsupported, 2618 1.1 mrg "output format not supported for ast_expr", 2619 1.1 mrg return isl_printer_free(p)); 2620 1.1 mrg } 2621 1.1 mrg 2622 1.1 mrg return p; 2623 1.1 mrg } 2624 1.1 mrg 2625 1.1 mrg #undef KEY 2626 1.1 mrg #define KEY enum isl_ast_expr_op_type 2627 1.1 mrg #undef KEY_ERROR 2628 1.1 mrg #define KEY_ERROR isl_ast_expr_op_error 2629 1.1 mrg #undef KEY_END 2630 1.1 mrg #define KEY_END (isl_ast_expr_op_address_of + 1) 2631 1.1 mrg #undef KEY_STR 2632 1.1 mrg #define KEY_STR op_str 2633 1.1 mrg #undef KEY_EXTRACT 2634 1.1 mrg #define KEY_EXTRACT extract_op_type 2635 1.1 mrg #undef KEY_GET 2636 1.1 mrg #define KEY_GET get_op_type 2637 1.1 mrg #include "extract_key.c" 2638 1.1 mrg 2639 1.1 mrg /* Return the next token, which is assumed to be a key in a YAML mapping, 2640 1.1 mrg * from "s" as a string. 2641 1.1 mrg */ 2642 1.1 mrg static __isl_give char *next_key(__isl_keep isl_stream *s) 2643 1.1 mrg { 2644 1.1 mrg struct isl_token *tok; 2645 1.1 mrg char *str; 2646 1.1 mrg isl_ctx *ctx; 2647 1.1 mrg 2648 1.1 mrg if (!s) 2649 1.1 mrg return NULL; 2650 1.1 mrg tok = isl_stream_next_token(s); 2651 1.1 mrg if (!tok) { 2652 1.1 mrg isl_stream_error(s, NULL, "unexpected EOF"); 2653 1.1 mrg return NULL; 2654 1.1 mrg } 2655 1.1 mrg ctx = isl_stream_get_ctx(s); 2656 1.1 mrg str = isl_token_get_str(ctx, tok); 2657 1.1 mrg isl_token_free(tok); 2658 1.1 mrg return str; 2659 1.1 mrg } 2660 1.1 mrg 2661 1.1 mrg /* Remove the next token, which is assumed to be the key "expected" 2662 1.1 mrg * in a YAML mapping, from "s" and move to the corresponding value. 2663 1.1 mrg */ 2664 1.1 mrg static isl_stat eat_key(__isl_keep isl_stream *s, const char *expected) 2665 1.1 mrg { 2666 1.1 mrg char *str; 2667 1.1 mrg int ok; 2668 1.1 mrg 2669 1.1 mrg str = next_key(s); 2670 1.1 mrg if (!str) 2671 1.1 mrg return isl_stat_error; 2672 1.1 mrg ok = !strcmp(str, expected); 2673 1.1 mrg free(str); 2674 1.1 mrg 2675 1.1 mrg if (!ok) { 2676 1.1 mrg isl_stream_error(s, NULL, "expecting different key"); 2677 1.1 mrg return isl_stat_error; 2678 1.1 mrg } 2679 1.1 mrg 2680 1.1 mrg if (isl_stream_yaml_next(s) < 0) 2681 1.1 mrg return isl_stat_error; 2682 1.1 mrg 2683 1.1 mrg return isl_stat_ok; 2684 1.1 mrg } 2685 1.1 mrg 2686 1.1 mrg #undef EL_BASE 2687 1.1 mrg #define EL_BASE ast_expr 2688 1.1 mrg 2689 1.1 mrg #include <isl_list_read_yaml_templ.c> 2690 1.1 mrg 2691 1.1 mrg /* Read an isl_ast_expr object of type isl_ast_expr_op from "s", 2692 1.1 mrg * where the "op" key has already been read by the caller. 2693 1.1 mrg * 2694 1.1 mrg * Read the operation type and the arguments and 2695 1.1 mrg * return the corresponding isl_ast_expr object. 2696 1.1 mrg */ 2697 1.1 mrg static __isl_give isl_ast_expr *read_op(__isl_keep isl_stream *s) 2698 1.1 mrg { 2699 1.1 mrg enum isl_ast_expr_op_type op; 2700 1.1 mrg isl_ast_expr_list *list; 2701 1.1 mrg 2702 1.1 mrg op = get_op_type(s); 2703 1.1 mrg if (op < 0) 2704 1.1 mrg return NULL; 2705 1.1 mrg if (isl_stream_yaml_next(s) < 0) 2706 1.1 mrg return NULL; 2707 1.1 mrg if (eat_key(s, "args") < 0) 2708 1.1 mrg return NULL; 2709 1.1 mrg 2710 1.1 mrg list = isl_stream_yaml_read_ast_expr_list(s); 2711 1.1 mrg 2712 1.1 mrg return alloc_op(op, list); 2713 1.1 mrg } 2714 1.1 mrg 2715 1.1 mrg /* Read an isl_ast_expr object of type isl_ast_expr_id from "s", 2716 1.1 mrg * where the "id" key has already been read by the caller. 2717 1.1 mrg */ 2718 1.1 mrg static __isl_give isl_ast_expr *read_id(__isl_keep isl_stream *s) 2719 1.1 mrg { 2720 1.1 mrg return isl_ast_expr_from_id(isl_stream_read_id(s)); 2721 1.1 mrg } 2722 1.1 mrg 2723 1.1 mrg /* Read an isl_ast_expr object of type isl_ast_expr_int from "s", 2724 1.1 mrg * where the "val" key has already been read by the caller. 2725 1.1 mrg */ 2726 1.1 mrg static __isl_give isl_ast_expr *read_int(__isl_keep isl_stream *s) 2727 1.1 mrg { 2728 1.1 mrg return isl_ast_expr_from_val(isl_stream_read_val(s)); 2729 1.1 mrg } 2730 1.1 mrg 2731 1.1 mrg #undef KEY 2732 1.1 mrg #define KEY enum isl_ast_expr_type 2733 1.1 mrg #undef KEY_ERROR 2734 1.1 mrg #define KEY_ERROR isl_ast_expr_error 2735 1.1 mrg #undef KEY_END 2736 1.1 mrg #define KEY_END (isl_ast_expr_int + 1) 2737 1.1 mrg #undef KEY_STR 2738 1.1 mrg #define KEY_STR expr_str 2739 1.1 mrg #undef KEY_EXTRACT 2740 1.1 mrg #define KEY_EXTRACT extract_expr_type 2741 1.1 mrg #undef KEY_GET 2742 1.1 mrg #define KEY_GET get_expr_type 2743 1.1 mrg #include "extract_key.c" 2744 1.1 mrg 2745 1.1 mrg /* Read an isl_ast_expr object from "s". 2746 1.1 mrg * 2747 1.1 mrg * The keys in the YAML mapping are assumed to appear 2748 1.1 mrg * in the same order as the one in which they are printed 2749 1.1 mrg * by print_ast_expr_isl. 2750 1.1 mrg * In particular, the isl_ast_expr_op type, which is the only one 2751 1.1 mrg * with more than one element, is identified by the "op" key and 2752 1.1 mrg * not by the "args" key. 2753 1.1 mrg */ 2754 1.1 mrg __isl_give isl_ast_expr *isl_stream_read_ast_expr(__isl_keep isl_stream *s) 2755 1.1 mrg { 2756 1.1 mrg enum isl_ast_expr_type type; 2757 1.1 mrg isl_bool more; 2758 1.1 mrg isl_ast_expr *expr; 2759 1.1 mrg 2760 1.1 mrg if (isl_stream_yaml_read_start_mapping(s)) 2761 1.1 mrg return NULL; 2762 1.1 mrg more = isl_stream_yaml_next(s); 2763 1.1 mrg if (more < 0) 2764 1.1 mrg return NULL; 2765 1.1 mrg if (!more) { 2766 1.1 mrg isl_stream_error(s, NULL, "missing key"); 2767 1.1 mrg return NULL; 2768 1.1 mrg } 2769 1.1 mrg 2770 1.1 mrg type = get_expr_type(s); 2771 1.1 mrg if (type < 0) 2772 1.1 mrg return NULL; 2773 1.1 mrg if (isl_stream_yaml_next(s) < 0) 2774 1.1 mrg return NULL; 2775 1.1 mrg switch (type) { 2776 1.1 mrg case isl_ast_expr_op: 2777 1.1 mrg expr = read_op(s); 2778 1.1 mrg break; 2779 1.1 mrg case isl_ast_expr_id: 2780 1.1 mrg expr = read_id(s); 2781 1.1 mrg break; 2782 1.1 mrg case isl_ast_expr_int: 2783 1.1 mrg expr = read_int(s); 2784 1.1 mrg break; 2785 1.1 mrg case isl_ast_expr_error: 2786 1.1 mrg return NULL; 2787 1.1 mrg } 2788 1.1 mrg 2789 1.1 mrg if (isl_stream_yaml_read_end_mapping(s) < 0) 2790 1.1 mrg return isl_ast_expr_free(expr); 2791 1.1 mrg 2792 1.1 mrg return expr; 2793 1.1 mrg } 2794 1.1 mrg 2795 1.1 mrg static __isl_give isl_printer *print_ast_node_isl(__isl_take isl_printer *p, 2796 1.1 mrg __isl_keep isl_ast_node *node); 2797 1.1 mrg 2798 1.1 mrg /* Print a YAML sequence containing the entries in "list" to "p". 2799 1.1 mrg */ 2800 1.1 mrg static __isl_give isl_printer *print_ast_node_list(__isl_take isl_printer *p, 2801 1.1 mrg __isl_keep isl_ast_node_list *list) 2802 1.1 mrg { 2803 1.1 mrg int i; 2804 1.1 mrg isl_size n; 2805 1.1 mrg 2806 1.1 mrg n = isl_ast_node_list_n_ast_node(list); 2807 1.1 mrg if (n < 0) 2808 1.1 mrg return isl_printer_free(p); 2809 1.1 mrg 2810 1.1 mrg p = isl_printer_yaml_start_sequence(p); 2811 1.1 mrg for (i = 0; i < n; ++i) { 2812 1.1 mrg isl_ast_node *node; 2813 1.1 mrg 2814 1.1 mrg node = isl_ast_node_list_get_ast_node(list, i); 2815 1.1 mrg p = print_ast_node_isl(p, node); 2816 1.1 mrg isl_ast_node_free(node); 2817 1.1 mrg p = isl_printer_yaml_next(p); 2818 1.1 mrg } 2819 1.1 mrg p = isl_printer_yaml_end_sequence(p); 2820 1.1 mrg 2821 1.1 mrg return p; 2822 1.1 mrg } 2823 1.1 mrg 2824 1.1 mrg /* Print "node" to "p" in "isl format". 2825 1.1 mrg * 2826 1.1 mrg * In particular, print the isl_ast_node as a YAML document. 2827 1.1 mrg */ 2828 1.1 mrg static __isl_give isl_printer *print_ast_node_isl(__isl_take isl_printer *p, 2829 1.1 mrg __isl_keep isl_ast_node *node) 2830 1.1 mrg { 2831 1.1 mrg switch (node->type) { 2832 1.1 mrg case isl_ast_node_for: 2833 1.1 mrg p = isl_printer_yaml_start_mapping(p); 2834 1.1 mrg p = isl_printer_print_str(p, "iterator"); 2835 1.1 mrg p = isl_printer_yaml_next(p); 2836 1.1 mrg p = isl_printer_print_ast_expr(p, node->u.f.iterator); 2837 1.1 mrg p = isl_printer_yaml_next(p); 2838 1.1 mrg if (node->u.f.degenerate) { 2839 1.1 mrg p = isl_printer_print_str(p, "value"); 2840 1.1 mrg p = isl_printer_yaml_next(p); 2841 1.1 mrg p = isl_printer_print_ast_expr(p, node->u.f.init); 2842 1.1 mrg p = isl_printer_yaml_next(p); 2843 1.1 mrg } else { 2844 1.1 mrg p = isl_printer_print_str(p, "init"); 2845 1.1 mrg p = isl_printer_yaml_next(p); 2846 1.1 mrg p = isl_printer_print_ast_expr(p, node->u.f.init); 2847 1.1 mrg p = isl_printer_yaml_next(p); 2848 1.1 mrg p = isl_printer_print_str(p, "cond"); 2849 1.1 mrg p = isl_printer_yaml_next(p); 2850 1.1 mrg p = isl_printer_print_ast_expr(p, node->u.f.cond); 2851 1.1 mrg p = isl_printer_yaml_next(p); 2852 1.1 mrg p = isl_printer_print_str(p, "inc"); 2853 1.1 mrg p = isl_printer_yaml_next(p); 2854 1.1 mrg p = isl_printer_print_ast_expr(p, node->u.f.inc); 2855 1.1 mrg p = isl_printer_yaml_next(p); 2856 1.1 mrg } 2857 1.1 mrg if (node->u.f.body) { 2858 1.1 mrg p = isl_printer_print_str(p, "body"); 2859 1.1 mrg p = isl_printer_yaml_next(p); 2860 1.1 mrg p = isl_printer_print_ast_node(p, node->u.f.body); 2861 1.1 mrg p = isl_printer_yaml_next(p); 2862 1.1 mrg } 2863 1.1 mrg p = isl_printer_yaml_end_mapping(p); 2864 1.1 mrg break; 2865 1.1 mrg case isl_ast_node_mark: 2866 1.1 mrg p = isl_printer_yaml_start_mapping(p); 2867 1.1 mrg p = isl_printer_print_str(p, "mark"); 2868 1.1 mrg p = isl_printer_yaml_next(p); 2869 1.1 mrg p = isl_printer_print_id(p, node->u.m.mark); 2870 1.1 mrg p = isl_printer_yaml_next(p); 2871 1.1 mrg p = isl_printer_print_str(p, "node"); 2872 1.1 mrg p = isl_printer_yaml_next(p); 2873 1.1 mrg p = isl_printer_print_ast_node(p, node->u.m.node); 2874 1.1 mrg p = isl_printer_yaml_end_mapping(p); 2875 1.1 mrg break; 2876 1.1 mrg case isl_ast_node_user: 2877 1.1 mrg p = isl_printer_yaml_start_mapping(p); 2878 1.1 mrg p = isl_printer_print_str(p, "user"); 2879 1.1 mrg p = isl_printer_yaml_next(p); 2880 1.1 mrg p = isl_printer_print_ast_expr(p, node->u.e.expr); 2881 1.1 mrg p = isl_printer_yaml_end_mapping(p); 2882 1.1 mrg break; 2883 1.1 mrg case isl_ast_node_if: 2884 1.1 mrg p = isl_printer_yaml_start_mapping(p); 2885 1.1 mrg p = isl_printer_print_str(p, "guard"); 2886 1.1 mrg p = isl_printer_yaml_next(p); 2887 1.1 mrg p = isl_printer_print_ast_expr(p, node->u.i.guard); 2888 1.1 mrg p = isl_printer_yaml_next(p); 2889 1.1 mrg if (node->u.i.then) { 2890 1.1 mrg p = isl_printer_print_str(p, "then"); 2891 1.1 mrg p = isl_printer_yaml_next(p); 2892 1.1 mrg p = isl_printer_print_ast_node(p, node->u.i.then); 2893 1.1 mrg p = isl_printer_yaml_next(p); 2894 1.1 mrg } 2895 1.1 mrg if (node->u.i.else_node) { 2896 1.1 mrg p = isl_printer_print_str(p, "else"); 2897 1.1 mrg p = isl_printer_yaml_next(p); 2898 1.1 mrg p = isl_printer_print_ast_node(p, node->u.i.else_node); 2899 1.1 mrg } 2900 1.1 mrg p = isl_printer_yaml_end_mapping(p); 2901 1.1 mrg break; 2902 1.1 mrg case isl_ast_node_block: 2903 1.1 mrg p = print_ast_node_list(p, node->u.b.children); 2904 1.1 mrg break; 2905 1.1 mrg case isl_ast_node_error: 2906 1.1 mrg break; 2907 1.1 mrg } 2908 1.1 mrg return p; 2909 1.1 mrg } 2910 1.1 mrg 2911 1.1 mrg /* Do we need to print a block around the body "node" of a for or if node? 2912 1.1 mrg * 2913 1.1 mrg * If the node is a block, then we need to print a block. 2914 1.1 mrg * Also if the node is a degenerate for then we will print it as 2915 1.1 mrg * an assignment followed by the body of the for loop, so we need a block 2916 1.1 mrg * as well. 2917 1.1 mrg * If the node is an if node with an else, then we print a block 2918 1.1 mrg * to avoid spurious dangling else warnings emitted by some compilers. 2919 1.1 mrg * If the node is a mark, then in principle, we would have to check 2920 1.1 mrg * the child of the mark node. However, even if the child would not 2921 1.1 mrg * require us to print a block, for readability it is probably best 2922 1.1 mrg * to print a block anyway. 2923 1.1 mrg * If the ast_always_print_block option has been set, then we print a block. 2924 1.1 mrg */ 2925 1.1 mrg static int need_block(__isl_keep isl_ast_node *node) 2926 1.1 mrg { 2927 1.1 mrg isl_ctx *ctx; 2928 1.1 mrg 2929 1.1 mrg if (node->type == isl_ast_node_block) 2930 1.1 mrg return 1; 2931 1.1 mrg if (node->type == isl_ast_node_for && node->u.f.degenerate) 2932 1.1 mrg return 1; 2933 1.1 mrg if (node->type == isl_ast_node_if && node->u.i.else_node) 2934 1.1 mrg return 1; 2935 1.1 mrg if (node->type == isl_ast_node_mark) 2936 1.1 mrg return 1; 2937 1.1 mrg 2938 1.1 mrg ctx = isl_ast_node_get_ctx(node); 2939 1.1 mrg return isl_options_get_ast_always_print_block(ctx); 2940 1.1 mrg } 2941 1.1 mrg 2942 1.1 mrg static __isl_give isl_printer *print_ast_node_c(__isl_take isl_printer *p, 2943 1.1 mrg __isl_keep isl_ast_node *node, 2944 1.1 mrg __isl_keep isl_ast_print_options *options, int in_block, int in_list); 2945 1.1 mrg static __isl_give isl_printer *print_if_c(__isl_take isl_printer *p, 2946 1.1 mrg __isl_keep isl_ast_node *node, 2947 1.1 mrg __isl_keep isl_ast_print_options *options, int new_line, 2948 1.1 mrg int force_block); 2949 1.1 mrg 2950 1.1 mrg /* Print the body "node" of a for or if node. 2951 1.1 mrg * If "else_node" is set, then it is printed as well. 2952 1.1 mrg * If "force_block" is set, then print out the body as a block. 2953 1.1 mrg * 2954 1.1 mrg * We first check if we need to print out a block. 2955 1.1 mrg * We always print out a block if there is an else node to make 2956 1.1 mrg * sure that the else node is matched to the correct if node. 2957 1.1 mrg * For consistency, the corresponding else node is also printed as a block. 2958 1.1 mrg * 2959 1.1 mrg * If the else node is itself an if, then we print it as 2960 1.1 mrg * 2961 1.1 mrg * } else if (..) { 2962 1.1 mrg * } 2963 1.1 mrg * 2964 1.1 mrg * Otherwise the else node is printed as 2965 1.1 mrg * 2966 1.1 mrg * } else { 2967 1.1 mrg * node 2968 1.1 mrg * } 2969 1.1 mrg */ 2970 1.1 mrg static __isl_give isl_printer *print_body_c(__isl_take isl_printer *p, 2971 1.1 mrg __isl_keep isl_ast_node *node, __isl_keep isl_ast_node *else_node, 2972 1.1 mrg __isl_keep isl_ast_print_options *options, int force_block) 2973 1.1 mrg { 2974 1.1 mrg if (!node) 2975 1.1 mrg return isl_printer_free(p); 2976 1.1 mrg 2977 1.1 mrg if (!force_block && !else_node && !need_block(node)) { 2978 1.1 mrg p = isl_printer_end_line(p); 2979 1.1 mrg p = isl_printer_indent(p, 2); 2980 1.1 mrg p = isl_ast_node_print(node, p, 2981 1.1 mrg isl_ast_print_options_copy(options)); 2982 1.1 mrg p = isl_printer_indent(p, -2); 2983 1.1 mrg return p; 2984 1.1 mrg } 2985 1.1 mrg 2986 1.1 mrg p = isl_printer_print_str(p, " {"); 2987 1.1 mrg p = isl_printer_end_line(p); 2988 1.1 mrg p = isl_printer_indent(p, 2); 2989 1.1 mrg p = print_ast_node_c(p, node, options, 1, 0); 2990 1.1 mrg p = isl_printer_indent(p, -2); 2991 1.1 mrg p = isl_printer_start_line(p); 2992 1.1 mrg p = isl_printer_print_str(p, "}"); 2993 1.1 mrg if (else_node) { 2994 1.1 mrg if (else_node->type == isl_ast_node_if) { 2995 1.1 mrg p = isl_printer_print_str(p, " else "); 2996 1.1 mrg p = print_if_c(p, else_node, options, 0, 1); 2997 1.1 mrg } else { 2998 1.1 mrg p = isl_printer_print_str(p, " else"); 2999 1.1 mrg p = print_body_c(p, else_node, NULL, options, 1); 3000 1.1 mrg } 3001 1.1 mrg } else 3002 1.1 mrg p = isl_printer_end_line(p); 3003 1.1 mrg 3004 1.1 mrg return p; 3005 1.1 mrg } 3006 1.1 mrg 3007 1.1 mrg /* Print the start of a compound statement. 3008 1.1 mrg */ 3009 1.1 mrg static __isl_give isl_printer *start_block(__isl_take isl_printer *p) 3010 1.1 mrg { 3011 1.1 mrg p = isl_printer_start_line(p); 3012 1.1 mrg p = isl_printer_print_str(p, "{"); 3013 1.1 mrg p = isl_printer_end_line(p); 3014 1.1 mrg p = isl_printer_indent(p, 2); 3015 1.1 mrg 3016 1.1 mrg return p; 3017 1.1 mrg } 3018 1.1 mrg 3019 1.1 mrg /* Print the end of a compound statement. 3020 1.1 mrg */ 3021 1.1 mrg static __isl_give isl_printer *end_block(__isl_take isl_printer *p) 3022 1.1 mrg { 3023 1.1 mrg p = isl_printer_indent(p, -2); 3024 1.1 mrg p = isl_printer_start_line(p); 3025 1.1 mrg p = isl_printer_print_str(p, "}"); 3026 1.1 mrg p = isl_printer_end_line(p); 3027 1.1 mrg 3028 1.1 mrg return p; 3029 1.1 mrg } 3030 1.1 mrg 3031 1.1 mrg /* Print the for node "node". 3032 1.1 mrg * 3033 1.1 mrg * If the for node is degenerate, it is printed as 3034 1.1 mrg * 3035 1.1 mrg * type iterator = init; 3036 1.1 mrg * body 3037 1.1 mrg * 3038 1.1 mrg * Otherwise, it is printed as 3039 1.1 mrg * 3040 1.1 mrg * for (type iterator = init; cond; iterator += inc) 3041 1.1 mrg * body 3042 1.1 mrg * 3043 1.1 mrg * "in_block" is set if we are currently inside a block. 3044 1.1 mrg * "in_list" is set if the current node is not alone in the block. 3045 1.1 mrg * If we are not in a block or if the current not is not alone in the block 3046 1.1 mrg * then we print a block around a degenerate for loop such that the variable 3047 1.1 mrg * declaration will not conflict with any potential other declaration 3048 1.1 mrg * of the same variable. 3049 1.1 mrg */ 3050 1.1 mrg static __isl_give isl_printer *print_for_c(__isl_take isl_printer *p, 3051 1.1 mrg __isl_keep isl_ast_node *node, 3052 1.1 mrg __isl_keep isl_ast_print_options *options, int in_block, int in_list) 3053 1.1 mrg { 3054 1.1 mrg isl_id *id; 3055 1.1 mrg const char *name; 3056 1.1 mrg const char *type; 3057 1.1 mrg 3058 1.1 mrg type = isl_options_get_ast_iterator_type(isl_printer_get_ctx(p)); 3059 1.1 mrg if (!node->u.f.degenerate) { 3060 1.1 mrg id = isl_ast_expr_get_id(node->u.f.iterator); 3061 1.1 mrg name = isl_id_get_name(id); 3062 1.1 mrg isl_id_free(id); 3063 1.1 mrg p = isl_printer_start_line(p); 3064 1.1 mrg p = isl_printer_print_str(p, "for ("); 3065 1.1 mrg p = isl_printer_print_str(p, type); 3066 1.1 mrg p = isl_printer_print_str(p, " "); 3067 1.1 mrg p = isl_printer_print_str(p, name); 3068 1.1 mrg p = isl_printer_print_str(p, " = "); 3069 1.1 mrg p = isl_printer_print_ast_expr(p, node->u.f.init); 3070 1.1 mrg p = isl_printer_print_str(p, "; "); 3071 1.1 mrg p = isl_printer_print_ast_expr(p, node->u.f.cond); 3072 1.1 mrg p = isl_printer_print_str(p, "; "); 3073 1.1 mrg p = isl_printer_print_str(p, name); 3074 1.1 mrg p = isl_printer_print_str(p, " += "); 3075 1.1 mrg p = isl_printer_print_ast_expr(p, node->u.f.inc); 3076 1.1 mrg p = isl_printer_print_str(p, ")"); 3077 1.1 mrg p = print_body_c(p, node->u.f.body, NULL, options, 0); 3078 1.1 mrg } else { 3079 1.1 mrg id = isl_ast_expr_get_id(node->u.f.iterator); 3080 1.1 mrg name = isl_id_get_name(id); 3081 1.1 mrg isl_id_free(id); 3082 1.1 mrg if (!in_block || in_list) 3083 1.1 mrg p = start_block(p); 3084 1.1 mrg p = isl_printer_start_line(p); 3085 1.1 mrg p = isl_printer_print_str(p, type); 3086 1.1 mrg p = isl_printer_print_str(p, " "); 3087 1.1 mrg p = isl_printer_print_str(p, name); 3088 1.1 mrg p = isl_printer_print_str(p, " = "); 3089 1.1 mrg p = isl_printer_print_ast_expr(p, node->u.f.init); 3090 1.1 mrg p = isl_printer_print_str(p, ";"); 3091 1.1 mrg p = isl_printer_end_line(p); 3092 1.1 mrg p = print_ast_node_c(p, node->u.f.body, options, 1, 0); 3093 1.1 mrg if (!in_block || in_list) 3094 1.1 mrg p = end_block(p); 3095 1.1 mrg } 3096 1.1 mrg 3097 1.1 mrg return p; 3098 1.1 mrg } 3099 1.1 mrg 3100 1.1 mrg /* Print the if node "node". 3101 1.1 mrg * If "new_line" is set then the if node should be printed on a new line. 3102 1.1 mrg * If "force_block" is set, then print out the body as a block. 3103 1.1 mrg */ 3104 1.1 mrg static __isl_give isl_printer *print_if_c(__isl_take isl_printer *p, 3105 1.1 mrg __isl_keep isl_ast_node *node, 3106 1.1 mrg __isl_keep isl_ast_print_options *options, int new_line, 3107 1.1 mrg int force_block) 3108 1.1 mrg { 3109 1.1 mrg if (new_line) 3110 1.1 mrg p = isl_printer_start_line(p); 3111 1.1 mrg p = isl_printer_print_str(p, "if ("); 3112 1.1 mrg p = isl_printer_print_ast_expr(p, node->u.i.guard); 3113 1.1 mrg p = isl_printer_print_str(p, ")"); 3114 1.1 mrg p = print_body_c(p, node->u.i.then, node->u.i.else_node, options, 3115 1.1 mrg force_block); 3116 1.1 mrg 3117 1.1 mrg return p; 3118 1.1 mrg } 3119 1.1 mrg 3120 1.1 mrg /* Print the "node" to "p". 3121 1.1 mrg * 3122 1.1 mrg * "in_block" is set if we are currently inside a block. 3123 1.1 mrg * If so, we do not print a block around the children of a block node. 3124 1.1 mrg * We do this to avoid an extra block around the body of a degenerate 3125 1.1 mrg * for node. 3126 1.1 mrg * 3127 1.1 mrg * "in_list" is set if the current node is not alone in the block. 3128 1.1 mrg */ 3129 1.1 mrg static __isl_give isl_printer *print_ast_node_c(__isl_take isl_printer *p, 3130 1.1 mrg __isl_keep isl_ast_node *node, 3131 1.1 mrg __isl_keep isl_ast_print_options *options, int in_block, int in_list) 3132 1.1 mrg { 3133 1.1 mrg switch (node->type) { 3134 1.1 mrg case isl_ast_node_for: 3135 1.1 mrg if (options->print_for) 3136 1.1 mrg return options->print_for(p, 3137 1.1 mrg isl_ast_print_options_copy(options), 3138 1.1 mrg node, options->print_for_user); 3139 1.1 mrg p = print_for_c(p, node, options, in_block, in_list); 3140 1.1 mrg break; 3141 1.1 mrg case isl_ast_node_if: 3142 1.1 mrg p = print_if_c(p, node, options, 1, 0); 3143 1.1 mrg break; 3144 1.1 mrg case isl_ast_node_block: 3145 1.1 mrg if (!in_block) 3146 1.1 mrg p = start_block(p); 3147 1.1 mrg p = isl_ast_node_list_print(node->u.b.children, p, options); 3148 1.1 mrg if (!in_block) 3149 1.1 mrg p = end_block(p); 3150 1.1 mrg break; 3151 1.1 mrg case isl_ast_node_mark: 3152 1.1 mrg p = isl_printer_start_line(p); 3153 1.1 mrg p = isl_printer_print_str(p, "// "); 3154 1.1 mrg p = isl_printer_print_str(p, isl_id_get_name(node->u.m.mark)); 3155 1.1 mrg p = isl_printer_end_line(p); 3156 1.1 mrg p = print_ast_node_c(p, node->u.m.node, options, 0, in_list); 3157 1.1 mrg break; 3158 1.1 mrg case isl_ast_node_user: 3159 1.1 mrg if (options->print_user) 3160 1.1 mrg return options->print_user(p, 3161 1.1 mrg isl_ast_print_options_copy(options), 3162 1.1 mrg node, options->print_user_user); 3163 1.1 mrg p = isl_printer_start_line(p); 3164 1.1 mrg p = isl_printer_print_ast_expr(p, node->u.e.expr); 3165 1.1 mrg p = isl_printer_print_str(p, ";"); 3166 1.1 mrg p = isl_printer_end_line(p); 3167 1.1 mrg break; 3168 1.1 mrg case isl_ast_node_error: 3169 1.1 mrg break; 3170 1.1 mrg } 3171 1.1 mrg return p; 3172 1.1 mrg } 3173 1.1 mrg 3174 1.1 mrg /* Print the for node "node" to "p". 3175 1.1 mrg */ 3176 1.1 mrg __isl_give isl_printer *isl_ast_node_for_print(__isl_keep isl_ast_node *node, 3177 1.1 mrg __isl_take isl_printer *p, __isl_take isl_ast_print_options *options) 3178 1.1 mrg { 3179 1.1 mrg if (isl_ast_node_check_for(node) < 0 || !options) 3180 1.1 mrg goto error; 3181 1.1 mrg p = print_for_c(p, node, options, 0, 0); 3182 1.1 mrg isl_ast_print_options_free(options); 3183 1.1 mrg return p; 3184 1.1 mrg error: 3185 1.1 mrg isl_ast_print_options_free(options); 3186 1.1 mrg isl_printer_free(p); 3187 1.1 mrg return NULL; 3188 1.1 mrg } 3189 1.1 mrg 3190 1.1 mrg /* Print the if node "node" to "p". 3191 1.1 mrg */ 3192 1.1 mrg __isl_give isl_printer *isl_ast_node_if_print(__isl_keep isl_ast_node *node, 3193 1.1 mrg __isl_take isl_printer *p, __isl_take isl_ast_print_options *options) 3194 1.1 mrg { 3195 1.1 mrg if (isl_ast_node_check_if(node) < 0 || !options) 3196 1.1 mrg goto error; 3197 1.1 mrg p = print_if_c(p, node, options, 1, 0); 3198 1.1 mrg isl_ast_print_options_free(options); 3199 1.1 mrg return p; 3200 1.1 mrg error: 3201 1.1 mrg isl_ast_print_options_free(options); 3202 1.1 mrg isl_printer_free(p); 3203 1.1 mrg return NULL; 3204 1.1 mrg } 3205 1.1 mrg 3206 1.1 mrg /* Print "node" to "p". 3207 1.1 mrg * 3208 1.1 mrg * "node" is assumed to be either the outermost node in an AST or 3209 1.1 mrg * a node that is known not to be a block. 3210 1.1 mrg * If "node" is a block (and is therefore outermost) and 3211 1.1 mrg * if the ast_print_outermost_block options is not set, 3212 1.1 mrg * then act as if the printing occurs inside a block, such 3213 1.1 mrg * that no "extra" block will get printed. 3214 1.1 mrg */ 3215 1.1 mrg __isl_give isl_printer *isl_ast_node_print(__isl_keep isl_ast_node *node, 3216 1.1 mrg __isl_take isl_printer *p, __isl_take isl_ast_print_options *options) 3217 1.1 mrg { 3218 1.1 mrg int in_block = 0; 3219 1.1 mrg 3220 1.1 mrg if (!options || !node) 3221 1.1 mrg goto error; 3222 1.1 mrg if (node->type == isl_ast_node_block) { 3223 1.1 mrg isl_ctx *ctx; 3224 1.1 mrg 3225 1.1 mrg ctx = isl_ast_node_get_ctx(node); 3226 1.1 mrg in_block = !isl_options_get_ast_print_outermost_block(ctx); 3227 1.1 mrg } 3228 1.1 mrg p = print_ast_node_c(p, node, options, in_block, 0); 3229 1.1 mrg isl_ast_print_options_free(options); 3230 1.1 mrg return p; 3231 1.1 mrg error: 3232 1.1 mrg isl_ast_print_options_free(options); 3233 1.1 mrg isl_printer_free(p); 3234 1.1 mrg return NULL; 3235 1.1 mrg } 3236 1.1 mrg 3237 1.1 mrg /* Print "node" to "p". 3238 1.1 mrg */ 3239 1.1 mrg __isl_give isl_printer *isl_printer_print_ast_node(__isl_take isl_printer *p, 3240 1.1 mrg __isl_keep isl_ast_node *node) 3241 1.1 mrg { 3242 1.1 mrg int format; 3243 1.1 mrg isl_ast_print_options *options; 3244 1.1 mrg 3245 1.1 mrg if (!p) 3246 1.1 mrg return NULL; 3247 1.1 mrg 3248 1.1 mrg format = isl_printer_get_output_format(p); 3249 1.1 mrg switch (format) { 3250 1.1 mrg case ISL_FORMAT_ISL: 3251 1.1 mrg p = print_ast_node_isl(p, node); 3252 1.1 mrg break; 3253 1.1 mrg case ISL_FORMAT_C: 3254 1.1 mrg options = isl_ast_print_options_alloc(isl_printer_get_ctx(p)); 3255 1.1 mrg p = isl_ast_node_print(node, p, options); 3256 1.1 mrg break; 3257 1.1 mrg default: 3258 1.1 mrg isl_die(isl_printer_get_ctx(p), isl_error_unsupported, 3259 1.1 mrg "output format not supported for ast_node", 3260 1.1 mrg return isl_printer_free(p)); 3261 1.1 mrg } 3262 1.1 mrg 3263 1.1 mrg return p; 3264 1.1 mrg } 3265 1.1 mrg 3266 1.1 mrg /* Print the list of nodes "list" to "p". 3267 1.1 mrg */ 3268 1.1 mrg __isl_give isl_printer *isl_ast_node_list_print( 3269 1.1 mrg __isl_keep isl_ast_node_list *list, __isl_take isl_printer *p, 3270 1.1 mrg __isl_keep isl_ast_print_options *options) 3271 1.1 mrg { 3272 1.1 mrg int i; 3273 1.1 mrg 3274 1.1 mrg if (!p || !list || !options) 3275 1.1 mrg return isl_printer_free(p); 3276 1.1 mrg 3277 1.1 mrg for (i = 0; i < list->n; ++i) 3278 1.1 mrg p = print_ast_node_c(p, list->p[i], options, 1, 1); 3279 1.1 mrg 3280 1.1 mrg return p; 3281 1.1 mrg } 3282 1.1 mrg 3283 1.1 mrg /* Is the next token on "s" the start of a YAML sequence 3284 1.1 mrg * (rather than a YAML mapping)? 3285 1.1 mrg * 3286 1.1 mrg * A YAML sequence starts with either a '[' or a '-', depending on the format. 3287 1.1 mrg */ 3288 1.1 mrg static isl_bool next_is_sequence(__isl_keep isl_stream *s) 3289 1.1 mrg { 3290 1.1 mrg struct isl_token *tok; 3291 1.1 mrg int type; 3292 1.1 mrg int seq; 3293 1.1 mrg 3294 1.1 mrg tok = isl_stream_next_token(s); 3295 1.1 mrg if (!tok) 3296 1.1 mrg return isl_bool_error; 3297 1.1 mrg type = isl_token_get_type(tok); 3298 1.1 mrg seq = type == '[' || type == '-'; 3299 1.1 mrg isl_stream_push_token(s, tok); 3300 1.1 mrg 3301 1.1 mrg return isl_bool_ok(seq); 3302 1.1 mrg } 3303 1.1 mrg 3304 1.1 mrg #undef EL_BASE 3305 1.1 mrg #define EL_BASE ast_node 3306 1.1 mrg 3307 1.1 mrg #include <isl_list_read_yaml_templ.c> 3308 1.1 mrg 3309 1.1 mrg /* Read an isl_ast_node object of type isl_ast_node_block from "s". 3310 1.1 mrg */ 3311 1.1 mrg static __isl_give isl_ast_node *read_block(__isl_keep isl_stream *s) 3312 1.1 mrg { 3313 1.1 mrg isl_ast_node_list *children; 3314 1.1 mrg 3315 1.1 mrg children = isl_stream_yaml_read_ast_node_list(s); 3316 1.1 mrg return isl_ast_node_block_from_children(children); 3317 1.1 mrg } 3318 1.1 mrg 3319 1.1 mrg /* Textual representation of the first YAML key used 3320 1.1 mrg * while printing an isl_ast_node of a given type. 3321 1.1 mrg * 3322 1.1 mrg * An isl_ast_node of type isl_ast_node_block is not printed 3323 1.1 mrg * as a YAML mapping and is therefore assigned a dummy key. 3324 1.1 mrg */ 3325 1.1 mrg static char *node_first_str[] = { 3326 1.1 mrg [isl_ast_node_for] = "iterator", 3327 1.1 mrg [isl_ast_node_mark] = "mark", 3328 1.1 mrg [isl_ast_node_user] = "user", 3329 1.1 mrg [isl_ast_node_if] = "guard", 3330 1.1 mrg [isl_ast_node_block] = "", 3331 1.1 mrg }; 3332 1.1 mrg 3333 1.1 mrg #undef KEY 3334 1.1 mrg #define KEY enum isl_ast_node_type 3335 1.1 mrg #undef KEY_ERROR 3336 1.1 mrg #define KEY_ERROR isl_ast_node_error 3337 1.1 mrg #undef KEY_END 3338 1.1 mrg #define KEY_END (isl_ast_node_user + 1) 3339 1.1 mrg #undef KEY_STR 3340 1.1 mrg #define KEY_STR node_first_str 3341 1.1 mrg #undef KEY_EXTRACT 3342 1.1 mrg #define KEY_EXTRACT extract_node_type 3343 1.1 mrg #undef KEY_GET 3344 1.1 mrg #define KEY_GET get_node_type 3345 1.1 mrg #include "extract_key.c" 3346 1.1 mrg 3347 1.1 mrg static __isl_give isl_ast_node *read_body(__isl_keep isl_stream *s, 3348 1.1 mrg __isl_take isl_ast_node *node) 3349 1.1 mrg { 3350 1.1 mrg if (eat_key(s, "body") < 0) 3351 1.1 mrg return isl_ast_node_free(node); 3352 1.1 mrg node = isl_ast_node_for_set_body(node, isl_stream_read_ast_node(s)); 3353 1.1 mrg if (isl_stream_yaml_next(s) < 0) 3354 1.1 mrg return isl_ast_node_free(node); 3355 1.1 mrg return node; 3356 1.1 mrg } 3357 1.1 mrg 3358 1.1 mrg /* Read an isl_ast_node object of type isl_ast_node_for from "s", 3359 1.1 mrg * where the initial "iterator" key has already been read by the caller. 3360 1.1 mrg * 3361 1.1 mrg * If the initial value is printed as the value of the key "value", 3362 1.1 mrg * then the for-loop is degenerate and can at most have 3363 1.1 mrg * a further "body" element. 3364 1.1 mrg * Otherwise, the for-loop also has "cond" and "inc" elements. 3365 1.1 mrg */ 3366 1.1 mrg static __isl_give isl_ast_node *read_for(__isl_keep isl_stream *s) 3367 1.1 mrg { 3368 1.1 mrg isl_id *id; 3369 1.1 mrg isl_ast_expr *expr; 3370 1.1 mrg isl_ast_node *node; 3371 1.1 mrg char *key; 3372 1.1 mrg isl_bool more; 3373 1.1 mrg int is_value, is_init; 3374 1.1 mrg 3375 1.1 mrg expr = isl_stream_read_ast_expr(s); 3376 1.1 mrg id = isl_ast_expr_id_get_id(expr); 3377 1.1 mrg isl_ast_expr_free(expr); 3378 1.1 mrg if (!id) 3379 1.1 mrg return NULL; 3380 1.1 mrg if (isl_stream_yaml_next(s) < 0) 3381 1.1 mrg id = isl_id_free(id); 3382 1.1 mrg 3383 1.1 mrg node = isl_ast_node_alloc_for(id); 3384 1.1 mrg 3385 1.1 mrg key = next_key(s); 3386 1.1 mrg if (!key) 3387 1.1 mrg return isl_ast_node_free(node); 3388 1.1 mrg is_value = !strcmp(key, "value"); 3389 1.1 mrg is_init = !strcmp(key, "init"); 3390 1.1 mrg free(key); 3391 1.1 mrg if (!is_value && !is_init) 3392 1.1 mrg isl_die(isl_stream_get_ctx(s), isl_error_invalid, 3393 1.1 mrg "unexpected key", return isl_ast_node_free(node)); 3394 1.1 mrg if (isl_stream_yaml_next(s) < 0) 3395 1.1 mrg return isl_ast_node_free(node); 3396 1.1 mrg node = isl_ast_node_for_set_init(node, isl_stream_read_ast_expr(s)); 3397 1.1 mrg if ((more = isl_stream_yaml_next(s)) < 0) 3398 1.1 mrg return isl_ast_node_free(node); 3399 1.1 mrg if (is_value) { 3400 1.1 mrg node = isl_ast_node_for_mark_degenerate(node); 3401 1.1 mrg if (more) 3402 1.1 mrg node = read_body(s, node); 3403 1.1 mrg return node; 3404 1.1 mrg } 3405 1.1 mrg 3406 1.1 mrg if (eat_key(s, "cond") < 0) 3407 1.1 mrg return isl_ast_node_free(node); 3408 1.1 mrg node = isl_ast_node_for_set_cond(node, isl_stream_read_ast_expr(s)); 3409 1.1 mrg if (isl_stream_yaml_next(s) < 0) 3410 1.1 mrg return isl_ast_node_free(node); 3411 1.1 mrg if (eat_key(s, "inc") < 0) 3412 1.1 mrg return isl_ast_node_free(node); 3413 1.1 mrg node = isl_ast_node_for_set_inc(node, isl_stream_read_ast_expr(s)); 3414 1.1 mrg if ((more = isl_stream_yaml_next(s)) < 0) 3415 1.1 mrg return isl_ast_node_free(node); 3416 1.1 mrg 3417 1.1 mrg if (more) 3418 1.1 mrg node = read_body(s, node); 3419 1.1 mrg 3420 1.1 mrg return node; 3421 1.1 mrg } 3422 1.1 mrg 3423 1.1 mrg /* Read an isl_ast_node object of type isl_ast_node_mark from "s", 3424 1.1 mrg * where the initial "mark" key has already been read by the caller. 3425 1.1 mrg */ 3426 1.1 mrg static __isl_give isl_ast_node *read_mark(__isl_keep isl_stream *s) 3427 1.1 mrg { 3428 1.1 mrg isl_id *id; 3429 1.1 mrg isl_ast_node *node; 3430 1.1 mrg 3431 1.1 mrg id = isl_stream_read_id(s); 3432 1.1 mrg if (!id) 3433 1.1 mrg return NULL; 3434 1.1 mrg if (isl_stream_yaml_next(s) < 0) 3435 1.1 mrg goto error; 3436 1.1 mrg if (eat_key(s, "node") < 0) 3437 1.1 mrg goto error; 3438 1.1 mrg node = isl_stream_read_ast_node(s); 3439 1.1 mrg node = isl_ast_node_alloc_mark(id, node); 3440 1.1 mrg if (isl_stream_yaml_next(s) < 0) 3441 1.1 mrg return isl_ast_node_free(node); 3442 1.1 mrg return node; 3443 1.1 mrg error: 3444 1.1 mrg isl_id_free(id); 3445 1.1 mrg return NULL; 3446 1.1 mrg } 3447 1.1 mrg 3448 1.1 mrg /* Read an isl_ast_node object of type isl_ast_node_user from "s", 3449 1.1 mrg * where the "user" key has already been read by the caller. 3450 1.1 mrg */ 3451 1.1 mrg static __isl_give isl_ast_node *read_user(__isl_keep isl_stream *s) 3452 1.1 mrg { 3453 1.1 mrg isl_ast_node *node; 3454 1.1 mrg 3455 1.1 mrg node = isl_ast_node_alloc_user(isl_stream_read_ast_expr(s)); 3456 1.1 mrg if (isl_stream_yaml_next(s) < 0) 3457 1.1 mrg return isl_ast_node_free(node); 3458 1.1 mrg return node; 3459 1.1 mrg } 3460 1.1 mrg 3461 1.1 mrg /* Read an isl_ast_node object of type isl_ast_node_if from "s", 3462 1.1 mrg * where the initial "guard" key has already been read by the caller. 3463 1.1 mrg */ 3464 1.1 mrg static __isl_give isl_ast_node *read_if(__isl_keep isl_stream *s) 3465 1.1 mrg { 3466 1.1 mrg isl_bool more; 3467 1.1 mrg isl_ast_node *node; 3468 1.1 mrg 3469 1.1 mrg node = isl_ast_node_alloc_if(isl_stream_read_ast_expr(s)); 3470 1.1 mrg if ((more = isl_stream_yaml_next(s)) < 0) 3471 1.1 mrg return isl_ast_node_free(node); 3472 1.1 mrg if (!more) 3473 1.1 mrg return node; 3474 1.1 mrg 3475 1.1 mrg if (eat_key(s, "then") < 0) 3476 1.1 mrg return isl_ast_node_free(node); 3477 1.1 mrg node = isl_ast_node_if_set_then(node, isl_stream_read_ast_node(s)); 3478 1.1 mrg if ((more = isl_stream_yaml_next(s)) < 0) 3479 1.1 mrg return isl_ast_node_free(node); 3480 1.1 mrg if (!more) 3481 1.1 mrg return node; 3482 1.1 mrg 3483 1.1 mrg if (eat_key(s, "else") < 0) 3484 1.1 mrg return isl_ast_node_free(node); 3485 1.1 mrg node = isl_ast_node_if_set_else_node(node, isl_stream_read_ast_node(s)); 3486 1.1 mrg if (isl_stream_yaml_next(s) < 0) 3487 1.1 mrg return isl_ast_node_free(node); 3488 1.1 mrg 3489 1.1 mrg return node; 3490 1.1 mrg } 3491 1.1 mrg 3492 1.1 mrg /* Read an isl_ast_node object from "s". 3493 1.1 mrg * 3494 1.1 mrg * A block node is printed as a YAML sequence by print_ast_node_isl. 3495 1.1 mrg * Every other node type is printed as a YAML mapping. 3496 1.1 mrg * 3497 1.1 mrg * First check if the next element is a sequence and if so, 3498 1.1 mrg * read a block node. 3499 1.1 mrg * Otherwise, read a node based on the first mapping key 3500 1.1 mrg * that is used to print a node type. 3501 1.1 mrg * Note that the keys in the YAML mapping are assumed to appear 3502 1.1 mrg * in the same order as the one in which they are printed 3503 1.1 mrg * by print_ast_node_isl. 3504 1.1 mrg */ 3505 1.1 mrg __isl_give isl_ast_node *isl_stream_read_ast_node(__isl_keep isl_stream *s) 3506 1.1 mrg { 3507 1.1 mrg enum isl_ast_node_type type; 3508 1.1 mrg isl_bool more; 3509 1.1 mrg isl_bool seq; 3510 1.1 mrg isl_ast_node *node; 3511 1.1 mrg 3512 1.1 mrg seq = next_is_sequence(s); 3513 1.1 mrg if (seq < 0) 3514 1.1 mrg return NULL; 3515 1.1 mrg if (seq) 3516 1.1 mrg return read_block(s); 3517 1.1 mrg 3518 1.1 mrg if (isl_stream_yaml_read_start_mapping(s)) 3519 1.1 mrg return NULL; 3520 1.1 mrg more = isl_stream_yaml_next(s); 3521 1.1 mrg if (more < 0) 3522 1.1 mrg return NULL; 3523 1.1 mrg if (!more) { 3524 1.1 mrg isl_stream_error(s, NULL, "missing key"); 3525 1.1 mrg return NULL; 3526 1.1 mrg } 3527 1.1 mrg 3528 1.1 mrg type = get_node_type(s); 3529 1.1 mrg if (type < 0) 3530 1.1 mrg return NULL; 3531 1.1 mrg if (isl_stream_yaml_next(s) < 0) 3532 1.1 mrg return NULL; 3533 1.1 mrg 3534 1.1 mrg switch (type) { 3535 1.1 mrg case isl_ast_node_block: 3536 1.1 mrg isl_die(isl_stream_get_ctx(s), isl_error_internal, 3537 1.1 mrg "block cannot be detected as mapping", 3538 1.1 mrg return NULL); 3539 1.1 mrg case isl_ast_node_for: 3540 1.1 mrg node = read_for(s); 3541 1.1 mrg break; 3542 1.1 mrg case isl_ast_node_mark: 3543 1.1 mrg node = read_mark(s); 3544 1.1 mrg break; 3545 1.1 mrg case isl_ast_node_user: 3546 1.1 mrg node = read_user(s); 3547 1.1 mrg break; 3548 1.1 mrg case isl_ast_node_if: 3549 1.1 mrg node = read_if(s); 3550 1.1 mrg break; 3551 1.1 mrg case isl_ast_node_error: 3552 1.1 mrg return NULL; 3553 1.1 mrg } 3554 1.1 mrg 3555 1.1 mrg if (isl_stream_yaml_read_end_mapping(s) < 0) 3556 1.1 mrg return isl_ast_node_free(node); 3557 1.1 mrg 3558 1.1 mrg return node; 3559 1.1 mrg } 3560 1.1 mrg 3561 1.1 mrg #define ISL_AST_MACRO_FDIV_Q (1 << 0) 3562 1.1 mrg #define ISL_AST_MACRO_MIN (1 << 1) 3563 1.1 mrg #define ISL_AST_MACRO_MAX (1 << 2) 3564 1.1 mrg #define ISL_AST_MACRO_ALL (ISL_AST_MACRO_FDIV_Q | \ 3565 1.1 mrg ISL_AST_MACRO_MIN | \ 3566 1.1 mrg ISL_AST_MACRO_MAX) 3567 1.1 mrg 3568 1.1 mrg static int ast_expr_required_macros(__isl_keep isl_ast_expr *expr, int macros); 3569 1.1 mrg 3570 1.1 mrg /* Wrapper around ast_expr_required_macros for use 3571 1.1 mrg * as an isl_ast_expr_list_foreach callback. 3572 1.1 mrg */ 3573 1.1 mrg static isl_stat entry_required_macros(__isl_take isl_ast_expr *expr, void *user) 3574 1.1 mrg { 3575 1.1 mrg int *macros = user; 3576 1.1 mrg 3577 1.1 mrg *macros = ast_expr_required_macros(expr, *macros); 3578 1.1 mrg isl_ast_expr_free(expr); 3579 1.1 mrg 3580 1.1 mrg return isl_stat_ok; 3581 1.1 mrg } 3582 1.1 mrg 3583 1.1 mrg /* If "expr" contains an isl_ast_expr_op_min, isl_ast_expr_op_max or 3584 1.1 mrg * isl_ast_expr_op_fdiv_q then set the corresponding bit in "macros". 3585 1.1 mrg */ 3586 1.1 mrg static int ast_expr_required_macros(__isl_keep isl_ast_expr *expr, int macros) 3587 1.1 mrg { 3588 1.1 mrg if (macros == ISL_AST_MACRO_ALL) 3589 1.1 mrg return macros; 3590 1.1 mrg 3591 1.1 mrg if (expr->type != isl_ast_expr_op) 3592 1.1 mrg return macros; 3593 1.1 mrg 3594 1.1 mrg if (expr->u.op.op == isl_ast_expr_op_min) 3595 1.1 mrg macros |= ISL_AST_MACRO_MIN; 3596 1.1 mrg if (expr->u.op.op == isl_ast_expr_op_max) 3597 1.1 mrg macros |= ISL_AST_MACRO_MAX; 3598 1.1 mrg if (expr->u.op.op == isl_ast_expr_op_fdiv_q) 3599 1.1 mrg macros |= ISL_AST_MACRO_FDIV_Q; 3600 1.1 mrg 3601 1.1 mrg isl_ast_expr_list_foreach(expr->u.op.args, 3602 1.1 mrg &entry_required_macros, ¯os); 3603 1.1 mrg 3604 1.1 mrg return macros; 3605 1.1 mrg } 3606 1.1 mrg 3607 1.1 mrg static int ast_node_list_required_macros(__isl_keep isl_ast_node_list *list, 3608 1.1 mrg int macros); 3609 1.1 mrg 3610 1.1 mrg /* If "node" contains an isl_ast_expr_op_min, isl_ast_expr_op_max or 3611 1.1 mrg * isl_ast_expr_op_fdiv_q then set the corresponding bit in "macros". 3612 1.1 mrg */ 3613 1.1 mrg static int ast_node_required_macros(__isl_keep isl_ast_node *node, int macros) 3614 1.1 mrg { 3615 1.1 mrg if (macros == ISL_AST_MACRO_ALL) 3616 1.1 mrg return macros; 3617 1.1 mrg 3618 1.1 mrg switch (node->type) { 3619 1.1 mrg case isl_ast_node_for: 3620 1.1 mrg macros = ast_expr_required_macros(node->u.f.init, macros); 3621 1.1 mrg if (!node->u.f.degenerate) { 3622 1.1 mrg macros = ast_expr_required_macros(node->u.f.cond, 3623 1.1 mrg macros); 3624 1.1 mrg macros = ast_expr_required_macros(node->u.f.inc, 3625 1.1 mrg macros); 3626 1.1 mrg } 3627 1.1 mrg macros = ast_node_required_macros(node->u.f.body, macros); 3628 1.1 mrg break; 3629 1.1 mrg case isl_ast_node_if: 3630 1.1 mrg macros = ast_expr_required_macros(node->u.i.guard, macros); 3631 1.1 mrg macros = ast_node_required_macros(node->u.i.then, macros); 3632 1.1 mrg if (node->u.i.else_node) 3633 1.1 mrg macros = ast_node_required_macros(node->u.i.else_node, 3634 1.1 mrg macros); 3635 1.1 mrg break; 3636 1.1 mrg case isl_ast_node_block: 3637 1.1 mrg macros = ast_node_list_required_macros(node->u.b.children, 3638 1.1 mrg macros); 3639 1.1 mrg break; 3640 1.1 mrg case isl_ast_node_mark: 3641 1.1 mrg macros = ast_node_required_macros(node->u.m.node, macros); 3642 1.1 mrg break; 3643 1.1 mrg case isl_ast_node_user: 3644 1.1 mrg macros = ast_expr_required_macros(node->u.e.expr, macros); 3645 1.1 mrg break; 3646 1.1 mrg case isl_ast_node_error: 3647 1.1 mrg break; 3648 1.1 mrg } 3649 1.1 mrg 3650 1.1 mrg return macros; 3651 1.1 mrg } 3652 1.1 mrg 3653 1.1 mrg /* If "list" contains an isl_ast_expr_op_min, isl_ast_expr_op_max or 3654 1.1 mrg * isl_ast_expr_op_fdiv_q then set the corresponding bit in "macros". 3655 1.1 mrg */ 3656 1.1 mrg static int ast_node_list_required_macros(__isl_keep isl_ast_node_list *list, 3657 1.1 mrg int macros) 3658 1.1 mrg { 3659 1.1 mrg int i; 3660 1.1 mrg 3661 1.1 mrg for (i = 0; i < list->n; ++i) 3662 1.1 mrg macros = ast_node_required_macros(list->p[i], macros); 3663 1.1 mrg 3664 1.1 mrg return macros; 3665 1.1 mrg } 3666 1.1 mrg 3667 1.1 mrg /* Data structure for keeping track of whether a macro definition 3668 1.1 mrg * for a given type has already been printed. 3669 1.1 mrg * The value is zero if no definition has been printed and non-zero otherwise. 3670 1.1 mrg */ 3671 1.1 mrg struct isl_ast_expr_op_printed { 3672 1.1 mrg char printed[isl_ast_expr_op_last + 1]; 3673 1.1 mrg }; 3674 1.1 mrg 3675 1.1 mrg /* Create an empty struct isl_ast_expr_op_printed. 3676 1.1 mrg */ 3677 1.1 mrg static void *create_printed(isl_ctx *ctx) 3678 1.1 mrg { 3679 1.1 mrg return isl_calloc_type(ctx, struct isl_ast_expr_op_printed); 3680 1.1 mrg } 3681 1.1 mrg 3682 1.1 mrg /* Free a struct isl_ast_expr_op_printed. 3683 1.1 mrg */ 3684 1.1 mrg static void free_printed(void *user) 3685 1.1 mrg { 3686 1.1 mrg free(user); 3687 1.1 mrg } 3688 1.1 mrg 3689 1.1 mrg /* Ensure that "p" has an isl_ast_expr_op_printed note identified by "id". 3690 1.1 mrg */ 3691 1.1 mrg static __isl_give isl_printer *alloc_printed(__isl_take isl_printer *p, 3692 1.1 mrg __isl_keep isl_id *id) 3693 1.1 mrg { 3694 1.1 mrg return alloc_note(p, id, &create_printed, &free_printed); 3695 1.1 mrg } 3696 1.1 mrg 3697 1.1 mrg /* Create an identifier that is used to store 3698 1.1 mrg * an isl_ast_expr_op_printed note. 3699 1.1 mrg */ 3700 1.1 mrg static __isl_give isl_id *printed_id(isl_ctx *ctx) 3701 1.1 mrg { 3702 1.1 mrg return isl_id_alloc(ctx, "isl_ast_expr_op_type_printed", NULL); 3703 1.1 mrg } 3704 1.1 mrg 3705 1.1 mrg /* Did the user specify that a macro definition should only be 3706 1.1 mrg * printed once and has a macro definition for "type" already 3707 1.1 mrg * been printed to "p"? 3708 1.1 mrg * If definitions should only be printed once, but a definition 3709 1.1 mrg * for "p" has not yet been printed, then mark it as having been 3710 1.1 mrg * printed so that it will not printed again. 3711 1.1 mrg * The actual printing is taken care of by the caller. 3712 1.1 mrg */ 3713 1.1 mrg static isl_bool already_printed_once(__isl_keep isl_printer *p, 3714 1.1 mrg enum isl_ast_expr_op_type type) 3715 1.1 mrg { 3716 1.1 mrg isl_ctx *ctx; 3717 1.1 mrg isl_id *id; 3718 1.1 mrg struct isl_ast_expr_op_printed *printed; 3719 1.1 mrg 3720 1.1 mrg if (!p) 3721 1.1 mrg return isl_bool_error; 3722 1.1 mrg 3723 1.1 mrg ctx = isl_printer_get_ctx(p); 3724 1.1 mrg if (!isl_options_get_ast_print_macro_once(ctx)) 3725 1.1 mrg return isl_bool_false; 3726 1.1 mrg 3727 1.1 mrg if (type > isl_ast_expr_op_last) 3728 1.1 mrg isl_die(isl_printer_get_ctx(p), isl_error_invalid, 3729 1.1 mrg "invalid type", return isl_bool_error); 3730 1.1 mrg 3731 1.1 mrg id = printed_id(isl_printer_get_ctx(p)); 3732 1.1 mrg p = alloc_printed(p, id); 3733 1.1 mrg printed = get_note(p, id); 3734 1.1 mrg isl_id_free(id); 3735 1.1 mrg if (!printed) 3736 1.1 mrg return isl_bool_error; 3737 1.1 mrg 3738 1.1 mrg if (printed->printed[type]) 3739 1.1 mrg return isl_bool_true; 3740 1.1 mrg 3741 1.1 mrg printed->printed[type] = 1; 3742 1.1 mrg return isl_bool_false; 3743 1.1 mrg } 3744 1.1 mrg 3745 1.1 mrg /* Print a macro definition for the operator "type". 3746 1.1 mrg * 3747 1.1 mrg * If the user has specified that a macro definition should 3748 1.1 mrg * only be printed once to any given printer and if the macro definition 3749 1.1 mrg * has already been printed to "p", then do not print the definition. 3750 1.1 mrg */ 3751 1.1 mrg __isl_give isl_printer *isl_ast_expr_op_type_print_macro( 3752 1.1 mrg enum isl_ast_expr_op_type type, __isl_take isl_printer *p) 3753 1.1 mrg { 3754 1.1 mrg isl_bool skip; 3755 1.1 mrg 3756 1.1 mrg skip = already_printed_once(p, type); 3757 1.1 mrg if (skip < 0) 3758 1.1 mrg return isl_printer_free(p); 3759 1.1 mrg if (skip) 3760 1.1 mrg return p; 3761 1.1 mrg 3762 1.1 mrg switch (type) { 3763 1.1 mrg case isl_ast_expr_op_min: 3764 1.1 mrg p = isl_printer_start_line(p); 3765 1.1 mrg p = isl_printer_print_str(p, "#define "); 3766 1.1 mrg p = isl_printer_print_str(p, get_op_str_c(p, type)); 3767 1.1 mrg p = isl_printer_print_str(p, 3768 1.1 mrg "(x,y) ((x) < (y) ? (x) : (y))"); 3769 1.1 mrg p = isl_printer_end_line(p); 3770 1.1 mrg break; 3771 1.1 mrg case isl_ast_expr_op_max: 3772 1.1 mrg p = isl_printer_start_line(p); 3773 1.1 mrg p = isl_printer_print_str(p, "#define "); 3774 1.1 mrg p = isl_printer_print_str(p, get_op_str_c(p, type)); 3775 1.1 mrg p = isl_printer_print_str(p, 3776 1.1 mrg "(x,y) ((x) > (y) ? (x) : (y))"); 3777 1.1 mrg p = isl_printer_end_line(p); 3778 1.1 mrg break; 3779 1.1 mrg case isl_ast_expr_op_fdiv_q: 3780 1.1 mrg p = isl_printer_start_line(p); 3781 1.1 mrg p = isl_printer_print_str(p, "#define "); 3782 1.1 mrg p = isl_printer_print_str(p, get_op_str_c(p, type)); 3783 1.1 mrg p = isl_printer_print_str(p, 3784 1.1 mrg "(n,d) " 3785 1.1 mrg "(((n)<0) ? -((-(n)+(d)-1)/(d)) : (n)/(d))"); 3786 1.1 mrg p = isl_printer_end_line(p); 3787 1.1 mrg break; 3788 1.1 mrg default: 3789 1.1 mrg break; 3790 1.1 mrg } 3791 1.1 mrg 3792 1.1 mrg return p; 3793 1.1 mrg } 3794 1.1 mrg 3795 1.1 mrg /* This is an alternative name for the function above. 3796 1.1 mrg */ 3797 1.1 mrg __isl_give isl_printer *isl_ast_op_type_print_macro( 3798 1.1 mrg enum isl_ast_expr_op_type type, __isl_take isl_printer *p) 3799 1.1 mrg { 3800 1.1 mrg return isl_ast_expr_op_type_print_macro(type, p); 3801 1.1 mrg } 3802 1.1 mrg 3803 1.1 mrg /* Call "fn" for each type of operation represented in the "macros" 3804 1.1 mrg * bit vector. 3805 1.1 mrg */ 3806 1.1 mrg static isl_stat foreach_ast_expr_op_type(int macros, 3807 1.1 mrg isl_stat (*fn)(enum isl_ast_expr_op_type type, void *user), void *user) 3808 1.1 mrg { 3809 1.1 mrg if (macros & ISL_AST_MACRO_MIN && fn(isl_ast_expr_op_min, user) < 0) 3810 1.1 mrg return isl_stat_error; 3811 1.1 mrg if (macros & ISL_AST_MACRO_MAX && fn(isl_ast_expr_op_max, user) < 0) 3812 1.1 mrg return isl_stat_error; 3813 1.1 mrg if (macros & ISL_AST_MACRO_FDIV_Q && 3814 1.1 mrg fn(isl_ast_expr_op_fdiv_q, user) < 0) 3815 1.1 mrg return isl_stat_error; 3816 1.1 mrg 3817 1.1 mrg return isl_stat_ok; 3818 1.1 mrg } 3819 1.1 mrg 3820 1.1 mrg /* Call "fn" for each type of operation that appears in "expr" 3821 1.1 mrg * and that requires a macro definition. 3822 1.1 mrg */ 3823 1.1 mrg isl_stat isl_ast_expr_foreach_ast_expr_op_type(__isl_keep isl_ast_expr *expr, 3824 1.1 mrg isl_stat (*fn)(enum isl_ast_expr_op_type type, void *user), void *user) 3825 1.1 mrg { 3826 1.1 mrg int macros; 3827 1.1 mrg 3828 1.1 mrg if (!expr) 3829 1.1 mrg return isl_stat_error; 3830 1.1 mrg 3831 1.1 mrg macros = ast_expr_required_macros(expr, 0); 3832 1.1 mrg return foreach_ast_expr_op_type(macros, fn, user); 3833 1.1 mrg } 3834 1.1 mrg 3835 1.1 mrg /* This is an alternative name for the function above. 3836 1.1 mrg */ 3837 1.1 mrg isl_stat isl_ast_expr_foreach_ast_op_type(__isl_keep isl_ast_expr *expr, 3838 1.1 mrg isl_stat (*fn)(enum isl_ast_expr_op_type type, void *user), void *user) 3839 1.1 mrg { 3840 1.1 mrg return isl_ast_expr_foreach_ast_expr_op_type(expr, fn, user); 3841 1.1 mrg } 3842 1.1 mrg 3843 1.1 mrg /* Call "fn" for each type of operation that appears in "node" 3844 1.1 mrg * and that requires a macro definition. 3845 1.1 mrg */ 3846 1.1 mrg isl_stat isl_ast_node_foreach_ast_expr_op_type(__isl_keep isl_ast_node *node, 3847 1.1 mrg isl_stat (*fn)(enum isl_ast_expr_op_type type, void *user), void *user) 3848 1.1 mrg { 3849 1.1 mrg int macros; 3850 1.1 mrg 3851 1.1 mrg if (!node) 3852 1.1 mrg return isl_stat_error; 3853 1.1 mrg 3854 1.1 mrg macros = ast_node_required_macros(node, 0); 3855 1.1 mrg return foreach_ast_expr_op_type(macros, fn, user); 3856 1.1 mrg } 3857 1.1 mrg 3858 1.1 mrg /* This is an alternative name for the function above. 3859 1.1 mrg */ 3860 1.1 mrg isl_stat isl_ast_node_foreach_ast_op_type(__isl_keep isl_ast_node *node, 3861 1.1 mrg isl_stat (*fn)(enum isl_ast_expr_op_type type, void *user), void *user) 3862 1.1 mrg { 3863 1.1 mrg return isl_ast_node_foreach_ast_expr_op_type(node, fn, user); 3864 1.1 mrg } 3865 1.1 mrg 3866 1.1 mrg static isl_stat ast_op_type_print_macro(enum isl_ast_expr_op_type type, 3867 1.1 mrg void *user) 3868 1.1 mrg { 3869 1.1 mrg isl_printer **p = user; 3870 1.1 mrg 3871 1.1 mrg *p = isl_ast_expr_op_type_print_macro(type, *p); 3872 1.1 mrg 3873 1.1 mrg return isl_stat_ok; 3874 1.1 mrg } 3875 1.1 mrg 3876 1.1 mrg /* Print macro definitions for all the macros used in the result 3877 1.1 mrg * of printing "expr". 3878 1.1 mrg */ 3879 1.1 mrg __isl_give isl_printer *isl_ast_expr_print_macros( 3880 1.1 mrg __isl_keep isl_ast_expr *expr, __isl_take isl_printer *p) 3881 1.1 mrg { 3882 1.1 mrg if (isl_ast_expr_foreach_ast_expr_op_type(expr, 3883 1.1 mrg &ast_op_type_print_macro, &p) < 0) 3884 1.1 mrg return isl_printer_free(p); 3885 1.1 mrg return p; 3886 1.1 mrg } 3887 1.1 mrg 3888 1.1 mrg /* Print macro definitions for all the macros used in the result 3889 1.1 mrg * of printing "node". 3890 1.1 mrg */ 3891 1.1 mrg __isl_give isl_printer *isl_ast_node_print_macros( 3892 1.1 mrg __isl_keep isl_ast_node *node, __isl_take isl_printer *p) 3893 1.1 mrg { 3894 1.1 mrg if (isl_ast_node_foreach_ast_expr_op_type(node, 3895 1.1 mrg &ast_op_type_print_macro, &p) < 0) 3896 1.1 mrg return isl_printer_free(p); 3897 1.1 mrg return p; 3898 1.1 mrg } 3899 1.1 mrg 3900 1.1 mrg /* Return a string containing C code representing this isl_ast_expr. 3901 1.1 mrg */ 3902 1.1 mrg __isl_give char *isl_ast_expr_to_C_str(__isl_keep isl_ast_expr *expr) 3903 1.1 mrg { 3904 1.1 mrg isl_printer *p; 3905 1.1 mrg char *str; 3906 1.1 mrg 3907 1.1 mrg if (!expr) 3908 1.1 mrg return NULL; 3909 1.1 mrg 3910 1.1 mrg p = isl_printer_to_str(isl_ast_expr_get_ctx(expr)); 3911 1.1 mrg p = isl_printer_set_output_format(p, ISL_FORMAT_C); 3912 1.1 mrg p = isl_printer_print_ast_expr(p, expr); 3913 1.1 mrg 3914 1.1 mrg str = isl_printer_get_str(p); 3915 1.1 mrg 3916 1.1 mrg isl_printer_free(p); 3917 1.1 mrg 3918 1.1 mrg return str; 3919 1.1 mrg } 3920 1.1 mrg 3921 1.1 mrg /* Return a string containing C code representing this isl_ast_node. 3922 1.1 mrg */ 3923 1.1 mrg __isl_give char *isl_ast_node_to_C_str(__isl_keep isl_ast_node *node) 3924 1.1 mrg { 3925 1.1 mrg isl_printer *p; 3926 1.1 mrg char *str; 3927 1.1 mrg 3928 1.1 mrg if (!node) 3929 1.1 mrg return NULL; 3930 1.1 mrg 3931 1.1 mrg p = isl_printer_to_str(isl_ast_node_get_ctx(node)); 3932 1.1 mrg p = isl_printer_set_output_format(p, ISL_FORMAT_C); 3933 1.1 mrg p = isl_printer_print_ast_node(p, node); 3934 1.1 mrg 3935 1.1 mrg str = isl_printer_get_str(p); 3936 1.1 mrg 3937 1.1 mrg isl_printer_free(p); 3938 1.1 mrg 3939 1.1 mrg return str; 3940 1.1 mrg } 3941