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