tracer.c 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450
  1. /* The tracer pass for the GNU compiler.
  2. Contributed by Jan Hubicka, SuSE Labs.
  3. Adapted to work on GIMPLE instead of RTL by Robert Kidd, UIUC.
  4. Copyright (C) 2001-2015 Free Software Foundation, Inc.
  5. This file is part of GCC.
  6. GCC is free software; you can redistribute it and/or modify it
  7. under the terms of the GNU General Public License as published by
  8. the Free Software Foundation; either version 3, or (at your option)
  9. any later version.
  10. GCC is distributed in the hope that it will be useful, but WITHOUT
  11. ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
  12. or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
  13. License for more details.
  14. You should have received a copy of the GNU General Public License
  15. along with GCC; see the file COPYING3. If not see
  16. <http://www.gnu.org/licenses/>. */
  17. /* This pass performs the tail duplication needed for superblock formation.
  18. For more information see:
  19. Design and Analysis of Profile-Based Optimization in Compaq's
  20. Compilation Tools for Alpha; Journal of Instruction-Level
  21. Parallelism 3 (2000) 1-25
  22. Unlike Compaq's implementation we don't do the loop peeling as most
  23. probably a better job can be done by a special pass and we don't
  24. need to worry too much about the code size implications as the tail
  25. duplicates are crossjumped again if optimizations are not
  26. performed. */
  27. #include "config.h"
  28. #include "system.h"
  29. #include "coretypes.h"
  30. #include "tm.h"
  31. #include "hash-set.h"
  32. #include "machmode.h"
  33. #include "vec.h"
  34. #include "double-int.h"
  35. #include "input.h"
  36. #include "alias.h"
  37. #include "symtab.h"
  38. #include "wide-int.h"
  39. #include "inchash.h"
  40. #include "tree.h"
  41. #include "fold-const.h"
  42. #include "rtl.h"
  43. #include "hard-reg-set.h"
  44. #include "profile.h"
  45. #include "predict.h"
  46. #include "input.h"
  47. #include "function.h"
  48. #include "dominance.h"
  49. #include "cfg.h"
  50. #include "cfganal.h"
  51. #include "basic-block.h"
  52. #include "flags.h"
  53. #include "params.h"
  54. #include "coverage.h"
  55. #include "tree-pass.h"
  56. #include "tree-ssa-alias.h"
  57. #include "internal-fn.h"
  58. #include "gimple-expr.h"
  59. #include "is-a.h"
  60. #include "gimple.h"
  61. #include "gimple-iterator.h"
  62. #include "tree-cfg.h"
  63. #include "tree-ssa.h"
  64. #include "tree-inline.h"
  65. #include "cfgloop.h"
  66. #include "fibonacci_heap.h"
  67. static int count_insns (basic_block);
  68. static bool ignore_bb_p (const_basic_block);
  69. static bool better_p (const_edge, const_edge);
  70. static edge find_best_successor (basic_block);
  71. static edge find_best_predecessor (basic_block);
  72. static int find_trace (basic_block, basic_block *);
  73. /* Minimal outgoing edge probability considered for superblock formation. */
  74. static int probability_cutoff;
  75. static int branch_ratio_cutoff;
  76. /* A bit BB->index is set if BB has already been seen, i.e. it is
  77. connected to some trace already. */
  78. sbitmap bb_seen;
  79. static inline void
  80. mark_bb_seen (basic_block bb)
  81. {
  82. unsigned int size = SBITMAP_SIZE (bb_seen);
  83. if ((unsigned int)bb->index >= size)
  84. bb_seen = sbitmap_resize (bb_seen, size * 2, 0);
  85. bitmap_set_bit (bb_seen, bb->index);
  86. }
  87. static inline bool
  88. bb_seen_p (basic_block bb)
  89. {
  90. return bitmap_bit_p (bb_seen, bb->index);
  91. }
  92. /* Return true if we should ignore the basic block for purposes of tracing. */
  93. static bool
  94. ignore_bb_p (const_basic_block bb)
  95. {
  96. gimple g;
  97. if (bb->index < NUM_FIXED_BLOCKS)
  98. return true;
  99. if (optimize_bb_for_size_p (bb))
  100. return true;
  101. /* A transaction is a single entry multiple exit region. It must be
  102. duplicated in its entirety or not at all. */
  103. g = last_stmt (CONST_CAST_BB (bb));
  104. if (g && gimple_code (g) == GIMPLE_TRANSACTION)
  105. return true;
  106. return false;
  107. }
  108. /* Return number of instructions in the block. */
  109. static int
  110. count_insns (basic_block bb)
  111. {
  112. gimple_stmt_iterator gsi;
  113. gimple stmt;
  114. int n = 0;
  115. for (gsi = gsi_start_bb (bb); !gsi_end_p (gsi); gsi_next (&gsi))
  116. {
  117. stmt = gsi_stmt (gsi);
  118. n += estimate_num_insns (stmt, &eni_size_weights);
  119. }
  120. return n;
  121. }
  122. /* Return true if E1 is more frequent than E2. */
  123. static bool
  124. better_p (const_edge e1, const_edge e2)
  125. {
  126. if (e1->count != e2->count)
  127. return e1->count > e2->count;
  128. if (e1->src->frequency * e1->probability !=
  129. e2->src->frequency * e2->probability)
  130. return (e1->src->frequency * e1->probability
  131. > e2->src->frequency * e2->probability);
  132. /* This is needed to avoid changes in the decision after
  133. CFG is modified. */
  134. if (e1->src != e2->src)
  135. return e1->src->index > e2->src->index;
  136. return e1->dest->index > e2->dest->index;
  137. }
  138. /* Return most frequent successor of basic block BB. */
  139. static edge
  140. find_best_successor (basic_block bb)
  141. {
  142. edge e;
  143. edge best = NULL;
  144. edge_iterator ei;
  145. FOR_EACH_EDGE (e, ei, bb->succs)
  146. if (!best || better_p (e, best))
  147. best = e;
  148. if (!best || ignore_bb_p (best->dest))
  149. return NULL;
  150. if (best->probability <= probability_cutoff)
  151. return NULL;
  152. return best;
  153. }
  154. /* Return most frequent predecessor of basic block BB. */
  155. static edge
  156. find_best_predecessor (basic_block bb)
  157. {
  158. edge e;
  159. edge best = NULL;
  160. edge_iterator ei;
  161. FOR_EACH_EDGE (e, ei, bb->preds)
  162. if (!best || better_p (e, best))
  163. best = e;
  164. if (!best || ignore_bb_p (best->src))
  165. return NULL;
  166. if (EDGE_FREQUENCY (best) * REG_BR_PROB_BASE
  167. < bb->frequency * branch_ratio_cutoff)
  168. return NULL;
  169. return best;
  170. }
  171. /* Find the trace using bb and record it in the TRACE array.
  172. Return number of basic blocks recorded. */
  173. static int
  174. find_trace (basic_block bb, basic_block *trace)
  175. {
  176. int i = 0;
  177. edge e;
  178. if (dump_file)
  179. fprintf (dump_file, "Trace seed %i [%i]", bb->index, bb->frequency);
  180. while ((e = find_best_predecessor (bb)) != NULL)
  181. {
  182. basic_block bb2 = e->src;
  183. if (bb_seen_p (bb2) || (e->flags & (EDGE_DFS_BACK | EDGE_COMPLEX))
  184. || find_best_successor (bb2) != e)
  185. break;
  186. if (dump_file)
  187. fprintf (dump_file, ",%i [%i]", bb->index, bb->frequency);
  188. bb = bb2;
  189. }
  190. if (dump_file)
  191. fprintf (dump_file, " forward %i [%i]", bb->index, bb->frequency);
  192. trace[i++] = bb;
  193. /* Follow the trace in forward direction. */
  194. while ((e = find_best_successor (bb)) != NULL)
  195. {
  196. bb = e->dest;
  197. if (bb_seen_p (bb) || (e->flags & (EDGE_DFS_BACK | EDGE_COMPLEX))
  198. || find_best_predecessor (bb) != e)
  199. break;
  200. if (dump_file)
  201. fprintf (dump_file, ",%i [%i]", bb->index, bb->frequency);
  202. trace[i++] = bb;
  203. }
  204. if (dump_file)
  205. fprintf (dump_file, "\n");
  206. return i;
  207. }
  208. /* Look for basic blocks in frequency order, construct traces and tail duplicate
  209. if profitable. */
  210. static bool
  211. tail_duplicate (void)
  212. {
  213. auto_vec<fibonacci_node<long, basic_block_def>*> blocks;
  214. blocks.safe_grow_cleared (last_basic_block_for_fn (cfun));
  215. basic_block *trace = XNEWVEC (basic_block, n_basic_blocks_for_fn (cfun));
  216. int *counts = XNEWVEC (int, last_basic_block_for_fn (cfun));
  217. int ninsns = 0, nduplicated = 0;
  218. gcov_type weighted_insns = 0, traced_insns = 0;
  219. fibonacci_heap<long, basic_block_def> heap (LONG_MIN);
  220. gcov_type cover_insns;
  221. int max_dup_insns;
  222. basic_block bb;
  223. bool changed = false;
  224. /* Create an oversized sbitmap to reduce the chance that we need to
  225. resize it. */
  226. bb_seen = sbitmap_alloc (last_basic_block_for_fn (cfun) * 2);
  227. bitmap_clear (bb_seen);
  228. initialize_original_copy_tables ();
  229. if (profile_info && flag_branch_probabilities)
  230. probability_cutoff = PARAM_VALUE (TRACER_MIN_BRANCH_PROBABILITY_FEEDBACK);
  231. else
  232. probability_cutoff = PARAM_VALUE (TRACER_MIN_BRANCH_PROBABILITY);
  233. probability_cutoff = REG_BR_PROB_BASE / 100 * probability_cutoff;
  234. branch_ratio_cutoff =
  235. (REG_BR_PROB_BASE / 100 * PARAM_VALUE (TRACER_MIN_BRANCH_RATIO));
  236. FOR_EACH_BB_FN (bb, cfun)
  237. {
  238. int n = count_insns (bb);
  239. if (!ignore_bb_p (bb))
  240. blocks[bb->index] = heap.insert (-bb->frequency, bb);
  241. counts [bb->index] = n;
  242. ninsns += n;
  243. weighted_insns += n * bb->frequency;
  244. }
  245. if (profile_info && flag_branch_probabilities)
  246. cover_insns = PARAM_VALUE (TRACER_DYNAMIC_COVERAGE_FEEDBACK);
  247. else
  248. cover_insns = PARAM_VALUE (TRACER_DYNAMIC_COVERAGE);
  249. cover_insns = (weighted_insns * cover_insns + 50) / 100;
  250. max_dup_insns = (ninsns * PARAM_VALUE (TRACER_MAX_CODE_GROWTH) + 50) / 100;
  251. while (traced_insns < cover_insns && nduplicated < max_dup_insns
  252. && !heap.empty ())
  253. {
  254. basic_block bb = heap.extract_min ();
  255. int n, pos;
  256. if (!bb)
  257. break;
  258. blocks[bb->index] = NULL;
  259. if (ignore_bb_p (bb))
  260. continue;
  261. gcc_assert (!bb_seen_p (bb));
  262. n = find_trace (bb, trace);
  263. bb = trace[0];
  264. traced_insns += bb->frequency * counts [bb->index];
  265. if (blocks[bb->index])
  266. {
  267. heap.delete_node (blocks[bb->index]);
  268. blocks[bb->index] = NULL;
  269. }
  270. for (pos = 1; pos < n; pos++)
  271. {
  272. basic_block bb2 = trace[pos];
  273. if (blocks[bb2->index])
  274. {
  275. heap.delete_node (blocks[bb2->index]);
  276. blocks[bb2->index] = NULL;
  277. }
  278. traced_insns += bb2->frequency * counts [bb2->index];
  279. if (EDGE_COUNT (bb2->preds) > 1
  280. && can_duplicate_block_p (bb2)
  281. /* We have the tendency to duplicate the loop header
  282. of all do { } while loops. Do not do that - it is
  283. not profitable and it might create a loop with multiple
  284. entries or at least rotate the loop. */
  285. && bb2->loop_father->header != bb2)
  286. {
  287. edge e;
  288. basic_block copy;
  289. nduplicated += counts [bb2->index];
  290. e = find_edge (bb, bb2);
  291. copy = duplicate_block (bb2, e, bb);
  292. flush_pending_stmts (e);
  293. add_phi_args_after_copy (&copy, 1, NULL);
  294. /* Reconsider the original copy of block we've duplicated.
  295. Removing the most common predecessor may make it to be
  296. head. */
  297. blocks[bb2->index] = heap.insert (-bb2->frequency, bb2);
  298. if (dump_file)
  299. fprintf (dump_file, "Duplicated %i as %i [%i]\n",
  300. bb2->index, copy->index, copy->frequency);
  301. bb2 = copy;
  302. changed = true;
  303. }
  304. mark_bb_seen (bb2);
  305. bb = bb2;
  306. /* In case the trace became infrequent, stop duplicating. */
  307. if (ignore_bb_p (bb))
  308. break;
  309. }
  310. if (dump_file)
  311. fprintf (dump_file, " covered now %.1f\n\n",
  312. traced_insns * 100.0 / weighted_insns);
  313. }
  314. if (dump_file)
  315. fprintf (dump_file, "Duplicated %i insns (%i%%)\n", nduplicated,
  316. nduplicated * 100 / ninsns);
  317. free_original_copy_tables ();
  318. sbitmap_free (bb_seen);
  319. free (trace);
  320. free (counts);
  321. return changed;
  322. }
  323. namespace {
  324. const pass_data pass_data_tracer =
  325. {
  326. GIMPLE_PASS, /* type */
  327. "tracer", /* name */
  328. OPTGROUP_NONE, /* optinfo_flags */
  329. TV_TRACER, /* tv_id */
  330. 0, /* properties_required */
  331. 0, /* properties_provided */
  332. 0, /* properties_destroyed */
  333. 0, /* todo_flags_start */
  334. TODO_update_ssa, /* todo_flags_finish */
  335. };
  336. class pass_tracer : public gimple_opt_pass
  337. {
  338. public:
  339. pass_tracer (gcc::context *ctxt)
  340. : gimple_opt_pass (pass_data_tracer, ctxt)
  341. {}
  342. /* opt_pass methods: */
  343. virtual bool gate (function *)
  344. {
  345. return (optimize > 0 && flag_tracer && flag_reorder_blocks);
  346. }
  347. virtual unsigned int execute (function *);
  348. }; // class pass_tracer
  349. unsigned int
  350. pass_tracer::execute (function *fun)
  351. {
  352. bool changed;
  353. if (n_basic_blocks_for_fn (fun) <= NUM_FIXED_BLOCKS + 1)
  354. return 0;
  355. mark_dfs_back_edges ();
  356. if (dump_file)
  357. brief_dump_cfg (dump_file, dump_flags);
  358. /* Trace formation is done on the fly inside tail_duplicate */
  359. changed = tail_duplicate ();
  360. if (changed)
  361. {
  362. free_dominance_info (CDI_DOMINATORS);
  363. /* If we changed the CFG schedule loops for fixup by cleanup_cfg. */
  364. loops_state_set (LOOPS_NEED_FIXUP);
  365. }
  366. if (dump_file)
  367. brief_dump_cfg (dump_file, dump_flags);
  368. return changed ? TODO_cleanup_cfg : 0;
  369. }
  370. } // anon namespace
  371. gimple_opt_pass *
  372. make_pass_tracer (gcc::context *ctxt)
  373. {
  374. return new pass_tracer (ctxt);
  375. }