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 bool thunk = false; 657 if (!gimple_has_body_p (node->decl) && !node->thunk.thunk_p) 658 continue; 659 660 /* Don't profile functions produced for builtin stuff. */ 661 if (DECL_SOURCE_LOCATION (node->decl) == BUILTINS_LOCATION) 662 continue; 663 664 if (lookup_attribute ("no_profile_instrument_function", 665 DECL_ATTRIBUTES (node->decl))) 666 continue; 667 /* Do not instrument extern inline functions when testing coverage. 668 While this is not perfectly consistent (early inlined extern inlines 669 will get acocunted), testsuite expects that. */ 670 if (DECL_EXTERNAL (node->decl) 671 && flag_test_coverage) 672 continue; 673 674 if (node->thunk.thunk_p) 675 { 676 /* We can not expand variadic thunks to Gimple. */ 677 if (stdarg_p (TREE_TYPE (node->decl))) 678 continue; 679 thunk = true; 680 /* When generate profile, expand thunk to gimple so it can be 681 instrumented same way as other functions. */ 682 if (profile_arc_flag) 683 node->expand_thunk (false, true); 684 /* Read cgraph profile but keep function as thunk at profile-use 685 time. */ 686 else 687 { 688 read_thunk_profile (node); 689 continue; 690 } 691 } 692 693 push_cfun (DECL_STRUCT_FUNCTION (node->decl)); 694 695 if (dump_file) 696 dump_function_header (dump_file, cfun->decl, dump_flags); 697 698 /* Local pure-const may imply need to fixup the cfg. */ 699 if (gimple_has_body_p (node->decl) 700 && (execute_fixup_cfg () & TODO_cleanup_cfg)) 701 cleanup_tree_cfg (); 702 703 branch_prob (thunk); 704 705 if (! flag_branch_probabilities 706 && flag_profile_values) 707 gimple_gen_ic_func_profiler (); 708 709 if (flag_branch_probabilities 710 && !thunk 711 && flag_profile_values 712 && flag_value_profile_transformations) 713 gimple_value_profile_transformations (); 714 715 /* The above could hose dominator info. Currently there is 716 none coming in, this is a safety valve. It should be 717 easy to adjust it, if and when there is some. */ 718 free_dominance_info (CDI_DOMINATORS); 719 free_dominance_info (CDI_POST_DOMINATORS); 720 pop_cfun (); 721 } 722 723 /* Drop pure/const flags from instrumented functions. */ 724 if (profile_arc_flag || flag_test_coverage) 725 FOR_EACH_DEFINED_FUNCTION (node) 726 { 727 if (!gimple_has_body_p (node->decl) 728 || !(!node->clone_of 729 || node->decl != node->clone_of->decl)) 730 continue; 731 732 /* Don't profile functions produced for builtin stuff. */ 733 if (DECL_SOURCE_LOCATION (node->decl) == BUILTINS_LOCATION) 734 continue; 735 736 node->set_const_flag (false, false); 737 node->set_pure_flag (false, false); 738 } 739 740 /* Update call statements and rebuild the cgraph. */ 741 FOR_EACH_DEFINED_FUNCTION (node) 742 { 743 basic_block bb; 744 745 if (!gimple_has_body_p (node->decl) 746 || !(!node->clone_of 747 || node->decl != node->clone_of->decl)) 748 continue; 749 750 /* Don't profile functions produced for builtin stuff. */ 751 if (DECL_SOURCE_LOCATION (node->decl) == BUILTINS_LOCATION) 752 continue; 753 754 push_cfun (DECL_STRUCT_FUNCTION (node->decl)); 755 756 FOR_EACH_BB_FN (bb, cfun) 757 { 758 gimple_stmt_iterator gsi; 759 for (gsi = gsi_start_bb (bb); !gsi_end_p (gsi); gsi_next (&gsi)) 760 { 761 gimple *stmt = gsi_stmt (gsi); 762 if (is_gimple_call (stmt)) 763 update_stmt (stmt); 764 } 765 } 766 767 /* re-merge split blocks. */ 768 cleanup_tree_cfg (); 769 update_ssa (TODO_update_ssa); 770 771 cgraph_edge::rebuild_edges (); 772 773 pop_cfun (); 774 } 775 776 handle_missing_profiles (); 777 778 del_node_map (); 779 return 0; 780 } 781 782 namespace { 783 784 const pass_data pass_data_ipa_tree_profile = 785 { 786 SIMPLE_IPA_PASS, /* type */ 787 "profile", /* name */ 788 OPTGROUP_NONE, /* optinfo_flags */ 789 TV_IPA_PROFILE, /* tv_id */ 790 0, /* properties_required */ 791 0, /* properties_provided */ 792 0, /* properties_destroyed */ 793 0, /* todo_flags_start */ 794 TODO_dump_symtab, /* todo_flags_finish */ 795 }; 796 797 class pass_ipa_tree_profile : public simple_ipa_opt_pass 798 { 799 public: 800 pass_ipa_tree_profile (gcc::context *ctxt) 801 : simple_ipa_opt_pass (pass_data_ipa_tree_profile, ctxt) 802 {} 803 804 /* opt_pass methods: */ 805 virtual bool gate (function *); 806 virtual unsigned int execute (function *) { return tree_profiling (); } 807 808 }; // class pass_ipa_tree_profile 809 810 bool 811 pass_ipa_tree_profile::gate (function *) 812 { 813 /* When profile instrumentation, use or test coverage shall be performed. 814 But for AutoFDO, this there is no instrumentation, thus this pass is 815 diabled. */ 816 return (!in_lto_p && !flag_auto_profile 817 && (flag_branch_probabilities || flag_test_coverage 818 || profile_arc_flag)); 819 } 820 821 } // anon namespace 822 823 simple_ipa_opt_pass * 824 make_pass_ipa_tree_profile (gcc::context *ctxt) 825 { 826 return new pass_ipa_tree_profile (ctxt); 827 } 828 829 #include "gt-tree-profile.h" 830