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