1 /* jit-builtins.c -- Handling of builtin functions during JIT-compilation. 2 Copyright (C) 2014-2017 Free Software Foundation, Inc. 3 4 This file is part of GCC. 5 6 GCC is free software; you can redistribute it and/or modify it under 7 the terms of the GNU General Public License as published by the Free 8 Software Foundation; either version 3, or (at your option) any later 9 version. 10 11 GCC is distributed in the hope that it will be useful, but WITHOUT ANY 12 WARRANTY; without even the implied warranty of MERCHANTABILITY or 13 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 14 for more details. 15 16 You should have received a copy of the GNU General Public License 17 along with GCC; see the file COPYING3. If not see 18 <http://www.gnu.org/licenses/>. */ 19 20 #include "config.h" 21 #include "system.h" 22 #include "coretypes.h" 23 #include "target.h" 24 #include "jit-playback.h" 25 #include "stringpool.h" 26 27 #include "jit-builtins.h" 28 29 namespace gcc { 30 31 namespace jit { 32 33 const char *const prefix = "__builtin_"; 34 const size_t prefix_len = strlen (prefix); 35 36 /* Create "builtin_data", a const table of the data within builtins.def. */ 37 struct builtin_data 38 { 39 const char *name; 40 enum built_in_class fnclass; 41 enum jit_builtin_type type; 42 bool both_p; 43 bool fallback_p; 44 enum built_in_attribute attr; 45 bool implicit_p; 46 47 const char *get_asm_name () const 48 { 49 if (both_p && fallback_p) 50 return name + prefix_len; 51 else 52 return name; 53 } 54 }; 55 56 #define DEF_BUILTIN(X, NAME, CLASS, TYPE, LT, BOTH_P, FALLBACK_P, \ 57 NONANSI_P, ATTRS, IMPLICIT, COND) \ 58 {NAME, CLASS, TYPE, BOTH_P, FALLBACK_P, ATTRS, IMPLICIT}, 59 static const struct builtin_data builtin_data[] = 60 { 61 #include "builtins.def" 62 }; 63 64 /* Helper function for find_builtin_by_name. */ 65 66 static bool 67 matches_builtin (const char *in_name, 68 const struct builtin_data& bd) 69 { 70 const bool debug = 0; 71 gcc_assert (bd.name); 72 73 if (debug) 74 fprintf (stderr, "seen builtin: %s\n", bd.name); 75 76 if (0 == strcmp (bd.name, in_name)) 77 { 78 return true; 79 } 80 81 if (bd.both_p) 82 { 83 /* Then the macros in builtins.def gave a "__builtin_" 84 prefix to bd.name, but we should also recognize the form 85 without the prefix. */ 86 gcc_assert (0 == strncmp (bd.name, prefix, prefix_len)); 87 if (debug) 88 fprintf (stderr, "testing without prefix as: %s\n", 89 bd.name + prefix_len); 90 if (0 == strcmp (bd.name + prefix_len, in_name)) 91 { 92 return true; 93 } 94 } 95 96 return false; 97 } 98 99 /* Locate the built-in function that matches name IN_NAME, 100 writing the result to OUT_ID and returning true if found, 101 or returning false if not found. */ 102 103 static bool 104 find_builtin_by_name (const char *in_name, 105 enum built_in_function *out_id) 106 { 107 /* Locate builtin. This currently works by performing repeated 108 strcmp against every possible candidate, which is likely to 109 inefficient. 110 111 We start at index 1 to skip the initial entry (BUILT_IN_NONE), which 112 has a NULL name. */ 113 for (unsigned int i = 1; 114 i < sizeof (builtin_data) / sizeof (builtin_data[0]); 115 i++) 116 { 117 const struct builtin_data& bd = builtin_data[i]; 118 if (matches_builtin (in_name, bd)) 119 { 120 /* Found a match. */ 121 *out_id = static_cast<enum built_in_function> (i); 122 return true; 123 } 124 } 125 126 /* Not found. */ 127 return false; 128 } 129 130 // class builtins_manager 131 132 /* Constructor for gcc::jit::builtins_manager. */ 133 134 builtins_manager::builtins_manager (recording::context *ctxt) 135 : m_ctxt (ctxt) 136 { 137 memset (m_types, 0, sizeof (m_types)); 138 memset (m_builtin_functions, 0, sizeof (m_builtin_functions)); 139 memset (m_attributes, 0, sizeof (m_attributes)); 140 } 141 142 /* Locate a builtin function by name. 143 Create a recording::function of the appropriate type, reusing them 144 if they've already been seen. */ 145 146 recording::function * 147 builtins_manager::get_builtin_function (const char *name) 148 { 149 enum built_in_function builtin_id; 150 if (!find_builtin_by_name (name, &builtin_id)) 151 { 152 m_ctxt->add_error (NULL, "builtin \"%s\" not found", name); 153 return NULL; 154 } 155 156 return get_builtin_function_by_id (builtin_id); 157 } 158 159 /* Locate a builtin function by id. 160 Create a recording::function of the appropriate type, reusing them 161 if they've already been seen. */ 162 163 recording::function * 164 builtins_manager::get_builtin_function_by_id (enum built_in_function builtin_id) 165 { 166 gcc_assert (builtin_id >= 0); 167 gcc_assert (builtin_id < END_BUILTINS); 168 169 /* Lazily build the functions, caching them so that repeated calls for 170 the same id on a context give back the same object. */ 171 if (!m_builtin_functions[builtin_id]) 172 { 173 recording::function *fn = make_builtin_function (builtin_id); 174 if (fn) 175 { 176 m_builtin_functions[builtin_id] = fn; 177 m_ctxt->record (fn); 178 } 179 } 180 181 return m_builtin_functions[builtin_id]; 182 } 183 184 /* Create the recording::function for a given builtin function, by ID. */ 185 186 recording::function * 187 builtins_manager::make_builtin_function (enum built_in_function builtin_id) 188 { 189 const struct builtin_data& bd = builtin_data[builtin_id]; 190 enum jit_builtin_type type_id = bd.type; 191 recording::type *t = get_type (type_id); 192 if (!t) 193 return NULL; 194 recording::function_type *func_type = t->as_a_function_type (); 195 if (!func_type) 196 return NULL; 197 198 vec<recording::type *> param_types = func_type->get_param_types (); 199 recording::param **params = new recording::param *[param_types.length ()]; 200 201 int i; 202 recording::type *param_type; 203 FOR_EACH_VEC_ELT (param_types, i, param_type) 204 { 205 char buf[16]; 206 snprintf (buf, 16, "arg%d", i); 207 params[i] = m_ctxt->new_param (NULL, 208 param_type, 209 buf); 210 } 211 const char *asm_name = bd.get_asm_name (); 212 recording::function *result = 213 new recording::function (m_ctxt, 214 NULL, 215 GCC_JIT_FUNCTION_IMPORTED, // FIXME 216 func_type->get_return_type (), 217 m_ctxt->new_string (asm_name), 218 param_types.length (), 219 params, 220 func_type->is_variadic (), 221 builtin_id); 222 delete[] params; 223 224 /* PR/64020 - If the client code is using builtin cos or sin, 225 tree-ssa-math-opt.c's execute_cse_sincos_1 may attempt 226 to optimize them to use __builtin_cexpi; for this, 227 BUILT_IN_CEXPI needs to exist. 228 229 Hence query the cache for BUILT_IN_CEXPI to ensure it gets 230 built. */ 231 if (builtin_id == BUILT_IN_COS || builtin_id == BUILT_IN_SIN) 232 (void)get_builtin_function_by_id (BUILT_IN_CEXPI); 233 234 /* builtins.c:expand_builtin_cexpi can optimize the various 235 CEXP builtins to SINCOS builtins, and hence we may require 236 SINCOS builtins latter. 237 238 Ensure the appropriate SINCOS builtin exists. */ 239 if (builtin_id == BUILT_IN_CEXPIF) 240 (void)get_builtin_function_by_id (BUILT_IN_SINCOSF); 241 else if (builtin_id == BUILT_IN_CEXPI) 242 (void)get_builtin_function_by_id (BUILT_IN_SINCOS); 243 else if (builtin_id == BUILT_IN_CEXPIL) 244 (void)get_builtin_function_by_id (BUILT_IN_SINCOSL); 245 246 return result; 247 } 248 249 /* Get the recording::type for a given type of builtin function, 250 by ID, creating it if it doesn't already exist. */ 251 252 recording::type * 253 builtins_manager::get_type (enum jit_builtin_type type_id) 254 { 255 if (!m_types[type_id]) 256 m_types[type_id] = make_type (type_id); 257 return m_types[type_id]; 258 } 259 260 /* Create the recording::type for a given type of builtin function. */ 261 262 recording::type * 263 builtins_manager::make_type (enum jit_builtin_type type_id) 264 { 265 /* Use builtin-types.def to construct a switch statement, with each 266 case deferring to one of the methods below: 267 - DEF_PRIMITIVE_TYPE is handled as a call to make_primitive_type. 268 - the various DEF_FUNCTION_TYPE_n are handled by variadic calls 269 to make_fn_type. 270 - similarly for DEF_FUNCTION_TYPE_VAR_n, but setting the 271 "is_variadic" argument. 272 - DEF_POINTER_TYPE is handled by make_ptr_type. 273 That should handle everything, but just in case we also suppy a 274 gcc_unreachable default clause. */ 275 switch (type_id) 276 { 277 #define DEF_PRIMITIVE_TYPE(ENUM, VALUE) \ 278 case ENUM: return make_primitive_type (ENUM); 279 #define DEF_FUNCTION_TYPE_0(ENUM, RETURN) \ 280 case ENUM: return make_fn_type (ENUM, RETURN, 0, 0); 281 #define DEF_FUNCTION_TYPE_1(ENUM, RETURN, ARG1) \ 282 case ENUM: return make_fn_type (ENUM, RETURN, 0, 1, ARG1); 283 #define DEF_FUNCTION_TYPE_2(ENUM, RETURN, ARG1, ARG2) \ 284 case ENUM: return make_fn_type (ENUM, RETURN, 0, 2, ARG1, ARG2); 285 #define DEF_FUNCTION_TYPE_3(ENUM, RETURN, ARG1, ARG2, ARG3) \ 286 case ENUM: return make_fn_type (ENUM, RETURN, 0, 3, ARG1, ARG2, ARG3); 287 #define DEF_FUNCTION_TYPE_4(ENUM, RETURN, ARG1, ARG2, ARG3, ARG4) \ 288 case ENUM: return make_fn_type (ENUM, RETURN, 0, 4, ARG1, ARG2, ARG3, \ 289 ARG4); 290 #define DEF_FUNCTION_TYPE_5(ENUM, RETURN, ARG1, ARG2, ARG3, ARG4, ARG5) \ 291 case ENUM: return make_fn_type (ENUM, RETURN, 0, 5, ARG1, ARG2, ARG3, \ 292 ARG4, ARG5); 293 #define DEF_FUNCTION_TYPE_6(ENUM, RETURN, ARG1, ARG2, ARG3, ARG4, ARG5, \ 294 ARG6) \ 295 case ENUM: return make_fn_type (ENUM, RETURN, 0, 6, ARG1, ARG2, ARG3, \ 296 ARG4, ARG5, ARG6); 297 #define DEF_FUNCTION_TYPE_7(ENUM, RETURN, ARG1, ARG2, ARG3, ARG4, ARG5, \ 298 ARG6, ARG7) \ 299 case ENUM: return make_fn_type (ENUM, RETURN, 0, 7, ARG1, ARG2, ARG3, \ 300 ARG4, ARG5, ARG6, ARG7); 301 #define DEF_FUNCTION_TYPE_8(ENUM, RETURN, ARG1, ARG2, ARG3, ARG4, ARG5, \ 302 ARG6, ARG7, ARG8) \ 303 case ENUM: return make_fn_type (ENUM, RETURN, 0, 8, ARG1, ARG2, ARG3, \ 304 ARG4, ARG5, ARG6, ARG7, ARG8); 305 #define DEF_FUNCTION_TYPE_9(ENUM, RETURN, ARG1, ARG2, ARG3, ARG4, ARG5, \ 306 ARG6, ARG7, ARG8, ARG9) \ 307 case ENUM: return make_fn_type (ENUM, RETURN, 0, 9, ARG1, ARG2, ARG3, \ 308 ARG4, ARG5, ARG6, ARG7, ARG8, ARG9); 309 #define DEF_FUNCTION_TYPE_10(ENUM, RETURN, ARG1, ARG2, ARG3, ARG4, ARG5, \ 310 ARG6, ARG7, ARG8, ARG9, ARG10) \ 311 case ENUM: return make_fn_type (ENUM, RETURN, 0, 10, ARG1, ARG2, ARG3, \ 312 ARG4, ARG5, ARG6, ARG7, ARG8, ARG9, \ 313 ARG10); 314 #define DEF_FUNCTION_TYPE_11(ENUM, RETURN, ARG1, ARG2, ARG3, ARG4, ARG5, \ 315 ARG6, ARG7, ARG8, ARG9, ARG10, ARG11) \ 316 case ENUM: return make_fn_type (ENUM, RETURN, 0, 11, ARG1, ARG2, ARG3, \ 317 ARG4, ARG5, ARG6, ARG7, ARG8, ARG9, \ 318 ARG10, ARG11); 319 #define DEF_FUNCTION_TYPE_VAR_0(ENUM, RETURN) \ 320 case ENUM: return make_fn_type (ENUM, RETURN, 1, 0); 321 #define DEF_FUNCTION_TYPE_VAR_1(ENUM, RETURN, ARG1) \ 322 case ENUM: return make_fn_type (ENUM, RETURN, 1, 1, ARG1); 323 #define DEF_FUNCTION_TYPE_VAR_2(ENUM, RETURN, ARG1, ARG2) \ 324 case ENUM: return make_fn_type (ENUM, RETURN, 1, 2, ARG1, ARG2); 325 #define DEF_FUNCTION_TYPE_VAR_3(ENUM, RETURN, ARG1, ARG2, ARG3) \ 326 case ENUM: return make_fn_type (ENUM, RETURN, 1, 3, ARG1, ARG2, ARG3); 327 #define DEF_FUNCTION_TYPE_VAR_4(ENUM, RETURN, ARG1, ARG2, ARG3, ARG4) \ 328 case ENUM: return make_fn_type (ENUM, RETURN, 1, 4, ARG1, ARG2, ARG3, \ 329 ARG4); 330 #define DEF_FUNCTION_TYPE_VAR_5(ENUM, RETURN, ARG1, ARG2, ARG3, ARG4, ARG5) \ 331 case ENUM: return make_fn_type (ENUM, RETURN, 1, 5, ARG1, ARG2, ARG3, \ 332 ARG4, ARG5); 333 #define DEF_FUNCTION_TYPE_VAR_6(ENUM, RETURN, ARG1, ARG2, ARG3, ARG4, ARG5, \ 334 ARG6) \ 335 case ENUM: return make_fn_type (ENUM, RETURN, 1, 6, ARG1, ARG2, ARG3, \ 336 ARG4, ARG5, ARG6); 337 #define DEF_FUNCTION_TYPE_VAR_7(ENUM, RETURN, ARG1, ARG2, ARG3, ARG4, ARG5, \ 338 ARG6, ARG7) \ 339 case ENUM: return make_fn_type (ENUM, RETURN, 1, 7, ARG1, ARG2, ARG3, \ 340 ARG4, ARG5, ARG6, ARG7); 341 #define DEF_POINTER_TYPE(ENUM, TYPE) \ 342 case ENUM: return make_ptr_type (ENUM, TYPE); 343 344 #include "builtin-types.def" 345 346 #undef DEF_PRIMITIVE_TYPE 347 #undef DEF_FUNCTION_TYPE_0 348 #undef DEF_FUNCTION_TYPE_1 349 #undef DEF_FUNCTION_TYPE_2 350 #undef DEF_FUNCTION_TYPE_3 351 #undef DEF_FUNCTION_TYPE_4 352 #undef DEF_FUNCTION_TYPE_5 353 #undef DEF_FUNCTION_TYPE_6 354 #undef DEF_FUNCTION_TYPE_7 355 #undef DEF_FUNCTION_TYPE_8 356 #undef DEF_FUNCTION_TYPE_9 357 #undef DEF_FUNCTION_TYPE_10 358 #undef DEF_FUNCTION_TYPE_11 359 #undef DEF_FUNCTION_TYPE_VAR_0 360 #undef DEF_FUNCTION_TYPE_VAR_1 361 #undef DEF_FUNCTION_TYPE_VAR_2 362 #undef DEF_FUNCTION_TYPE_VAR_3 363 #undef DEF_FUNCTION_TYPE_VAR_4 364 #undef DEF_FUNCTION_TYPE_VAR_5 365 #undef DEF_FUNCTION_TYPE_VAR_6 366 #undef DEF_FUNCTION_TYPE_VAR_7 367 #undef DEF_POINTER_TYPE 368 369 default: 370 gcc_unreachable (); 371 } 372 } 373 374 /* Create the recording::type for a given primitive type within the 375 builtin system. 376 377 Only some types are currently supported. */ 378 379 recording::type* 380 builtins_manager::make_primitive_type (enum jit_builtin_type type_id) 381 { 382 switch (type_id) 383 { 384 default: 385 // only some of these types are implemented so far: 386 m_ctxt->add_error (NULL, 387 "unimplemented primitive type for builtin: %d", type_id); 388 return NULL; 389 390 case BT_VOID: return m_ctxt->get_type (GCC_JIT_TYPE_VOID); 391 case BT_BOOL: return m_ctxt->get_type (GCC_JIT_TYPE_BOOL); 392 case BT_INT: return m_ctxt->get_type (GCC_JIT_TYPE_INT); 393 case BT_UINT: return m_ctxt->get_type (GCC_JIT_TYPE_UNSIGNED_INT); 394 case BT_LONG: return m_ctxt->get_type (GCC_JIT_TYPE_LONG); 395 case BT_ULONG: return m_ctxt->get_type (GCC_JIT_TYPE_UNSIGNED_LONG); 396 case BT_LONGLONG: return m_ctxt->get_type (GCC_JIT_TYPE_LONG_LONG); 397 case BT_ULONGLONG: 398 return m_ctxt->get_type (GCC_JIT_TYPE_UNSIGNED_LONG_LONG); 399 // case BT_INT128: 400 // case BT_UINT128: 401 // case BT_INTMAX: 402 // case BT_UINTMAX: 403 case BT_UINT16: return m_ctxt->get_int_type (2, false); 404 case BT_UINT32: return m_ctxt->get_int_type (4, false); 405 case BT_UINT64: return m_ctxt->get_int_type (8, false); 406 // case BT_WORD: 407 // case BT_UNWINDWORD: 408 case BT_FLOAT: return m_ctxt->get_type (GCC_JIT_TYPE_FLOAT); 409 case BT_DOUBLE: return m_ctxt->get_type (GCC_JIT_TYPE_DOUBLE); 410 case BT_LONGDOUBLE: return m_ctxt->get_type (GCC_JIT_TYPE_LONG_DOUBLE); 411 case BT_COMPLEX_FLOAT: 412 return m_ctxt->get_type (GCC_JIT_TYPE_COMPLEX_FLOAT); 413 case BT_COMPLEX_DOUBLE: 414 return m_ctxt->get_type (GCC_JIT_TYPE_COMPLEX_DOUBLE); 415 case BT_COMPLEX_LONGDOUBLE: 416 return m_ctxt->get_type (GCC_JIT_TYPE_COMPLEX_LONG_DOUBLE); 417 case BT_PTR: return m_ctxt->get_type (GCC_JIT_TYPE_VOID_PTR); 418 case BT_FILEPTR: return m_ctxt->get_type (GCC_JIT_TYPE_FILE_PTR); 419 // case BT_CONST: 420 // case BT_VOLATILE_PTR: 421 // case BT_CONST_VOLATILE_PTR: 422 // case BT_PTRMODE: 423 // case BT_INT_PTR: 424 // case BT_FLOAT_PTR: 425 case BT_DOUBLE_PTR: 426 return m_ctxt->get_type (GCC_JIT_TYPE_DOUBLE)->get_pointer (); 427 // case BT_CONST_DOUBLE_PTR: 428 // case BT_LONGDOUBLE_PTR: 429 // case BT_PID: 430 // case BT_SIZE: 431 // case BT_SSIZE: 432 // case BT_WINT: 433 // case BT_STRING: 434 case BT_CONST_STRING: return m_ctxt->get_type (GCC_JIT_TYPE_CONST_CHAR_PTR); 435 // case BT_DFLOAT32: 436 // case BT_DFLOAT64: 437 // case BT_DFLOAT128: 438 // case BT_DFLOAT32_PTR: 439 // case BT_DFLOAT64_PTR: 440 // case BT_DFLOAT128_PTR: 441 // case BT_VALIST_REF: 442 // case BT_VALIST_ARG: 443 // case BT_I1: 444 // case BT_I2: 445 // case BT_I4: 446 // case BT_I8: 447 // case BT_I16: 448 } 449 } 450 451 /* Create the recording::function_type for a given function type 452 signature. */ 453 454 recording::function_type * 455 builtins_manager::make_fn_type (enum jit_builtin_type, 456 enum jit_builtin_type return_type_id, 457 bool is_variadic, 458 int num_args, ...) 459 { 460 va_list list; 461 int i; 462 recording::type **param_types = new recording::type *[num_args]; 463 recording::type *return_type = NULL; 464 recording::function_type *result = NULL; 465 466 va_start (list, num_args); 467 for (i = 0; i < num_args; ++i) 468 { 469 enum jit_builtin_type arg_type_id = 470 (enum jit_builtin_type) va_arg (list, int); 471 param_types[i] = get_type (arg_type_id); 472 if (!param_types[i]) 473 goto error; 474 } 475 va_end (list); 476 477 return_type = get_type (return_type_id); 478 if (!return_type) 479 goto error; 480 481 result = m_ctxt->new_function_type (return_type, 482 num_args, 483 param_types, 484 is_variadic); 485 486 error: 487 delete[] param_types; 488 return result; 489 } 490 491 /* Handler for DEF_POINTER_TYPE within builtins_manager::make_type. */ 492 493 recording::type * 494 builtins_manager::make_ptr_type (enum jit_builtin_type, 495 enum jit_builtin_type other_type_id) 496 { 497 recording::type *base_type = get_type (other_type_id); 498 return base_type->get_pointer (); 499 } 500 501 /* Playback support. */ 502 503 /* A builtins_manager is associated with a recording::context 504 and might be reused for multiple compiles on various 505 playback::contexts, perhaps with different options. 506 507 Purge any playback state. Currently this is just the table of 508 attributes. */ 509 510 void 511 builtins_manager::finish_playback (void) 512 { 513 memset (m_attributes, 0, sizeof (m_attributes)); 514 } 515 516 /* Get the enum built_in_class for BUILTIN_ID. */ 517 518 enum built_in_class 519 builtins_manager::get_class (enum built_in_function builtin_id) 520 { 521 return builtin_data[builtin_id].fnclass; 522 } 523 524 /* Is BUILTIN_ID implicit? */ 525 526 bool 527 builtins_manager::implicit_p (enum built_in_function builtin_id) 528 { 529 return builtin_data[builtin_id].implicit_p; 530 } 531 532 /* Get any attributes (in tree form) for the function declaration 533 for BUILTIN_ID. 534 535 These are created on-demand, and cached within the m_attributes 536 array, until finish_playback. */ 537 538 tree 539 builtins_manager::get_attrs_tree (enum built_in_function builtin_id) 540 { 541 enum built_in_attribute attr = builtin_data[builtin_id].attr; 542 return get_attrs_tree (attr); 543 } 544 545 /* As above, but for an enum built_in_attribute. */ 546 547 tree 548 builtins_manager::get_attrs_tree (enum built_in_attribute attr) 549 { 550 gcc_assert (attr < ATTR_LAST); 551 if (!m_attributes [attr]) 552 m_attributes [attr] = make_attrs_tree (attr); 553 return m_attributes [attr]; 554 } 555 556 /* Handle a cache-miss within the m_attributes array by 557 generating the attributes for enum built_in_attribute 558 in tree form. */ 559 560 tree 561 builtins_manager::make_attrs_tree (enum built_in_attribute attr) 562 { 563 switch (attr) 564 { 565 /* Generate cases from builtin-attrs.def. */ 566 #define DEF_ATTR_NULL_TREE(ENUM) \ 567 case ENUM: return NULL_TREE; 568 #define DEF_ATTR_INT(ENUM, VALUE) \ 569 case ENUM: return build_int_cst (integer_type_node, VALUE); 570 #define DEF_ATTR_STRING(ENUM, VALUE) \ 571 case ENUM: return build_string (strlen (VALUE), VALUE); 572 #define DEF_ATTR_IDENT(ENUM, STRING) \ 573 case ENUM: return get_identifier (STRING); 574 #define DEF_ATTR_TREE_LIST(ENUM, PURPOSE, VALUE, CHAIN) \ 575 case ENUM: return tree_cons (get_attrs_tree (PURPOSE), \ 576 get_attrs_tree (VALUE), \ 577 get_attrs_tree (CHAIN)); 578 #include "builtin-attrs.def" 579 #undef DEF_ATTR_NULL_TREE 580 #undef DEF_ATTR_INT 581 #undef DEF_ATTR_IDENT 582 #undef DEF_ATTR_TREE_LIST 583 584 default: 585 /* We somehow got a value not covered by the autogenerated 586 cases. */ 587 gcc_unreachable (); 588 return NULL; 589 } 590 } 591 592 } // namespace jit 593 } // namespace gcc 594