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