Mercurial > hg > CbC > CbC_gcc
comparison gcc/tree-profile.c @ 55:77e2b8dfacca gcc-4.4.5
update it from 4.4.3 to 4.5.0
author | ryoma <e075725@ie.u-ryukyu.ac.jp> |
---|---|
date | Fri, 12 Feb 2010 23:39:51 +0900 |
parents | a06113de4d67 |
children | b7f97abdc517 |
comparison
equal
deleted
inserted
replaced
52:c156f1bd5cd9 | 55:77e2b8dfacca |
---|---|
71 tree_init_ic_make_global_vars (void) | 71 tree_init_ic_make_global_vars (void) |
72 { | 72 { |
73 tree gcov_type_ptr; | 73 tree gcov_type_ptr; |
74 | 74 |
75 ptr_void = build_pointer_type (void_type_node); | 75 ptr_void = build_pointer_type (void_type_node); |
76 | 76 |
77 ic_void_ptr_var | 77 ic_void_ptr_var |
78 = build_decl (VAR_DECL, | 78 = build_decl (UNKNOWN_LOCATION, VAR_DECL, |
79 get_identifier ("__gcov_indirect_call_callee"), | 79 get_identifier ("__gcov_indirect_call_callee"), |
80 ptr_void); | 80 ptr_void); |
81 TREE_STATIC (ic_void_ptr_var) = 1; | 81 TREE_STATIC (ic_void_ptr_var) = 1; |
82 TREE_PUBLIC (ic_void_ptr_var) = 0; | 82 TREE_PUBLIC (ic_void_ptr_var) = 0; |
83 DECL_ARTIFICIAL (ic_void_ptr_var) = 1; | 83 DECL_ARTIFICIAL (ic_void_ptr_var) = 1; |
84 DECL_INITIAL (ic_void_ptr_var) = NULL; | 84 DECL_INITIAL (ic_void_ptr_var) = NULL; |
85 assemble_variable (ic_void_ptr_var, 0, 0, 0); | 85 varpool_finalize_decl (ic_void_ptr_var); |
86 | 86 |
87 gcov_type_ptr = build_pointer_type (get_gcov_type ()); | 87 gcov_type_ptr = build_pointer_type (get_gcov_type ()); |
88 ic_gcov_type_ptr_var | 88 ic_gcov_type_ptr_var |
89 = build_decl (VAR_DECL, | 89 = build_decl (UNKNOWN_LOCATION, VAR_DECL, |
90 get_identifier ("__gcov_indirect_call_counters"), | 90 get_identifier ("__gcov_indirect_call_counters"), |
91 gcov_type_ptr); | 91 gcov_type_ptr); |
92 TREE_STATIC (ic_gcov_type_ptr_var) = 1; | 92 TREE_STATIC (ic_gcov_type_ptr_var) = 1; |
93 TREE_PUBLIC (ic_gcov_type_ptr_var) = 0; | 93 TREE_PUBLIC (ic_gcov_type_ptr_var) = 0; |
94 DECL_ARTIFICIAL (ic_gcov_type_ptr_var) = 1; | 94 DECL_ARTIFICIAL (ic_gcov_type_ptr_var) = 1; |
95 DECL_INITIAL (ic_gcov_type_ptr_var) = NULL; | 95 DECL_INITIAL (ic_gcov_type_ptr_var) = NULL; |
96 assemble_variable (ic_gcov_type_ptr_var, 0, 0, 0); | 96 varpool_finalize_decl (ic_gcov_type_ptr_var); |
97 } | 97 } |
98 | 98 |
99 static void | 99 static void |
100 tree_init_edge_profiler (void) | 100 tree_init_edge_profiler (void) |
101 { | 101 { |
137 tree_one_value_profiler_fn | 137 tree_one_value_profiler_fn |
138 = build_fn_decl ("__gcov_one_value_profiler", | 138 = build_fn_decl ("__gcov_one_value_profiler", |
139 one_value_profiler_fn_type); | 139 one_value_profiler_fn_type); |
140 | 140 |
141 tree_init_ic_make_global_vars (); | 141 tree_init_ic_make_global_vars (); |
142 | 142 |
143 /* void (*) (gcov_type *, gcov_type, void *, void *) */ | 143 /* void (*) (gcov_type *, gcov_type, void *, void *) */ |
144 ic_profiler_fn_type | 144 ic_profiler_fn_type |
145 = build_function_type_list (void_type_node, | 145 = build_function_type_list (void_type_node, |
146 gcov_type_ptr, gcov_type_node, | 146 gcov_type_ptr, gcov_type_node, |
147 ptr_void, | 147 ptr_void, |
157 = build_fn_decl ("__gcov_average_profiler", | 157 = build_fn_decl ("__gcov_average_profiler", |
158 average_profiler_fn_type); | 158 average_profiler_fn_type); |
159 tree_ior_profiler_fn | 159 tree_ior_profiler_fn |
160 = build_fn_decl ("__gcov_ior_profiler", | 160 = build_fn_decl ("__gcov_ior_profiler", |
161 average_profiler_fn_type); | 161 average_profiler_fn_type); |
162 /* LTO streamer needs assembler names. Because we create these decls | |
163 late, we need to initialize them by hand. */ | |
164 DECL_ASSEMBLER_NAME (tree_interval_profiler_fn); | |
165 DECL_ASSEMBLER_NAME (tree_pow2_profiler_fn); | |
166 DECL_ASSEMBLER_NAME (tree_one_value_profiler_fn); | |
167 DECL_ASSEMBLER_NAME (tree_indirect_call_profiler_fn); | |
168 DECL_ASSEMBLER_NAME (tree_average_profiler_fn); | |
169 DECL_ASSEMBLER_NAME (tree_ior_profiler_fn); | |
162 } | 170 } |
163 } | 171 } |
164 | 172 |
165 /* New call was added, make goto call edges if neccesary. */ | 173 /* New call was added, make goto call edges if neccesary. */ |
166 | 174 |
174 if (!gsi_end_p (gsi)) | 182 if (!gsi_end_p (gsi)) |
175 split_block (gimple_bb (stmt), stmt); | 183 split_block (gimple_bb (stmt), stmt); |
176 make_abnormal_goto_edges (gimple_bb (stmt), true); | 184 make_abnormal_goto_edges (gimple_bb (stmt), true); |
177 } | 185 } |
178 | 186 |
179 /* Output instructions as GIMPLE trees to increment the edge | 187 /* Output instructions as GIMPLE trees to increment the edge |
180 execution count, and insert them on E. We rely on | 188 execution count, and insert them on E. We rely on |
181 gsi_insert_on_edge to preserve the order. */ | 189 gsi_insert_on_edge to preserve the order. */ |
182 | 190 |
183 static void | 191 static void |
184 tree_gen_edge_profiler (int edgeno, edge e) | 192 tree_gen_edge_profiler (int edgeno, edge e) |
185 { | 193 { |
206 | 214 |
207 static tree | 215 static tree |
208 prepare_instrumented_value (gimple_stmt_iterator *gsi, histogram_value value) | 216 prepare_instrumented_value (gimple_stmt_iterator *gsi, histogram_value value) |
209 { | 217 { |
210 tree val = value->hvalue.value; | 218 tree val = value->hvalue.value; |
219 if (POINTER_TYPE_P (TREE_TYPE (val))) | |
220 val = fold_convert (sizetype, val); | |
211 return force_gimple_operand_gsi (gsi, fold_convert (gcov_type_node, val), | 221 return force_gimple_operand_gsi (gsi, fold_convert (gcov_type_node, val), |
212 true, NULL_TREE, true, GSI_SAME_STMT); | 222 true, NULL_TREE, true, GSI_SAME_STMT); |
213 } | 223 } |
214 | 224 |
215 /* Output instructions as GIMPLE trees to increment the interval histogram | 225 /* Output instructions as GIMPLE trees to increment the interval histogram |
216 counter. VALUE is the expression whose value is profiled. TAG is the | 226 counter. VALUE is the expression whose value is profiled. TAG is the |
217 tag of the section for counters, BASE is offset of the counter position. */ | 227 tag of the section for counters, BASE is offset of the counter position. */ |
218 | 228 |
219 static void | 229 static void |
220 tree_gen_interval_profiler (histogram_value value, unsigned tag, unsigned base) | 230 tree_gen_interval_profiler (histogram_value value, unsigned tag, unsigned base) |
221 { | 231 { |
226 tree val; | 236 tree val; |
227 tree start = build_int_cst_type (integer_type_node, | 237 tree start = build_int_cst_type (integer_type_node, |
228 value->hdata.intvl.int_start); | 238 value->hdata.intvl.int_start); |
229 tree steps = build_int_cst_type (unsigned_type_node, | 239 tree steps = build_int_cst_type (unsigned_type_node, |
230 value->hdata.intvl.steps); | 240 value->hdata.intvl.steps); |
231 | 241 |
232 ref_ptr = force_gimple_operand_gsi (&gsi, | 242 ref_ptr = force_gimple_operand_gsi (&gsi, |
233 build_addr (ref, current_function_decl), | 243 build_addr (ref, current_function_decl), |
234 true, NULL_TREE, true, GSI_SAME_STMT); | 244 true, NULL_TREE, true, GSI_SAME_STMT); |
235 val = prepare_instrumented_value (&gsi, value); | 245 val = prepare_instrumented_value (&gsi, value); |
236 call = gimple_build_call (tree_interval_profiler_fn, 4, | 246 call = gimple_build_call (tree_interval_profiler_fn, 4, |
237 ref_ptr, val, start, steps); | 247 ref_ptr, val, start, steps); |
238 gsi_insert_before (&gsi, call, GSI_NEW_STMT); | 248 gsi_insert_before (&gsi, call, GSI_NEW_STMT); |
239 add_abnormal_goto_call_edges (gsi); | 249 add_abnormal_goto_call_edges (gsi); |
240 } | 250 } |
241 | 251 |
242 /* Output instructions as GIMPLE trees to increment the power of two histogram | 252 /* Output instructions as GIMPLE trees to increment the power of two histogram |
243 counter. VALUE is the expression whose value is profiled. TAG is the tag | 253 counter. VALUE is the expression whose value is profiled. TAG is the tag |
244 of the section for counters, BASE is offset of the counter position. */ | 254 of the section for counters, BASE is offset of the counter position. */ |
245 | 255 |
246 static void | 256 static void |
247 tree_gen_pow2_profiler (histogram_value value, unsigned tag, unsigned base) | 257 tree_gen_pow2_profiler (histogram_value value, unsigned tag, unsigned base) |
248 { | 258 { |
249 gimple stmt = value->hvalue.stmt; | 259 gimple stmt = value->hvalue.stmt; |
250 gimple_stmt_iterator gsi = gsi_for_stmt (stmt); | 260 gimple_stmt_iterator gsi = gsi_for_stmt (stmt); |
251 tree ref_ptr = tree_coverage_counter_addr (tag, base); | 261 tree ref_ptr = tree_coverage_counter_addr (tag, base); |
252 gimple call; | 262 gimple call; |
253 tree val; | 263 tree val; |
254 | 264 |
255 ref_ptr = force_gimple_operand_gsi (&gsi, ref_ptr, | 265 ref_ptr = force_gimple_operand_gsi (&gsi, ref_ptr, |
256 true, NULL_TREE, true, GSI_SAME_STMT); | 266 true, NULL_TREE, true, GSI_SAME_STMT); |
257 val = prepare_instrumented_value (&gsi, value); | 267 val = prepare_instrumented_value (&gsi, value); |
258 call = gimple_build_call (tree_pow2_profiler_fn, 2, ref_ptr, val); | 268 call = gimple_build_call (tree_pow2_profiler_fn, 2, ref_ptr, val); |
259 gsi_insert_before (&gsi, call, GSI_NEW_STMT); | 269 gsi_insert_before (&gsi, call, GSI_NEW_STMT); |
270 gimple stmt = value->hvalue.stmt; | 280 gimple stmt = value->hvalue.stmt; |
271 gimple_stmt_iterator gsi = gsi_for_stmt (stmt); | 281 gimple_stmt_iterator gsi = gsi_for_stmt (stmt); |
272 tree ref_ptr = tree_coverage_counter_addr (tag, base); | 282 tree ref_ptr = tree_coverage_counter_addr (tag, base); |
273 gimple call; | 283 gimple call; |
274 tree val; | 284 tree val; |
275 | 285 |
276 ref_ptr = force_gimple_operand_gsi (&gsi, ref_ptr, | 286 ref_ptr = force_gimple_operand_gsi (&gsi, ref_ptr, |
277 true, NULL_TREE, true, GSI_SAME_STMT); | 287 true, NULL_TREE, true, GSI_SAME_STMT); |
278 val = prepare_instrumented_value (&gsi, value); | 288 val = prepare_instrumented_value (&gsi, value); |
279 call = gimple_build_call (tree_one_value_profiler_fn, 2, ref_ptr, val); | 289 call = gimple_build_call (tree_one_value_profiler_fn, 2, ref_ptr, val); |
280 gsi_insert_before (&gsi, call, GSI_NEW_STMT); | 290 gsi_insert_before (&gsi, call, GSI_NEW_STMT); |
281 add_abnormal_goto_call_edges (gsi); | 291 add_abnormal_goto_call_edges (gsi); |
282 } | 292 } |
283 | 293 |
284 | 294 |
285 /* Output instructions as GIMPLE trees for code to find the most | 295 /* Output instructions as GIMPLE trees for code to find the most |
286 common called function in indirect call. | 296 common called function in indirect call. |
287 VALUE is the call expression whose indirect callee is profiled. | 297 VALUE is the call expression whose indirect callee is profiled. |
288 TAG is the tag of the section for counters, BASE is offset of the | 298 TAG is the tag of the section for counters, BASE is offset of the |
289 counter position. */ | 299 counter position. */ |
290 | 300 |
291 static void | 301 static void |
299 | 309 |
300 ref_ptr = force_gimple_operand_gsi (&gsi, ref_ptr, | 310 ref_ptr = force_gimple_operand_gsi (&gsi, ref_ptr, |
301 true, NULL_TREE, true, GSI_SAME_STMT); | 311 true, NULL_TREE, true, GSI_SAME_STMT); |
302 | 312 |
303 /* Insert code: | 313 /* Insert code: |
304 | 314 |
305 __gcov_indirect_call_counters = get_relevant_counter_ptr (); | 315 __gcov_indirect_call_counters = get_relevant_counter_ptr (); |
306 __gcov_indirect_call_callee = (void *) indirect call argument; | 316 __gcov_indirect_call_callee = (void *) indirect call argument; |
307 */ | 317 */ |
308 | 318 |
309 tmp1 = create_tmp_var (ptr_void, "PROF"); | 319 tmp1 = create_tmp_var (ptr_void, "PROF"); |
310 stmt1 = gimple_build_assign (ic_gcov_type_ptr_var, ref_ptr); | 320 stmt1 = gimple_build_assign (ic_gcov_type_ptr_var, ref_ptr); |
333 gimple stmt1, stmt2; | 343 gimple stmt1, stmt2; |
334 tree tree_uid, cur_func; | 344 tree tree_uid, cur_func; |
335 | 345 |
336 if (!c_node->needed) | 346 if (!c_node->needed) |
337 return; | 347 return; |
338 | 348 |
339 tree_init_edge_profiler (); | 349 tree_init_edge_profiler (); |
340 | 350 |
341 FOR_EACH_EDGE (e, ei, ENTRY_BLOCK_PTR->succs) | 351 FOR_EACH_EDGE (e, ei, ENTRY_BLOCK_PTR->succs) |
342 { | 352 { |
343 tree void0; | 353 tree void0; |
344 | 354 |
345 bb = split_edge (e); | 355 bb = split_edge (e); |
346 gsi = gsi_start_bb (bb); | 356 gsi = gsi_start_bb (bb); |
347 | 357 |
348 cur_func = force_gimple_operand_gsi (&gsi, | 358 cur_func = force_gimple_operand_gsi (&gsi, |
349 build_addr (current_function_decl, | 359 build_addr (current_function_decl, |
350 current_function_decl), | 360 current_function_decl), |
351 true, NULL_TREE, | 361 true, NULL_TREE, |
352 true, GSI_SAME_STMT); | 362 true, GSI_SAME_STMT); |
353 tree_uid = build_int_cst (gcov_type_node, c_node->pid); | 363 tree_uid = build_int_cst (gcov_type_node, c_node->pid); |
354 stmt1 = gimple_build_call (tree_indirect_call_profiler_fn, 4, | 364 stmt1 = gimple_build_call (tree_indirect_call_profiler_fn, 4, |
369 stmt2 = gimple_build_assign (ic_void_ptr_var, void0); | 379 stmt2 = gimple_build_assign (ic_void_ptr_var, void0); |
370 gsi_insert_after (&gsi, stmt2, GSI_NEW_STMT); | 380 gsi_insert_after (&gsi, stmt2, GSI_NEW_STMT); |
371 } | 381 } |
372 } | 382 } |
373 | 383 |
374 /* Output instructions as GIMPLE trees for code to find the most common value | 384 /* Output instructions as GIMPLE trees for code to find the most common value |
375 of a difference between two evaluations of an expression. | 385 of a difference between two evaluations of an expression. |
376 VALUE is the expression whose value is profiled. TAG is the tag of the | 386 VALUE is the expression whose value is profiled. TAG is the tag of the |
377 section for counters, BASE is offset of the counter position. */ | 387 section for counters, BASE is offset of the counter position. */ |
378 | 388 |
379 static void | 389 static void |
386 internal_error ("unimplemented functionality"); | 396 internal_error ("unimplemented functionality"); |
387 #endif | 397 #endif |
388 gcc_unreachable (); | 398 gcc_unreachable (); |
389 } | 399 } |
390 | 400 |
391 /* Output instructions as GIMPLE trees to increment the average histogram | 401 /* Output instructions as GIMPLE trees to increment the average histogram |
392 counter. VALUE is the expression whose value is profiled. TAG is the | 402 counter. VALUE is the expression whose value is profiled. TAG is the |
393 tag of the section for counters, BASE is offset of the counter position. */ | 403 tag of the section for counters, BASE is offset of the counter position. */ |
394 | 404 |
395 static void | 405 static void |
396 tree_gen_average_profiler (histogram_value value, unsigned tag, unsigned base) | 406 tree_gen_average_profiler (histogram_value value, unsigned tag, unsigned base) |
397 { | 407 { |
398 gimple stmt = value->hvalue.stmt; | 408 gimple stmt = value->hvalue.stmt; |
399 gimple_stmt_iterator gsi = gsi_for_stmt (stmt); | 409 gimple_stmt_iterator gsi = gsi_for_stmt (stmt); |
400 tree ref_ptr = tree_coverage_counter_addr (tag, base); | 410 tree ref_ptr = tree_coverage_counter_addr (tag, base); |
401 gimple call; | 411 gimple call; |
402 tree val; | 412 tree val; |
403 | 413 |
404 ref_ptr = force_gimple_operand_gsi (&gsi, ref_ptr, | 414 ref_ptr = force_gimple_operand_gsi (&gsi, ref_ptr, |
405 true, NULL_TREE, | 415 true, NULL_TREE, |
406 true, GSI_SAME_STMT); | 416 true, GSI_SAME_STMT); |
407 val = prepare_instrumented_value (&gsi, value); | 417 val = prepare_instrumented_value (&gsi, value); |
408 call = gimple_build_call (tree_average_profiler_fn, 2, ref_ptr, val); | 418 call = gimple_build_call (tree_average_profiler_fn, 2, ref_ptr, val); |
409 gsi_insert_before (&gsi, call, GSI_NEW_STMT); | 419 gsi_insert_before (&gsi, call, GSI_NEW_STMT); |
410 add_abnormal_goto_call_edges (gsi); | 420 add_abnormal_goto_call_edges (gsi); |
411 } | 421 } |
412 | 422 |
413 /* Output instructions as GIMPLE trees to increment the ior histogram | 423 /* Output instructions as GIMPLE trees to increment the ior histogram |
414 counter. VALUE is the expression whose value is profiled. TAG is the | 424 counter. VALUE is the expression whose value is profiled. TAG is the |
415 tag of the section for counters, BASE is offset of the counter position. */ | 425 tag of the section for counters, BASE is offset of the counter position. */ |
416 | 426 |
417 static void | 427 static void |
418 tree_gen_ior_profiler (histogram_value value, unsigned tag, unsigned base) | 428 tree_gen_ior_profiler (histogram_value value, unsigned tag, unsigned base) |
419 { | 429 { |
420 gimple stmt = value->hvalue.stmt; | 430 gimple stmt = value->hvalue.stmt; |
421 gimple_stmt_iterator gsi = gsi_for_stmt (stmt); | 431 gimple_stmt_iterator gsi = gsi_for_stmt (stmt); |
422 tree ref_ptr = tree_coverage_counter_addr (tag, base); | 432 tree ref_ptr = tree_coverage_counter_addr (tag, base); |
423 gimple call; | 433 gimple call; |
424 tree val; | 434 tree val; |
425 | 435 |
426 ref_ptr = force_gimple_operand_gsi (&gsi, ref_ptr, | 436 ref_ptr = force_gimple_operand_gsi (&gsi, ref_ptr, |
427 true, NULL_TREE, true, GSI_SAME_STMT); | 437 true, NULL_TREE, true, GSI_SAME_STMT); |
428 val = prepare_instrumented_value (&gsi, value); | 438 val = prepare_instrumented_value (&gsi, value); |
429 call = gimple_build_call (tree_ior_profiler_fn, 2, ref_ptr, val); | 439 call = gimple_build_call (tree_ior_profiler_fn, 2, ref_ptr, val); |
430 gsi_insert_before (&gsi, call, GSI_NEW_STMT); | 440 gsi_insert_before (&gsi, call, GSI_NEW_STMT); |
461 /* Re-set global shared temporary variable for edge-counters. */ | 471 /* Re-set global shared temporary variable for edge-counters. */ |
462 gcov_type_tmp_var = NULL_TREE; | 472 gcov_type_tmp_var = NULL_TREE; |
463 | 473 |
464 branch_prob (); | 474 branch_prob (); |
465 | 475 |
466 if (! flag_branch_probabilities | 476 if (! flag_branch_probabilities |
467 && flag_profile_values) | 477 && flag_profile_values) |
468 tree_gen_ic_func_profiler (); | 478 tree_gen_ic_func_profiler (); |
469 | 479 |
470 if (flag_branch_probabilities | 480 if (flag_branch_probabilities |
471 && flag_profile_values | 481 && flag_profile_values |
478 free_dominance_info (CDI_POST_DOMINATORS); | 488 free_dominance_info (CDI_POST_DOMINATORS); |
479 cfun->after_tree_profile = 1; | 489 cfun->after_tree_profile = 1; |
480 return 0; | 490 return 0; |
481 } | 491 } |
482 | 492 |
483 struct gimple_opt_pass pass_tree_profile = | 493 struct gimple_opt_pass pass_tree_profile = |
484 { | 494 { |
485 { | 495 { |
486 GIMPLE_PASS, | 496 GIMPLE_PASS, |
487 "tree_profile", /* name */ | 497 "tree_profile", /* name */ |
488 do_tree_profiling, /* gate */ | 498 do_tree_profiling, /* gate */ |
490 NULL, /* sub */ | 500 NULL, /* sub */ |
491 NULL, /* next */ | 501 NULL, /* next */ |
492 0, /* static_pass_number */ | 502 0, /* static_pass_number */ |
493 TV_BRANCH_PROB, /* tv_id */ | 503 TV_BRANCH_PROB, /* tv_id */ |
494 PROP_gimple_leh | PROP_cfg, /* properties_required */ | 504 PROP_gimple_leh | PROP_cfg, /* properties_required */ |
495 PROP_gimple_leh | PROP_cfg, /* properties_provided */ | 505 0, /* properties_provided */ |
496 0, /* properties_destroyed */ | 506 0, /* properties_destroyed */ |
497 0, /* todo_flags_start */ | 507 0, /* todo_flags_start */ |
498 TODO_verify_stmts | TODO_dump_func /* todo_flags_finish */ | 508 TODO_verify_stmts | TODO_dump_func /* todo_flags_finish */ |
499 } | 509 } |
500 }; | 510 }; |