1 /* Calculate branch probabilities, and basic block execution counts. 2 Copyright (C) 1990-2016 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 "backend.h" 31 #include "target.h" 32 #include "tree.h" 33 #include "gimple.h" 34 #include "cfghooks.h" 35 #include "tree-pass.h" 36 #include "ssa.h" 37 #include "cgraph.h" 38 #include "coverage.h" 39 #include "diagnostic-core.h" 40 #include "fold-const.h" 41 #include "varasm.h" 42 #include "tree-nested.h" 43 #include "gimplify.h" 44 #include "gimple-iterator.h" 45 #include "gimplify-me.h" 46 #include "tree-cfg.h" 47 #include "tree-into-ssa.h" 48 #include "value-prof.h" 49 #include "profile.h" 50 #include "tree-cfgcleanup.h" 51 #include "params.h" 52 53 static GTY(()) tree gcov_type_node; 54 static GTY(()) tree tree_interval_profiler_fn; 55 static GTY(()) tree tree_pow2_profiler_fn; 56 static GTY(()) tree tree_one_value_profiler_fn; 57 static GTY(()) tree tree_indirect_call_profiler_fn; 58 static GTY(()) tree tree_time_profiler_fn; 59 static GTY(()) tree tree_average_profiler_fn; 60 static GTY(()) tree tree_ior_profiler_fn; 61 62 63 static GTY(()) tree ic_void_ptr_var; 64 static GTY(()) tree ic_gcov_type_ptr_var; 65 static GTY(()) tree ptr_void; 66 67 /* Do initialization work for the edge profiler. */ 68 69 /* Add code: 70 __thread gcov* __gcov_indirect_call_counters; // pointer to actual counter 71 __thread void* __gcov_indirect_call_callee; // actual callee address 72 __thread int __gcov_function_counter; // time profiler function counter 73 */ 74 static void 75 init_ic_make_global_vars (void) 76 { 77 tree gcov_type_ptr; 78 79 ptr_void = build_pointer_type (void_type_node); 80 81 ic_void_ptr_var 82 = build_decl (UNKNOWN_LOCATION, VAR_DECL, 83 get_identifier ( 84 (PARAM_VALUE (PARAM_INDIR_CALL_TOPN_PROFILE) ? 85 "__gcov_indirect_call_topn_callee" : 86 "__gcov_indirect_call_callee")), 87 ptr_void); 88 TREE_PUBLIC (ic_void_ptr_var) = 1; 89 DECL_EXTERNAL (ic_void_ptr_var) = 1; 90 TREE_STATIC (ic_void_ptr_var) = 1; 91 DECL_ARTIFICIAL (ic_void_ptr_var) = 1; 92 DECL_INITIAL (ic_void_ptr_var) = NULL; 93 if (targetm.have_tls) 94 set_decl_tls_model (ic_void_ptr_var, decl_default_tls_model (ic_void_ptr_var)); 95 96 gcov_type_ptr = build_pointer_type (get_gcov_type ()); 97 98 ic_gcov_type_ptr_var 99 = build_decl (UNKNOWN_LOCATION, VAR_DECL, 100 get_identifier ( 101 (PARAM_VALUE (PARAM_INDIR_CALL_TOPN_PROFILE) ? 102 "__gcov_indirect_call_topn_counters" : 103 "__gcov_indirect_call_counters")), 104 gcov_type_ptr); 105 TREE_PUBLIC (ic_gcov_type_ptr_var) = 1; 106 DECL_EXTERNAL (ic_gcov_type_ptr_var) = 1; 107 TREE_STATIC (ic_gcov_type_ptr_var) = 1; 108 DECL_ARTIFICIAL (ic_gcov_type_ptr_var) = 1; 109 DECL_INITIAL (ic_gcov_type_ptr_var) = NULL; 110 if (targetm.have_tls) 111 set_decl_tls_model (ic_gcov_type_ptr_var, decl_default_tls_model (ic_gcov_type_ptr_var)); 112 } 113 114 /* Create the type and function decls for the interface with gcov. */ 115 116 void 117 gimple_init_edge_profiler (void) 118 { 119 tree interval_profiler_fn_type; 120 tree pow2_profiler_fn_type; 121 tree one_value_profiler_fn_type; 122 tree gcov_type_ptr; 123 tree ic_profiler_fn_type; 124 tree average_profiler_fn_type; 125 tree time_profiler_fn_type; 126 127 if (!gcov_type_node) 128 { 129 gcov_type_node = get_gcov_type (); 130 gcov_type_ptr = build_pointer_type (gcov_type_node); 131 132 /* void (*) (gcov_type *, gcov_type, int, unsigned) */ 133 interval_profiler_fn_type 134 = build_function_type_list (void_type_node, 135 gcov_type_ptr, gcov_type_node, 136 integer_type_node, 137 unsigned_type_node, NULL_TREE); 138 tree_interval_profiler_fn 139 = build_fn_decl ("__gcov_interval_profiler", 140 interval_profiler_fn_type); 141 TREE_NOTHROW (tree_interval_profiler_fn) = 1; 142 DECL_ATTRIBUTES (tree_interval_profiler_fn) 143 = tree_cons (get_identifier ("leaf"), NULL, 144 DECL_ATTRIBUTES (tree_interval_profiler_fn)); 145 146 /* void (*) (gcov_type *, gcov_type) */ 147 pow2_profiler_fn_type 148 = build_function_type_list (void_type_node, 149 gcov_type_ptr, gcov_type_node, 150 NULL_TREE); 151 tree_pow2_profiler_fn = build_fn_decl ("__gcov_pow2_profiler", 152 pow2_profiler_fn_type); 153 TREE_NOTHROW (tree_pow2_profiler_fn) = 1; 154 DECL_ATTRIBUTES (tree_pow2_profiler_fn) 155 = tree_cons (get_identifier ("leaf"), NULL, 156 DECL_ATTRIBUTES (tree_pow2_profiler_fn)); 157 158 /* void (*) (gcov_type *, gcov_type) */ 159 one_value_profiler_fn_type 160 = build_function_type_list (void_type_node, 161 gcov_type_ptr, gcov_type_node, 162 NULL_TREE); 163 tree_one_value_profiler_fn 164 = build_fn_decl ("__gcov_one_value_profiler", 165 one_value_profiler_fn_type); 166 TREE_NOTHROW (tree_one_value_profiler_fn) = 1; 167 DECL_ATTRIBUTES (tree_one_value_profiler_fn) 168 = tree_cons (get_identifier ("leaf"), NULL, 169 DECL_ATTRIBUTES (tree_one_value_profiler_fn)); 170 171 init_ic_make_global_vars (); 172 173 /* void (*) (gcov_type, void *) */ 174 ic_profiler_fn_type 175 = build_function_type_list (void_type_node, 176 gcov_type_node, 177 ptr_void, 178 NULL_TREE); 179 tree_indirect_call_profiler_fn 180 = build_fn_decl ( (PARAM_VALUE (PARAM_INDIR_CALL_TOPN_PROFILE) ? 181 "__gcov_indirect_call_topn_profiler": 182 "__gcov_indirect_call_profiler_v2"), 183 ic_profiler_fn_type); 184 185 TREE_NOTHROW (tree_indirect_call_profiler_fn) = 1; 186 DECL_ATTRIBUTES (tree_indirect_call_profiler_fn) 187 = tree_cons (get_identifier ("leaf"), NULL, 188 DECL_ATTRIBUTES (tree_indirect_call_profiler_fn)); 189 190 /* void (*) (gcov_type *, gcov_type, void *) */ 191 time_profiler_fn_type 192 = build_function_type_list (void_type_node, 193 gcov_type_ptr, NULL_TREE); 194 tree_time_profiler_fn 195 = build_fn_decl ("__gcov_time_profiler", 196 time_profiler_fn_type); 197 TREE_NOTHROW (tree_time_profiler_fn) = 1; 198 DECL_ATTRIBUTES (tree_time_profiler_fn) 199 = tree_cons (get_identifier ("leaf"), NULL, 200 DECL_ATTRIBUTES (tree_time_profiler_fn)); 201 202 /* void (*) (gcov_type *, gcov_type) */ 203 average_profiler_fn_type 204 = build_function_type_list (void_type_node, 205 gcov_type_ptr, gcov_type_node, NULL_TREE); 206 tree_average_profiler_fn 207 = build_fn_decl ("__gcov_average_profiler", 208 average_profiler_fn_type); 209 TREE_NOTHROW (tree_average_profiler_fn) = 1; 210 DECL_ATTRIBUTES (tree_average_profiler_fn) 211 = tree_cons (get_identifier ("leaf"), NULL, 212 DECL_ATTRIBUTES (tree_average_profiler_fn)); 213 tree_ior_profiler_fn 214 = build_fn_decl ("__gcov_ior_profiler", 215 average_profiler_fn_type); 216 TREE_NOTHROW (tree_ior_profiler_fn) = 1; 217 DECL_ATTRIBUTES (tree_ior_profiler_fn) 218 = tree_cons (get_identifier ("leaf"), NULL, 219 DECL_ATTRIBUTES (tree_ior_profiler_fn)); 220 221 /* LTO streamer needs assembler names. Because we create these decls 222 late, we need to initialize them by hand. */ 223 DECL_ASSEMBLER_NAME (tree_interval_profiler_fn); 224 DECL_ASSEMBLER_NAME (tree_pow2_profiler_fn); 225 DECL_ASSEMBLER_NAME (tree_one_value_profiler_fn); 226 DECL_ASSEMBLER_NAME (tree_indirect_call_profiler_fn); 227 DECL_ASSEMBLER_NAME (tree_time_profiler_fn); 228 DECL_ASSEMBLER_NAME (tree_average_profiler_fn); 229 DECL_ASSEMBLER_NAME (tree_ior_profiler_fn); 230 } 231 } 232 233 /* Output instructions as GIMPLE trees to increment the edge 234 execution count, and insert them on E. We rely on 235 gsi_insert_on_edge to preserve the order. */ 236 237 void 238 gimple_gen_edge_profiler (int edgeno, edge e) 239 { 240 tree ref, one, gcov_type_tmp_var; 241 gassign *stmt1, *stmt2, *stmt3; 242 243 ref = tree_coverage_counter_ref (GCOV_COUNTER_ARCS, edgeno); 244 one = build_int_cst (gcov_type_node, 1); 245 gcov_type_tmp_var = make_temp_ssa_name (gcov_type_node, 246 NULL, "PROF_edge_counter"); 247 stmt1 = gimple_build_assign (gcov_type_tmp_var, ref); 248 gcov_type_tmp_var = make_temp_ssa_name (gcov_type_node, 249 NULL, "PROF_edge_counter"); 250 stmt2 = gimple_build_assign (gcov_type_tmp_var, PLUS_EXPR, 251 gimple_assign_lhs (stmt1), one); 252 stmt3 = gimple_build_assign (unshare_expr (ref), gimple_assign_lhs (stmt2)); 253 gsi_insert_on_edge (e, stmt1); 254 gsi_insert_on_edge (e, stmt2); 255 gsi_insert_on_edge (e, stmt3); 256 } 257 258 /* Emits code to get VALUE to instrument at GSI, and returns the 259 variable containing the value. */ 260 261 static tree 262 prepare_instrumented_value (gimple_stmt_iterator *gsi, histogram_value value) 263 { 264 tree val = value->hvalue.value; 265 if (POINTER_TYPE_P (TREE_TYPE (val))) 266 val = fold_convert (build_nonstandard_integer_type 267 (TYPE_PRECISION (TREE_TYPE (val)), 1), val); 268 return force_gimple_operand_gsi (gsi, fold_convert (gcov_type_node, val), 269 true, NULL_TREE, true, GSI_SAME_STMT); 270 } 271 272 /* Output instructions as GIMPLE trees to increment the interval histogram 273 counter. VALUE is the expression whose value is profiled. TAG is the 274 tag of the section for counters, BASE is offset of the counter position. */ 275 276 void 277 gimple_gen_interval_profiler (histogram_value value, unsigned tag, unsigned base) 278 { 279 gimple *stmt = value->hvalue.stmt; 280 gimple_stmt_iterator gsi = gsi_for_stmt (stmt); 281 tree ref = tree_coverage_counter_ref (tag, base), ref_ptr; 282 gcall *call; 283 tree val; 284 tree start = build_int_cst_type (integer_type_node, 285 value->hdata.intvl.int_start); 286 tree steps = build_int_cst_type (unsigned_type_node, 287 value->hdata.intvl.steps); 288 289 ref_ptr = force_gimple_operand_gsi (&gsi, 290 build_addr (ref), 291 true, NULL_TREE, true, GSI_SAME_STMT); 292 val = prepare_instrumented_value (&gsi, value); 293 call = gimple_build_call (tree_interval_profiler_fn, 4, 294 ref_ptr, val, start, steps); 295 gsi_insert_before (&gsi, call, GSI_NEW_STMT); 296 } 297 298 /* Output instructions as GIMPLE trees to increment the power of two histogram 299 counter. VALUE is the expression whose value is profiled. TAG is the tag 300 of the section for counters, BASE is offset of the counter position. */ 301 302 void 303 gimple_gen_pow2_profiler (histogram_value value, unsigned tag, unsigned base) 304 { 305 gimple *stmt = value->hvalue.stmt; 306 gimple_stmt_iterator gsi = gsi_for_stmt (stmt); 307 tree ref_ptr = tree_coverage_counter_addr (tag, base); 308 gcall *call; 309 tree val; 310 311 ref_ptr = force_gimple_operand_gsi (&gsi, ref_ptr, 312 true, NULL_TREE, true, GSI_SAME_STMT); 313 val = prepare_instrumented_value (&gsi, value); 314 call = gimple_build_call (tree_pow2_profiler_fn, 2, ref_ptr, val); 315 gsi_insert_before (&gsi, call, GSI_NEW_STMT); 316 } 317 318 /* Output instructions as GIMPLE trees for code to find the most common value. 319 VALUE is the expression whose value is profiled. TAG is the tag of the 320 section for counters, BASE is offset of the counter position. */ 321 322 void 323 gimple_gen_one_value_profiler (histogram_value value, unsigned tag, unsigned base) 324 { 325 gimple *stmt = value->hvalue.stmt; 326 gimple_stmt_iterator gsi = gsi_for_stmt (stmt); 327 tree ref_ptr = tree_coverage_counter_addr (tag, base); 328 gcall *call; 329 tree val; 330 331 ref_ptr = force_gimple_operand_gsi (&gsi, ref_ptr, 332 true, NULL_TREE, true, GSI_SAME_STMT); 333 val = prepare_instrumented_value (&gsi, value); 334 call = gimple_build_call (tree_one_value_profiler_fn, 2, ref_ptr, val); 335 gsi_insert_before (&gsi, call, GSI_NEW_STMT); 336 } 337 338 339 /* Output instructions as GIMPLE trees for code to find the most 340 common called function in indirect call. 341 VALUE is the call expression whose indirect callee is profiled. 342 TAG is the tag of the section for counters, BASE is offset of the 343 counter position. */ 344 345 void 346 gimple_gen_ic_profiler (histogram_value value, unsigned tag, unsigned base) 347 { 348 tree tmp1; 349 gassign *stmt1, *stmt2, *stmt3; 350 gimple *stmt = value->hvalue.stmt; 351 gimple_stmt_iterator gsi = gsi_for_stmt (stmt); 352 tree ref_ptr = tree_coverage_counter_addr (tag, base); 353 354 if ( (PARAM_VALUE (PARAM_INDIR_CALL_TOPN_PROFILE) && 355 tag == GCOV_COUNTER_V_INDIR) || 356 (!PARAM_VALUE (PARAM_INDIR_CALL_TOPN_PROFILE) && 357 tag == GCOV_COUNTER_ICALL_TOPNV)) 358 return; 359 360 ref_ptr = force_gimple_operand_gsi (&gsi, ref_ptr, 361 true, NULL_TREE, true, GSI_SAME_STMT); 362 363 /* Insert code: 364 365 stmt1: __gcov_indirect_call_counters = get_relevant_counter_ptr (); 366 stmt2: tmp1 = (void *) (indirect call argument value) 367 stmt3: __gcov_indirect_call_callee = tmp1; 368 */ 369 370 stmt1 = gimple_build_assign (ic_gcov_type_ptr_var, ref_ptr); 371 tmp1 = make_temp_ssa_name (ptr_void, NULL, "PROF"); 372 stmt2 = gimple_build_assign (tmp1, unshare_expr (value->hvalue.value)); 373 stmt3 = gimple_build_assign (ic_void_ptr_var, gimple_assign_lhs (stmt2)); 374 375 gsi_insert_before (&gsi, stmt1, GSI_SAME_STMT); 376 gsi_insert_before (&gsi, stmt2, GSI_SAME_STMT); 377 gsi_insert_before (&gsi, stmt3, GSI_SAME_STMT); 378 } 379 380 381 /* Output instructions as GIMPLE trees for code to find the most 382 common called function in indirect call. Insert instructions at the 383 beginning of every possible called function. 384 */ 385 386 void 387 gimple_gen_ic_func_profiler (void) 388 { 389 struct cgraph_node * c_node = cgraph_node::get (current_function_decl); 390 gimple_stmt_iterator gsi; 391 gcall *stmt1; 392 gassign *stmt2; 393 tree tree_uid, cur_func, void0; 394 395 if (c_node->only_called_directly_p ()) 396 return; 397 398 gimple_init_edge_profiler (); 399 400 /* Insert code: 401 402 stmt1: __gcov_indirect_call_profiler_v2 (profile_id, 403 ¤t_function_decl) 404 */ 405 gsi = gsi_after_labels (split_edge (single_succ_edge 406 (ENTRY_BLOCK_PTR_FOR_FN (cfun)))); 407 408 cur_func = force_gimple_operand_gsi (&gsi, 409 build_addr (current_function_decl), 410 true, NULL_TREE, 411 true, GSI_SAME_STMT); 412 tree_uid = build_int_cst 413 (gcov_type_node, 414 cgraph_node::get (current_function_decl)->profile_id); 415 stmt1 = gimple_build_call (tree_indirect_call_profiler_fn, 2, 416 tree_uid, cur_func); 417 gsi_insert_before (&gsi, stmt1, GSI_SAME_STMT); 418 419 /* Set __gcov_indirect_call_callee to 0, 420 so that calls from other modules won't get misattributed 421 to the last caller of the current callee. */ 422 void0 = build_int_cst (build_pointer_type (void_type_node), 0); 423 stmt2 = gimple_build_assign (ic_void_ptr_var, void0); 424 gsi_insert_before (&gsi, stmt2, GSI_SAME_STMT); 425 } 426 427 /* Output instructions as GIMPLE tree at the beginning for each function. 428 TAG is the tag of the section for counters, BASE is offset of the 429 counter position and GSI is the iterator we place the counter. */ 430 431 void 432 gimple_gen_time_profiler (unsigned tag, unsigned base, 433 gimple_stmt_iterator &gsi) 434 { 435 tree ref_ptr = tree_coverage_counter_addr (tag, base); 436 gcall *call; 437 438 ref_ptr = force_gimple_operand_gsi (&gsi, ref_ptr, 439 true, NULL_TREE, true, GSI_SAME_STMT); 440 call = gimple_build_call (tree_time_profiler_fn, 1, ref_ptr); 441 gsi_insert_before (&gsi, call, GSI_NEW_STMT); 442 } 443 444 /* Output instructions as GIMPLE trees for code to find the most common value 445 of a difference between two evaluations of an expression. 446 VALUE is the expression whose value is profiled. TAG is the tag of the 447 section for counters, BASE is offset of the counter position. */ 448 449 void 450 gimple_gen_const_delta_profiler (histogram_value value ATTRIBUTE_UNUSED, 451 unsigned tag ATTRIBUTE_UNUSED, 452 unsigned base ATTRIBUTE_UNUSED) 453 { 454 /* FIXME implement this. */ 455 if (flag_checking) 456 internal_error ("unimplemented functionality"); 457 gcc_unreachable (); 458 } 459 460 /* Output instructions as GIMPLE trees to increment the average histogram 461 counter. VALUE is the expression whose value is profiled. TAG is the 462 tag of the section for counters, BASE is offset of the counter position. */ 463 464 void 465 gimple_gen_average_profiler (histogram_value value, unsigned tag, unsigned base) 466 { 467 gimple *stmt = value->hvalue.stmt; 468 gimple_stmt_iterator gsi = gsi_for_stmt (stmt); 469 tree ref_ptr = tree_coverage_counter_addr (tag, base); 470 gcall *call; 471 tree val; 472 473 ref_ptr = force_gimple_operand_gsi (&gsi, ref_ptr, 474 true, NULL_TREE, 475 true, GSI_SAME_STMT); 476 val = prepare_instrumented_value (&gsi, value); 477 call = gimple_build_call (tree_average_profiler_fn, 2, ref_ptr, val); 478 gsi_insert_before (&gsi, call, GSI_NEW_STMT); 479 } 480 481 /* Output instructions as GIMPLE trees to increment the ior histogram 482 counter. VALUE is the expression whose value is profiled. TAG is the 483 tag of the section for counters, BASE is offset of the counter position. */ 484 485 void 486 gimple_gen_ior_profiler (histogram_value value, unsigned tag, unsigned base) 487 { 488 gimple *stmt = value->hvalue.stmt; 489 gimple_stmt_iterator gsi = gsi_for_stmt (stmt); 490 tree ref_ptr = tree_coverage_counter_addr (tag, base); 491 gcall *call; 492 tree val; 493 494 ref_ptr = force_gimple_operand_gsi (&gsi, ref_ptr, 495 true, NULL_TREE, true, GSI_SAME_STMT); 496 val = prepare_instrumented_value (&gsi, value); 497 call = gimple_build_call (tree_ior_profiler_fn, 2, ref_ptr, val); 498 gsi_insert_before (&gsi, call, GSI_NEW_STMT); 499 } 500 501 /* Profile all functions in the callgraph. */ 502 503 static unsigned int 504 tree_profiling (void) 505 { 506 struct cgraph_node *node; 507 508 /* This is a small-ipa pass that gets called only once, from 509 cgraphunit.c:ipa_passes(). */ 510 gcc_assert (symtab->state == IPA_SSA); 511 512 init_node_map (true); 513 514 FOR_EACH_DEFINED_FUNCTION (node) 515 { 516 if (!gimple_has_body_p (node->decl)) 517 continue; 518 519 /* Don't profile functions produced for builtin stuff. */ 520 if (DECL_SOURCE_LOCATION (node->decl) == BUILTINS_LOCATION) 521 continue; 522 523 /* Do not instrument extern inline functions when testing coverage. 524 While this is not perfectly consistent (early inlined extern inlines 525 will get acocunted), testsuite expects that. */ 526 if (DECL_EXTERNAL (node->decl) 527 && flag_test_coverage) 528 continue; 529 530 push_cfun (DECL_STRUCT_FUNCTION (node->decl)); 531 532 /* Local pure-const may imply need to fixup the cfg. */ 533 if (execute_fixup_cfg () & TODO_cleanup_cfg) 534 cleanup_tree_cfg (); 535 536 branch_prob (); 537 538 if (! flag_branch_probabilities 539 && flag_profile_values) 540 gimple_gen_ic_func_profiler (); 541 542 if (flag_branch_probabilities 543 && flag_profile_values 544 && flag_value_profile_transformations) 545 gimple_value_profile_transformations (); 546 547 /* The above could hose dominator info. Currently there is 548 none coming in, this is a safety valve. It should be 549 easy to adjust it, if and when there is some. */ 550 free_dominance_info (CDI_DOMINATORS); 551 free_dominance_info (CDI_POST_DOMINATORS); 552 pop_cfun (); 553 } 554 555 /* Drop pure/const flags from instrumented functions. */ 556 if (profile_arc_flag || flag_test_coverage) 557 FOR_EACH_DEFINED_FUNCTION (node) 558 { 559 if (!gimple_has_body_p (node->decl) 560 || !(!node->clone_of 561 || node->decl != node->clone_of->decl)) 562 continue; 563 564 /* Don't profile functions produced for builtin stuff. */ 565 if (DECL_SOURCE_LOCATION (node->decl) == BUILTINS_LOCATION) 566 continue; 567 568 node->set_const_flag (false, false); 569 node->set_pure_flag (false, false); 570 } 571 572 /* Update call statements and rebuild the cgraph. */ 573 FOR_EACH_DEFINED_FUNCTION (node) 574 { 575 basic_block bb; 576 577 if (!gimple_has_body_p (node->decl) 578 || !(!node->clone_of 579 || node->decl != node->clone_of->decl)) 580 continue; 581 582 /* Don't profile functions produced for builtin stuff. */ 583 if (DECL_SOURCE_LOCATION (node->decl) == BUILTINS_LOCATION) 584 continue; 585 586 push_cfun (DECL_STRUCT_FUNCTION (node->decl)); 587 588 FOR_EACH_BB_FN (bb, cfun) 589 { 590 gimple_stmt_iterator gsi; 591 for (gsi = gsi_start_bb (bb); !gsi_end_p (gsi); gsi_next (&gsi)) 592 { 593 gimple *stmt = gsi_stmt (gsi); 594 if (is_gimple_call (stmt)) 595 update_stmt (stmt); 596 } 597 } 598 599 /* re-merge split blocks. */ 600 cleanup_tree_cfg (); 601 update_ssa (TODO_update_ssa); 602 603 cgraph_edge::rebuild_edges (); 604 605 pop_cfun (); 606 } 607 608 handle_missing_profiles (); 609 610 del_node_map (); 611 return 0; 612 } 613 614 namespace { 615 616 const pass_data pass_data_ipa_tree_profile = 617 { 618 SIMPLE_IPA_PASS, /* type */ 619 "profile", /* name */ 620 OPTGROUP_NONE, /* optinfo_flags */ 621 TV_IPA_PROFILE, /* tv_id */ 622 0, /* properties_required */ 623 0, /* properties_provided */ 624 0, /* properties_destroyed */ 625 0, /* todo_flags_start */ 626 TODO_dump_symtab, /* todo_flags_finish */ 627 }; 628 629 class pass_ipa_tree_profile : public simple_ipa_opt_pass 630 { 631 public: 632 pass_ipa_tree_profile (gcc::context *ctxt) 633 : simple_ipa_opt_pass (pass_data_ipa_tree_profile, ctxt) 634 {} 635 636 /* opt_pass methods: */ 637 virtual bool gate (function *); 638 virtual unsigned int execute (function *) { return tree_profiling (); } 639 640 }; // class pass_ipa_tree_profile 641 642 bool 643 pass_ipa_tree_profile::gate (function *) 644 { 645 /* When profile instrumentation, use or test coverage shall be performed. 646 But for AutoFDO, this there is no instrumentation, thus this pass is 647 diabled. */ 648 return (!in_lto_p && !flag_auto_profile 649 && (flag_branch_probabilities || flag_test_coverage 650 || profile_arc_flag)); 651 } 652 653 } // anon namespace 654 655 simple_ipa_opt_pass * 656 make_pass_ipa_tree_profile (gcc::context *ctxt) 657 { 658 return new pass_ipa_tree_profile (ctxt); 659 } 660 661 #include "gt-tree-profile.h" 662