1 /* Calculate branch probabilities, and basic block execution counts. 2 Copyright (C) 1990-2013 Free Software Foundation, Inc. 3 Contributed by James E. Wilson, UC Berkeley/Cygnus Support; 4 based on some ideas from Dain Samples of UC Berkeley. 5 Further mangling by Bob Manson, Cygnus Support. 6 Converted to use trees by Dale Johannesen, Apple Computer. 7 8 This file is part of GCC. 9 10 GCC is free software; you can redistribute it and/or modify it under 11 the terms of the GNU General Public License as published by the Free 12 Software Foundation; either version 3, or (at your option) any later 13 version. 14 15 GCC is distributed in the hope that it will be useful, but WITHOUT ANY 16 WARRANTY; without even the implied warranty of MERCHANTABILITY or 17 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 18 for more details. 19 20 You should have received a copy of the GNU General Public License 21 along with GCC; see the file COPYING3. If not see 22 <http://www.gnu.org/licenses/>. */ 23 24 /* Generate basic block profile instrumentation and auxiliary files. 25 Tree-based version. See profile.c for overview. */ 26 27 #include "config.h" 28 #include "system.h" 29 #include "coretypes.h" 30 #include "tm.h" 31 #include "flags.h" 32 #include "function.h" 33 #include "basic-block.h" 34 #include "diagnostic-core.h" 35 #include "coverage.h" 36 #include "tree.h" 37 #include "tree-flow.h" 38 #include "tree-pass.h" 39 #include "value-prof.h" 40 #include "cgraph.h" 41 #include "profile.h" 42 #include "target.h" 43 44 static GTY(()) tree gcov_type_node; 45 static GTY(()) tree tree_interval_profiler_fn; 46 static GTY(()) tree tree_pow2_profiler_fn; 47 static GTY(()) tree tree_one_value_profiler_fn; 48 static GTY(()) tree tree_indirect_call_profiler_fn; 49 static GTY(()) tree tree_average_profiler_fn; 50 static GTY(()) tree tree_ior_profiler_fn; 51 52 53 static GTY(()) tree ic_void_ptr_var; 54 static GTY(()) tree ic_gcov_type_ptr_var; 55 static GTY(()) tree ptr_void; 56 57 /* Do initialization work for the edge profiler. */ 58 59 /* Add code: 60 static gcov* __gcov_indirect_call_counters; // pointer to actual counter 61 static void* __gcov_indirect_call_callee; // actual callee address 62 */ 63 static void 64 init_ic_make_global_vars (void) 65 { 66 tree gcov_type_ptr; 67 68 ptr_void = build_pointer_type (void_type_node); 69 70 ic_void_ptr_var 71 = build_decl (UNKNOWN_LOCATION, VAR_DECL, 72 get_identifier ("__gcov_indirect_call_callee"), 73 ptr_void); 74 TREE_STATIC (ic_void_ptr_var) = 1; 75 TREE_PUBLIC (ic_void_ptr_var) = 0; 76 DECL_ARTIFICIAL (ic_void_ptr_var) = 1; 77 DECL_INITIAL (ic_void_ptr_var) = NULL; 78 if (targetm.have_tls) 79 DECL_TLS_MODEL (ic_void_ptr_var) = 80 decl_default_tls_model (ic_void_ptr_var); 81 82 varpool_finalize_decl (ic_void_ptr_var); 83 84 gcov_type_ptr = build_pointer_type (get_gcov_type ()); 85 ic_gcov_type_ptr_var 86 = build_decl (UNKNOWN_LOCATION, VAR_DECL, 87 get_identifier ("__gcov_indirect_call_counters"), 88 gcov_type_ptr); 89 TREE_STATIC (ic_gcov_type_ptr_var) = 1; 90 TREE_PUBLIC (ic_gcov_type_ptr_var) = 0; 91 DECL_ARTIFICIAL (ic_gcov_type_ptr_var) = 1; 92 DECL_INITIAL (ic_gcov_type_ptr_var) = NULL; 93 if (targetm.have_tls) 94 DECL_TLS_MODEL (ic_gcov_type_ptr_var) = 95 decl_default_tls_model (ic_gcov_type_ptr_var); 96 97 varpool_finalize_decl (ic_gcov_type_ptr_var); 98 } 99 100 /* Create the type and function decls for the interface with gcov. */ 101 102 void 103 gimple_init_edge_profiler (void) 104 { 105 tree interval_profiler_fn_type; 106 tree pow2_profiler_fn_type; 107 tree one_value_profiler_fn_type; 108 tree gcov_type_ptr; 109 tree ic_profiler_fn_type; 110 tree average_profiler_fn_type; 111 112 if (!gcov_type_node) 113 { 114 gcov_type_node = get_gcov_type (); 115 gcov_type_ptr = build_pointer_type (gcov_type_node); 116 117 /* void (*) (gcov_type *, gcov_type, int, unsigned) */ 118 interval_profiler_fn_type 119 = build_function_type_list (void_type_node, 120 gcov_type_ptr, gcov_type_node, 121 integer_type_node, 122 unsigned_type_node, NULL_TREE); 123 tree_interval_profiler_fn 124 = build_fn_decl ("__gcov_interval_profiler", 125 interval_profiler_fn_type); 126 TREE_NOTHROW (tree_interval_profiler_fn) = 1; 127 DECL_ATTRIBUTES (tree_interval_profiler_fn) 128 = tree_cons (get_identifier ("leaf"), NULL, 129 DECL_ATTRIBUTES (tree_interval_profiler_fn)); 130 131 /* void (*) (gcov_type *, gcov_type) */ 132 pow2_profiler_fn_type 133 = build_function_type_list (void_type_node, 134 gcov_type_ptr, gcov_type_node, 135 NULL_TREE); 136 tree_pow2_profiler_fn = build_fn_decl ("__gcov_pow2_profiler", 137 pow2_profiler_fn_type); 138 TREE_NOTHROW (tree_pow2_profiler_fn) = 1; 139 DECL_ATTRIBUTES (tree_pow2_profiler_fn) 140 = tree_cons (get_identifier ("leaf"), NULL, 141 DECL_ATTRIBUTES (tree_pow2_profiler_fn)); 142 143 /* void (*) (gcov_type *, gcov_type) */ 144 one_value_profiler_fn_type 145 = build_function_type_list (void_type_node, 146 gcov_type_ptr, gcov_type_node, 147 NULL_TREE); 148 tree_one_value_profiler_fn 149 = build_fn_decl ("__gcov_one_value_profiler", 150 one_value_profiler_fn_type); 151 TREE_NOTHROW (tree_one_value_profiler_fn) = 1; 152 DECL_ATTRIBUTES (tree_one_value_profiler_fn) 153 = tree_cons (get_identifier ("leaf"), NULL, 154 DECL_ATTRIBUTES (tree_one_value_profiler_fn)); 155 156 init_ic_make_global_vars (); 157 158 /* void (*) (gcov_type *, gcov_type, void *, void *) */ 159 ic_profiler_fn_type 160 = build_function_type_list (void_type_node, 161 gcov_type_ptr, gcov_type_node, 162 ptr_void, 163 ptr_void, NULL_TREE); 164 tree_indirect_call_profiler_fn 165 = build_fn_decl ("__gcov_indirect_call_profiler", 166 ic_profiler_fn_type); 167 TREE_NOTHROW (tree_indirect_call_profiler_fn) = 1; 168 DECL_ATTRIBUTES (tree_indirect_call_profiler_fn) 169 = tree_cons (get_identifier ("leaf"), NULL, 170 DECL_ATTRIBUTES (tree_indirect_call_profiler_fn)); 171 172 /* void (*) (gcov_type *, gcov_type) */ 173 average_profiler_fn_type 174 = build_function_type_list (void_type_node, 175 gcov_type_ptr, gcov_type_node, NULL_TREE); 176 tree_average_profiler_fn 177 = build_fn_decl ("__gcov_average_profiler", 178 average_profiler_fn_type); 179 TREE_NOTHROW (tree_average_profiler_fn) = 1; 180 DECL_ATTRIBUTES (tree_average_profiler_fn) 181 = tree_cons (get_identifier ("leaf"), NULL, 182 DECL_ATTRIBUTES (tree_average_profiler_fn)); 183 tree_ior_profiler_fn 184 = build_fn_decl ("__gcov_ior_profiler", 185 average_profiler_fn_type); 186 TREE_NOTHROW (tree_ior_profiler_fn) = 1; 187 DECL_ATTRIBUTES (tree_ior_profiler_fn) 188 = tree_cons (get_identifier ("leaf"), NULL, 189 DECL_ATTRIBUTES (tree_ior_profiler_fn)); 190 191 /* LTO streamer needs assembler names. Because we create these decls 192 late, we need to initialize them by hand. */ 193 DECL_ASSEMBLER_NAME (tree_interval_profiler_fn); 194 DECL_ASSEMBLER_NAME (tree_pow2_profiler_fn); 195 DECL_ASSEMBLER_NAME (tree_one_value_profiler_fn); 196 DECL_ASSEMBLER_NAME (tree_indirect_call_profiler_fn); 197 DECL_ASSEMBLER_NAME (tree_average_profiler_fn); 198 DECL_ASSEMBLER_NAME (tree_ior_profiler_fn); 199 } 200 } 201 202 /* Output instructions as GIMPLE trees to increment the edge 203 execution count, and insert them on E. We rely on 204 gsi_insert_on_edge to preserve the order. */ 205 206 void 207 gimple_gen_edge_profiler (int edgeno, edge e) 208 { 209 tree ref, one, gcov_type_tmp_var; 210 gimple stmt1, stmt2, stmt3; 211 212 ref = tree_coverage_counter_ref (GCOV_COUNTER_ARCS, edgeno); 213 one = build_int_cst (gcov_type_node, 1); 214 gcov_type_tmp_var = make_temp_ssa_name (gcov_type_node, 215 NULL, "PROF_edge_counter"); 216 stmt1 = gimple_build_assign (gcov_type_tmp_var, ref); 217 gcov_type_tmp_var = make_temp_ssa_name (gcov_type_node, 218 NULL, "PROF_edge_counter"); 219 stmt2 = gimple_build_assign_with_ops (PLUS_EXPR, gcov_type_tmp_var, 220 gimple_assign_lhs (stmt1), one); 221 stmt3 = gimple_build_assign (unshare_expr (ref), gimple_assign_lhs (stmt2)); 222 gsi_insert_on_edge (e, stmt1); 223 gsi_insert_on_edge (e, stmt2); 224 gsi_insert_on_edge (e, stmt3); 225 } 226 227 /* Emits code to get VALUE to instrument at GSI, and returns the 228 variable containing the value. */ 229 230 static tree 231 prepare_instrumented_value (gimple_stmt_iterator *gsi, histogram_value value) 232 { 233 tree val = value->hvalue.value; 234 if (POINTER_TYPE_P (TREE_TYPE (val))) 235 val = fold_convert (build_nonstandard_integer_type 236 (TYPE_PRECISION (TREE_TYPE (val)), 1), val); 237 return force_gimple_operand_gsi (gsi, fold_convert (gcov_type_node, val), 238 true, NULL_TREE, true, GSI_SAME_STMT); 239 } 240 241 /* Output instructions as GIMPLE trees to increment the interval histogram 242 counter. VALUE is the expression whose value is profiled. TAG is the 243 tag of the section for counters, BASE is offset of the counter position. */ 244 245 void 246 gimple_gen_interval_profiler (histogram_value value, unsigned tag, unsigned base) 247 { 248 gimple stmt = value->hvalue.stmt; 249 gimple_stmt_iterator gsi = gsi_for_stmt (stmt); 250 tree ref = tree_coverage_counter_ref (tag, base), ref_ptr; 251 gimple call; 252 tree val; 253 tree start = build_int_cst_type (integer_type_node, 254 value->hdata.intvl.int_start); 255 tree steps = build_int_cst_type (unsigned_type_node, 256 value->hdata.intvl.steps); 257 258 ref_ptr = force_gimple_operand_gsi (&gsi, 259 build_addr (ref, current_function_decl), 260 true, NULL_TREE, true, GSI_SAME_STMT); 261 val = prepare_instrumented_value (&gsi, value); 262 call = gimple_build_call (tree_interval_profiler_fn, 4, 263 ref_ptr, val, start, steps); 264 gsi_insert_before (&gsi, call, GSI_NEW_STMT); 265 } 266 267 /* Output instructions as GIMPLE trees to increment the power of two histogram 268 counter. VALUE is the expression whose value is profiled. TAG is the tag 269 of the section for counters, BASE is offset of the counter position. */ 270 271 void 272 gimple_gen_pow2_profiler (histogram_value value, unsigned tag, unsigned base) 273 { 274 gimple stmt = value->hvalue.stmt; 275 gimple_stmt_iterator gsi = gsi_for_stmt (stmt); 276 tree ref_ptr = tree_coverage_counter_addr (tag, base); 277 gimple call; 278 tree val; 279 280 ref_ptr = force_gimple_operand_gsi (&gsi, ref_ptr, 281 true, NULL_TREE, true, GSI_SAME_STMT); 282 val = prepare_instrumented_value (&gsi, value); 283 call = gimple_build_call (tree_pow2_profiler_fn, 2, ref_ptr, val); 284 gsi_insert_before (&gsi, call, GSI_NEW_STMT); 285 } 286 287 /* Output instructions as GIMPLE trees for code to find the most common value. 288 VALUE is the expression whose value is profiled. TAG is the tag of the 289 section for counters, BASE is offset of the counter position. */ 290 291 void 292 gimple_gen_one_value_profiler (histogram_value value, unsigned tag, unsigned base) 293 { 294 gimple stmt = value->hvalue.stmt; 295 gimple_stmt_iterator gsi = gsi_for_stmt (stmt); 296 tree ref_ptr = tree_coverage_counter_addr (tag, base); 297 gimple call; 298 tree val; 299 300 ref_ptr = force_gimple_operand_gsi (&gsi, ref_ptr, 301 true, NULL_TREE, true, GSI_SAME_STMT); 302 val = prepare_instrumented_value (&gsi, value); 303 call = gimple_build_call (tree_one_value_profiler_fn, 2, ref_ptr, val); 304 gsi_insert_before (&gsi, call, GSI_NEW_STMT); 305 } 306 307 308 /* Output instructions as GIMPLE trees for code to find the most 309 common called function in indirect call. 310 VALUE is the call expression whose indirect callee is profiled. 311 TAG is the tag of the section for counters, BASE is offset of the 312 counter position. */ 313 314 void 315 gimple_gen_ic_profiler (histogram_value value, unsigned tag, unsigned base) 316 { 317 tree tmp1; 318 gimple stmt1, stmt2, stmt3; 319 gimple stmt = value->hvalue.stmt; 320 gimple_stmt_iterator gsi = gsi_for_stmt (stmt); 321 tree ref_ptr = tree_coverage_counter_addr (tag, base); 322 323 ref_ptr = force_gimple_operand_gsi (&gsi, ref_ptr, 324 true, NULL_TREE, true, GSI_SAME_STMT); 325 326 /* Insert code: 327 328 stmt1: __gcov_indirect_call_counters = get_relevant_counter_ptr (); 329 stmt2: tmp1 = (void *) (indirect call argument value) 330 stmt3: __gcov_indirect_call_callee = tmp1; 331 */ 332 333 stmt1 = gimple_build_assign (ic_gcov_type_ptr_var, ref_ptr); 334 tmp1 = make_temp_ssa_name (ptr_void, NULL, "PROF"); 335 stmt2 = gimple_build_assign (tmp1, unshare_expr (value->hvalue.value)); 336 stmt3 = gimple_build_assign (ic_void_ptr_var, gimple_assign_lhs (stmt2)); 337 338 gsi_insert_before (&gsi, stmt1, GSI_SAME_STMT); 339 gsi_insert_before (&gsi, stmt2, GSI_SAME_STMT); 340 gsi_insert_before (&gsi, stmt3, GSI_SAME_STMT); 341 } 342 343 344 /* Output instructions as GIMPLE trees for code to find the most 345 common called function in indirect call. Insert instructions at the 346 beginning of every possible called function. 347 */ 348 349 void 350 gimple_gen_ic_func_profiler (void) 351 { 352 struct cgraph_node * c_node = cgraph_get_node (current_function_decl); 353 gimple_stmt_iterator gsi; 354 gimple stmt1, stmt2; 355 tree tree_uid, cur_func, counter_ptr, ptr_var, void0; 356 357 if (cgraph_only_called_directly_p (c_node)) 358 return; 359 360 gimple_init_edge_profiler (); 361 362 /* Insert code: 363 364 stmt1: __gcov_indirect_call_profiler (__gcov_indirect_call_counters, 365 current_function_funcdef_no, 366 ¤t_function_decl, 367 __gcov_indirect_call_callee); 368 */ 369 gsi = gsi_after_labels (single_succ (ENTRY_BLOCK_PTR)); 370 371 cur_func = force_gimple_operand_gsi (&gsi, 372 build_addr (current_function_decl, 373 current_function_decl), 374 true, NULL_TREE, 375 true, GSI_SAME_STMT); 376 counter_ptr = force_gimple_operand_gsi (&gsi, ic_gcov_type_ptr_var, 377 true, NULL_TREE, true, 378 GSI_SAME_STMT); 379 ptr_var = force_gimple_operand_gsi (&gsi, ic_void_ptr_var, 380 true, NULL_TREE, true, 381 GSI_SAME_STMT); 382 tree_uid = build_int_cst (gcov_type_node, current_function_funcdef_no); 383 stmt1 = gimple_build_call (tree_indirect_call_profiler_fn, 4, 384 counter_ptr, tree_uid, cur_func, ptr_var); 385 gsi_insert_before (&gsi, stmt1, GSI_SAME_STMT); 386 387 /* Set __gcov_indirect_call_callee to 0, 388 so that calls from other modules won't get misattributed 389 to the last caller of the current callee. */ 390 void0 = build_int_cst (build_pointer_type (void_type_node), 0); 391 stmt2 = gimple_build_assign (ic_void_ptr_var, void0); 392 gsi_insert_before (&gsi, stmt2, GSI_SAME_STMT); 393 } 394 395 /* Output instructions as GIMPLE trees for code to find the most common value 396 of a difference between two evaluations of an expression. 397 VALUE is the expression whose value is profiled. TAG is the tag of the 398 section for counters, BASE is offset of the counter position. */ 399 400 void 401 gimple_gen_const_delta_profiler (histogram_value value ATTRIBUTE_UNUSED, 402 unsigned tag ATTRIBUTE_UNUSED, 403 unsigned base ATTRIBUTE_UNUSED) 404 { 405 /* FIXME implement this. */ 406 #ifdef ENABLE_CHECKING 407 internal_error ("unimplemented functionality"); 408 #endif 409 gcc_unreachable (); 410 } 411 412 /* Output instructions as GIMPLE trees to increment the average histogram 413 counter. VALUE is the expression whose value is profiled. TAG is the 414 tag of the section for counters, BASE is offset of the counter position. */ 415 416 void 417 gimple_gen_average_profiler (histogram_value value, unsigned tag, unsigned base) 418 { 419 gimple stmt = value->hvalue.stmt; 420 gimple_stmt_iterator gsi = gsi_for_stmt (stmt); 421 tree ref_ptr = tree_coverage_counter_addr (tag, base); 422 gimple call; 423 tree val; 424 425 ref_ptr = force_gimple_operand_gsi (&gsi, ref_ptr, 426 true, NULL_TREE, 427 true, GSI_SAME_STMT); 428 val = prepare_instrumented_value (&gsi, value); 429 call = gimple_build_call (tree_average_profiler_fn, 2, ref_ptr, val); 430 gsi_insert_before (&gsi, call, GSI_NEW_STMT); 431 } 432 433 /* Output instructions as GIMPLE trees to increment the ior histogram 434 counter. VALUE is the expression whose value is profiled. TAG is the 435 tag of the section for counters, BASE is offset of the counter position. */ 436 437 void 438 gimple_gen_ior_profiler (histogram_value value, unsigned tag, unsigned base) 439 { 440 gimple stmt = value->hvalue.stmt; 441 gimple_stmt_iterator gsi = gsi_for_stmt (stmt); 442 tree ref_ptr = tree_coverage_counter_addr (tag, base); 443 gimple call; 444 tree val; 445 446 ref_ptr = force_gimple_operand_gsi (&gsi, ref_ptr, 447 true, NULL_TREE, true, GSI_SAME_STMT); 448 val = prepare_instrumented_value (&gsi, value); 449 call = gimple_build_call (tree_ior_profiler_fn, 2, ref_ptr, val); 450 gsi_insert_before (&gsi, call, GSI_NEW_STMT); 451 } 452 453 /* Profile all functions in the callgraph. */ 454 455 static unsigned int 456 tree_profiling (void) 457 { 458 struct cgraph_node *node; 459 460 /* This is a small-ipa pass that gets called only once, from 461 cgraphunit.c:ipa_passes(). */ 462 gcc_assert (cgraph_state == CGRAPH_STATE_IPA_SSA); 463 464 init_node_map(); 465 466 FOR_EACH_DEFINED_FUNCTION (node) 467 { 468 if (!gimple_has_body_p (node->symbol.decl)) 469 continue; 470 471 /* Don't profile functions produced for builtin stuff. */ 472 if (DECL_SOURCE_LOCATION (node->symbol.decl) == BUILTINS_LOCATION) 473 continue; 474 475 push_cfun (DECL_STRUCT_FUNCTION (node->symbol.decl)); 476 477 /* Local pure-const may imply need to fixup the cfg. */ 478 if (execute_fixup_cfg () & TODO_cleanup_cfg) 479 cleanup_tree_cfg (); 480 481 branch_prob (); 482 483 if (! flag_branch_probabilities 484 && flag_profile_values) 485 gimple_gen_ic_func_profiler (); 486 487 if (flag_branch_probabilities 488 && flag_profile_values 489 && flag_value_profile_transformations) 490 gimple_value_profile_transformations (); 491 492 /* The above could hose dominator info. Currently there is 493 none coming in, this is a safety valve. It should be 494 easy to adjust it, if and when there is some. */ 495 free_dominance_info (CDI_DOMINATORS); 496 free_dominance_info (CDI_POST_DOMINATORS); 497 pop_cfun (); 498 } 499 500 /* Drop pure/const flags from instrumented functions. */ 501 FOR_EACH_DEFINED_FUNCTION (node) 502 { 503 if (!gimple_has_body_p (node->symbol.decl) 504 || !(!node->clone_of 505 || node->symbol.decl != node->clone_of->symbol.decl)) 506 continue; 507 508 /* Don't profile functions produced for builtin stuff. */ 509 if (DECL_SOURCE_LOCATION (node->symbol.decl) == BUILTINS_LOCATION) 510 continue; 511 512 cgraph_set_const_flag (node, false, false); 513 cgraph_set_pure_flag (node, false, false); 514 } 515 516 /* Update call statements and rebuild the cgraph. */ 517 FOR_EACH_DEFINED_FUNCTION (node) 518 { 519 basic_block bb; 520 521 if (!gimple_has_body_p (node->symbol.decl) 522 || !(!node->clone_of 523 || node->symbol.decl != node->clone_of->symbol.decl)) 524 continue; 525 526 /* Don't profile functions produced for builtin stuff. */ 527 if (DECL_SOURCE_LOCATION (node->symbol.decl) == BUILTINS_LOCATION) 528 continue; 529 530 push_cfun (DECL_STRUCT_FUNCTION (node->symbol.decl)); 531 532 FOR_EACH_BB (bb) 533 { 534 gimple_stmt_iterator gsi; 535 for (gsi = gsi_start_bb (bb); !gsi_end_p (gsi); gsi_next (&gsi)) 536 { 537 gimple stmt = gsi_stmt (gsi); 538 if (is_gimple_call (stmt)) 539 update_stmt (stmt); 540 } 541 } 542 543 update_ssa (TODO_update_ssa); 544 545 rebuild_cgraph_edges (); 546 547 pop_cfun (); 548 } 549 550 del_node_map(); 551 return 0; 552 } 553 554 /* When profile instrumentation, use or test coverage shall be performed. */ 555 556 static bool 557 gate_tree_profile_ipa (void) 558 { 559 return (!in_lto_p 560 && (flag_branch_probabilities || flag_test_coverage 561 || profile_arc_flag)); 562 } 563 564 struct simple_ipa_opt_pass pass_ipa_tree_profile = 565 { 566 { 567 SIMPLE_IPA_PASS, 568 "profile", /* name */ 569 OPTGROUP_NONE, /* optinfo_flags */ 570 gate_tree_profile_ipa, /* gate */ 571 tree_profiling, /* execute */ 572 NULL, /* sub */ 573 NULL, /* next */ 574 0, /* static_pass_number */ 575 TV_IPA_PROFILE, /* tv_id */ 576 0, /* properties_required */ 577 0, /* properties_provided */ 578 0, /* properties_destroyed */ 579 0, /* todo_flags_start */ 580 0 /* todo_flags_finish */ 581 } 582 }; 583 584 #include "gt-tree-profile.h" 585