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