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