tree-profile.c 22 KB

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