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