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.
8 This file is part of GCC.
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
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
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/>. */
24 /* Generate basic block profile instrumentation and auxiliary files.
25 Tree-based version. See profile.c for overview. */
29 #include "coretypes.h"
35 #include "tree-pass.h"
39 #include "diagnostic-core.h"
42 #include "fold-const.h"
43 #include "internal-fn.h"
45 #include "tree-nested.h"
47 #include "gimple-iterator.h"
48 #include "gimplify-me.h"
50 #include "tree-into-ssa.h"
51 #include "value-prof.h"
53 #include "tree-cfgcleanup.h"
56 static GTY(()) tree gcov_type_node;
57 static GTY(()) tree tree_interval_profiler_fn;
58 static GTY(()) tree tree_pow2_profiler_fn;
59 static GTY(()) tree tree_one_value_profiler_fn;
60 static GTY(()) tree tree_indirect_call_profiler_fn;
61 static GTY(()) tree tree_time_profiler_fn;
62 static GTY(()) tree tree_average_profiler_fn;
63 static GTY(()) tree tree_ior_profiler_fn;
66 static GTY(()) tree ic_void_ptr_var;
67 static GTY(()) tree ic_gcov_type_ptr_var;
68 static GTY(()) tree ptr_void;
70 /* Do initialization work for the edge profiler. */
73 __thread gcov* __gcov_indirect_call_counters; // pointer to actual counter
74 __thread void* __gcov_indirect_call_callee; // actual callee address
75 __thread int __gcov_function_counter; // time profiler function counter
78 init_ic_make_global_vars (void)
82 ptr_void = build_pointer_type (void_type_node);
85 = build_decl (UNKNOWN_LOCATION, VAR_DECL,
87 (PARAM_VALUE (PARAM_INDIR_CALL_TOPN_PROFILE) ?
88 "__gcov_indirect_call_topn_callee" :
89 "__gcov_indirect_call_callee")),
91 TREE_PUBLIC (ic_void_ptr_var) = 1;
92 DECL_EXTERNAL (ic_void_ptr_var) = 1;
93 TREE_STATIC (ic_void_ptr_var) = 1;
94 DECL_ARTIFICIAL (ic_void_ptr_var) = 1;
95 DECL_INITIAL (ic_void_ptr_var) = NULL;
97 set_decl_tls_model (ic_void_ptr_var, decl_default_tls_model (ic_void_ptr_var));
99 varpool_node::finalize_decl (ic_void_ptr_var);
101 gcov_type_ptr = build_pointer_type (get_gcov_type ());
104 = build_decl (UNKNOWN_LOCATION, VAR_DECL,
106 (PARAM_VALUE (PARAM_INDIR_CALL_TOPN_PROFILE) ?
107 "__gcov_indirect_call_topn_counters" :
108 "__gcov_indirect_call_counters")),
110 TREE_PUBLIC (ic_gcov_type_ptr_var) = 1;
111 DECL_EXTERNAL (ic_gcov_type_ptr_var) = 1;
112 TREE_STATIC (ic_gcov_type_ptr_var) = 1;
113 DECL_ARTIFICIAL (ic_gcov_type_ptr_var) = 1;
114 DECL_INITIAL (ic_gcov_type_ptr_var) = NULL;
115 if (targetm.have_tls)
116 set_decl_tls_model (ic_gcov_type_ptr_var, decl_default_tls_model (ic_gcov_type_ptr_var));
118 varpool_node::finalize_decl (ic_gcov_type_ptr_var);
121 /* Create the type and function decls for the interface with gcov. */
124 gimple_init_edge_profiler (void)
126 tree interval_profiler_fn_type;
127 tree pow2_profiler_fn_type;
128 tree one_value_profiler_fn_type;
130 tree ic_profiler_fn_type;
131 tree average_profiler_fn_type;
132 tree time_profiler_fn_type;
136 gcov_type_node = get_gcov_type ();
137 gcov_type_ptr = build_pointer_type (gcov_type_node);
139 /* void (*) (gcov_type *, gcov_type, int, unsigned) */
140 interval_profiler_fn_type
141 = build_function_type_list (void_type_node,
142 gcov_type_ptr, gcov_type_node,
144 unsigned_type_node, NULL_TREE);
145 tree_interval_profiler_fn
146 = build_fn_decl ("__gcov_interval_profiler",
147 interval_profiler_fn_type);
148 TREE_NOTHROW (tree_interval_profiler_fn) = 1;
149 DECL_ATTRIBUTES (tree_interval_profiler_fn)
150 = tree_cons (get_identifier ("leaf"), NULL,
151 DECL_ATTRIBUTES (tree_interval_profiler_fn));
153 /* void (*) (gcov_type *, gcov_type) */
154 pow2_profiler_fn_type
155 = build_function_type_list (void_type_node,
156 gcov_type_ptr, gcov_type_node,
158 tree_pow2_profiler_fn = build_fn_decl ("__gcov_pow2_profiler",
159 pow2_profiler_fn_type);
160 TREE_NOTHROW (tree_pow2_profiler_fn) = 1;
161 DECL_ATTRIBUTES (tree_pow2_profiler_fn)
162 = tree_cons (get_identifier ("leaf"), NULL,
163 DECL_ATTRIBUTES (tree_pow2_profiler_fn));
165 /* void (*) (gcov_type *, gcov_type) */
166 one_value_profiler_fn_type
167 = build_function_type_list (void_type_node,
168 gcov_type_ptr, gcov_type_node,
170 tree_one_value_profiler_fn
171 = build_fn_decl ("__gcov_one_value_profiler",
172 one_value_profiler_fn_type);
173 TREE_NOTHROW (tree_one_value_profiler_fn) = 1;
174 DECL_ATTRIBUTES (tree_one_value_profiler_fn)
175 = tree_cons (get_identifier ("leaf"), NULL,
176 DECL_ATTRIBUTES (tree_one_value_profiler_fn));
178 init_ic_make_global_vars ();
180 /* void (*) (gcov_type, void *) */
182 = build_function_type_list (void_type_node,
186 tree_indirect_call_profiler_fn
187 = build_fn_decl ( (PARAM_VALUE (PARAM_INDIR_CALL_TOPN_PROFILE) ?
188 "__gcov_indirect_call_topn_profiler":
189 "__gcov_indirect_call_profiler_v2"),
190 ic_profiler_fn_type);
192 TREE_NOTHROW (tree_indirect_call_profiler_fn) = 1;
193 DECL_ATTRIBUTES (tree_indirect_call_profiler_fn)
194 = tree_cons (get_identifier ("leaf"), NULL,
195 DECL_ATTRIBUTES (tree_indirect_call_profiler_fn));
197 /* void (*) (gcov_type *, gcov_type, void *) */
198 time_profiler_fn_type
199 = build_function_type_list (void_type_node,
200 gcov_type_ptr, NULL_TREE);
201 tree_time_profiler_fn
202 = build_fn_decl ("__gcov_time_profiler",
203 time_profiler_fn_type);
204 TREE_NOTHROW (tree_time_profiler_fn) = 1;
205 DECL_ATTRIBUTES (tree_time_profiler_fn)
206 = tree_cons (get_identifier ("leaf"), NULL,
207 DECL_ATTRIBUTES (tree_time_profiler_fn));
209 /* void (*) (gcov_type *, gcov_type) */
210 average_profiler_fn_type
211 = build_function_type_list (void_type_node,
212 gcov_type_ptr, gcov_type_node, NULL_TREE);
213 tree_average_profiler_fn
214 = build_fn_decl ("__gcov_average_profiler",
215 average_profiler_fn_type);
216 TREE_NOTHROW (tree_average_profiler_fn) = 1;
217 DECL_ATTRIBUTES (tree_average_profiler_fn)
218 = tree_cons (get_identifier ("leaf"), NULL,
219 DECL_ATTRIBUTES (tree_average_profiler_fn));
221 = build_fn_decl ("__gcov_ior_profiler",
222 average_profiler_fn_type);
223 TREE_NOTHROW (tree_ior_profiler_fn) = 1;
224 DECL_ATTRIBUTES (tree_ior_profiler_fn)
225 = tree_cons (get_identifier ("leaf"), NULL,
226 DECL_ATTRIBUTES (tree_ior_profiler_fn));
228 /* LTO streamer needs assembler names. Because we create these decls
229 late, we need to initialize them by hand. */
230 DECL_ASSEMBLER_NAME (tree_interval_profiler_fn);
231 DECL_ASSEMBLER_NAME (tree_pow2_profiler_fn);
232 DECL_ASSEMBLER_NAME (tree_one_value_profiler_fn);
233 DECL_ASSEMBLER_NAME (tree_indirect_call_profiler_fn);
234 DECL_ASSEMBLER_NAME (tree_time_profiler_fn);
235 DECL_ASSEMBLER_NAME (tree_average_profiler_fn);
236 DECL_ASSEMBLER_NAME (tree_ior_profiler_fn);
240 /* Output instructions as GIMPLE trees to increment the edge
241 execution count, and insert them on E. We rely on
242 gsi_insert_on_edge to preserve the order. */
245 gimple_gen_edge_profiler (int edgeno, edge e)
247 tree ref, one, gcov_type_tmp_var;
248 gassign *stmt1, *stmt2, *stmt3;
250 ref = tree_coverage_counter_ref (GCOV_COUNTER_ARCS, edgeno);
251 one = build_int_cst (gcov_type_node, 1);
252 gcov_type_tmp_var = make_temp_ssa_name (gcov_type_node,
253 NULL, "PROF_edge_counter");
254 stmt1 = gimple_build_assign (gcov_type_tmp_var, ref);
255 gcov_type_tmp_var = make_temp_ssa_name (gcov_type_node,
256 NULL, "PROF_edge_counter");
257 stmt2 = gimple_build_assign (gcov_type_tmp_var, PLUS_EXPR,
258 gimple_assign_lhs (stmt1), one);
259 stmt3 = gimple_build_assign (unshare_expr (ref), gimple_assign_lhs (stmt2));
260 gsi_insert_on_edge (e, stmt1);
261 gsi_insert_on_edge (e, stmt2);
262 gsi_insert_on_edge (e, stmt3);
265 /* Emits code to get VALUE to instrument at GSI, and returns the
266 variable containing the value. */
269 prepare_instrumented_value (gimple_stmt_iterator *gsi, histogram_value value)
271 tree val = value->hvalue.value;
272 if (POINTER_TYPE_P (TREE_TYPE (val)))
273 val = fold_convert (build_nonstandard_integer_type
274 (TYPE_PRECISION (TREE_TYPE (val)), 1), val);
275 return force_gimple_operand_gsi (gsi, fold_convert (gcov_type_node, val),
276 true, NULL_TREE, true, GSI_SAME_STMT);
279 /* Output instructions as GIMPLE trees to increment the interval histogram
280 counter. VALUE is the expression whose value is profiled. TAG is the
281 tag of the section for counters, BASE is offset of the counter position. */
284 gimple_gen_interval_profiler (histogram_value value, unsigned tag, unsigned base)
286 gimple *stmt = value->hvalue.stmt;
287 gimple_stmt_iterator gsi = gsi_for_stmt (stmt);
288 tree ref = tree_coverage_counter_ref (tag, base), ref_ptr;
291 tree start = build_int_cst_type (integer_type_node,
292 value->hdata.intvl.int_start);
293 tree steps = build_int_cst_type (unsigned_type_node,
294 value->hdata.intvl.steps);
296 ref_ptr = force_gimple_operand_gsi (&gsi,
298 true, NULL_TREE, true, GSI_SAME_STMT);
299 val = prepare_instrumented_value (&gsi, value);
300 call = gimple_build_call (tree_interval_profiler_fn, 4,
301 ref_ptr, val, start, steps);
302 gsi_insert_before (&gsi, call, GSI_NEW_STMT);
305 /* Output instructions as GIMPLE trees to increment the power of two histogram
306 counter. VALUE is the expression whose value is profiled. TAG is the tag
307 of the section for counters, BASE is offset of the counter position. */
310 gimple_gen_pow2_profiler (histogram_value value, unsigned tag, unsigned base)
312 gimple *stmt = value->hvalue.stmt;
313 gimple_stmt_iterator gsi = gsi_for_stmt (stmt);
314 tree ref_ptr = tree_coverage_counter_addr (tag, base);
318 ref_ptr = force_gimple_operand_gsi (&gsi, ref_ptr,
319 true, NULL_TREE, true, GSI_SAME_STMT);
320 val = prepare_instrumented_value (&gsi, value);
321 call = gimple_build_call (tree_pow2_profiler_fn, 2, ref_ptr, val);
322 gsi_insert_before (&gsi, call, GSI_NEW_STMT);
325 /* Output instructions as GIMPLE trees for code to find the most common value.
326 VALUE is the expression whose value is profiled. TAG is the tag of the
327 section for counters, BASE is offset of the counter position. */
330 gimple_gen_one_value_profiler (histogram_value value, unsigned tag, unsigned base)
332 gimple *stmt = value->hvalue.stmt;
333 gimple_stmt_iterator gsi = gsi_for_stmt (stmt);
334 tree ref_ptr = tree_coverage_counter_addr (tag, base);
338 ref_ptr = force_gimple_operand_gsi (&gsi, ref_ptr,
339 true, NULL_TREE, true, GSI_SAME_STMT);
340 val = prepare_instrumented_value (&gsi, value);
341 call = gimple_build_call (tree_one_value_profiler_fn, 2, ref_ptr, val);
342 gsi_insert_before (&gsi, call, GSI_NEW_STMT);
346 /* Output instructions as GIMPLE trees for code to find the most
347 common called function in indirect call.
348 VALUE is the call expression whose indirect callee is profiled.
349 TAG is the tag of the section for counters, BASE is offset of the
353 gimple_gen_ic_profiler (histogram_value value, unsigned tag, unsigned base)
356 gassign *stmt1, *stmt2, *stmt3;
357 gimple *stmt = value->hvalue.stmt;
358 gimple_stmt_iterator gsi = gsi_for_stmt (stmt);
359 tree ref_ptr = tree_coverage_counter_addr (tag, base);
361 if ( (PARAM_VALUE (PARAM_INDIR_CALL_TOPN_PROFILE) &&
362 tag == GCOV_COUNTER_V_INDIR) ||
363 (!PARAM_VALUE (PARAM_INDIR_CALL_TOPN_PROFILE) &&
364 tag == GCOV_COUNTER_ICALL_TOPNV))
367 ref_ptr = force_gimple_operand_gsi (&gsi, ref_ptr,
368 true, NULL_TREE, true, GSI_SAME_STMT);
372 stmt1: __gcov_indirect_call_counters = get_relevant_counter_ptr ();
373 stmt2: tmp1 = (void *) (indirect call argument value)
374 stmt3: __gcov_indirect_call_callee = tmp1;
377 stmt1 = gimple_build_assign (ic_gcov_type_ptr_var, ref_ptr);
378 tmp1 = make_temp_ssa_name (ptr_void, NULL, "PROF");
379 stmt2 = gimple_build_assign (tmp1, unshare_expr (value->hvalue.value));
380 stmt3 = gimple_build_assign (ic_void_ptr_var, gimple_assign_lhs (stmt2));
382 gsi_insert_before (&gsi, stmt1, GSI_SAME_STMT);
383 gsi_insert_before (&gsi, stmt2, GSI_SAME_STMT);
384 gsi_insert_before (&gsi, stmt3, GSI_SAME_STMT);
388 /* Output instructions as GIMPLE trees for code to find the most
389 common called function in indirect call. Insert instructions at the
390 beginning of every possible called function.
394 gimple_gen_ic_func_profiler (void)
396 struct cgraph_node * c_node = cgraph_node::get (current_function_decl);
397 gimple_stmt_iterator gsi;
400 tree tree_uid, cur_func, void0;
402 if (c_node->only_called_directly_p ())
405 gimple_init_edge_profiler ();
409 stmt1: __gcov_indirect_call_profiler_v2 (profile_id,
410 ¤t_function_decl)
412 gsi = gsi_after_labels (split_edge (single_succ_edge
413 (ENTRY_BLOCK_PTR_FOR_FN (cfun))));
415 cur_func = force_gimple_operand_gsi (&gsi,
416 build_addr (current_function_decl),
418 true, GSI_SAME_STMT);
419 tree_uid = build_int_cst
421 cgraph_node::get (current_function_decl)->profile_id);
422 stmt1 = gimple_build_call (tree_indirect_call_profiler_fn, 2,
424 gsi_insert_before (&gsi, stmt1, GSI_SAME_STMT);
426 /* Set __gcov_indirect_call_callee to 0,
427 so that calls from other modules won't get misattributed
428 to the last caller of the current callee. */
429 void0 = build_int_cst (build_pointer_type (void_type_node), 0);
430 stmt2 = gimple_build_assign (ic_void_ptr_var, void0);
431 gsi_insert_before (&gsi, stmt2, GSI_SAME_STMT);
434 /* Output instructions as GIMPLE tree at the beginning for each function.
435 TAG is the tag of the section for counters, BASE is offset of the
436 counter position and GSI is the iterator we place the counter. */
439 gimple_gen_time_profiler (unsigned tag, unsigned base,
440 gimple_stmt_iterator &gsi)
442 tree ref_ptr = tree_coverage_counter_addr (tag, base);
445 ref_ptr = force_gimple_operand_gsi (&gsi, ref_ptr,
446 true, NULL_TREE, true, GSI_SAME_STMT);
447 call = gimple_build_call (tree_time_profiler_fn, 1, ref_ptr);
448 gsi_insert_before (&gsi, call, GSI_NEW_STMT);
451 /* Output instructions as GIMPLE trees for code to find the most common value
452 of a difference between two evaluations of an expression.
453 VALUE is the expression whose value is profiled. TAG is the tag of the
454 section for counters, BASE is offset of the counter position. */
457 gimple_gen_const_delta_profiler (histogram_value value ATTRIBUTE_UNUSED,
458 unsigned tag ATTRIBUTE_UNUSED,
459 unsigned base ATTRIBUTE_UNUSED)
461 /* FIXME implement this. */
463 internal_error ("unimplemented functionality");
467 /* Output instructions as GIMPLE trees to increment the average histogram
468 counter. VALUE is the expression whose value is profiled. TAG is the
469 tag of the section for counters, BASE is offset of the counter position. */
472 gimple_gen_average_profiler (histogram_value value, unsigned tag, unsigned base)
474 gimple *stmt = value->hvalue.stmt;
475 gimple_stmt_iterator gsi = gsi_for_stmt (stmt);
476 tree ref_ptr = tree_coverage_counter_addr (tag, base);
480 ref_ptr = force_gimple_operand_gsi (&gsi, ref_ptr,
482 true, GSI_SAME_STMT);
483 val = prepare_instrumented_value (&gsi, value);
484 call = gimple_build_call (tree_average_profiler_fn, 2, ref_ptr, val);
485 gsi_insert_before (&gsi, call, GSI_NEW_STMT);
488 /* Output instructions as GIMPLE trees to increment the ior histogram
489 counter. VALUE is the expression whose value is profiled. TAG is the
490 tag of the section for counters, BASE is offset of the counter position. */
493 gimple_gen_ior_profiler (histogram_value value, unsigned tag, unsigned base)
495 gimple *stmt = value->hvalue.stmt;
496 gimple_stmt_iterator gsi = gsi_for_stmt (stmt);
497 tree ref_ptr = tree_coverage_counter_addr (tag, base);
501 ref_ptr = force_gimple_operand_gsi (&gsi, ref_ptr,
502 true, NULL_TREE, true, GSI_SAME_STMT);
503 val = prepare_instrumented_value (&gsi, value);
504 call = gimple_build_call (tree_ior_profiler_fn, 2, ref_ptr, val);
505 gsi_insert_before (&gsi, call, GSI_NEW_STMT);
508 /* Profile all functions in the callgraph. */
511 tree_profiling (void)
513 struct cgraph_node *node;
515 /* This is a small-ipa pass that gets called only once, from
516 cgraphunit.c:ipa_passes(). */
517 gcc_assert (symtab->state == IPA_SSA);
519 init_node_map (true);
521 FOR_EACH_DEFINED_FUNCTION (node)
523 if (!gimple_has_body_p (node->decl))
526 /* Don't profile functions produced for builtin stuff. */
527 if (DECL_SOURCE_LOCATION (node->decl) == BUILTINS_LOCATION)
530 /* Do not instrument extern inline functions when testing coverage.
531 While this is not perfectly consistent (early inlined extern inlines
532 will get acocunted), testsuite expects that. */
533 if (DECL_EXTERNAL (node->decl)
534 && flag_test_coverage)
537 push_cfun (DECL_STRUCT_FUNCTION (node->decl));
539 /* Local pure-const may imply need to fixup the cfg. */
540 if (execute_fixup_cfg () & TODO_cleanup_cfg)
545 if (! flag_branch_probabilities
546 && flag_profile_values)
547 gimple_gen_ic_func_profiler ();
549 if (flag_branch_probabilities
550 && flag_profile_values
551 && flag_value_profile_transformations)
552 gimple_value_profile_transformations ();
554 /* The above could hose dominator info. Currently there is
555 none coming in, this is a safety valve. It should be
556 easy to adjust it, if and when there is some. */
557 free_dominance_info (CDI_DOMINATORS);
558 free_dominance_info (CDI_POST_DOMINATORS);
562 /* Drop pure/const flags from instrumented functions. */
563 if (profile_arc_flag || flag_test_coverage)
564 FOR_EACH_DEFINED_FUNCTION (node)
566 if (!gimple_has_body_p (node->decl)
568 || node->decl != node->clone_of->decl))
571 /* Don't profile functions produced for builtin stuff. */
572 if (DECL_SOURCE_LOCATION (node->decl) == BUILTINS_LOCATION)
575 node->set_const_flag (false, false);
576 node->set_pure_flag (false, false);
579 /* Update call statements and rebuild the cgraph. */
580 FOR_EACH_DEFINED_FUNCTION (node)
584 if (!gimple_has_body_p (node->decl)
586 || node->decl != node->clone_of->decl))
589 /* Don't profile functions produced for builtin stuff. */
590 if (DECL_SOURCE_LOCATION (node->decl) == BUILTINS_LOCATION)
593 push_cfun (DECL_STRUCT_FUNCTION (node->decl));
595 FOR_EACH_BB_FN (bb, cfun)
597 gimple_stmt_iterator gsi;
598 for (gsi = gsi_start_bb (bb); !gsi_end_p (gsi); gsi_next (&gsi))
600 gimple *stmt = gsi_stmt (gsi);
601 if (is_gimple_call (stmt))
606 /* re-merge split blocks. */
608 update_ssa (TODO_update_ssa);
610 cgraph_edge::rebuild_edges ();
615 handle_missing_profiles ();
623 const pass_data pass_data_ipa_tree_profile =
625 SIMPLE_IPA_PASS, /* type */
626 "profile", /* name */
627 OPTGROUP_NONE, /* optinfo_flags */
628 TV_IPA_PROFILE, /* tv_id */
629 0, /* properties_required */
630 0, /* properties_provided */
631 0, /* properties_destroyed */
632 0, /* todo_flags_start */
633 TODO_dump_symtab, /* todo_flags_finish */
636 class pass_ipa_tree_profile : public simple_ipa_opt_pass
639 pass_ipa_tree_profile (gcc::context *ctxt)
640 : simple_ipa_opt_pass (pass_data_ipa_tree_profile, ctxt)
643 /* opt_pass methods: */
644 virtual bool gate (function *);
645 virtual unsigned int execute (function *) { return tree_profiling (); }
647 }; // class pass_ipa_tree_profile
650 pass_ipa_tree_profile::gate (function *)
652 /* When profile instrumentation, use or test coverage shall be performed.
653 But for AutoFDO, this there is no instrumentation, thus this pass is
655 return (!in_lto_p && !flag_auto_profile
656 && (flag_branch_probabilities || flag_test_coverage
657 || profile_arc_flag));
662 simple_ipa_opt_pass *
663 make_pass_ipa_tree_profile (gcc::context *ctxt)
665 return new pass_ipa_tree_profile (ctxt);
668 #include "gt-tree-profile.h"