Mercurial > hg > CbC > CbC_gcc
comparison gcc/ipa-struct-reorg.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 |
---|---|
32 #include "tree-flow.h" | 32 #include "tree-flow.h" |
33 #include "tree-flow-inline.h" | 33 #include "tree-flow-inline.h" |
34 #include "langhooks.h" | 34 #include "langhooks.h" |
35 #include "pointer-set.h" | 35 #include "pointer-set.h" |
36 #include "hashtab.h" | 36 #include "hashtab.h" |
37 #include "c-tree.h" | |
38 #include "toplev.h" | 37 #include "toplev.h" |
39 #include "flags.h" | 38 #include "flags.h" |
40 #include "debug.h" | 39 #include "debug.h" |
41 #include "target.h" | 40 #include "target.h" |
42 #include "cgraph.h" | 41 #include "cgraph.h" |
51 #include "tree-pass.h" | 50 #include "tree-pass.h" |
52 #include "ipa-struct-reorg.h" | 51 #include "ipa-struct-reorg.h" |
53 #include "opts.h" | 52 #include "opts.h" |
54 #include "ipa-type-escape.h" | 53 #include "ipa-type-escape.h" |
55 #include "tree-dump.h" | 54 #include "tree-dump.h" |
56 #include "c-common.h" | |
57 #include "gimple.h" | 55 #include "gimple.h" |
58 | 56 |
59 /* This optimization implements structure peeling. | 57 /* This optimization implements structure peeling. |
60 | 58 |
61 For example, given a structure type: | 59 For example, given a structure type: |
223 static inline tree | 221 static inline tree |
224 get_type_of_var (tree var) | 222 get_type_of_var (tree var) |
225 { | 223 { |
226 if (!var) | 224 if (!var) |
227 return NULL; | 225 return NULL; |
228 | 226 |
229 if (TREE_CODE (var) == PARM_DECL) | 227 if (TREE_CODE (var) == PARM_DECL) |
230 return DECL_ARG_TYPE (var); | 228 return DECL_ARG_TYPE (var); |
231 else | 229 else |
232 return TREE_TYPE (var); | 230 return TREE_TYPE (var); |
233 } | 231 } |
234 | 232 |
235 /* Set of actions we do for each newly generated STMT. */ | 233 /* Set of actions we do for each newly generated STMT. */ |
236 | 234 |
237 static inline void | 235 static inline void |
238 finalize_stmt (gimple stmt) | 236 finalize_stmt (gimple stmt) |
239 { | 237 { |
240 update_stmt (stmt); | 238 update_stmt (stmt); |
248 { | 246 { |
249 gimple_seq_add_stmt (stmts, stmt); | 247 gimple_seq_add_stmt (stmts, stmt); |
250 finalize_stmt (stmt); | 248 finalize_stmt (stmt); |
251 } | 249 } |
252 | 250 |
253 /* Given structure type SRT_TYPE and field FIELD, | 251 /* This function returns true if two fields FIELD1 and FIELD2 are |
254 this function is looking for a field with the same name | 252 semantically equal, and false otherwise. */ |
253 | |
254 static bool | |
255 compare_fields (tree field1, tree field2) | |
256 { | |
257 if (DECL_NAME (field1) && DECL_NAME (field2)) | |
258 { | |
259 const char *name1 = IDENTIFIER_POINTER (DECL_NAME (field1)); | |
260 const char *name2 = IDENTIFIER_POINTER (DECL_NAME (field2)); | |
261 | |
262 gcc_assert (name1 && name2); | |
263 | |
264 if (strcmp (name1, name2)) | |
265 return false; | |
266 | |
267 } | |
268 else if (DECL_NAME (field1) || DECL_NAME (field2)) | |
269 return false; | |
270 | |
271 if (!is_equal_types (TREE_TYPE (field1), TREE_TYPE (field2))) | |
272 return false; | |
273 | |
274 return true; | |
275 } | |
276 | |
277 /* Given structure type SRT_TYPE and field FIELD, | |
278 this function is looking for a field with the same name | |
255 and type as FIELD in STR_TYPE. It returns it if found, | 279 and type as FIELD in STR_TYPE. It returns it if found, |
256 or NULL_TREE otherwise. */ | 280 or NULL_TREE otherwise. */ |
257 | 281 |
258 static tree | 282 static tree |
259 find_field_in_struct_1 (tree str_type, tree field) | 283 find_field_in_struct_1 (tree str_type, tree field) |
260 { | 284 { |
261 tree str_field; | 285 tree str_field; |
262 | 286 |
263 for (str_field = TYPE_FIELDS (str_type); str_field; | 287 if (!DECL_NAME (field)) |
288 return NULL; | |
289 | |
290 for (str_field = TYPE_FIELDS (str_type); str_field; | |
264 str_field = TREE_CHAIN (str_field)) | 291 str_field = TREE_CHAIN (str_field)) |
265 { | 292 { |
266 const char * str_field_name; | 293 |
267 const char * field_name; | 294 if (!DECL_NAME (str_field)) |
268 | 295 continue; |
269 str_field_name = IDENTIFIER_POINTER (DECL_NAME (str_field)); | 296 |
270 field_name = IDENTIFIER_POINTER (DECL_NAME (field)); | 297 if (compare_fields (field, str_field)) |
271 | 298 return str_field; |
272 gcc_assert (str_field_name); | |
273 gcc_assert (field_name); | |
274 | |
275 if (!strcmp (str_field_name, field_name)) | |
276 { | |
277 /* Check field types. */ | |
278 if (is_equal_types (TREE_TYPE (str_field), TREE_TYPE (field))) | |
279 return str_field; | |
280 } | |
281 } | 299 } |
282 | 300 |
283 return NULL_TREE; | 301 return NULL_TREE; |
284 } | 302 } |
285 | 303 |
286 /* Given a field declaration FIELD_DECL, this function | 304 /* Given a field declaration FIELD_DECL, this function |
287 returns corresponding field entry in structure STR. */ | 305 returns corresponding field entry in structure STR. */ |
288 | 306 |
289 static struct field_entry * | 307 static struct field_entry * |
290 find_field_in_struct (d_str str, tree field_decl) | 308 find_field_in_struct (d_str str, tree field_decl) |
291 { | 309 { |
292 int i; | 310 int i; |
293 | 311 |
294 tree field = find_field_in_struct_1 (str->decl, field_decl); | 312 tree field = find_field_in_struct_1 (str->decl, field_decl); |
295 | 313 |
296 for (i = 0; i < str->num_fields; i++) | 314 for (i = 0; i < str->num_fields; i++) |
297 if (str->fields[i].decl == field) | 315 if (str->fields[i].decl == field) |
298 return &(str->fields[i]); | 316 return &(str->fields[i]); |
299 | 317 |
300 return NULL; | 318 return NULL; |
301 } | 319 } |
302 | 320 |
303 /* This function checks whether ARG is a result of multiplication | 321 /* This function checks whether ARG is a result of multiplication |
304 of some number by STRUCT_SIZE. If yes, the function returns true | 322 of some number by STRUCT_SIZE. If yes, the function returns true |
305 and this number is filled into NUM. */ | 323 and this number is filled into NUM. */ |
306 | 324 |
307 static bool | 325 static bool |
308 is_result_of_mult (tree arg, tree *num, tree struct_size) | 326 is_result_of_mult (tree arg, tree *num, tree struct_size) |
309 { | 327 { |
316 if (size_def_stmt && is_gimple_assign (size_def_stmt)) | 334 if (size_def_stmt && is_gimple_assign (size_def_stmt)) |
317 { | 335 { |
318 tree lhs = gimple_assign_lhs (size_def_stmt); | 336 tree lhs = gimple_assign_lhs (size_def_stmt); |
319 | 337 |
320 /* We expect temporary here. */ | 338 /* We expect temporary here. */ |
321 if (!is_gimple_reg (lhs)) | 339 if (!is_gimple_reg (lhs)) |
322 return false; | 340 return false; |
323 | 341 |
324 if (gimple_assign_rhs_code (size_def_stmt) == MULT_EXPR) | 342 if (gimple_assign_rhs_code (size_def_stmt) == MULT_EXPR) |
325 { | 343 { |
326 tree arg0 = gimple_assign_rhs1 (size_def_stmt); | 344 tree arg0 = gimple_assign_rhs1 (size_def_stmt); |
344 return false; | 362 return false; |
345 } | 363 } |
346 | 364 |
347 | 365 |
348 /* This function returns true if access ACC corresponds to the pattern | 366 /* This function returns true if access ACC corresponds to the pattern |
349 generated by compiler when an address of element i of an array | 367 generated by compiler when an address of element i of an array |
350 of structures STR_DECL (pointed by p) is calculated (p[i]). If this | 368 of structures STR_DECL (pointed by p) is calculated (p[i]). If this |
351 pattern is recognized correctly, this function returns true | 369 pattern is recognized correctly, this function returns true |
352 and fills missing fields in ACC. Otherwise it returns false. */ | 370 and fills missing fields in ACC. Otherwise it returns false. */ |
353 | 371 |
354 static bool | 372 static bool |
355 decompose_indirect_ref_acc (tree str_decl, struct field_access_site *acc) | 373 decompose_indirect_ref_acc (tree str_decl, struct field_access_site *acc) |
356 { | 374 { |
357 tree ref_var; | 375 tree ref_var; |
358 tree struct_size, op0, op1; | 376 tree struct_size, op0, op1; |
359 tree before_cast; | 377 tree before_cast; |
360 enum tree_code rhs_code; | 378 enum tree_code rhs_code; |
361 | 379 |
362 ref_var = TREE_OPERAND (acc->ref, 0); | 380 ref_var = TREE_OPERAND (acc->ref, 0); |
363 | 381 |
364 if (TREE_CODE (ref_var) != SSA_NAME) | 382 if (TREE_CODE (ref_var) != SSA_NAME) |
365 return false; | 383 return false; |
366 | 384 |
377 return false; | 395 return false; |
378 | 396 |
379 op0 = gimple_assign_rhs1 (acc->ref_def_stmt); | 397 op0 = gimple_assign_rhs1 (acc->ref_def_stmt); |
380 op1 = gimple_assign_rhs2 (acc->ref_def_stmt); | 398 op1 = gimple_assign_rhs2 (acc->ref_def_stmt); |
381 | 399 |
382 if (!is_array_access_through_pointer_and_index (rhs_code, op0, op1, | 400 if (!is_array_access_through_pointer_and_index (rhs_code, op0, op1, |
383 &acc->base, &acc->offset, | 401 &acc->base, &acc->offset, |
384 &acc->cast_stmt)) | 402 &acc->cast_stmt)) |
385 return false; | 403 return false; |
386 | 404 |
387 if (acc->cast_stmt) | 405 if (acc->cast_stmt) |
388 before_cast = SINGLE_SSA_TREE_OPERAND (acc->cast_stmt, SSA_OP_USE); | 406 before_cast = SINGLE_SSA_TREE_OPERAND (acc->cast_stmt, SSA_OP_USE); |
392 if (!before_cast) | 410 if (!before_cast) |
393 return false; | 411 return false; |
394 | 412 |
395 | 413 |
396 if (SSA_NAME_IS_DEFAULT_DEF (before_cast)) | 414 if (SSA_NAME_IS_DEFAULT_DEF (before_cast)) |
397 return false; | 415 return false; |
398 | 416 |
399 struct_size = TYPE_SIZE_UNIT (str_decl); | 417 struct_size = TYPE_SIZE_UNIT (str_decl); |
400 | 418 |
401 if (!is_result_of_mult (before_cast, &acc->num, struct_size)) | 419 if (!is_result_of_mult (before_cast, &acc->num, struct_size)) |
402 return false; | 420 return false; |
403 | 421 |
404 return true; | 422 return true; |
405 } | 423 } |
406 | 424 |
407 | 425 |
408 /* This function checks whether the access ACC of structure type STR | 426 /* This function checks whether the access ACC of structure type STR |
409 is of the form suitable for transformation. If yes, it returns true. | 427 is of the form suitable for transformation. If yes, it returns true. |
410 False otherwise. */ | 428 False otherwise. */ |
411 | 429 |
412 static bool | 430 static bool |
413 decompose_access (tree str_decl, struct field_access_site *acc) | 431 decompose_access (tree str_decl, struct field_access_site *acc) |
438 if it is already in hashtable of function accesses F_ACCS. */ | 456 if it is already in hashtable of function accesses F_ACCS. */ |
439 | 457 |
440 static struct field_access_site * | 458 static struct field_access_site * |
441 is_in_field_accs (gimple stmt, htab_t f_accs) | 459 is_in_field_accs (gimple stmt, htab_t f_accs) |
442 { | 460 { |
443 return (struct field_access_site *) | 461 return (struct field_access_site *) |
444 htab_find_with_hash (f_accs, stmt, htab_hash_pointer (stmt)); | 462 htab_find_with_hash (f_accs, stmt, htab_hash_pointer (stmt)); |
445 } | 463 } |
446 | 464 |
447 /* This function adds an access ACC to the hashtable | 465 /* This function adds an access ACC to the hashtable |
448 F_ACCS of field accesses. */ | 466 F_ACCS of field accesses. */ |
449 | 467 |
450 static void | 468 static void |
451 add_field_acc_to_acc_sites (struct field_access_site *acc, | 469 add_field_acc_to_acc_sites (struct field_access_site *acc, |
452 htab_t f_accs) | 470 htab_t f_accs) |
453 { | 471 { |
454 void **slot; | 472 void **slot; |
455 | 473 |
456 gcc_assert (!is_in_field_accs (acc->stmt, f_accs)); | 474 gcc_assert (!is_in_field_accs (acc->stmt, f_accs)); |
457 slot = htab_find_slot_with_hash (f_accs, acc->stmt, | 475 slot = htab_find_slot_with_hash (f_accs, acc->stmt, |
458 htab_hash_pointer (acc->stmt), | 476 htab_hash_pointer (acc->stmt), |
459 INSERT); | 477 INSERT); |
460 *slot = acc; | 478 *slot = acc; |
461 } | 479 } |
462 | 480 |
463 /* This function adds the VAR to vector of variables of | 481 /* This function adds the VAR to vector of variables of |
464 an access site defined by statement STMT. If access entry | 482 an access site defined by statement STMT. If access entry |
465 with statement STMT does not exist in hashtable of | 483 with statement STMT does not exist in hashtable of |
466 accesses ACCS, this function creates it. */ | 484 accesses ACCS, this function creates it. */ |
467 | 485 |
468 static void | 486 static void |
469 add_access_to_acc_sites (gimple stmt, tree var, htab_t accs) | 487 add_access_to_acc_sites (gimple stmt, tree var, htab_t accs) |
470 { | 488 { |
471 struct access_site *acc; | 489 struct access_site *acc; |
472 | 490 |
473 acc = (struct access_site *) | 491 acc = (struct access_site *) |
474 htab_find_with_hash (accs, stmt, htab_hash_pointer (stmt)); | 492 htab_find_with_hash (accs, stmt, htab_hash_pointer (stmt)); |
475 | 493 |
476 if (!acc) | 494 if (!acc) |
477 { | 495 { |
478 void **slot; | 496 void **slot; |
482 acc->vars = VEC_alloc (tree, heap, 10); | 500 acc->vars = VEC_alloc (tree, heap, 10); |
483 slot = htab_find_slot_with_hash (accs, stmt, | 501 slot = htab_find_slot_with_hash (accs, stmt, |
484 htab_hash_pointer (stmt), INSERT); | 502 htab_hash_pointer (stmt), INSERT); |
485 *slot = acc; | 503 *slot = acc; |
486 | 504 |
487 } | 505 } |
488 VEC_safe_push (tree, heap, acc->vars, var); | 506 VEC_safe_push (tree, heap, acc->vars, var); |
489 } | 507 } |
490 | 508 |
491 /* This function adds NEW_DECL to function | 509 /* This function adds NEW_DECL to function |
492 referenced vars, and marks it for renaming. */ | 510 referenced vars, and marks it for renaming. */ |
493 | 511 |
494 static void | 512 static void |
495 finalize_var_creation (tree new_decl) | 513 finalize_var_creation (tree new_decl) |
496 { | 514 { |
497 add_referenced_var (new_decl); | 515 add_referenced_var (new_decl); |
498 if (is_global_var (new_decl)) | 516 mark_sym_for_renaming (new_decl); |
499 mark_call_clobbered (new_decl, ESCAPE_UNKNOWN); | |
500 mark_sym_for_renaming (new_decl); | |
501 } | 517 } |
502 | 518 |
503 /* This function finalizes VAR creation if it is a global VAR_DECL. */ | 519 /* This function finalizes VAR creation if it is a global VAR_DECL. */ |
504 | 520 |
505 static void | 521 static void |
521 notice_global_symbol (new_decl); | 537 notice_global_symbol (new_decl); |
522 varpool_mark_needed_node (new_node); | 538 varpool_mark_needed_node (new_node); |
523 varpool_finalize_decl (new_decl); | 539 varpool_finalize_decl (new_decl); |
524 } | 540 } |
525 | 541 |
526 /* This function finalizes the creation of new variables, | 542 /* This function finalizes the creation of new variables, |
527 defined by *SLOT->new_vars. */ | 543 defined by *SLOT->new_vars. */ |
528 | 544 |
529 static int | 545 static int |
530 finalize_new_vars_creation (void **slot, void *data ATTRIBUTE_UNUSED) | 546 finalize_new_vars_creation (void **slot, void *data ATTRIBUTE_UNUSED) |
531 { | 547 { |
532 new_var n_var = *(new_var *) slot; | 548 new_var n_var = *(new_var *) slot; |
549 | 565 |
550 for (i = 0; VEC_iterate (tree, var->new_vars, i, n_var); i++) | 566 for (i = 0; VEC_iterate (tree, var->new_vars, i, n_var); i++) |
551 { | 567 { |
552 tree type = strip_type(get_type_of_var (n_var)); | 568 tree type = strip_type(get_type_of_var (n_var)); |
553 gcc_assert (type); | 569 gcc_assert (type); |
554 | 570 |
555 if (type == new_type) | 571 if (type == new_type) |
556 return n_var; | 572 return n_var; |
557 } | 573 } |
558 | 574 |
559 return NULL_TREE; | 575 return NULL_TREE; |
560 } | 576 } |
561 | 577 |
562 /* This function returns new_var node, the orig_var of which is DECL. | 578 /* This function returns new_var node, the orig_var of which is DECL. |
563 It looks for new_var's in NEW_VARS_HTAB. If not found, | 579 It looks for new_var's in NEW_VARS_HTAB. If not found, |
564 the function returns NULL. */ | 580 the function returns NULL. */ |
565 | 581 |
566 static new_var | 582 static new_var |
567 is_in_new_vars_htab (tree decl, htab_t new_vars_htab) | 583 is_in_new_vars_htab (tree decl, htab_t new_vars_htab) |
568 { | 584 { |
569 return (new_var) htab_find_with_hash (new_vars_htab, decl, | 585 return (new_var) htab_find_with_hash (new_vars_htab, decl, |
570 htab_hash_pointer (decl)); | 586 DECL_UID (decl)); |
571 } | 587 } |
572 | 588 |
573 /* Given original variable ORIG_VAR, this function returns | 589 /* Given original variable ORIG_VAR, this function returns |
574 new variable corresponding to it of NEW_TYPE type. */ | 590 new variable corresponding to it of NEW_TYPE type. */ |
575 | 591 |
606 add_referenced_var (*res); | 622 add_referenced_var (*res); |
607 | 623 |
608 if (exact_log2 (struct_size_int) == -1) | 624 if (exact_log2 (struct_size_int) == -1) |
609 { | 625 { |
610 tree size = build_int_cst (TREE_TYPE (num), struct_size_int); | 626 tree size = build_int_cst (TREE_TYPE (num), struct_size_int); |
611 new_stmt = gimple_build_assign_with_ops (MULT_EXPR, *res, num, size); | 627 new_stmt = gimple_build_assign (*res, fold_build2 (MULT_EXPR, |
628 TREE_TYPE (num), | |
629 num, size)); | |
612 } | 630 } |
613 else | 631 else |
614 { | 632 { |
615 tree C = build_int_cst (TREE_TYPE (num), exact_log2 (struct_size_int)); | 633 tree C = build_int_cst (TREE_TYPE (num), exact_log2 (struct_size_int)); |
616 | 634 |
617 new_stmt = gimple_build_assign_with_ops (LSHIFT_EXPR, *res, num, C); | 635 new_stmt = gimple_build_assign (*res, fold_build2 (LSHIFT_EXPR, |
636 TREE_TYPE (num), | |
637 num, C)); | |
618 } | 638 } |
619 | 639 |
620 finalize_stmt (new_stmt); | 640 finalize_stmt (new_stmt); |
621 return new_stmt; | 641 return new_stmt; |
622 } | 642 } |
623 | 643 |
624 /* This function generates and returns a statement, that cast variable | 644 /* This function generates and returns a statement, that cast variable |
625 BEFORE_CAST to NEW_TYPE. The cast result variable is stored | 645 BEFORE_CAST to NEW_TYPE. The cast result variable is stored |
626 into RES_P. ORIG_CAST_STMT is the original cast statement. */ | 646 into RES_P. ORIG_CAST_STMT is the original cast statement. */ |
627 | 647 |
628 static gimple | 648 static gimple |
629 gen_cast_stmt (tree before_cast, tree new_type, gimple orig_cast_stmt, | 649 gen_cast_stmt (tree before_cast, tree new_type, gimple orig_cast_stmt, |
630 tree *res_p) | 650 tree *res_p) |
649 make_edge_and_fix_phis_of_dest (basic_block bb, edge e) | 669 make_edge_and_fix_phis_of_dest (basic_block bb, edge e) |
650 { | 670 { |
651 edge new_e; | 671 edge new_e; |
652 tree arg; | 672 tree arg; |
653 gimple_stmt_iterator si; | 673 gimple_stmt_iterator si; |
654 | 674 |
655 new_e = make_edge (bb, e->dest, e->flags); | 675 new_e = make_edge (bb, e->dest, e->flags); |
656 | 676 |
657 for (si = gsi_start_phis (new_e->dest); !gsi_end_p (si); gsi_next (&si)) | 677 for (si = gsi_start_phis (new_e->dest); !gsi_end_p (si); gsi_next (&si)) |
658 { | 678 { |
659 gimple phi = gsi_stmt (si); | 679 gimple phi = gsi_stmt (si); |
660 arg = PHI_ARG_DEF_FROM_EDGE (phi, e); | 680 arg = PHI_ARG_DEF_FROM_EDGE (phi, e); |
661 add_phi_arg (phi, arg, new_e); | 681 add_phi_arg (phi, arg, new_e, gimple_phi_arg_location_from_edge (phi, e)); |
662 } | 682 } |
663 | 683 |
664 return new_e; | 684 return new_e; |
665 } | 685 } |
666 | 686 |
672 gimple_stmt_iterator bsi; | 692 gimple_stmt_iterator bsi; |
673 | 693 |
674 if (!stmt || !new_stmt) | 694 if (!stmt || !new_stmt) |
675 return; | 695 return; |
676 | 696 |
677 bsi = gsi_for_stmt (stmt); | 697 bsi = gsi_for_stmt (stmt); |
678 gsi_insert_before (&bsi, new_stmt, GSI_SAME_STMT); | 698 gsi_insert_before (&bsi, new_stmt, GSI_SAME_STMT); |
679 } | 699 } |
680 | 700 |
681 /* Insert NEW_STMTS after STMT. */ | 701 /* Insert NEW_STMTS after STMT. */ |
682 | 702 |
683 static void | 703 static void |
686 gimple_stmt_iterator bsi; | 706 gimple_stmt_iterator bsi; |
687 | 707 |
688 if (!stmt || !new_stmts) | 708 if (!stmt || !new_stmts) |
689 return; | 709 return; |
690 | 710 |
691 bsi = gsi_for_stmt (stmt); | 711 bsi = gsi_for_stmt (stmt); |
692 gsi_insert_seq_after (&bsi, new_stmts, GSI_SAME_STMT); | 712 gsi_insert_seq_after (&bsi, new_stmts, GSI_SAME_STMT); |
693 } | 713 } |
694 | 714 |
695 /* Insert NEW_STMT after STMT. */ | 715 /* Insert NEW_STMT after STMT. */ |
696 | 716 |
697 static void | 717 static void |
700 gimple_stmt_iterator bsi; | 720 gimple_stmt_iterator bsi; |
701 | 721 |
702 if (!stmt || !new_stmt) | 722 if (!stmt || !new_stmt) |
703 return; | 723 return; |
704 | 724 |
705 bsi = gsi_for_stmt (stmt); | 725 bsi = gsi_for_stmt (stmt); |
706 gsi_insert_after (&bsi, new_stmt, GSI_SAME_STMT); | 726 gsi_insert_after (&bsi, new_stmt, GSI_SAME_STMT); |
707 } | 727 } |
708 | 728 |
709 /* This function returns vector of allocation sites | 729 /* This function returns vector of allocation sites |
710 that appear in function FN_DECL. */ | 730 that appear in function FN_DECL. */ |
711 | 731 |
712 static fallocs_t | 732 static fallocs_t |
713 get_fallocs (tree fn_decl) | 733 get_fallocs (tree fn_decl) |
714 { | 734 { |
715 return (fallocs_t) htab_find_with_hash (alloc_sites, fn_decl, | 735 return (fallocs_t) htab_find_with_hash (alloc_sites, fn_decl, |
716 htab_hash_pointer (fn_decl)); | 736 htab_hash_pointer (fn_decl)); |
717 } | 737 } |
718 | 738 |
719 /* If ALLOC_STMT is D.2225_7 = <alloc_func> (D.2224_6); | 739 /* If ALLOC_STMT is D.2225_7 = <alloc_func> (D.2224_6); |
720 and it is a part of allocation of a structure, | 740 and it is a part of allocation of a structure, |
721 then it is usually followed by a cast stmt | 741 then it is usually followed by a cast stmt |
722 p_8 = (struct str_t *) D.2225_7; | 742 p_8 = (struct str_t *) D.2225_7; |
723 which is returned by this function. */ | 743 which is returned by this function. */ |
724 | 744 |
725 static gimple | 745 static gimple |
726 get_final_alloc_stmt (gimple alloc_stmt) | 746 get_final_alloc_stmt (gimple alloc_stmt) |
729 use_operand_p use_p; | 749 use_operand_p use_p; |
730 tree alloc_res; | 750 tree alloc_res; |
731 | 751 |
732 if (!alloc_stmt) | 752 if (!alloc_stmt) |
733 return NULL; | 753 return NULL; |
734 | 754 |
735 if (!is_gimple_call (alloc_stmt)) | 755 if (!is_gimple_call (alloc_stmt)) |
736 return NULL; | 756 return NULL; |
737 | 757 |
738 alloc_res = gimple_get_lhs (alloc_stmt); | 758 alloc_res = gimple_get_lhs (alloc_stmt); |
739 | 759 |
744 return NULL; | 764 return NULL; |
745 else | 765 else |
746 return final_stmt; | 766 return final_stmt; |
747 } | 767 } |
748 | 768 |
749 /* This function returns true if STMT is one of allocation | 769 /* This function returns true if STMT is one of allocation |
750 sites of function FN_DECL. It returns false otherwise. */ | 770 sites of function FN_DECL. It returns false otherwise. */ |
751 | 771 |
752 static bool | 772 static bool |
753 is_part_of_malloc (gimple stmt, tree fn_decl) | 773 is_part_of_malloc (gimple stmt, tree fn_decl) |
754 { | 774 { |
755 fallocs_t fallocs = get_fallocs (fn_decl); | 775 fallocs_t fallocs = get_fallocs (fn_decl); |
756 | 776 |
757 if (fallocs) | 777 if (fallocs) |
758 { | 778 { |
759 alloc_site_t *call; | 779 alloc_site_t *call; |
760 unsigned i; | 780 unsigned i; |
761 | 781 |
772 { | 792 { |
773 bool found; | 793 bool found; |
774 gimple stmt; | 794 gimple stmt; |
775 }; | 795 }; |
776 | 796 |
777 /* This function looks for DATA->stmt among | 797 /* This function looks for DATA->stmt among |
778 the statements involved in the field access, | 798 the statements involved in the field access, |
779 defined by SLOT. It stops when it's found. */ | 799 defined by SLOT. It stops when it's found. */ |
780 | 800 |
781 static int | 801 static int |
782 find_in_field_accs (void **slot, void *data) | 802 find_in_field_accs (void **slot, void *data) |
783 { | 803 { |
826 { | 846 { |
827 tree fn_decl; | 847 tree fn_decl; |
828 d_str str; | 848 d_str str; |
829 }; | 849 }; |
830 | 850 |
831 /* This function returns component_ref with the BASE and | 851 /* This function returns component_ref with the BASE and |
832 field named FIELD_ID from structure TYPE. */ | 852 field named FIELD_ID from structure TYPE. */ |
833 | 853 |
834 static inline tree | 854 static inline tree |
835 build_comp_ref (tree base, tree field_id, tree type) | 855 build_comp_ref (tree base, tree field_id, tree type) |
836 { | 856 { |
837 tree field; | 857 tree field; |
838 bool found = false; | 858 bool found = false; |
839 | 859 |
840 | 860 |
841 /* Find field of structure type with the same name as field_id. */ | 861 /* Find field of structure type with the same name as field_id. */ |
842 for (field = TYPE_FIELDS (type); field; field = TREE_CHAIN (field)) | 862 for (field = TYPE_FIELDS (type); field; field = TREE_CHAIN (field)) |
843 { | 863 { |
844 if (DECL_NAME (field) == field_id) | 864 if (DECL_NAME (field) == field_id) |
852 | 872 |
853 return build3 (COMPONENT_REF, TREE_TYPE (field), base, field, NULL_TREE); | 873 return build3 (COMPONENT_REF, TREE_TYPE (field), base, field, NULL_TREE); |
854 } | 874 } |
855 | 875 |
856 | 876 |
857 /* This struct represent data used for walk_tree | 877 /* This struct represent data used for walk_tree |
858 called from function find_pos_in_stmt. | 878 called from function find_pos_in_stmt. |
859 - ref is a tree to be found, | 879 - ref is a tree to be found, |
860 - and pos is a pointer that points to ref in stmt. */ | 880 - and pos is a pointer that points to ref in stmt. */ |
861 struct ref_pos | 881 struct ref_pos |
862 { | 882 { |
863 tree *pos; | 883 tree *pos; |
864 tree ref; | 884 tree ref; |
885 tree container; | |
865 }; | 886 }; |
866 | 887 |
867 | 888 |
868 /* This is a callback function for walk_tree, called from | 889 /* This is a callback function for walk_tree, called from |
869 collect_accesses_in_bb function. DATA is a pointer to ref_pos structure. | 890 collect_accesses_in_bb function. DATA is a pointer to ref_pos structure. |
870 When *TP is equal to DATA->ref, the walk_tree stops, | 891 When *TP is equal to DATA->ref, the walk_tree stops, |
871 and found position, equal to TP, is assigned to DATA->pos. */ | 892 and found position, equal to TP, is assigned to DATA->pos. */ |
872 | 893 |
873 static tree | 894 static tree |
882 { | 903 { |
883 r_pos->pos = tp; | 904 r_pos->pos = tp; |
884 return t; | 905 return t; |
885 } | 906 } |
886 | 907 |
887 *walk_subtrees = 1; | 908 r_pos->container = t; |
909 *walk_subtrees = 1; | |
888 return NULL_TREE; | 910 return NULL_TREE; |
889 } | 911 } |
890 | 912 |
891 | 913 |
892 /* This function looks for the pointer of REF in STMT, | 914 /* This function looks for the pointer of REF in STMT, |
893 It returns it, if found, and NULL otherwise. */ | 915 It returns it, if found, and NULL otherwise. */ |
894 | 916 |
895 static tree * | 917 static tree * |
896 find_pos_in_stmt (gimple stmt, tree ref) | 918 find_pos_in_stmt (gimple stmt, tree ref, struct ref_pos * r_pos) |
897 { | 919 { |
898 struct ref_pos r_pos; | |
899 struct walk_stmt_info wi; | 920 struct walk_stmt_info wi; |
900 | 921 |
901 r_pos.ref = ref; | 922 r_pos->ref = ref; |
902 r_pos.pos = NULL; | 923 r_pos->pos = NULL; |
924 r_pos->container = NULL_TREE; | |
903 memset (&wi, 0, sizeof (wi)); | 925 memset (&wi, 0, sizeof (wi)); |
904 wi.info = &r_pos; | 926 wi.info = r_pos; |
905 walk_gimple_op (stmt, find_pos_in_stmt_1, &wi); | 927 walk_gimple_op (stmt, find_pos_in_stmt_1, &wi); |
906 | 928 |
907 return r_pos.pos; | 929 return r_pos->pos; |
908 } | 930 } |
909 | 931 |
910 /* This structure is used to represent array | 932 /* This structure is used to represent array |
911 or pointer-to wrappers of structure type. | 933 or pointer-to wrappers of structure type. |
912 For example, if type1 is structure type, | 934 For example, if type1 is structure type, |
913 then for type1 ** we generate two type_wrapper | 935 then for type1 ** we generate two type_wrapper |
914 structures with wrap = 0 each one. | 936 structures with wrap = 0 each one. |
915 It's used to unwind the original type up to | 937 It's used to unwind the original type up to |
916 structure type, replace it with the new structure type | 938 structure type, replace it with the new structure type |
917 and wrap it back in the opposite order. */ | 939 and wrap it back in the opposite order. */ |
918 | 940 |
919 typedef struct type_wrapper | 941 typedef struct type_wrapper |
920 { | 942 { |
921 /* 0 stand for pointer wrapper, and 1 for array wrapper. */ | 943 /* 0 stand for pointer wrapper, and 1 for array wrapper. */ |
922 bool wrap; | 944 bool wrap; |
923 | 945 |
924 /* Relevant for arrays as domain or index. */ | 946 /* Relevant for arrays as domain or index. */ |
925 tree domain; | 947 tree domain; |
926 }type_wrapper_t; | 948 }type_wrapper_t; |
927 | 949 |
928 DEF_VEC_O (type_wrapper_t); | 950 DEF_VEC_O (type_wrapper_t); |
929 DEF_VEC_ALLOC_O (type_wrapper_t, heap); | 951 DEF_VEC_ALLOC_O (type_wrapper_t, heap); |
930 | 952 |
931 /* This function replace field access ACC by the new | 953 /* This function replace field access ACC by the new |
932 field access of structure type NEW_TYPE. */ | 954 field access of structure type NEW_TYPE. */ |
933 | 955 |
934 static void | 956 static void |
935 replace_field_acc (struct field_access_site *acc, tree new_type) | 957 replace_field_acc (struct field_access_site *acc, tree new_type) |
936 { | 958 { |
940 tree *pos; | 962 tree *pos; |
941 tree new_acc; | 963 tree new_acc; |
942 tree field_id = DECL_NAME (acc->field_decl); | 964 tree field_id = DECL_NAME (acc->field_decl); |
943 VEC (type_wrapper_t, heap) *wrapper = VEC_alloc (type_wrapper_t, heap, 10); | 965 VEC (type_wrapper_t, heap) *wrapper = VEC_alloc (type_wrapper_t, heap, 10); |
944 type_wrapper_t *wr_p = NULL; | 966 type_wrapper_t *wr_p = NULL; |
945 | 967 struct ref_pos r_pos; |
968 | |
946 while (TREE_CODE (ref_var) == INDIRECT_REF | 969 while (TREE_CODE (ref_var) == INDIRECT_REF |
947 || TREE_CODE (ref_var) == ARRAY_REF) | 970 || TREE_CODE (ref_var) == ARRAY_REF) |
948 { | 971 { |
949 type_wrapper_t wr; | 972 type_wrapper_t wr; |
950 | 973 |
968 | 991 |
969 while (VEC_length (type_wrapper_t, wrapper) != 0) | 992 while (VEC_length (type_wrapper_t, wrapper) != 0) |
970 { | 993 { |
971 tree type = TREE_TYPE (TREE_TYPE (new_ref)); | 994 tree type = TREE_TYPE (TREE_TYPE (new_ref)); |
972 | 995 |
973 wr_p = VEC_last (type_wrapper_t, wrapper); | 996 wr_p = VEC_last (type_wrapper_t, wrapper); |
974 if (wr_p->wrap) /* Array. */ | 997 if (wr_p->wrap) /* Array. */ |
975 new_ref = build4 (ARRAY_REF, type, new_ref, | 998 new_ref = build4 (ARRAY_REF, type, new_ref, |
976 wr_p->domain, NULL_TREE, NULL_TREE); | 999 wr_p->domain, NULL_TREE, NULL_TREE); |
977 else /* Pointer. */ | 1000 else /* Pointer. */ |
978 new_ref = build1 (INDIRECT_REF, type, new_ref); | 1001 new_ref = build1 (INDIRECT_REF, type, new_ref); |
979 VEC_pop (type_wrapper_t, wrapper); | 1002 VEC_pop (type_wrapper_t, wrapper); |
980 } | 1003 } |
981 | 1004 |
982 new_acc = build_comp_ref (new_ref, field_id, new_type); | 1005 new_acc = build_comp_ref (new_ref, field_id, new_type); |
983 VEC_free (type_wrapper_t, heap, wrapper); | 1006 VEC_free (type_wrapper_t, heap, wrapper); |
984 | 1007 |
985 if (is_gimple_assign (acc->stmt)) | 1008 if (is_gimple_assign (acc->stmt)) |
986 { | 1009 { |
987 lhs = gimple_assign_lhs (acc->stmt); | 1010 lhs = gimple_assign_lhs (acc->stmt); |
988 rhs = gimple_assign_rhs1 (acc->stmt); | 1011 rhs = gimple_assign_rhs1 (acc->stmt); |
989 | 1012 |
990 if (lhs == acc->comp_ref) | 1013 if (lhs == acc->comp_ref) |
991 gimple_assign_set_lhs (acc->stmt, new_acc); | 1014 gimple_assign_set_lhs (acc->stmt, new_acc); |
992 else if (rhs == acc->comp_ref) | 1015 else if (rhs == acc->comp_ref) |
993 gimple_assign_set_rhs1 (acc->stmt, new_acc); | 1016 gimple_assign_set_rhs1 (acc->stmt, new_acc); |
994 else | 1017 else |
995 { | 1018 { |
996 pos = find_pos_in_stmt (acc->stmt, acc->comp_ref); | 1019 pos = find_pos_in_stmt (acc->stmt, acc->comp_ref, &r_pos); |
997 gcc_assert (pos); | 1020 gcc_assert (pos); |
998 *pos = new_acc; | 1021 *pos = new_acc; |
999 } | 1022 } |
1000 } | 1023 } |
1001 else | 1024 else |
1002 { | 1025 { |
1003 pos = find_pos_in_stmt (acc->stmt, acc->comp_ref); | 1026 pos = find_pos_in_stmt (acc->stmt, acc->comp_ref, &r_pos); |
1004 gcc_assert (pos); | 1027 gcc_assert (pos); |
1005 *pos = new_acc; | 1028 *pos = new_acc; |
1006 } | 1029 } |
1007 | 1030 |
1008 finalize_stmt (acc->stmt); | 1031 finalize_stmt (acc->stmt); |
1009 } | 1032 } |
1010 | 1033 |
1011 /* This function replace field access ACC by a new field access | 1034 /* This function replace field access ACC by a new field access |
1012 of structure type NEW_TYPE. */ | 1035 of structure type NEW_TYPE. */ |
1013 | 1036 |
1014 static void | 1037 static void |
1015 replace_field_access_stmt (struct field_access_site *acc, tree new_type) | 1038 replace_field_access_stmt (struct field_access_site *acc, tree new_type) |
1016 { | 1039 { |
1021 replace_field_acc (acc, new_type); | 1044 replace_field_acc (acc, new_type); |
1022 else | 1045 else |
1023 gcc_unreachable (); | 1046 gcc_unreachable (); |
1024 } | 1047 } |
1025 | 1048 |
1026 /* This function looks for d_str, represented by TYPE, in the structures | 1049 /* This function looks for d_str, represented by TYPE, in the structures |
1027 vector. If found, it returns an index of found structure. Otherwise | 1050 vector. If found, it returns an index of found structure. Otherwise |
1028 it returns a length of the structures vector. */ | 1051 it returns a length of the structures vector. */ |
1029 | 1052 |
1030 static unsigned | 1053 static unsigned |
1031 find_structure (tree type) | 1054 find_structure (tree type) |
1032 { | 1055 { |
1033 d_str str; | 1056 d_str str; |
1034 unsigned i; | 1057 unsigned i; |
1041 | 1064 |
1042 return VEC_length (structure, structures); | 1065 return VEC_length (structure, structures); |
1043 } | 1066 } |
1044 | 1067 |
1045 /* In this function we create new statements that have the same | 1068 /* In this function we create new statements that have the same |
1046 form as ORIG_STMT, but of type NEW_TYPE. The statements | 1069 form as ORIG_STMT, but of type NEW_TYPE. The statements |
1047 treated by this function are simple assignments, | 1070 treated by this function are simple assignments, |
1048 like assignments: p.8_7 = p; or statements with rhs of | 1071 like assignments: p.8_7 = p; or statements with rhs of |
1049 tree codes PLUS_EXPR and MINUS_EXPR. */ | 1072 tree codes PLUS_EXPR and MINUS_EXPR. */ |
1050 | 1073 |
1051 static gimple | 1074 static gimple |
1052 create_base_plus_offset (gimple orig_stmt, tree new_type, tree offset) | 1075 create_base_plus_offset (gimple orig_stmt, tree new_type, tree offset) |
1053 { | 1076 { |
1058 | 1081 |
1059 lhs = gimple_assign_lhs (orig_stmt); | 1082 lhs = gimple_assign_lhs (orig_stmt); |
1060 | 1083 |
1061 gcc_assert (TREE_CODE (lhs) == VAR_DECL | 1084 gcc_assert (TREE_CODE (lhs) == VAR_DECL |
1062 || TREE_CODE (lhs) == SSA_NAME); | 1085 || TREE_CODE (lhs) == SSA_NAME); |
1063 | 1086 |
1064 new_lhs = find_new_var_of_type (lhs, new_type); | 1087 new_lhs = find_new_var_of_type (lhs, new_type); |
1065 gcc_assert (new_lhs); | 1088 gcc_assert (new_lhs); |
1066 finalize_var_creation (new_lhs); | 1089 finalize_var_creation (new_lhs); |
1067 | 1090 |
1068 switch (gimple_assign_rhs_code (orig_stmt)) | 1091 switch (gimple_assign_rhs_code (orig_stmt)) |
1073 { | 1096 { |
1074 tree op0 = gimple_assign_rhs1 (orig_stmt); | 1097 tree op0 = gimple_assign_rhs1 (orig_stmt); |
1075 tree op1 = gimple_assign_rhs2 (orig_stmt); | 1098 tree op1 = gimple_assign_rhs2 (orig_stmt); |
1076 unsigned str0, str1; | 1099 unsigned str0, str1; |
1077 unsigned length = VEC_length (structure, structures); | 1100 unsigned length = VEC_length (structure, structures); |
1078 | 1101 |
1079 | 1102 |
1080 str0 = find_structure (strip_type (get_type_of_var (op0))); | 1103 str0 = find_structure (strip_type (get_type_of_var (op0))); |
1081 str1 = find_structure (strip_type (get_type_of_var (op1))); | 1104 str1 = find_structure (strip_type (get_type_of_var (op1))); |
1082 gcc_assert ((str0 != length) || (str1 != length)); | 1105 gcc_assert ((str0 != length) || (str1 != length)); |
1083 | 1106 |
1084 if (str0 != length) | 1107 if (str0 != length) |
1085 new_op0 = find_new_var_of_type (op0, new_type); | 1108 new_op0 = find_new_var_of_type (op0, new_type); |
1086 if (str1 != length) | 1109 if (str1 != length) |
1087 new_op1 = find_new_var_of_type (op1, new_type); | 1110 new_op1 = find_new_var_of_type (op1, new_type); |
1088 | 1111 |
1094 break; | 1117 break; |
1095 | 1118 |
1096 default: | 1119 default: |
1097 gcc_unreachable(); | 1120 gcc_unreachable(); |
1098 } | 1121 } |
1099 | 1122 |
1100 new_stmt = gimple_build_assign_with_ops (gimple_assign_rhs_code (orig_stmt), | 1123 new_stmt = gimple_build_assign_with_ops (gimple_assign_rhs_code (orig_stmt), |
1101 new_lhs, new_op0, new_op1); | 1124 new_lhs, new_op0, new_op1); |
1102 finalize_stmt (new_stmt); | 1125 finalize_stmt (new_stmt); |
1103 | 1126 |
1104 return new_stmt; | 1127 return new_stmt; |
1105 } | 1128 } |
1106 | 1129 |
1107 /* Given a field access F_ACC of the FIELD, this function | 1130 /* Given a field access F_ACC of the FIELD, this function |
1108 replaces it by the new field access. */ | 1131 replaces it by the new field access. */ |
1109 | 1132 |
1110 static void | 1133 static void |
1111 create_new_field_access (struct field_access_site *f_acc, | 1134 create_new_field_access (struct field_access_site *f_acc, |
1112 struct field_entry field) | 1135 struct field_entry field) |
1115 gimple new_stmt; | 1138 gimple new_stmt; |
1116 tree size_res; | 1139 tree size_res; |
1117 gimple mult_stmt; | 1140 gimple mult_stmt; |
1118 gimple cast_stmt; | 1141 gimple cast_stmt; |
1119 tree cast_res = NULL; | 1142 tree cast_res = NULL; |
1120 | 1143 |
1121 if (f_acc->num) | 1144 if (f_acc->num) |
1122 { | 1145 { |
1123 mult_stmt = gen_size (f_acc->num, new_type, &size_res); | 1146 mult_stmt = gen_size (f_acc->num, new_type, &size_res); |
1124 insert_before_stmt (f_acc->ref_def_stmt, mult_stmt); | 1147 insert_before_stmt (f_acc->ref_def_stmt, mult_stmt); |
1125 } | 1148 } |
1126 | 1149 |
1127 if (f_acc->cast_stmt) | 1150 if (f_acc->cast_stmt) |
1128 { | 1151 { |
1129 cast_stmt = gen_cast_stmt (size_res, new_type, | 1152 cast_stmt = gen_cast_stmt (size_res, new_type, |
1130 f_acc->cast_stmt, &cast_res); | 1153 f_acc->cast_stmt, &cast_res); |
1131 insert_after_stmt (f_acc->cast_stmt, cast_stmt); | 1154 insert_after_stmt (f_acc->cast_stmt, cast_stmt); |
1132 } | 1155 } |
1133 | 1156 |
1134 if (f_acc->ref_def_stmt) | 1157 if (f_acc->ref_def_stmt) |
1137 if (cast_res) | 1160 if (cast_res) |
1138 offset = cast_res; | 1161 offset = cast_res; |
1139 else | 1162 else |
1140 offset = size_res; | 1163 offset = size_res; |
1141 | 1164 |
1142 new_stmt = create_base_plus_offset (f_acc->ref_def_stmt, | 1165 new_stmt = create_base_plus_offset (f_acc->ref_def_stmt, |
1143 new_type, offset); | 1166 new_type, offset); |
1144 insert_after_stmt (f_acc->ref_def_stmt, new_stmt); | 1167 insert_after_stmt (f_acc->ref_def_stmt, new_stmt); |
1145 } | 1168 } |
1146 | 1169 |
1147 /* In stmt D.2163_19 = D.2162_18->b; we replace variable | 1170 /* In stmt D.2163_19 = D.2162_18->b; we replace variable |
1148 D.2162_18 by an appropriate variable of new_type type. */ | 1171 D.2162_18 by an appropriate variable of new_type type. */ |
1149 replace_field_access_stmt (f_acc, new_type); | 1172 replace_field_access_stmt (f_acc, new_type); |
1150 } | 1173 } |
1151 | 1174 |
1152 /* This function creates a new condition statement | 1175 /* This function creates a new condition statement |
1153 corresponding to the original COND_STMT, adds new basic block | 1176 corresponding to the original COND_STMT, adds new basic block |
1154 and redirects condition edges. NEW_VAR is a new condition | 1177 and redirects condition edges. NEW_VAR is a new condition |
1155 variable located in the condition statement at the position POS. */ | 1178 variable located in the condition statement at the position POS. */ |
1156 | 1179 |
1157 static void | 1180 static void |
1158 create_new_stmts_for_cond_expr_1 (tree new_var, gimple cond_stmt, unsigned pos) | 1181 create_new_stmts_for_cond_expr_1 (tree new_var, gimple cond_stmt, unsigned pos) |
1159 { | 1182 { |
1181 gsi_insert_after (&si, new_stmt, GSI_NEW_STMT); | 1204 gsi_insert_after (&si, new_stmt, GSI_NEW_STMT); |
1182 | 1205 |
1183 /* Create false and true edges from new_bb. */ | 1206 /* Create false and true edges from new_bb. */ |
1184 make_edge_and_fix_phis_of_dest (new_bb, true_e); | 1207 make_edge_and_fix_phis_of_dest (new_bb, true_e); |
1185 make_edge_and_fix_phis_of_dest (new_bb, false_e); | 1208 make_edge_and_fix_phis_of_dest (new_bb, false_e); |
1186 | 1209 |
1187 /* Redirect one of original edges to point to new_bb. */ | 1210 /* Redirect one of original edges to point to new_bb. */ |
1188 if (gimple_cond_code (cond_stmt) == NE_EXPR) | 1211 if (gimple_cond_code (cond_stmt) == NE_EXPR) |
1189 redirect_edge_succ (true_e, new_bb); | 1212 redirect_edge_succ (true_e, new_bb); |
1190 else | 1213 else |
1191 redirect_edge_succ (false_e, new_bb); | 1214 redirect_edge_succ (false_e, new_bb); |
1192 } | 1215 } |
1193 | 1216 |
1194 /* This function creates new condition statements corresponding | 1217 /* This function creates new condition statements corresponding |
1195 to original condition STMT, one for each new type, and | 1218 to original condition STMT, one for each new type, and |
1196 recursively redirect edges to newly generated basic blocks. */ | 1219 recursively redirect edges to newly generated basic blocks. */ |
1197 | 1220 |
1198 static void | 1221 static void |
1199 create_new_stmts_for_cond_expr (gimple stmt) | 1222 create_new_stmts_for_cond_expr (gimple stmt) |
1200 { | 1223 { |
1220 s1 = (str1 != length) ? true : false; | 1243 s1 = (str1 != length) ? true : false; |
1221 | 1244 |
1222 gcc_assert (s0 || s1); | 1245 gcc_assert (s0 || s1); |
1223 /* For now we allow only comparison with 0 or NULL. */ | 1246 /* For now we allow only comparison with 0 or NULL. */ |
1224 gcc_assert (integer_zerop (arg0) || integer_zerop (arg1)); | 1247 gcc_assert (integer_zerop (arg0) || integer_zerop (arg1)); |
1225 | 1248 |
1226 str = integer_zerop (arg0) ? | 1249 str = integer_zerop (arg0) ? |
1227 VEC_index (structure, structures, str1): | 1250 VEC_index (structure, structures, str1): |
1228 VEC_index (structure, structures, str0); | 1251 VEC_index (structure, structures, str0); |
1229 arg = integer_zerop (arg0) ? arg1 : arg0; | 1252 arg = integer_zerop (arg0) ? arg1 : arg0; |
1230 pos = integer_zerop (arg0) ? 1 : 0; | 1253 pos = integer_zerop (arg0) ? 1 : 0; |
1231 | 1254 |
1232 for (i = 0; VEC_iterate (tree, str->new_types, i, type); i++) | 1255 for (i = 0; VEC_iterate (tree, str->new_types, i, type); i++) |
1233 { | 1256 { |
1234 tree new_arg; | 1257 tree new_arg; |
1235 | 1258 |
1236 new_arg = find_new_var_of_type (arg, type); | 1259 new_arg = find_new_var_of_type (arg, type); |
1237 create_new_stmts_for_cond_expr_1 (new_arg, stmt, pos); | 1260 create_new_stmts_for_cond_expr_1 (new_arg, stmt, pos); |
1238 } | 1261 } |
1239 } | 1262 } |
1263 | |
1264 /* This function looks for VAR in STMT, and replace it with NEW_VAR. | |
1265 If needed, it wraps NEW_VAR in pointers and indirect references | |
1266 before insertion. */ | |
1267 | |
1268 static void | |
1269 insert_new_var_in_stmt (gimple stmt, tree var, tree new_var) | |
1270 { | |
1271 struct ref_pos r_pos; | |
1272 tree *pos; | |
1273 | |
1274 pos = find_pos_in_stmt (stmt, var, &r_pos); | |
1275 gcc_assert (pos); | |
1276 | |
1277 while (r_pos.container && (TREE_CODE(r_pos.container) == INDIRECT_REF | |
1278 || TREE_CODE(r_pos.container) == ADDR_EXPR)) | |
1279 { | |
1280 tree type = TREE_TYPE (TREE_TYPE (new_var)); | |
1281 | |
1282 if (TREE_CODE(r_pos.container) == INDIRECT_REF) | |
1283 new_var = build1 (INDIRECT_REF, type, new_var); | |
1284 else | |
1285 new_var = build_fold_addr_expr (new_var); | |
1286 pos = find_pos_in_stmt (stmt, r_pos.container, &r_pos); | |
1287 } | |
1288 | |
1289 *pos = new_var; | |
1290 } | |
1291 | |
1240 | 1292 |
1241 /* Create a new general access to replace original access ACC | 1293 /* Create a new general access to replace original access ACC |
1242 for structure type NEW_TYPE. */ | 1294 for structure type NEW_TYPE. */ |
1243 | 1295 |
1244 static gimple | 1296 static gimple |
1247 gimple old_stmt = acc->stmt; | 1299 gimple old_stmt = acc->stmt; |
1248 tree var; | 1300 tree var; |
1249 gimple new_stmt = gimple_copy (old_stmt); | 1301 gimple new_stmt = gimple_copy (old_stmt); |
1250 unsigned i; | 1302 unsigned i; |
1251 | 1303 |
1304 /* We are really building a new stmt, clear the virtual operands. */ | |
1305 if (gimple_has_mem_ops (new_stmt)) | |
1306 { | |
1307 gimple_set_vuse (new_stmt, NULL_TREE); | |
1308 gimple_set_vdef (new_stmt, NULL_TREE); | |
1309 } | |
1310 | |
1252 for (i = 0; VEC_iterate (tree, acc->vars, i, var); i++) | 1311 for (i = 0; VEC_iterate (tree, acc->vars, i, var); i++) |
1253 { | 1312 { |
1254 tree *pos; | |
1255 tree new_var = find_new_var_of_type (var, new_type); | 1313 tree new_var = find_new_var_of_type (var, new_type); |
1256 tree lhs, rhs = NULL_TREE; | 1314 tree lhs, rhs = NULL_TREE; |
1257 | 1315 |
1258 gcc_assert (new_var); | 1316 gcc_assert (new_var); |
1259 finalize_var_creation (new_var); | 1317 finalize_var_creation (new_var); |
1260 | 1318 |
1261 if (is_gimple_assign (new_stmt)) | 1319 if (is_gimple_assign (new_stmt)) |
1262 { | 1320 { |
1263 lhs = gimple_assign_lhs (new_stmt); | 1321 lhs = gimple_assign_lhs (new_stmt); |
1264 | 1322 |
1265 if (TREE_CODE (lhs) == SSA_NAME) | 1323 if (TREE_CODE (lhs) == SSA_NAME) |
1266 lhs = SSA_NAME_VAR (lhs); | 1324 lhs = SSA_NAME_VAR (lhs); |
1267 if (gimple_assign_rhs_code (new_stmt) == SSA_NAME) | 1325 if (gimple_assign_rhs_code (new_stmt) == SSA_NAME) |
1268 rhs = SSA_NAME_VAR (gimple_assign_rhs1 (new_stmt)); | 1326 rhs = SSA_NAME_VAR (gimple_assign_rhs1 (new_stmt)); |
1269 | 1327 |
1270 /* It can happen that rhs is a constructor. | 1328 /* It can happen that rhs is a constructor. |
1271 Then we have to replace it to be of new_type. */ | 1329 Then we have to replace it to be of new_type. */ |
1272 if (gimple_assign_rhs_code (new_stmt) == CONSTRUCTOR) | 1330 if (gimple_assign_rhs_code (new_stmt) == CONSTRUCTOR) |
1273 { | 1331 { |
1274 /* Dealing only with empty constructors right now. */ | 1332 /* Dealing only with empty constructors right now. */ |
1275 gcc_assert (VEC_empty (constructor_elt, | 1333 gcc_assert (VEC_empty (constructor_elt, |
1276 CONSTRUCTOR_ELTS (rhs))); | 1334 CONSTRUCTOR_ELTS (rhs))); |
1277 rhs = build_constructor (new_type, 0); | 1335 rhs = build_constructor (new_type, 0); |
1278 gimple_assign_set_rhs1 (new_stmt, rhs); | 1336 gimple_assign_set_rhs1 (new_stmt, rhs); |
1279 } | 1337 } |
1280 | 1338 |
1281 if (lhs == var) | 1339 if (lhs == var) |
1282 gimple_assign_set_lhs (new_stmt, new_var); | 1340 gimple_assign_set_lhs (new_stmt, new_var); |
1283 else if (rhs == var) | 1341 else if (rhs == var) |
1284 gimple_assign_set_rhs1 (new_stmt, new_var); | 1342 gimple_assign_set_rhs1 (new_stmt, new_var); |
1285 else | 1343 else |
1286 { | 1344 insert_new_var_in_stmt (new_stmt, var, new_var); |
1287 pos = find_pos_in_stmt (new_stmt, var); | |
1288 gcc_assert (pos); | |
1289 *pos = new_var; | |
1290 } | |
1291 } | 1345 } |
1292 else | 1346 else |
1293 { | 1347 insert_new_var_in_stmt (new_stmt, var, new_var); |
1294 pos = find_pos_in_stmt (new_stmt, var); | |
1295 gcc_assert (pos); | |
1296 *pos = new_var; | |
1297 } | |
1298 } | 1348 } |
1299 | 1349 |
1300 finalize_stmt (new_stmt); | 1350 finalize_stmt (new_stmt); |
1301 return new_stmt; | 1351 return new_stmt; |
1302 } | 1352 } |
1318 new_stmt = create_general_new_stmt (acc, type); | 1368 new_stmt = create_general_new_stmt (acc, type); |
1319 insert_after_stmt (stmt, new_stmt); | 1369 insert_after_stmt (stmt, new_stmt); |
1320 } | 1370 } |
1321 } | 1371 } |
1322 | 1372 |
1323 /* This function creates a new general access of structure STR | 1373 /* This function creates a new general access of structure STR |
1324 to replace the access ACC. */ | 1374 to replace the access ACC. */ |
1325 | 1375 |
1326 static void | 1376 static void |
1327 create_new_general_access (struct access_site *acc, d_str str) | 1377 create_new_general_access (struct access_site *acc, d_str str) |
1328 { | 1378 { |
1375 if (gimple_bb (f_acc->stmt) == bb) | 1425 if (gimple_bb (f_acc->stmt) == bb) |
1376 create_new_field_access (f_acc, str->fields[i]); | 1426 create_new_field_access (f_acc, str->fields[i]); |
1377 return 1; | 1427 return 1; |
1378 } | 1428 } |
1379 | 1429 |
1380 /* This function creates new accesses for the structure | 1430 /* This function creates new accesses for the structure |
1381 type STR in basic block BB. */ | 1431 type STR in basic block BB. */ |
1382 | 1432 |
1383 static void | 1433 static void |
1384 create_new_accs_for_struct (d_str str, basic_block bb) | 1434 create_new_accs_for_struct (d_str str, basic_block bb) |
1385 { | 1435 { |
1387 struct create_acc_data dt; | 1437 struct create_acc_data dt; |
1388 | 1438 |
1389 dt.str = str; | 1439 dt.str = str; |
1390 dt.bb = bb; | 1440 dt.bb = bb; |
1391 dt.field_index = -1; | 1441 dt.field_index = -1; |
1392 | 1442 |
1393 for (i = 0; i < str->num_fields; i++) | 1443 for (i = 0; i < str->num_fields; i++) |
1394 { | 1444 { |
1395 dt.field_index = i; | 1445 dt.field_index = i; |
1396 | 1446 |
1397 if (str->fields[i].acc_sites) | 1447 if (str->fields[i].acc_sites) |
1398 htab_traverse (str->fields[i].acc_sites, | 1448 htab_traverse (str->fields[i].acc_sites, |
1399 create_new_field_acc, &dt); | 1449 create_new_field_acc, &dt); |
1400 } | 1450 } |
1401 if (str->accs) | 1451 if (str->accs) |
1402 htab_traverse (str->accs, create_new_acc, &dt); | 1452 htab_traverse (str->accs, create_new_acc, &dt); |
1403 } | 1453 } |
1404 | 1454 |
1405 /* This function inserts new variables from new_var, | 1455 /* This function inserts new variables from new_var, |
1406 defined by SLOT, into varpool. */ | 1456 defined by SLOT, into varpool. */ |
1407 | 1457 |
1408 static int | 1458 static int |
1409 update_varpool_with_new_var (void **slot, void *data ATTRIBUTE_UNUSED) | 1459 update_varpool_with_new_var (void **slot, void *data ATTRIBUTE_UNUSED) |
1410 { | 1460 { |
1411 new_var n_var = *(new_var *) slot; | 1461 new_var n_var = *(new_var *) slot; |
1415 for (i = 0; VEC_iterate (tree, n_var->new_vars, i, var); i++) | 1465 for (i = 0; VEC_iterate (tree, n_var->new_vars, i, var); i++) |
1416 insert_global_to_varpool (var); | 1466 insert_global_to_varpool (var); |
1417 return 1; | 1467 return 1; |
1418 } | 1468 } |
1419 | 1469 |
1420 /* This function prints a field access site, defined by SLOT. */ | 1470 /* This function prints a field access site, defined by SLOT. */ |
1421 | 1471 |
1422 static int | 1472 static int |
1423 dump_field_acc (void **slot, void *data ATTRIBUTE_UNUSED) | 1473 dump_field_acc (void **slot, void *data ATTRIBUTE_UNUSED) |
1424 { | 1474 { |
1425 struct field_access_site *f_acc = | 1475 struct field_access_site *f_acc = |
1453 malloc_hash (const void *x) | 1503 malloc_hash (const void *x) |
1454 { | 1504 { |
1455 return htab_hash_pointer (((const_fallocs_t)x)->func); | 1505 return htab_hash_pointer (((const_fallocs_t)x)->func); |
1456 } | 1506 } |
1457 | 1507 |
1458 /* This function returns nonzero if function of func_alloc_sites' X | 1508 /* This function returns nonzero if function of func_alloc_sites' X |
1459 is equal to Y. */ | 1509 is equal to Y. */ |
1460 | 1510 |
1461 static int | 1511 static int |
1462 malloc_eq (const void *x, const void *y) | 1512 malloc_eq (const void *x, const void *y) |
1463 { | 1513 { |
1475 VEC_free (tree, heap, acc->vars); | 1525 VEC_free (tree, heap, acc->vars); |
1476 free (acc); | 1526 free (acc); |
1477 return 1; | 1527 return 1; |
1478 } | 1528 } |
1479 | 1529 |
1480 /* This is a callback function for traversal over field accesses. | 1530 /* This is a callback function for traversal over field accesses. |
1481 It frees a field access represented by SLOT. */ | 1531 It frees a field access represented by SLOT. */ |
1482 | 1532 |
1483 static int | 1533 static int |
1484 free_field_accs (void **slot, void *data ATTRIBUTE_UNUSED) | 1534 free_field_accs (void **slot, void *data ATTRIBUTE_UNUSED) |
1485 { | 1535 { |
1487 | 1537 |
1488 free (f_acc); | 1538 free (f_acc); |
1489 return 1; | 1539 return 1; |
1490 } | 1540 } |
1491 | 1541 |
1492 /* This function inserts TYPE into vector of UNSUITABLE_TYPES, | 1542 /* This function inserts TYPE into vector of UNSUITABLE_TYPES, |
1493 if it is not there yet. */ | 1543 if it is not there yet. */ |
1494 | 1544 |
1495 static void | 1545 static void |
1496 add_unsuitable_type (VEC (tree, heap) **unsuitable_types, tree type) | 1546 add_unsuitable_type (VEC (tree, heap) **unsuitable_types, tree type) |
1497 { | 1547 { |
1504 type = TYPE_MAIN_VARIANT (type); | 1554 type = TYPE_MAIN_VARIANT (type); |
1505 | 1555 |
1506 for (i = 0; VEC_iterate (tree, *unsuitable_types, i, t); i++) | 1556 for (i = 0; VEC_iterate (tree, *unsuitable_types, i, t); i++) |
1507 if (is_equal_types (t, type)) | 1557 if (is_equal_types (t, type)) |
1508 break; | 1558 break; |
1509 | 1559 |
1510 if (i == VEC_length (tree, *unsuitable_types)) | 1560 if (i == VEC_length (tree, *unsuitable_types)) |
1511 VEC_safe_push (tree, heap, *unsuitable_types, type); | 1561 VEC_safe_push (tree, heap, *unsuitable_types, type); |
1512 } | 1562 } |
1513 | 1563 |
1514 /* Given a type TYPE, this function returns the name of the type. */ | 1564 /* Given a type TYPE, this function returns the name of the type. */ |
1528 return NULL; | 1578 return NULL; |
1529 } | 1579 } |
1530 | 1580 |
1531 /* This function is a temporary hack to overcome the types problem. | 1581 /* This function is a temporary hack to overcome the types problem. |
1532 When several compilation units are compiled together | 1582 When several compilation units are compiled together |
1533 with -combine, the TYPE_MAIN_VARIANT of the same type | 1583 with -combine, the TYPE_MAIN_VARIANT of the same type |
1534 can appear differently in different compilation units. | 1584 can appear differently in different compilation units. |
1535 Therefore this function first compares type names. | 1585 Therefore this function first compares type names. |
1536 If there are no names, structure bodies are recursively | 1586 If there are no names, structure bodies are recursively |
1537 compared. */ | 1587 compared. */ |
1538 | 1588 |
1539 static bool | 1589 static bool |
1540 is_equal_types (tree type1, tree type2) | 1590 is_equal_types (tree type1, tree type2) |
1541 { | 1591 { |
1557 if (TYPE_MAIN_VARIANT (type1) == TYPE_MAIN_VARIANT (type2)) | 1607 if (TYPE_MAIN_VARIANT (type1) == TYPE_MAIN_VARIANT (type2)) |
1558 return true; | 1608 return true; |
1559 | 1609 |
1560 name1 = get_type_name (type1); | 1610 name1 = get_type_name (type1); |
1561 name2 = get_type_name (type2); | 1611 name2 = get_type_name (type2); |
1562 | 1612 |
1563 if (name1 && name2 && !strcmp (name1, name2)) | 1613 if (name1 && name2) |
1564 return true; | 1614 return strcmp (name1, name2) == 0; |
1565 | 1615 |
1566 if (name1 && name2 && strcmp (name1, name2)) | |
1567 return false; | |
1568 | |
1569 switch (TREE_CODE (type1)) | 1616 switch (TREE_CODE (type1)) |
1570 { | 1617 { |
1571 case POINTER_TYPE: | 1618 case POINTER_TYPE: |
1572 case REFERENCE_TYPE: | 1619 case REFERENCE_TYPE: |
1573 { | 1620 { |
1578 case RECORD_TYPE: | 1625 case RECORD_TYPE: |
1579 case UNION_TYPE: | 1626 case UNION_TYPE: |
1580 case QUAL_UNION_TYPE: | 1627 case QUAL_UNION_TYPE: |
1581 case ENUMERAL_TYPE: | 1628 case ENUMERAL_TYPE: |
1582 { | 1629 { |
1583 tree field1; | 1630 tree field1, field2; |
1631 | |
1584 /* Compare fields of structure. */ | 1632 /* Compare fields of structure. */ |
1585 for (field1 = TYPE_FIELDS (type1); field1; | 1633 for (field1 = TYPE_FIELDS (type1), field2 = TYPE_FIELDS (type2); |
1586 field1 = TREE_CHAIN (field1)) | 1634 field1 && field2; |
1635 field1 = TREE_CHAIN (field1), field2 = TREE_CHAIN (field2)) | |
1587 { | 1636 { |
1588 tree field2 = find_field_in_struct_1 (type2, field1); | 1637 if (!compare_fields (field1, field2)) |
1589 if (!field2) | |
1590 return false; | 1638 return false; |
1591 } | 1639 } |
1592 return true; | 1640 if (field1 || field2) |
1641 return false; | |
1642 else | |
1643 return true; | |
1593 } | 1644 } |
1594 break; | 1645 break; |
1595 | 1646 |
1596 case INTEGER_TYPE: | 1647 case INTEGER_TYPE: |
1597 { | 1648 { |
1642 | 1693 |
1643 static void | 1694 static void |
1644 free_accesses (htab_t accs) | 1695 free_accesses (htab_t accs) |
1645 { | 1696 { |
1646 if (accs) | 1697 if (accs) |
1647 htab_traverse (accs, free_accs, NULL); | 1698 htab_traverse (accs, free_accs, NULL); |
1648 htab_delete (accs); | 1699 htab_delete (accs); |
1649 } | 1700 } |
1650 | 1701 |
1651 /* This function free field accesses hashtable F_ACCS. */ | 1702 /* This function free field accesses hashtable F_ACCS. */ |
1652 | 1703 |
1653 static void | 1704 static void |
1654 free_field_accesses (htab_t f_accs) | 1705 free_field_accesses (htab_t f_accs) |
1655 { | 1706 { |
1656 if (f_accs) | 1707 if (f_accs) |
1657 htab_traverse (f_accs, free_field_accs, NULL); | 1708 htab_traverse (f_accs, free_field_accs, NULL); |
1658 htab_delete (f_accs); | 1709 htab_delete (f_accs); |
1659 } | 1710 } |
1660 | 1711 |
1661 /* Update call graph with new edge generated by new MALLOC_STMT. | 1712 /* Update call graph with new edge generated by new MALLOC_STMT. |
1662 The edge origin is CONTEXT function. */ | 1713 The edge origin is CONTEXT function. */ |
1669 | 1720 |
1670 if (!malloc_stmt) | 1721 if (!malloc_stmt) |
1671 return; | 1722 return; |
1672 | 1723 |
1673 malloc_fn_decl = gimple_call_fndecl (malloc_stmt); | 1724 malloc_fn_decl = gimple_call_fndecl (malloc_stmt); |
1674 | 1725 |
1675 src = cgraph_node (context); | 1726 src = cgraph_node (context); |
1676 dest = cgraph_node (malloc_fn_decl); | 1727 dest = cgraph_node (malloc_fn_decl); |
1677 cgraph_create_edge (src, dest, malloc_stmt, | 1728 cgraph_create_edge (src, dest, malloc_stmt, |
1678 0, 0, gimple_bb (malloc_stmt)->loop_depth); | 1729 gimple_bb (malloc_stmt)->count, |
1679 } | 1730 compute_call_stmt_bb_frequency |
1680 | 1731 (context, gimple_bb (malloc_stmt)), |
1681 /* This function generates set of statements required | 1732 gimple_bb (malloc_stmt)->loop_depth); |
1733 } | |
1734 | |
1735 /* This function generates set of statements required | |
1682 to allocate number NUM of structures of type NEW_TYPE. | 1736 to allocate number NUM of structures of type NEW_TYPE. |
1683 The statements are stored in NEW_STMTS. The statement that contain | 1737 The statements are stored in NEW_STMTS. The statement that contain |
1684 call to malloc is returned. MALLOC_STMT is an original call to malloc. */ | 1738 call to malloc is returned. MALLOC_STMT is an original call to malloc. */ |
1685 | 1739 |
1686 static gimple | 1740 static gimple |
1695 tree cast_res; | 1749 tree cast_res; |
1696 | 1750 |
1697 gcc_assert (num && malloc_stmt && new_type); | 1751 gcc_assert (num && malloc_stmt && new_type); |
1698 *new_stmts = gimple_seq_alloc (); | 1752 *new_stmts = gimple_seq_alloc (); |
1699 | 1753 |
1700 /* Generate argument to malloc as multiplication of num | 1754 /* Generate argument to malloc as multiplication of num |
1701 and size of new_type. */ | 1755 and size of new_type. */ |
1702 new_stmt = gen_size (num, new_type, &new_malloc_size); | 1756 new_stmt = gen_size (num, new_type, &new_malloc_size); |
1703 gimple_seq_add_stmt (new_stmts, new_stmt); | 1757 gimple_seq_add_stmt (new_stmts, new_stmt); |
1704 | 1758 |
1705 /* Generate new call for malloc. */ | 1759 /* Generate new call for malloc. */ |
1706 malloc_res = create_tmp_var (ptr_type_node, NULL); | 1760 malloc_res = create_tmp_var (ptr_type_node, NULL); |
1707 add_referenced_var (malloc_res); | 1761 add_referenced_var (malloc_res); |
1708 | 1762 |
1709 malloc_fn_decl = gimple_call_fndecl (malloc_stmt); | 1763 malloc_fn_decl = gimple_call_fndecl (malloc_stmt); |
1710 call_stmt = gimple_build_call (malloc_fn_decl, 1, new_malloc_size); | 1764 call_stmt = gimple_build_call (malloc_fn_decl, 1, new_malloc_size); |
1711 gimple_call_set_lhs (call_stmt, malloc_res); | 1765 gimple_call_set_lhs (call_stmt, malloc_res); |
1712 finalize_stmt_and_append (new_stmts, call_stmt); | 1766 finalize_stmt_and_append (new_stmts, call_stmt); |
1713 | 1767 |
1714 /* Create new cast statement. */ | 1768 /* Create new cast statement. */ |
1715 final_stmt = get_final_alloc_stmt (malloc_stmt); | 1769 final_stmt = get_final_alloc_stmt (malloc_stmt); |
1716 gcc_assert (final_stmt); | 1770 gcc_assert (final_stmt); |
1717 new_stmt = gen_cast_stmt (malloc_res, new_type, final_stmt, &cast_res); | 1771 new_stmt = gen_cast_stmt (malloc_res, new_type, final_stmt, &cast_res); |
1718 gimple_seq_add_stmt (new_stmts, new_stmt); | 1772 gimple_seq_add_stmt (new_stmts, new_stmt); |
1719 | 1773 |
1720 return call_stmt; | 1774 return call_stmt; |
1721 } | 1775 } |
1722 | 1776 |
1723 /* This function returns a tree representing | 1777 /* This function returns a tree representing |
1724 the number of instances of structure STR_DECL allocated | 1778 the number of instances of structure STR_DECL allocated |
1725 by allocation STMT. If new statements are generated, | 1779 by allocation STMT. If new statements are generated, |
1726 they are filled into NEW_STMTS_P. */ | 1780 they are filled into NEW_STMTS_P. */ |
1727 | 1781 |
1728 static tree | 1782 static tree |
1729 gen_num_of_structs_in_malloc (gimple stmt, tree str_decl, | 1783 gen_num_of_structs_in_malloc (gimple stmt, tree str_decl, |
1730 gimple_seq *new_stmts_p) | 1784 gimple_seq *new_stmts_p) |
1731 { | 1785 { |
1732 tree arg; | 1786 tree arg; |
1733 tree struct_size; | 1787 tree struct_size; |
1743 arg = gimple_call_arg (stmt, 0); | 1797 arg = gimple_call_arg (stmt, 0); |
1744 | 1798 |
1745 if (TREE_CODE (arg) != SSA_NAME | 1799 if (TREE_CODE (arg) != SSA_NAME |
1746 && !TREE_CONSTANT (arg)) | 1800 && !TREE_CONSTANT (arg)) |
1747 return NULL_TREE; | 1801 return NULL_TREE; |
1748 | 1802 |
1749 struct_size = TYPE_SIZE_UNIT (str_decl); | 1803 struct_size = TYPE_SIZE_UNIT (str_decl); |
1750 struct_size_int = TREE_INT_CST_LOW (struct_size); | 1804 struct_size_int = TREE_INT_CST_LOW (struct_size); |
1751 | 1805 |
1752 gcc_assert (struct_size); | 1806 gcc_assert (struct_size); |
1753 | 1807 |
1754 if (TREE_CODE (arg) == SSA_NAME) | 1808 if (TREE_CODE (arg) == SSA_NAME) |
1755 { | 1809 { |
1756 tree num; | 1810 tree num; |
1757 gimple div_stmt; | 1811 gimple div_stmt; |
1758 | 1812 |
1759 if (is_result_of_mult (arg, &num, struct_size)) | 1813 if (is_result_of_mult (arg, &num, struct_size)) |
1760 return num; | 1814 return num; |
1761 | 1815 |
1762 num = create_tmp_var (integer_type_node, NULL); | 1816 num = create_tmp_var (integer_type_node, NULL); |
1763 | 1817 |
1764 if (num) | 1818 if (num) |
1765 add_referenced_var (num); | 1819 add_referenced_var (num); |
1768 div_stmt = gimple_build_assign_with_ops (TRUNC_DIV_EXPR, num, arg, | 1822 div_stmt = gimple_build_assign_with_ops (TRUNC_DIV_EXPR, num, arg, |
1769 struct_size); | 1823 struct_size); |
1770 else | 1824 else |
1771 { | 1825 { |
1772 tree C = build_int_cst (integer_type_node, | 1826 tree C = build_int_cst (integer_type_node, |
1773 exact_log2 (struct_size_int)); | 1827 exact_log2 (struct_size_int)); |
1774 | 1828 |
1775 div_stmt = gimple_build_assign_with_ops (RSHIFT_EXPR, num, arg, C); | 1829 div_stmt = gimple_build_assign_with_ops (RSHIFT_EXPR, num, arg, C); |
1776 } | 1830 } |
1777 gimple_seq_add_stmt (new_stmts_p, div_stmt); | 1831 gimple_seq_add_stmt (new_stmts_p, div_stmt); |
1778 finalize_stmt (div_stmt); | 1832 finalize_stmt (div_stmt); |
1779 return num; | 1833 return num; |
1780 } | 1834 } |
1781 | 1835 |
1782 if (CONSTANT_CLASS_P (arg) | 1836 if (CONSTANT_CLASS_P (arg) |
1783 && multiple_of_p (TREE_TYPE (struct_size), arg, struct_size)) | 1837 && multiple_of_p (TREE_TYPE (struct_size), arg, struct_size)) |
1784 return int_const_binop (TRUNC_DIV_EXPR, arg, struct_size, 0); | 1838 return int_const_binop (TRUNC_DIV_EXPR, arg, struct_size, 0); |
1785 | 1839 |
1786 return NULL_TREE; | 1840 return NULL_TREE; |
1787 } | 1841 } |
1788 | 1842 |
1789 /* This function is a callback for traversal on new_var's hashtable. | 1843 /* This function is a callback for traversal on new_var's hashtable. |
1790 SLOT is a pointer to new_var. This function prints to dump_file | 1844 SLOT is a pointer to new_var. This function prints to dump_file |
1791 an original variable and all new variables from the new_var | 1845 an original variable and all new variables from the new_var |
1792 pointed by *SLOT. */ | 1846 pointed by *SLOT. */ |
1793 | 1847 |
1794 static int | 1848 static int |
1795 dump_new_var (void **slot, void *data ATTRIBUTE_UNUSED) | 1849 dump_new_var (void **slot, void *data ATTRIBUTE_UNUSED) |
1796 { | 1850 { |
1797 new_var n_var = *(new_var *) slot; | 1851 new_var n_var = *(new_var *) slot; |
1807 print_generic_expr (dump_file, var_type, 0); | 1861 print_generic_expr (dump_file, var_type, 0); |
1808 fprintf (dump_file, "\n"); | 1862 fprintf (dump_file, "\n"); |
1809 | 1863 |
1810 for (i = 0; | 1864 for (i = 0; |
1811 VEC_iterate (tree, n_var->new_vars, i, var); i++) | 1865 VEC_iterate (tree, n_var->new_vars, i, var); i++) |
1812 { | 1866 { |
1813 var_type = get_type_of_var (var); | 1867 var_type = get_type_of_var (var); |
1814 | 1868 |
1815 fprintf (dump_file, " "); | 1869 fprintf (dump_file, " "); |
1816 print_generic_expr (dump_file, var, 0); | 1870 print_generic_expr (dump_file, var, 0); |
1817 fprintf (dump_file, " of type "); | 1871 fprintf (dump_file, " of type "); |
1818 print_generic_expr (dump_file, var_type, 0); | 1872 print_generic_expr (dump_file, var_type, 0); |
1819 fprintf (dump_file, "\n"); | 1873 fprintf (dump_file, "\n"); |
1821 return 1; | 1875 return 1; |
1822 } | 1876 } |
1823 | 1877 |
1824 /* This function copies attributes form ORIG_DECL to NEW_DECL. */ | 1878 /* This function copies attributes form ORIG_DECL to NEW_DECL. */ |
1825 | 1879 |
1826 static inline void | 1880 static inline void |
1827 copy_decl_attributes (tree new_decl, tree orig_decl) | 1881 copy_decl_attributes (tree new_decl, tree orig_decl) |
1828 { | 1882 { |
1829 | 1883 |
1830 DECL_ARTIFICIAL (new_decl) = 1; | 1884 DECL_ARTIFICIAL (new_decl) = 1; |
1831 DECL_EXTERNAL (new_decl) = DECL_EXTERNAL (orig_decl); | 1885 DECL_EXTERNAL (new_decl) = DECL_EXTERNAL (orig_decl); |
1833 TREE_PUBLIC (new_decl) = TREE_PUBLIC (orig_decl); | 1887 TREE_PUBLIC (new_decl) = TREE_PUBLIC (orig_decl); |
1834 TREE_USED (new_decl) = TREE_USED (orig_decl); | 1888 TREE_USED (new_decl) = TREE_USED (orig_decl); |
1835 DECL_CONTEXT (new_decl) = DECL_CONTEXT (orig_decl); | 1889 DECL_CONTEXT (new_decl) = DECL_CONTEXT (orig_decl); |
1836 TREE_THIS_VOLATILE (new_decl) = TREE_THIS_VOLATILE (orig_decl); | 1890 TREE_THIS_VOLATILE (new_decl) = TREE_THIS_VOLATILE (orig_decl); |
1837 TREE_ADDRESSABLE (new_decl) = TREE_ADDRESSABLE (orig_decl); | 1891 TREE_ADDRESSABLE (new_decl) = TREE_ADDRESSABLE (orig_decl); |
1838 | 1892 |
1839 if (TREE_CODE (orig_decl) == VAR_DECL) | 1893 if (TREE_CODE (orig_decl) == VAR_DECL) |
1840 { | 1894 { |
1841 TREE_READONLY (new_decl) = TREE_READONLY (orig_decl); | 1895 TREE_READONLY (new_decl) = TREE_READONLY (orig_decl); |
1842 DECL_TLS_MODEL (new_decl) = DECL_TLS_MODEL (orig_decl); | 1896 DECL_TLS_MODEL (new_decl) = DECL_TLS_MODEL (orig_decl); |
1843 } | 1897 } |
1844 } | 1898 } |
1845 | 1899 |
1846 /* This function wraps NEW_STR_TYPE in pointers or arrays wrapper | 1900 /* This function wraps NEW_STR_TYPE in pointers or arrays wrapper |
1847 the same way as a structure type is wrapped in DECL. | 1901 the same way as a structure type is wrapped in DECL. |
1848 It returns the generated type. */ | 1902 It returns the generated type. */ |
1849 | 1903 |
1850 static inline tree | 1904 static inline tree |
1851 gen_struct_type (tree decl, tree new_str_type) | 1905 gen_struct_type (tree decl, tree new_str_type) |
1852 { | 1906 { |
1853 tree type_orig = get_type_of_var (decl); | 1907 tree type_orig = get_type_of_var (decl); |
1854 tree new_type = new_str_type; | 1908 tree new_type = new_str_type; |
1855 VEC (type_wrapper_t, heap) *wrapper = VEC_alloc (type_wrapper_t, heap, 10); | 1909 VEC (type_wrapper_t, heap) *wrapper = VEC_alloc (type_wrapper_t, heap, 10); |
1856 type_wrapper_t wr; | 1910 type_wrapper_t wr; |
1857 type_wrapper_t *wr_p; | 1911 type_wrapper_t *wr_p; |
1858 | 1912 |
1859 while (POINTER_TYPE_P (type_orig) | 1913 while (POINTER_TYPE_P (type_orig) |
1860 || TREE_CODE (type_orig) == ARRAY_TYPE) | 1914 || TREE_CODE (type_orig) == ARRAY_TYPE) |
1861 { | 1915 { |
1862 if (POINTER_TYPE_P (type_orig)) | 1916 if (POINTER_TYPE_P (type_orig)) |
1863 { | 1917 { |
1864 wr.wrap = 0; | 1918 wr.wrap = 0; |
1865 wr.domain = NULL_TREE; | 1919 wr.domain = NULL_TREE; |
1866 } | 1920 } |
1874 type_orig = TREE_TYPE (type_orig); | 1928 type_orig = TREE_TYPE (type_orig); |
1875 } | 1929 } |
1876 | 1930 |
1877 while (VEC_length (type_wrapper_t, wrapper) != 0) | 1931 while (VEC_length (type_wrapper_t, wrapper) != 0) |
1878 { | 1932 { |
1879 wr_p = VEC_last (type_wrapper_t, wrapper); | 1933 wr_p = VEC_last (type_wrapper_t, wrapper); |
1880 | 1934 |
1881 if (wr_p->wrap) /* Array. */ | 1935 if (wr_p->wrap) /* Array. */ |
1882 new_type = build_array_type (new_type, wr_p->domain); | 1936 new_type = build_array_type (new_type, wr_p->domain); |
1883 else /* Pointer. */ | 1937 else /* Pointer. */ |
1884 new_type = build_pointer_type (new_type); | 1938 new_type = build_pointer_type (new_type); |
1885 | 1939 |
1886 VEC_pop (type_wrapper_t, wrapper); | 1940 VEC_pop (type_wrapper_t, wrapper); |
1887 } | 1941 } |
1888 | 1942 |
1889 VEC_free (type_wrapper_t, heap, wrapper); | 1943 VEC_free (type_wrapper_t, heap, wrapper); |
1890 return new_type; | 1944 return new_type; |
1891 } | 1945 } |
1892 | 1946 |
1893 /* This function generates and returns new variable name based on | 1947 /* This function generates and returns new variable name based on |
1894 ORIG_DECL name, combined with index I. | 1948 ORIG_DECL name, combined with index I. |
1903 | 1957 |
1904 if (!DECL_NAME (orig_decl) | 1958 if (!DECL_NAME (orig_decl) |
1905 || !IDENTIFIER_POINTER (DECL_NAME (orig_decl))) | 1959 || !IDENTIFIER_POINTER (DECL_NAME (orig_decl))) |
1906 return NULL; | 1960 return NULL; |
1907 | 1961 |
1908 /* If the original variable has a name, create an | 1962 /* If the original variable has a name, create an |
1909 appropriate new name for the new variable. */ | 1963 appropriate new name for the new variable. */ |
1910 | 1964 |
1911 old_name = IDENTIFIER_POINTER (DECL_NAME (orig_decl)); | 1965 old_name = IDENTIFIER_POINTER (DECL_NAME (orig_decl)); |
1912 prefix = XALLOCAVEC (char, strlen (old_name) + 1); | 1966 prefix = XALLOCAVEC (char, strlen (old_name) + 1); |
1913 strcpy (prefix, old_name); | 1967 strcpy (prefix, old_name); |
1921 add_to_new_vars_htab (new_var new_node, htab_t new_vars_htab) | 1975 add_to_new_vars_htab (new_var new_node, htab_t new_vars_htab) |
1922 { | 1976 { |
1923 void **slot; | 1977 void **slot; |
1924 | 1978 |
1925 slot = htab_find_slot_with_hash (new_vars_htab, new_node->orig_var, | 1979 slot = htab_find_slot_with_hash (new_vars_htab, new_node->orig_var, |
1926 htab_hash_pointer (new_node->orig_var), | 1980 DECL_UID (new_node->orig_var), |
1927 INSERT); | 1981 INSERT); |
1928 *slot = new_node; | 1982 *slot = new_node; |
1929 } | 1983 } |
1930 | 1984 |
1931 /* This function creates and returns new_var_data node | 1985 /* This function creates and returns new_var_data node |
1932 with empty new_vars and orig_var equal to VAR. */ | 1986 with empty new_vars and orig_var equal to VAR. */ |
1933 | 1987 |
1934 static new_var | 1988 static new_var |
1935 create_new_var_node (tree var, d_str str) | 1989 create_new_var_node (tree var, d_str str) |
1936 { | 1990 { |
1960 | 2014 |
1961 /* There is no support of initialized vars. */ | 2015 /* There is no support of initialized vars. */ |
1962 if (TREE_CODE (var) == VAR_DECL | 2016 if (TREE_CODE (var) == VAR_DECL |
1963 && DECL_INITIAL (var) != NULL_TREE) | 2017 && DECL_INITIAL (var) != NULL_TREE) |
1964 initialized = true; | 2018 initialized = true; |
1965 | 2019 |
1966 type = get_type_of_var (var); | 2020 type = get_type_of_var (var); |
1967 | 2021 |
1968 if (type) | 2022 if (type) |
1969 { | 2023 { |
1970 type = TYPE_MAIN_VARIANT (strip_type (type)); | 2024 type = TYPE_MAIN_VARIANT (strip_type (type)); |
1971 if (TREE_CODE (type) != RECORD_TYPE) | 2025 if (TREE_CODE (type) != RECORD_TYPE) |
1972 return false; | 2026 return false; |
1973 else | 2027 else |
1974 { | 2028 { |
1975 if (initialized && unsuitable_types && *unsuitable_types) | 2029 if (initialized && unsuitable_types && *unsuitable_types) |
1976 { | 2030 { |
1977 if (dump_file) | 2031 if (dump_file) |
1978 { | 2032 { |
1979 fprintf (dump_file, "The type "); | 2033 fprintf (dump_file, "The type "); |
1980 print_generic_expr (dump_file, type, 0); | 2034 print_generic_expr (dump_file, type, 0); |
1981 fprintf (dump_file, " is initialized...Excluded."); | 2035 fprintf (dump_file, " is initialized...Excluded."); |
1982 } | 2036 } |
1983 add_unsuitable_type (unsuitable_types, type); | 2037 add_unsuitable_type (unsuitable_types, type); |
1984 } | 2038 } |
1985 *type_p = type; | 2039 *type_p = type; |
1986 return true; | 2040 return true; |
1996 field_acc_hash (const void *x) | 2050 field_acc_hash (const void *x) |
1997 { | 2051 { |
1998 return htab_hash_pointer (((const struct field_access_site *)x)->stmt); | 2052 return htab_hash_pointer (((const struct field_access_site *)x)->stmt); |
1999 } | 2053 } |
2000 | 2054 |
2001 /* This function returns nonzero if stmt of field_access_site X | 2055 /* This function returns nonzero if stmt of field_access_site X |
2002 is equal to Y. */ | 2056 is equal to Y. */ |
2003 | 2057 |
2004 static int | 2058 static int |
2005 field_acc_eq (const void *x, const void *y) | 2059 field_acc_eq (const void *x, const void *y) |
2006 { | 2060 { |
2007 return ((const struct field_access_site *)x)->stmt == (const_gimple)y; | 2061 return ((const struct field_access_site *)x)->stmt == (const_gimple)y; |
2008 } | 2062 } |
2009 | 2063 |
2010 /* This function prints an access site, defined by SLOT. */ | 2064 /* This function prints an access site, defined by SLOT. */ |
2011 | 2065 |
2012 static int | 2066 static int |
2013 dump_acc (void **slot, void *data ATTRIBUTE_UNUSED) | 2067 dump_acc (void **slot, void *data ATTRIBUTE_UNUSED) |
2014 { | 2068 { |
2015 struct access_site *acc = *(struct access_site **) slot; | 2069 struct access_site *acc = *(struct access_site **) slot; |
2022 fprintf(dump_file, " : "); | 2076 fprintf(dump_file, " : "); |
2023 | 2077 |
2024 for (i = 0; VEC_iterate (tree, acc->vars, i, var); i++) | 2078 for (i = 0; VEC_iterate (tree, acc->vars, i, var); i++) |
2025 { | 2079 { |
2026 print_generic_expr (dump_file, var, 0); | 2080 print_generic_expr (dump_file, var, 0); |
2027 fprintf(dump_file, ", "); | 2081 fprintf(dump_file, ", "); |
2028 } | 2082 } |
2029 return 1; | 2083 return 1; |
2030 } | 2084 } |
2031 | 2085 |
2032 /* This function frees memory allocated for structure clusters, | 2086 /* This function frees memory allocated for structure clusters, |
2036 free_struct_cluster (struct field_cluster* cluster) | 2090 free_struct_cluster (struct field_cluster* cluster) |
2037 { | 2091 { |
2038 if (cluster) | 2092 if (cluster) |
2039 { | 2093 { |
2040 if (cluster->fields_in_cluster) | 2094 if (cluster->fields_in_cluster) |
2041 sbitmap_free (cluster->fields_in_cluster); | 2095 sbitmap_free (cluster->fields_in_cluster); |
2042 if (cluster->sibling) | 2096 if (cluster->sibling) |
2043 free_struct_cluster (cluster->sibling); | 2097 free_struct_cluster (cluster->sibling); |
2044 free (cluster); | 2098 free (cluster); |
2045 } | 2099 } |
2046 } | 2100 } |
2052 { | 2106 { |
2053 int i; | 2107 int i; |
2054 | 2108 |
2055 if (!d_node) | 2109 if (!d_node) |
2056 return; | 2110 return; |
2057 | 2111 |
2058 if (dump_file) | 2112 if (dump_file) |
2059 { | 2113 { |
2060 fprintf (dump_file, "\nRemoving data structure \""); | 2114 fprintf (dump_file, "\nRemoving data structure \""); |
2061 print_generic_expr (dump_file, d_node->decl, 0); | 2115 print_generic_expr (dump_file, d_node->decl, 0); |
2062 fprintf (dump_file, "\" from data_struct_list."); | 2116 fprintf (dump_file, "\" from data_struct_list."); |
2063 } | 2117 } |
2064 | 2118 |
2065 /* Free all space under d_node. */ | 2119 /* Free all space under d_node. */ |
2066 if (d_node->fields) | 2120 if (d_node->fields) |
2098 static void | 2152 static void |
2099 create_new_alloc_sites (fallocs_t m_data, tree context) | 2153 create_new_alloc_sites (fallocs_t m_data, tree context) |
2100 { | 2154 { |
2101 alloc_site_t *call; | 2155 alloc_site_t *call; |
2102 unsigned j; | 2156 unsigned j; |
2103 | 2157 |
2104 for (j = 0; VEC_iterate (alloc_site_t, m_data->allocs, j, call); j++) | 2158 for (j = 0; VEC_iterate (alloc_site_t, m_data->allocs, j, call); j++) |
2105 { | 2159 { |
2106 gimple stmt = call->stmt; | 2160 gimple stmt = call->stmt; |
2107 d_str str = call->str; | 2161 d_str str = call->str; |
2108 tree num; | 2162 tree num; |
2116 { | 2170 { |
2117 gimple last_stmt_tmp = gimple_seq_last_stmt (new_stmts); | 2171 gimple last_stmt_tmp = gimple_seq_last_stmt (new_stmts); |
2118 insert_seq_after_stmt (last_stmt, new_stmts); | 2172 insert_seq_after_stmt (last_stmt, new_stmts); |
2119 last_stmt = last_stmt_tmp; | 2173 last_stmt = last_stmt_tmp; |
2120 } | 2174 } |
2121 | 2175 |
2122 /* Generate an allocation sites for each new structure type. */ | 2176 /* Generate an allocation sites for each new structure type. */ |
2123 for (i = 0; VEC_iterate (tree, str->new_types, i, type); i++) | 2177 for (i = 0; VEC_iterate (tree, str->new_types, i, type); i++) |
2124 { | 2178 { |
2125 gimple new_malloc_stmt = NULL; | 2179 gimple new_malloc_stmt = NULL; |
2126 gimple last_stmt_tmp = NULL; | 2180 gimple last_stmt_tmp = NULL; |
2127 | 2181 |
2128 new_stmts = NULL; | 2182 new_stmts = NULL; |
2133 last_stmt = last_stmt_tmp; | 2187 last_stmt = last_stmt_tmp; |
2134 } | 2188 } |
2135 } | 2189 } |
2136 } | 2190 } |
2137 | 2191 |
2138 /* This function prints new variables from hashtable | 2192 /* This function prints new variables from hashtable |
2139 NEW_VARS_HTAB to dump_file. */ | 2193 NEW_VARS_HTAB to dump_file. */ |
2140 | 2194 |
2141 static void | 2195 static void |
2142 dump_new_vars (htab_t new_vars_htab) | 2196 dump_new_vars (htab_t new_vars_htab) |
2143 { | 2197 { |
2147 if (new_vars_htab) | 2201 if (new_vars_htab) |
2148 htab_traverse (new_vars_htab, dump_new_var, NULL); | 2202 htab_traverse (new_vars_htab, dump_new_var, NULL); |
2149 } | 2203 } |
2150 | 2204 |
2151 /* Given an original variable ORIG_DECL of structure type STR, | 2205 /* Given an original variable ORIG_DECL of structure type STR, |
2152 this function generates new variables of the types defined | 2206 this function generates new variables of the types defined |
2153 by STR->new_type. Generated types are saved in new_var node NODE. | 2207 by STR->new_type. Generated types are saved in new_var node NODE. |
2154 ORIG_DECL should has VAR_DECL tree_code. */ | 2208 ORIG_DECL should has VAR_DECL tree_code. */ |
2155 | 2209 |
2156 static void | 2210 static void |
2157 create_new_var_1 (tree orig_decl, d_str str, new_var node) | 2211 create_new_var_1 (tree orig_decl, d_str str, new_var node) |
2158 { | 2212 { |
2159 unsigned i; | 2213 unsigned i; |
2160 tree type; | 2214 tree type; |
2161 | 2215 |
2162 for (i = 0; | 2216 for (i = 0; |
2163 VEC_iterate (tree, str->new_types, i, type); i++) | 2217 VEC_iterate (tree, str->new_types, i, type); i++) |
2164 { | 2218 { |
2165 tree new_decl = NULL; | 2219 tree new_decl = NULL; |
2166 tree new_name; | 2220 tree new_name; |
2167 | 2221 |
2168 new_name = gen_var_name (orig_decl, i); | 2222 new_name = gen_var_name (orig_decl, i); |
2169 type = gen_struct_type (orig_decl, type); | 2223 type = gen_struct_type (orig_decl, type); |
2170 | 2224 |
2171 if (is_global_var (orig_decl)) | 2225 if (is_global_var (orig_decl)) |
2172 new_decl = build_decl (VAR_DECL, new_name, type); | 2226 new_decl = build_decl (DECL_SOURCE_LOCATION (orig_decl), |
2227 VAR_DECL, new_name, type); | |
2173 else | 2228 else |
2174 { | 2229 { |
2175 const char *name = new_name ? IDENTIFIER_POINTER (new_name) : NULL; | 2230 const char *name = new_name ? IDENTIFIER_POINTER (new_name) : NULL; |
2176 new_decl = create_tmp_var (type, name); | 2231 new_decl = create_tmp_var (type, name); |
2177 } | 2232 } |
2178 | 2233 |
2179 copy_decl_attributes (new_decl, orig_decl); | 2234 copy_decl_attributes (new_decl, orig_decl); |
2180 VEC_safe_push (tree, heap, node->new_vars, new_decl); | 2235 VEC_safe_push (tree, heap, node->new_vars, new_decl); |
2181 } | 2236 } |
2182 } | 2237 } |
2183 | 2238 |
2184 /* This function creates new variables to | 2239 /* This function creates new variables to |
2185 substitute the original variable VAR_DECL and adds | 2240 substitute the original variable VAR_DECL and adds |
2186 them to the new_var's hashtable NEW_VARS_HTAB. */ | 2241 them to the new_var's hashtable NEW_VARS_HTAB. */ |
2187 | 2242 |
2188 static void | 2243 static void |
2189 create_new_var (tree var_decl, htab_t new_vars_htab) | 2244 create_new_var (tree var_decl, htab_t new_vars_htab) |
2190 { | 2245 { |
2196 if (!var_decl || is_in_new_vars_htab (var_decl, new_vars_htab)) | 2251 if (!var_decl || is_in_new_vars_htab (var_decl, new_vars_htab)) |
2197 return; | 2252 return; |
2198 | 2253 |
2199 if (!is_candidate (var_decl, &type, NULL)) | 2254 if (!is_candidate (var_decl, &type, NULL)) |
2200 return; | 2255 return; |
2201 | 2256 |
2202 i = find_structure (type); | 2257 i = find_structure (type); |
2203 if (i == VEC_length (structure, structures)) | 2258 if (i == VEC_length (structure, structures)) |
2204 return; | 2259 return; |
2205 | 2260 |
2206 str = VEC_index (structure, structures, i); | 2261 str = VEC_index (structure, structures, i); |
2212 /* Hash value for new_var. */ | 2267 /* Hash value for new_var. */ |
2213 | 2268 |
2214 static hashval_t | 2269 static hashval_t |
2215 new_var_hash (const void *x) | 2270 new_var_hash (const void *x) |
2216 { | 2271 { |
2217 return htab_hash_pointer (((const_new_var)x)->orig_var); | 2272 return DECL_UID (((const_new_var)x)->orig_var); |
2218 } | 2273 } |
2219 | 2274 |
2220 /* This function returns nonzero if orig_var of new_var X is equal to Y. */ | 2275 /* This function returns nonzero if orig_var of new_var X |
2276 and tree Y have equal UIDs. */ | |
2221 | 2277 |
2222 static int | 2278 static int |
2223 new_var_eq (const void *x, const void *y) | 2279 new_var_eq (const void *x, const void *y) |
2224 { | 2280 { |
2225 return ((const_new_var)x)->orig_var == (const_tree)y; | 2281 if (DECL_P ((const_tree)y)) |
2226 } | 2282 return DECL_UID (((const_new_var)x)->orig_var) == DECL_UID ((const_tree)y); |
2227 | 2283 else |
2228 /* This function check whether a structure type represented by STR | 2284 return 0; |
2229 escapes due to ipa-type-escape analysis. If yes, this type is added | 2285 } |
2230 to UNSUITABLE_TYPES vector. */ | 2286 |
2287 /* This function check whether a structure type represented by STR | |
2288 escapes due to ipa-type-escape analysis. If yes, this type is added | |
2289 to UNSUITABLE_TYPES vector. */ | |
2231 | 2290 |
2232 static void | 2291 static void |
2233 check_type_escape (d_str str, VEC (tree, heap) **unsuitable_types) | 2292 check_type_escape (d_str str, VEC (tree, heap) **unsuitable_types) |
2234 { | 2293 { |
2235 tree type = str->decl; | 2294 tree type = str->decl; |
2259 acc_eq (const void *x, const void *y) | 2318 acc_eq (const void *x, const void *y) |
2260 { | 2319 { |
2261 return ((const struct access_site *)x)->stmt == (const_gimple)y; | 2320 return ((const struct access_site *)x)->stmt == (const_gimple)y; |
2262 } | 2321 } |
2263 | 2322 |
2264 /* Given a structure declaration STRUCT_DECL, and number of fields | 2323 /* Given a structure declaration STRUCT_DECL, and number of fields |
2265 in the structure NUM_FIELDS, this function creates and returns | 2324 in the structure NUM_FIELDS, this function creates and returns |
2266 corresponding field_entry's. */ | 2325 corresponding field_entry's. */ |
2267 | 2326 |
2268 static struct field_entry * | 2327 static struct field_entry * |
2269 get_fields (tree struct_decl, int num_fields) | 2328 get_fields (tree struct_decl, int num_fields) |
2270 { | 2329 { |
2271 struct field_entry *list; | 2330 struct field_entry *list; |
2272 tree t = TYPE_FIELDS (struct_decl); | 2331 tree t = TYPE_FIELDS (struct_decl); |
2273 int idx = 0; | 2332 int idx = 0; |
2274 | 2333 |
2275 list = | 2334 list = |
2276 (struct field_entry *) xmalloc (num_fields * sizeof (struct field_entry)); | 2335 (struct field_entry *) xmalloc (num_fields * sizeof (struct field_entry)); |
2277 | 2336 |
2278 for (idx = 0 ; t; t = TREE_CHAIN (t), idx++) | 2337 for (idx = 0 ; t; t = TREE_CHAIN (t), idx++) |
2279 if (TREE_CODE (t) == FIELD_DECL) | 2338 if (TREE_CODE (t) == FIELD_DECL) |
2280 { | 2339 { |
2281 list[idx].index = idx; | 2340 list[idx].index = idx; |
2282 list[idx].decl = t; | 2341 list[idx].decl = t; |
2283 list[idx].acc_sites = | 2342 list[idx].acc_sites = |
2284 htab_create (32, field_acc_hash, field_acc_eq, NULL); | 2343 htab_create (32, field_acc_hash, field_acc_eq, NULL); |
2285 list[idx].count = 0; | 2344 list[idx].count = 0; |
2286 list[idx].field_mapping = NULL_TREE; | 2345 list[idx].field_mapping = NULL_TREE; |
2287 } | 2346 } |
2288 | 2347 |
2299 | 2358 |
2300 if (accs) | 2359 if (accs) |
2301 htab_traverse (accs, dump_acc, NULL); | 2360 htab_traverse (accs, dump_acc, NULL); |
2302 } | 2361 } |
2303 | 2362 |
2304 /* This function is a callback for alloc_sites hashtable | 2363 /* This function is a callback for alloc_sites hashtable |
2305 traversal. SLOT is a pointer to fallocs_t. This function | 2364 traversal. SLOT is a pointer to fallocs_t. This function |
2306 removes all allocations of the structure defined by DATA. */ | 2365 removes all allocations of the structure defined by DATA. */ |
2307 | 2366 |
2308 static int | 2367 static int |
2309 remove_str_allocs_in_func (void **slot, void *data) | 2368 remove_str_allocs_in_func (void **slot, void *data) |
2336 htab_traverse (alloc_sites, remove_str_allocs_in_func, str); | 2395 htab_traverse (alloc_sites, remove_str_allocs_in_func, str); |
2337 } | 2396 } |
2338 | 2397 |
2339 /* This function removes the structure with index I from structures vector. */ | 2398 /* This function removes the structure with index I from structures vector. */ |
2340 | 2399 |
2341 static void | 2400 static void |
2342 remove_structure (unsigned i) | 2401 remove_structure (unsigned i) |
2343 { | 2402 { |
2344 d_str str; | 2403 d_str str; |
2345 | 2404 |
2346 if (i >= VEC_length (structure, structures)) | 2405 if (i >= VEC_length (structure, structures)) |
2347 return; | 2406 return; |
2348 | 2407 |
2349 str = VEC_index (structure, structures, i); | 2408 str = VEC_index (structure, structures, i); |
2350 | 2409 |
2351 /* Before removing the structure str, we have to remove its | 2410 /* Before removing the structure str, we have to remove its |
2352 allocations from alloc_sites hashtable. */ | 2411 allocations from alloc_sites hashtable. */ |
2353 remove_str_allocs (str); | 2412 remove_str_allocs (str); |
2354 free_data_struct (str); | 2413 free_data_struct (str); |
2355 VEC_ordered_remove (structure, structures, i); | 2414 VEC_ordered_remove (structure, structures, i); |
2367 unsigned length = VEC_length (structure, structures); | 2426 unsigned length = VEC_length (structure, structures); |
2368 | 2427 |
2369 if (gimple_cond_code (cond_stmt) != EQ_EXPR | 2428 if (gimple_cond_code (cond_stmt) != EQ_EXPR |
2370 && gimple_cond_code (cond_stmt) != NE_EXPR) | 2429 && gimple_cond_code (cond_stmt) != NE_EXPR) |
2371 return false; | 2430 return false; |
2372 | 2431 |
2373 arg0 = gimple_cond_lhs (cond_stmt); | 2432 arg0 = gimple_cond_lhs (cond_stmt); |
2374 arg1 = gimple_cond_rhs (cond_stmt); | 2433 arg1 = gimple_cond_rhs (cond_stmt); |
2375 | 2434 |
2376 str0 = find_structure (strip_type (get_type_of_var (arg0))); | 2435 str0 = find_structure (strip_type (get_type_of_var (arg0))); |
2377 str1 = find_structure (strip_type (get_type_of_var (arg1))); | 2436 str1 = find_structure (strip_type (get_type_of_var (arg1))); |
2378 | 2437 |
2379 s0 = (str0 != length) ? true : false; | 2438 s0 = (str0 != length) ? true : false; |
2380 s1 = (str1 != length) ? true : false; | 2439 s1 = (str1 != length) ? true : false; |
2381 | 2440 |
2382 if (!s0 && !s1) | 2441 if (!s0 && !s1) |
2383 return false; | 2442 return false; |
2384 | 2443 |
2385 /* For now we allow only comparison with 0 or NULL. */ | 2444 /* For now we allow only comparison with 0 or NULL. */ |
2386 if (!integer_zerop (arg0) && !integer_zerop (arg1)) | 2445 if (!integer_zerop (arg0) && !integer_zerop (arg1)) |
2387 return false; | 2446 return false; |
2388 | 2447 |
2389 return true; | 2448 return true; |
2390 } | 2449 } |
2391 | 2450 |
2392 /* This function excludes statements, that are | 2451 /* This function excludes statements, that are |
2393 part of allocation sites or field accesses, from the | 2452 part of allocation sites or field accesses, from the |
2394 hashtable of general accesses. SLOT represents general | 2453 hashtable of general accesses. SLOT represents general |
2395 access that will be checked. DATA is a pointer to | 2454 access that will be checked. DATA is a pointer to |
2396 exclude_data structure. */ | 2455 exclude_data structure. */ |
2397 | 2456 |
2398 static int | 2457 static int |
2399 exclude_from_accs (void **slot, void *data) | 2458 exclude_from_accs (void **slot, void *data) |
2400 { | 2459 { |
2410 htab_clear_slot (str->accs, slot); | 2469 htab_clear_slot (str->accs, slot); |
2411 } | 2470 } |
2412 return 1; | 2471 return 1; |
2413 } | 2472 } |
2414 | 2473 |
2415 /* Callback function for walk_tree called from collect_accesses_in_bb | 2474 /* Callback function for walk_tree called from collect_accesses_in_bb |
2416 function. DATA is the statement which is analyzed. */ | 2475 function. DATA is the statement which is analyzed. */ |
2417 | 2476 |
2418 static tree | 2477 static tree |
2419 get_stmt_accesses (tree *tp, int *walk_subtrees, void *data) | 2478 get_stmt_accesses (tree *tp, int *walk_subtrees, void *data) |
2420 { | 2479 { |
2438 if (dump_file) | 2497 if (dump_file) |
2439 { | 2498 { |
2440 fprintf (dump_file, "\nThe type "); | 2499 fprintf (dump_file, "\nThe type "); |
2441 print_generic_expr (dump_file, type, 0); | 2500 print_generic_expr (dump_file, type, 0); |
2442 fprintf (dump_file, " has bitfield."); | 2501 fprintf (dump_file, " has bitfield."); |
2443 } | 2502 } |
2444 remove_structure (i); | 2503 remove_structure (i); |
2445 } | 2504 } |
2446 } | 2505 } |
2447 break; | 2506 break; |
2448 | 2507 |
2461 unsigned i = find_structure (type); | 2520 unsigned i = find_structure (type); |
2462 | 2521 |
2463 if (i != VEC_length (structure, structures)) | 2522 if (i != VEC_length (structure, structures)) |
2464 { | 2523 { |
2465 d_str str = VEC_index (structure, structures, i); | 2524 d_str str = VEC_index (structure, structures, i); |
2466 struct field_entry * field = | 2525 struct field_entry * field = |
2467 find_field_in_struct (str, field_decl); | 2526 find_field_in_struct (str, field_decl); |
2468 | 2527 |
2469 if (field) | 2528 if (field) |
2470 { | 2529 { |
2471 struct field_access_site *acc = make_field_acc_node (); | 2530 struct field_access_site *acc = make_field_acc_node (); |
2475 acc->stmt = stmt; | 2534 acc->stmt = stmt; |
2476 acc->comp_ref = t; | 2535 acc->comp_ref = t; |
2477 acc->ref = ref; | 2536 acc->ref = ref; |
2478 acc->field_decl = field_decl; | 2537 acc->field_decl = field_decl; |
2479 | 2538 |
2480 /* Check whether the access is of the form | 2539 /* Check whether the access is of the form |
2481 we can deal with. */ | 2540 we can deal with. */ |
2482 if (!decompose_access (str->decl, acc)) | 2541 if (!decompose_access (str->decl, acc)) |
2483 { | 2542 { |
2484 if (dump_file) | 2543 if (dump_file) |
2485 { | 2544 { |
2486 fprintf (dump_file, "\nThe type "); | 2545 fprintf (dump_file, "\nThe type "); |
2487 print_generic_expr (dump_file, type, 0); | 2546 print_generic_expr (dump_file, type, 0); |
2488 fprintf (dump_file, | 2547 fprintf (dump_file, |
2489 " has complicate access in statement "); | 2548 " has complicate access in statement "); |
2490 print_gimple_stmt (dump_file, stmt, 0, 0); | 2549 print_gimple_stmt (dump_file, stmt, 0, 0); |
2491 } | 2550 } |
2492 | 2551 |
2493 remove_structure (i); | 2552 remove_structure (i); |
2494 free (acc); | 2553 free (acc); |
2495 } | 2554 } |
2496 else | 2555 else |
2497 { | 2556 { |
2502 /* Add stmt to the acc_sites of field. */ | 2561 /* Add stmt to the acc_sites of field. */ |
2503 add_field_acc_to_acc_sites (acc, field->acc_sites); | 2562 add_field_acc_to_acc_sites (acc, field->acc_sites); |
2504 } | 2563 } |
2505 *walk_subtrees = 0; | 2564 *walk_subtrees = 0; |
2506 } | 2565 } |
2507 } | 2566 } |
2508 } | 2567 } |
2509 } | 2568 } |
2510 break; | 2569 break; |
2511 | 2570 |
2512 case COND_EXPR: | 2571 case COND_EXPR: |
2518 tree t = TREE_OPERAND (cond, i); | 2577 tree t = TREE_OPERAND (cond, i); |
2519 | 2578 |
2520 *walk_subtrees = 1; | 2579 *walk_subtrees = 1; |
2521 walk_tree (&t, get_stmt_accesses, data, NULL); | 2580 walk_tree (&t, get_stmt_accesses, data, NULL); |
2522 } | 2581 } |
2523 *walk_subtrees = 0; | 2582 *walk_subtrees = 0; |
2524 } | 2583 } |
2525 break; | 2584 break; |
2526 | 2585 |
2527 case VAR_DECL: | 2586 case VAR_DECL: |
2528 case SSA_NAME: | 2587 case SSA_NAME: |
2565 VEC_free (structure, heap, structures); | 2624 VEC_free (structure, heap, structures); |
2566 structures = NULL; | 2625 structures = NULL; |
2567 } | 2626 } |
2568 | 2627 |
2569 /* This function is a callback for traversal over new_var's hashtable. | 2628 /* This function is a callback for traversal over new_var's hashtable. |
2570 SLOT is a pointer to new_var. This function frees memory allocated | 2629 SLOT is a pointer to new_var. This function frees memory allocated |
2571 for new_var and pointed by *SLOT. */ | 2630 for new_var and pointed by *SLOT. */ |
2572 | 2631 |
2573 static int | 2632 static int |
2574 free_new_var (void **slot, void *data ATTRIBUTE_UNUSED) | 2633 free_new_var (void **slot, void *data ATTRIBUTE_UNUSED) |
2575 { | 2634 { |
2585 | 2644 |
2586 static void | 2645 static void |
2587 free_new_vars_htab (htab_t new_vars_htab) | 2646 free_new_vars_htab (htab_t new_vars_htab) |
2588 { | 2647 { |
2589 if (new_vars_htab) | 2648 if (new_vars_htab) |
2590 htab_traverse (new_vars_htab, free_new_var, NULL); | 2649 htab_traverse (new_vars_htab, free_new_var, NULL); |
2591 htab_delete (new_vars_htab); | 2650 htab_delete (new_vars_htab); |
2592 new_vars_htab = NULL; | 2651 new_vars_htab = NULL; |
2593 } | 2652 } |
2594 | 2653 |
2595 /* This function creates new general and field accesses that appear in cfun. */ | 2654 /* This function creates new general and field accesses that appear in cfun. */ |
2620 static void | 2679 static void |
2621 create_new_local_vars (void) | 2680 create_new_local_vars (void) |
2622 { | 2681 { |
2623 tree var; | 2682 tree var; |
2624 referenced_var_iterator rvi; | 2683 referenced_var_iterator rvi; |
2625 | 2684 |
2626 new_local_vars = htab_create (num_referenced_vars, | 2685 new_local_vars = htab_create (num_referenced_vars, |
2627 new_var_hash, new_var_eq, NULL); | 2686 new_var_hash, new_var_eq, NULL); |
2628 | 2687 |
2629 FOR_EACH_REFERENCED_VAR (var, rvi) | 2688 FOR_EACH_REFERENCED_VAR (var, rvi) |
2630 { | 2689 { |
2631 if (!is_global_var (var)) | 2690 if (!is_global_var (var)) |
2632 create_new_var (var, new_local_vars); | 2691 create_new_var (var, new_local_vars); |
2633 } | 2692 } |
2634 | 2693 |
2635 if (new_local_vars) | 2694 if (new_local_vars) |
2636 htab_traverse (new_local_vars, finalize_new_vars_creation, NULL); | 2695 htab_traverse (new_local_vars, finalize_new_vars_creation, NULL); |
2637 dump_new_vars (new_local_vars); | 2696 dump_new_vars (new_local_vars); |
2638 } | 2697 } |
2639 | 2698 |
2640 /* This function prints the SHIFT number of spaces to the DUMP_FILE. */ | 2699 /* This function prints the SHIFT number of spaces to the DUMP_FILE. */ |
2641 | 2700 |
2643 print_shift (unsigned HOST_WIDE_INT shift) | 2702 print_shift (unsigned HOST_WIDE_INT shift) |
2644 { | 2703 { |
2645 unsigned HOST_WIDE_INT sh = shift; | 2704 unsigned HOST_WIDE_INT sh = shift; |
2646 | 2705 |
2647 while (sh--) | 2706 while (sh--) |
2648 fprintf (dump_file, " "); | 2707 fprintf (dump_file, " "); |
2649 } | 2708 } |
2650 | 2709 |
2651 /* This function updates field_mapping of FIELDS in CLUSTER with NEW_TYPE. */ | 2710 /* This function updates field_mapping of FIELDS in CLUSTER with NEW_TYPE. */ |
2652 | 2711 |
2653 static inline void | 2712 static inline void |
2656 { | 2715 { |
2657 int i; | 2716 int i; |
2658 | 2717 |
2659 for (i = 0; i < num_fields; i++) | 2718 for (i = 0; i < num_fields; i++) |
2660 if (TEST_BIT (cluster->fields_in_cluster, i)) | 2719 if (TEST_BIT (cluster->fields_in_cluster, i)) |
2661 fields[i].field_mapping = new_type; | 2720 fields[i].field_mapping = new_type; |
2662 } | 2721 } |
2663 | 2722 |
2664 /* This functions builds structure with FIELDS, | 2723 /* This functions builds structure with FIELDS, |
2665 NAME and attributes similar to ORIG_STRUCT. | 2724 NAME and attributes similar to ORIG_STRUCT. |
2666 It returns the newly created structure. */ | 2725 It returns the newly created structure. */ |
2667 | 2726 |
2668 static tree | 2727 static tree |
2669 build_basic_struct (tree fields, tree name, tree orig_struct) | 2728 build_basic_struct (tree fields, tree name, tree orig_struct) |
2670 { | 2729 { |
2674 | 2733 |
2675 if (TYPE_ATTRIBUTES (orig_struct)) | 2734 if (TYPE_ATTRIBUTES (orig_struct)) |
2676 attributes = unshare_expr (TYPE_ATTRIBUTES (orig_struct)); | 2735 attributes = unshare_expr (TYPE_ATTRIBUTES (orig_struct)); |
2677 ref = make_node (RECORD_TYPE); | 2736 ref = make_node (RECORD_TYPE); |
2678 TYPE_SIZE (ref) = 0; | 2737 TYPE_SIZE (ref) = 0; |
2679 decl_attributes (&ref, attributes, (int) ATTR_FLAG_TYPE_IN_PLACE); | 2738 decl_attributes (&ref, attributes, (int) ATTR_FLAG_TYPE_IN_PLACE); |
2680 TYPE_PACKED (ref) = TYPE_PACKED (orig_struct); | 2739 TYPE_PACKED (ref) = TYPE_PACKED (orig_struct); |
2681 for (x = fields; x; x = TREE_CHAIN (x)) | 2740 for (x = fields; x; x = TREE_CHAIN (x)) |
2682 { | 2741 { |
2683 DECL_CONTEXT (x) = ref; | 2742 DECL_CONTEXT (x) = ref; |
2684 DECL_PACKED (x) |= TYPE_PACKED (ref); | 2743 DECL_PACKED (x) |= TYPE_PACKED (ref); |
2688 TYPE_NAME (ref) = name; | 2747 TYPE_NAME (ref) = name; |
2689 | 2748 |
2690 return ref; | 2749 return ref; |
2691 } | 2750 } |
2692 | 2751 |
2693 /* This function copies FIELDS from CLUSTER into TREE_CHAIN as part | 2752 /* This function copies FIELDS from CLUSTER into TREE_CHAIN as part |
2694 of preparation for new structure building. NUM_FIELDS is a total | 2753 of preparation for new structure building. NUM_FIELDS is a total |
2695 number of fields in the structure. The function returns newly | 2754 number of fields in the structure. The function returns newly |
2696 generated fields. */ | 2755 generated fields. */ |
2697 | 2756 |
2698 static tree | 2757 static tree |
2699 create_fields (struct field_cluster * cluster, | 2758 create_fields (struct field_cluster * cluster, |
2700 struct field_entry * fields, int num_fields) | 2759 struct field_entry * fields, int num_fields) |
2701 { | 2760 { |
2702 int i; | 2761 int i; |
2703 tree new_types = NULL_TREE; | 2762 tree new_types = NULL_TREE; |
2704 tree last = NULL_TREE; | 2763 tree last = NULL_TREE; |
2718 TREE_CHAIN (last) = NULL_TREE; | 2777 TREE_CHAIN (last) = NULL_TREE; |
2719 return new_types; | 2778 return new_types; |
2720 | 2779 |
2721 } | 2780 } |
2722 | 2781 |
2723 /* This function creates a cluster name. The name is based on | 2782 /* This function creates a cluster name. The name is based on |
2724 the original structure name, if it is present. It has a form: | 2783 the original structure name, if it is present. It has a form: |
2725 | 2784 |
2726 <original_struct_name>_sub.<CLUST_NUM> | 2785 <original_struct_name>_sub.<CLUST_NUM> |
2727 | 2786 |
2728 The original structure name is taken from the type of DECL. | 2787 The original structure name is taken from the type of DECL. |
2729 If an original structure name is not present, it's generated to be: | 2788 If an original structure name is not present, it's generated to be: |
2730 | 2789 |
2738 const char * orig_name = get_type_name (decl); | 2797 const char * orig_name = get_type_name (decl); |
2739 char * tmp_name = NULL; | 2798 char * tmp_name = NULL; |
2740 char * prefix; | 2799 char * prefix; |
2741 char * new_name; | 2800 char * new_name; |
2742 size_t len; | 2801 size_t len; |
2743 | 2802 |
2744 if (!orig_name) | 2803 if (!orig_name) |
2745 ASM_FORMAT_PRIVATE_NAME(tmp_name, "struct", str_num); | 2804 ASM_FORMAT_PRIVATE_NAME(tmp_name, "struct", str_num); |
2746 | 2805 |
2747 len = strlen (tmp_name ? tmp_name : orig_name) + strlen ("_sub"); | 2806 len = strlen (tmp_name ? tmp_name : orig_name) + strlen ("_sub"); |
2748 prefix = XALLOCAVEC (char, len + 1); | 2807 prefix = XALLOCAVEC (char, len + 1); |
2749 memcpy (prefix, tmp_name ? tmp_name : orig_name, | 2808 memcpy (prefix, tmp_name ? tmp_name : orig_name, |
2750 strlen (tmp_name ? tmp_name : orig_name)); | 2809 strlen (tmp_name ? tmp_name : orig_name)); |
2751 strcpy (prefix + strlen (tmp_name ? tmp_name : orig_name), "_sub"); | 2810 strcpy (prefix + strlen (tmp_name ? tmp_name : orig_name), "_sub"); |
2752 | 2811 |
2753 ASM_FORMAT_PRIVATE_NAME (new_name, prefix, clust_num); | 2812 ASM_FORMAT_PRIVATE_NAME (new_name, prefix, clust_num); |
2754 return get_identifier (new_name); | 2813 return get_identifier (new_name); |
2755 } | 2814 } |
2756 | 2815 |
2757 /* This function checks whether the structure STR has bitfields. | 2816 /* This function checks whether the structure STR has bitfields. |
2776 } | 2835 } |
2777 break; | 2836 break; |
2778 } | 2837 } |
2779 } | 2838 } |
2780 | 2839 |
2781 /* This function adds to UNSUITABLE_TYPES those types that escape | 2840 /* This function adds to UNSUITABLE_TYPES those types that escape |
2782 due to results of ipa-type-escape analysis. See ipa-type-escape.[c,h]. */ | 2841 due to results of ipa-type-escape analysis. See ipa-type-escape.[c,h]. */ |
2783 | 2842 |
2784 static void | 2843 static void |
2785 exclude_escaping_types_1 (VEC (tree, heap) **unsuitable_types) | 2844 exclude_escaping_types_1 (VEC (tree, heap) **unsuitable_types) |
2786 { | 2845 { |
2819 } | 2878 } |
2820 } | 2879 } |
2821 } | 2880 } |
2822 } | 2881 } |
2823 | 2882 |
2824 /* This function looks for parameters of local functions | 2883 /* This function looks for parameters of local functions |
2825 which are of structure types, or derived from them (arrays | 2884 which are of structure types, or derived from them (arrays |
2826 of structures, pointers to structures, or their combinations). | 2885 of structures, pointers to structures, or their combinations). |
2827 We are not handling peeling of such structures right now. | 2886 We are not handling peeling of such structures right now. |
2828 The found structures types are added to UNSUITABLE_TYPES vector. */ | 2887 The found structures types are added to UNSUITABLE_TYPES vector. */ |
2829 | 2888 |
2830 static void | 2889 static void |
2835 for (c_node = cgraph_nodes; c_node; c_node = c_node->next) | 2894 for (c_node = cgraph_nodes; c_node; c_node = c_node->next) |
2836 if (cgraph_function_body_availability (c_node) == AVAIL_LOCAL) | 2895 if (cgraph_function_body_availability (c_node) == AVAIL_LOCAL) |
2837 { | 2896 { |
2838 tree fn = c_node->decl; | 2897 tree fn = c_node->decl; |
2839 tree arg; | 2898 tree arg; |
2840 | 2899 |
2841 for (arg = DECL_ARGUMENTS (fn); arg; arg = TREE_CHAIN (arg)) | 2900 for (arg = DECL_ARGUMENTS (fn); arg; arg = TREE_CHAIN (arg)) |
2842 { | 2901 { |
2843 tree type = TREE_TYPE (arg); | 2902 tree type = TREE_TYPE (arg); |
2844 | 2903 |
2845 type = strip_type (type); | 2904 type = strip_type (type); |
2846 if (TREE_CODE (type) == RECORD_TYPE) | 2905 if (TREE_CODE (type) == RECORD_TYPE) |
2847 { | 2906 { |
2848 add_unsuitable_type (unsuitable_types, | 2907 add_unsuitable_type (unsuitable_types, |
2849 TYPE_MAIN_VARIANT (type)); | 2908 TYPE_MAIN_VARIANT (type)); |
2850 if (dump_file) | 2909 if (dump_file) |
2851 { | 2910 { |
2852 fprintf (dump_file, "\nPointer to type \""); | 2911 fprintf (dump_file, "\nPointer to type \""); |
2853 print_generic_expr (dump_file, type, 0); | 2912 print_generic_expr (dump_file, type, 0); |
2854 fprintf (dump_file, | 2913 fprintf (dump_file, |
2855 "\" is passed to local function...Excluded."); | 2914 "\" is passed to local function...Excluded."); |
2856 } | 2915 } |
2857 } | 2916 } |
2858 } | 2917 } |
2859 } | 2918 } |
2860 } | 2919 } |
2861 | 2920 |
2862 /* This function analyzes structure form of structures | 2921 /* This function analyzes structure form of structures |
2863 potential for transformation. If we are not capable to transform | 2922 potential for transformation. If we are not capable to transform |
2864 structure of some form, we remove it from the structures hashtable. | 2923 structure of some form, we remove it from the structures hashtable. |
2865 Right now we cannot handle nested structs, when nesting is | 2924 Right now we cannot handle nested structs, when nesting is |
2866 through any level of pointers or arrays. | 2925 through any level of pointers or arrays. |
2867 | 2926 |
2868 TBD: release these constrains in future. | 2927 TBD: release these constrains in future. |
2869 | 2928 |
2870 Note, that in this function we suppose that all structures | 2929 Note, that in this function we suppose that all structures |
2871 in the program are members of the structures hashtable right now, | 2930 in the program are members of the structures hashtable right now, |
2872 without excluding escaping types. */ | 2931 without excluding escaping types. */ |
2873 | 2932 |
2874 static void | 2933 static void |
2875 check_struct_form (d_str str, VEC (tree, heap) **unsuitable_types) | 2934 check_struct_form (d_str str, VEC (tree, heap) **unsuitable_types) |
2876 { | 2935 { |
2877 int i; | 2936 int i; |
2878 | 2937 |
2879 for (i = 0; i < str->num_fields; i++) | 2938 for (i = 0; i < str->num_fields; i++) |
2880 { | 2939 { |
2881 tree f_type = strip_type(TREE_TYPE (str->fields[i].decl)); | 2940 tree f_type = strip_type(TREE_TYPE (str->fields[i].decl)); |
2882 | 2941 |
2883 if (TREE_CODE (f_type) == RECORD_TYPE) | 2942 if (TREE_CODE (f_type) == RECORD_TYPE) |
2884 { | 2943 { |
2885 add_unsuitable_type (unsuitable_types, TYPE_MAIN_VARIANT (f_type)); | 2944 add_unsuitable_type (unsuitable_types, TYPE_MAIN_VARIANT (f_type)); |
2886 add_unsuitable_type (unsuitable_types, str->decl); | 2945 add_unsuitable_type (unsuitable_types, str->decl); |
2887 if (dump_file) | 2946 if (dump_file) |
2925 VEC_safe_push (structure, heap, structures, &node); | 2984 VEC_safe_push (structure, heap, structures, &node); |
2926 | 2985 |
2927 if (dump_file) | 2986 if (dump_file) |
2928 { | 2987 { |
2929 fprintf (dump_file, "\nAdding data structure \""); | 2988 fprintf (dump_file, "\nAdding data structure \""); |
2930 print_generic_expr (dump_file, type, 0); | 2989 print_generic_expr (dump_file, type, 0); |
2931 fprintf (dump_file, "\" to data_struct_list."); | 2990 fprintf (dump_file, "\" to data_struct_list."); |
2932 } | 2991 } |
2933 } | 2992 } |
2934 | 2993 |
2935 /* This function adds an allocation site to alloc_sites hashtable. | 2994 /* This function adds an allocation site to alloc_sites hashtable. |
2936 The allocation site appears in STMT of function FN_DECL and | 2995 The allocation site appears in STMT of function FN_DECL and |
2937 allocates the structure represented by STR. */ | 2996 allocates the structure represented by STR. */ |
2938 | 2997 |
2939 static void | 2998 static void |
2940 add_alloc_site (tree fn_decl, gimple stmt, d_str str) | 2999 add_alloc_site (tree fn_decl, gimple stmt, d_str str) |
2941 { | 3000 { |
2943 alloc_site_t m_call; | 3002 alloc_site_t m_call; |
2944 | 3003 |
2945 m_call.stmt = stmt; | 3004 m_call.stmt = stmt; |
2946 m_call.str = str; | 3005 m_call.str = str; |
2947 | 3006 |
2948 fallocs = | 3007 fallocs = |
2949 (fallocs_t) htab_find_with_hash (alloc_sites, | 3008 (fallocs_t) htab_find_with_hash (alloc_sites, |
2950 fn_decl, htab_hash_pointer (fn_decl)); | 3009 fn_decl, htab_hash_pointer (fn_decl)); |
2951 | 3010 |
2952 if (!fallocs) | 3011 if (!fallocs) |
2953 { | 3012 { |
2954 void **slot; | 3013 void **slot; |
2955 | 3014 |
2956 fallocs = (fallocs_t) | 3015 fallocs = (fallocs_t) |
2957 xmalloc (sizeof (struct func_alloc_sites)); | 3016 xmalloc (sizeof (struct func_alloc_sites)); |
2958 fallocs->func = fn_decl; | 3017 fallocs->func = fn_decl; |
2959 fallocs->allocs = VEC_alloc (alloc_site_t, heap, 1); | 3018 fallocs->allocs = VEC_alloc (alloc_site_t, heap, 1); |
2960 slot = htab_find_slot_with_hash (alloc_sites, fn_decl, | 3019 slot = htab_find_slot_with_hash (alloc_sites, fn_decl, |
2961 htab_hash_pointer (fn_decl), INSERT); | 3020 htab_hash_pointer (fn_decl), INSERT); |
2962 *slot = fallocs; | 3021 *slot = fallocs; |
2963 } | 3022 } |
2964 VEC_safe_push (alloc_site_t, heap, | 3023 VEC_safe_push (alloc_site_t, heap, |
2965 fallocs->allocs, &m_call); | 3024 fallocs->allocs, &m_call); |
2966 | 3025 |
2967 if (dump_file) | 3026 if (dump_file) |
2968 { | 3027 { |
2969 fprintf (dump_file, "\nAdding stmt "); | 3028 fprintf (dump_file, "\nAdding stmt "); |
2970 print_gimple_stmt (dump_file, stmt, 0, 0); | 3029 print_gimple_stmt (dump_file, stmt, 0, 0); |
2971 fprintf (dump_file, " to list of mallocs."); | 3030 fprintf (dump_file, " to list of mallocs."); |
2973 } | 3032 } |
2974 | 3033 |
2975 /* This function returns true if the result of STMT, that contains a call | 3034 /* This function returns true if the result of STMT, that contains a call |
2976 to an allocation function, is cast to one of the structure types. | 3035 to an allocation function, is cast to one of the structure types. |
2977 STMT should be of the form: T.2 = <alloc_func> (T.1); | 3036 STMT should be of the form: T.2 = <alloc_func> (T.1); |
2978 If true, I_P contains an index of an allocated structure. | 3037 If true, I_P contains an index of an allocated structure. |
2979 Otherwise I_P contains the length of the vector of structures. */ | 3038 Otherwise I_P contains the length of the vector of structures. */ |
2980 | 3039 |
2981 static bool | 3040 static bool |
2982 is_alloc_of_struct (gimple stmt, unsigned *i_p) | 3041 is_alloc_of_struct (gimple stmt, unsigned *i_p) |
2983 { | 3042 { |
2997 return false; | 3056 return false; |
2998 | 3057 |
2999 lhs = gimple_assign_lhs (final_stmt); | 3058 lhs = gimple_assign_lhs (final_stmt); |
3000 | 3059 |
3001 type = get_type_of_var (lhs); | 3060 type = get_type_of_var (lhs); |
3002 | 3061 |
3003 if (!type) | 3062 if (!type) |
3004 return false; | 3063 return false; |
3005 | 3064 |
3006 if (!POINTER_TYPE_P (type) | 3065 if (!POINTER_TYPE_P (type) |
3007 || TREE_CODE (strip_type (type)) != RECORD_TYPE) | 3066 || TREE_CODE (strip_type (type)) != RECORD_TYPE) |
3013 return false; | 3072 return false; |
3014 | 3073 |
3015 return true; | 3074 return true; |
3016 } | 3075 } |
3017 | 3076 |
3018 /* This function prints non-field and field accesses | 3077 /* This function prints non-field and field accesses |
3019 of the structure STR. */ | 3078 of the structure STR. */ |
3020 | 3079 |
3021 static void | 3080 static void |
3022 dump_accs (d_str str) | 3081 dump_accs (d_str str) |
3023 { | 3082 { |
3024 int i; | 3083 int i; |
3028 | 3087 |
3029 for (i = 0; i < str->num_fields; i++) | 3088 for (i = 0; i < str->num_fields; i++) |
3030 { | 3089 { |
3031 fprintf (dump_file, "\nAccess site of field "); | 3090 fprintf (dump_file, "\nAccess site of field "); |
3032 print_generic_expr (dump_file, str->fields[i].decl, 0); | 3091 print_generic_expr (dump_file, str->fields[i].decl, 0); |
3033 dump_field_acc_sites (str->fields[i].acc_sites); | 3092 dump_field_acc_sites (str->fields[i].acc_sites); |
3034 fprintf (dump_file, ":\n"); | 3093 fprintf (dump_file, ":\n"); |
3035 } | 3094 } |
3036 fprintf (dump_file, "\nGeneral access sites\n"); | 3095 fprintf (dump_file, "\nGeneral access sites\n"); |
3037 dump_access_sites (str->accs); | 3096 dump_access_sites (str->accs); |
3038 } | 3097 } |
3039 | 3098 |
3040 /* This function checks whether an access statement, pointed by SLOT, | 3099 /* This function checks whether an access statement, pointed by SLOT, |
3041 is a condition we are capable to transform. It returns false if not, | 3100 is a condition we are capable to transform. It returns false if not, |
3042 setting bool *DATA to false. */ | 3101 setting bool *DATA to false. */ |
3043 | 3102 |
3044 static int | 3103 static int |
3045 safe_cond_expr_check (void **slot, void *data) | 3104 safe_cond_expr_check (void **slot, void *data) |
3046 { | 3105 { |
3047 struct access_site *acc = *(struct access_site **) slot; | 3106 struct access_site *acc = *(struct access_site **) slot; |
3048 | 3107 |
3071 struct exclude_data dt; | 3130 struct exclude_data dt; |
3072 dt.str = str; | 3131 dt.str = str; |
3073 dt.fn_decl = node->decl; | 3132 dt.fn_decl = node->decl; |
3074 | 3133 |
3075 if (dt.str->accs) | 3134 if (dt.str->accs) |
3076 htab_traverse (dt.str->accs, exclude_from_accs, &dt); | 3135 htab_traverse (dt.str->accs, exclude_from_accs, &dt); |
3077 } | 3136 } |
3078 | 3137 |
3079 /* Collect accesses to the structure types that appear in basic block BB. */ | 3138 /* Collect accesses to the structure types that appear in basic block BB. */ |
3080 | 3139 |
3081 static void | 3140 static void |
3109 static void | 3168 static void |
3110 gen_cluster (sbitmap fields, d_str str) | 3169 gen_cluster (sbitmap fields, d_str str) |
3111 { | 3170 { |
3112 struct field_cluster *crr_cluster = NULL; | 3171 struct field_cluster *crr_cluster = NULL; |
3113 | 3172 |
3114 crr_cluster = | 3173 crr_cluster = |
3115 (struct field_cluster *) xcalloc (1, sizeof (struct field_cluster)); | 3174 (struct field_cluster *) xcalloc (1, sizeof (struct field_cluster)); |
3116 crr_cluster->sibling = str->struct_clustering; | 3175 crr_cluster->sibling = str->struct_clustering; |
3117 str->struct_clustering = crr_cluster; | 3176 str->struct_clustering = crr_cluster; |
3118 crr_cluster->fields_in_cluster = fields; | 3177 crr_cluster->fields_in_cluster = fields; |
3119 } | 3178 } |
3123 static void | 3182 static void |
3124 peel_field (int i, d_str ds) | 3183 peel_field (int i, d_str ds) |
3125 { | 3184 { |
3126 struct field_cluster *crr_cluster = NULL; | 3185 struct field_cluster *crr_cluster = NULL; |
3127 | 3186 |
3128 crr_cluster = | 3187 crr_cluster = |
3129 (struct field_cluster *) xcalloc (1, sizeof (struct field_cluster)); | 3188 (struct field_cluster *) xcalloc (1, sizeof (struct field_cluster)); |
3130 crr_cluster->sibling = ds->struct_clustering; | 3189 crr_cluster->sibling = ds->struct_clustering; |
3131 ds->struct_clustering = crr_cluster; | 3190 ds->struct_clustering = crr_cluster; |
3132 crr_cluster->fields_in_cluster = | 3191 crr_cluster->fields_in_cluster = |
3133 sbitmap_alloc ((unsigned int) ds->num_fields); | 3192 sbitmap_alloc ((unsigned int) ds->num_fields); |
3134 sbitmap_zero (crr_cluster->fields_in_cluster); | 3193 sbitmap_zero (crr_cluster->fields_in_cluster); |
3135 SET_BIT (crr_cluster->fields_in_cluster, i); | 3194 SET_BIT (crr_cluster->fields_in_cluster, i); |
3136 } | 3195 } |
3137 | 3196 |
3138 /* This function calculates maximum field count in | 3197 /* This function calculates maximum field count in |
3139 the structure STR. */ | 3198 the structure STR. */ |
3140 | 3199 |
3141 static gcov_type | 3200 static gcov_type |
3142 get_max_field_count (d_str str) | 3201 get_max_field_count (d_str str) |
3143 { | 3202 { |
3144 gcov_type max = 0; | 3203 gcov_type max = 0; |
3145 int i; | 3204 int i; |
3146 | 3205 |
3147 for (i = 0; i < str->num_fields; i++) | 3206 for (i = 0; i < str->num_fields; i++) |
3148 if (str->fields[i].count > max) | 3207 if (str->fields[i].count > max) |
3149 max = str->fields[i].count; | 3208 max = str->fields[i].count; |
3150 | 3209 |
3151 return max; | 3210 return max; |
3152 } | 3211 } |
3153 | 3212 |
3154 /* Do struct-reorg transformation for individual function | 3213 /* Do struct-reorg transformation for individual function |
3155 represented by NODE. All structure types relevant | 3214 represented by NODE. All structure types relevant |
3156 for this function are transformed. */ | 3215 for this function are transformed. */ |
3157 | 3216 |
3158 static void | 3217 static void |
3159 do_reorg_for_func (struct cgraph_node *node) | 3218 do_reorg_for_func (struct cgraph_node *node) |
3160 { | 3219 { |
3161 create_new_local_vars (); | 3220 create_new_local_vars (); |
3162 create_new_alloc_sites_for_func (node); | 3221 create_new_alloc_sites_for_func (node); |
3163 create_new_accesses_for_func (); | 3222 create_new_accesses_for_func (); |
3164 update_ssa (TODO_update_ssa); | 3223 update_ssa (TODO_update_ssa); |
3165 cleanup_tree_cfg (); | 3224 cleanup_tree_cfg (); |
3166 | 3225 |
3167 /* Free auxiliary data representing local variables. */ | 3226 /* Free auxiliary data representing local variables. */ |
3168 free_new_vars_htab (new_local_vars); | 3227 free_new_vars_htab (new_local_vars); |
3169 } | 3228 } |
3170 | 3229 |
3171 /* Print structure TYPE, its name, if it exists, and body. | 3230 /* Print structure TYPE, its name, if it exists, and body. |
3172 INDENT defines the level of indentation (similar | 3231 INDENT defines the level of indentation (similar |
3173 to the option -i of indent command). SHIFT parameter | 3232 to the option -i of indent command). SHIFT parameter |
3174 defines a number of spaces by which a structure will | 3233 defines a number of spaces by which a structure will |
3175 be shifted right. */ | 3234 be shifted right. */ |
3176 | 3235 |
3177 static void | 3236 static void |
3178 dump_struct_type (tree type, unsigned HOST_WIDE_INT indent, | 3237 dump_struct_type (tree type, unsigned HOST_WIDE_INT indent, |
3179 unsigned HOST_WIDE_INT shift) | 3238 unsigned HOST_WIDE_INT shift) |
3187 if (TREE_CODE (type) != RECORD_TYPE) | 3246 if (TREE_CODE (type) != RECORD_TYPE) |
3188 { | 3247 { |
3189 print_generic_expr (dump_file, type, 0); | 3248 print_generic_expr (dump_file, type, 0); |
3190 return; | 3249 return; |
3191 } | 3250 } |
3192 | 3251 |
3193 print_shift (shift); | 3252 print_shift (shift); |
3194 struct_name = get_type_name (type); | 3253 struct_name = get_type_name (type); |
3195 fprintf (dump_file, "struct "); | 3254 fprintf (dump_file, "struct "); |
3196 if (struct_name) | 3255 if (struct_name) |
3197 fprintf (dump_file, "%s\n",struct_name); | 3256 fprintf (dump_file, "%s\n",struct_name); |
3198 print_shift (shift); | 3257 print_shift (shift); |
3199 fprintf (dump_file, "{\n"); | 3258 fprintf (dump_file, "{\n"); |
3200 | 3259 |
3201 for (field = TYPE_FIELDS (type); field; | 3260 for (field = TYPE_FIELDS (type); field; |
3202 field = TREE_CHAIN (field)) | 3261 field = TREE_CHAIN (field)) |
3203 { | 3262 { |
3204 unsigned HOST_WIDE_INT s = indent; | 3263 unsigned HOST_WIDE_INT s = indent; |
3205 tree f_type = TREE_TYPE (field); | 3264 tree f_type = TREE_TYPE (field); |
3206 | 3265 |
3207 print_shift (shift); | 3266 print_shift (shift); |
3208 while (s--) | 3267 while (s--) |
3209 fprintf (dump_file, " "); | 3268 fprintf (dump_file, " "); |
3210 dump_struct_type (f_type, indent, shift + indent); | 3269 dump_struct_type (f_type, indent, shift + indent); |
3211 fprintf(dump_file, " "); | 3270 fprintf(dump_file, " "); |
3214 } | 3273 } |
3215 print_shift (shift); | 3274 print_shift (shift); |
3216 fprintf (dump_file, "}\n"); | 3275 fprintf (dump_file, "}\n"); |
3217 } | 3276 } |
3218 | 3277 |
3219 /* This function creates new structure types to replace original type, | 3278 /* This function creates new structure types to replace original type, |
3220 indicated by STR->decl. The names of the new structure types are | 3279 indicated by STR->decl. The names of the new structure types are |
3221 derived from the original structure type. If the original structure | 3280 derived from the original structure type. If the original structure |
3222 type has no name, we assume that its name is 'struct.<STR_NUM>'. */ | 3281 type has no name, we assume that its name is 'struct.<STR_NUM>'. */ |
3223 | 3282 |
3224 static void | 3283 static void |
3225 create_new_type (d_str str, int *str_num) | 3284 create_new_type (d_str str, int *str_num) |
3226 { | 3285 { |
3227 int cluster_num = 0; | 3286 int cluster_num = 0; |
3228 | 3287 |
3229 struct field_cluster *cluster = str->struct_clustering; | 3288 struct field_cluster *cluster = str->struct_clustering; |
3230 while (cluster) | 3289 while (cluster) |
3231 { | 3290 { |
3232 tree name = gen_cluster_name (str->decl, cluster_num, | 3291 tree name = gen_cluster_name (str->decl, cluster_num, |
3233 *str_num); | 3292 *str_num); |
3234 tree fields; | 3293 tree fields; |
3235 tree new_type; | 3294 tree new_type; |
3236 cluster_num++; | 3295 cluster_num++; |
3237 | 3296 |
3238 fields = create_fields (cluster, str->fields, | 3297 fields = create_fields (cluster, str->fields, |
3239 str->num_fields); | 3298 str->num_fields); |
3240 new_type = build_basic_struct (fields, name, str->decl); | 3299 new_type = build_basic_struct (fields, name, str->decl); |
3241 | 3300 |
3242 update_fields_mapping (cluster, new_type, | 3301 update_fields_mapping (cluster, new_type, |
3243 str->fields, str->num_fields); | 3302 str->fields, str->num_fields); |
3244 | 3303 |
3245 VEC_safe_push (tree, heap, str->new_types, new_type); | 3304 VEC_safe_push (tree, heap, str->new_types, new_type); |
3246 cluster = cluster->sibling; | 3305 cluster = cluster->sibling; |
3247 } | 3306 } |
3248 (*str_num)++; | 3307 (*str_num)++; |
3249 } | 3308 } |
3250 | 3309 |
3251 /* This function is a callback for alloc_sites hashtable | 3310 /* This function is a callback for alloc_sites hashtable |
3252 traversal. SLOT is a pointer to fallocs_t. | 3311 traversal. SLOT is a pointer to fallocs_t. |
3253 This function frees memory pointed by *SLOT. */ | 3312 This function frees memory pointed by *SLOT. */ |
3254 | 3313 |
3255 static int | 3314 static int |
3256 free_falloc_sites (void **slot, void *data ATTRIBUTE_UNUSED) | 3315 free_falloc_sites (void **slot, void *data ATTRIBUTE_UNUSED) |
3257 { | 3316 { |
3280 break; | 3339 break; |
3281 } | 3340 } |
3282 } | 3341 } |
3283 | 3342 |
3284 /* Exclude structure types with bitfields. | 3343 /* Exclude structure types with bitfields. |
3285 We would not want to interfere with other optimizations | 3344 We would not want to interfere with other optimizations |
3286 that can be done in this case. The structure types with | 3345 that can be done in this case. The structure types with |
3287 bitfields are added to UNSUITABLE_TYPES vector. */ | 3346 bitfields are added to UNSUITABLE_TYPES vector. */ |
3288 | 3347 |
3289 static void | 3348 static void |
3290 exclude_types_with_bit_fields (VEC (tree, heap) **unsuitable_types) | 3349 exclude_types_with_bit_fields (VEC (tree, heap) **unsuitable_types) |
3291 { | 3350 { |
3298 | 3357 |
3299 /* This function checks three types of escape. A structure type escapes: | 3358 /* This function checks three types of escape. A structure type escapes: |
3300 | 3359 |
3301 1. if it's a type of parameter of a local function. | 3360 1. if it's a type of parameter of a local function. |
3302 2. if it's a type of function return value. | 3361 2. if it's a type of function return value. |
3303 3. if it escapes as a result of ipa-type-escape analysis. | 3362 3. if it escapes as a result of ipa-type-escape analysis. |
3304 | 3363 |
3305 The escaping structure types are added to UNSUITABLE_TYPES vector. */ | 3364 The escaping structure types are added to UNSUITABLE_TYPES vector. */ |
3306 | 3365 |
3307 static void | 3366 static void |
3308 exclude_escaping_types (VEC (tree, heap) **unsuitable_types) | 3367 exclude_escaping_types (VEC (tree, heap) **unsuitable_types) |
3310 exclude_types_passed_to_local_func (unsuitable_types); | 3369 exclude_types_passed_to_local_func (unsuitable_types); |
3311 exclude_returned_types (unsuitable_types); | 3370 exclude_returned_types (unsuitable_types); |
3312 exclude_escaping_types_1 (unsuitable_types); | 3371 exclude_escaping_types_1 (unsuitable_types); |
3313 } | 3372 } |
3314 | 3373 |
3315 /* This function analyzes whether the form of | 3374 /* This function analyzes whether the form of |
3316 structure is such that we are capable to transform it. | 3375 structure is such that we are capable to transform it. |
3317 Nested structures are checked here. Unsuitable structure | 3376 Nested structures are checked here. Unsuitable structure |
3318 types are added to UNSUITABLE_TYPE vector. */ | 3377 types are added to UNSUITABLE_TYPE vector. */ |
3319 | 3378 |
3320 static void | 3379 static void |
3321 analyze_struct_form (VEC (tree, heap) **unsuitable_types) | 3380 analyze_struct_form (VEC (tree, heap) **unsuitable_types) |
3325 | 3384 |
3326 for (i = 0; VEC_iterate (structure, structures, i, str); i++) | 3385 for (i = 0; VEC_iterate (structure, structures, i, str); i++) |
3327 check_struct_form (str, unsuitable_types); | 3386 check_struct_form (str, unsuitable_types); |
3328 } | 3387 } |
3329 | 3388 |
3330 /* This function looks for structure types instantiated in the program. | 3389 /* This function looks for structure types instantiated in the program. |
3331 The candidate types are added to the structures vector. | 3390 The candidate types are added to the structures vector. |
3332 Unsuitable types are collected into UNSUITABLE_TYPES vector. */ | 3391 Unsuitable types are collected into UNSUITABLE_TYPES vector. */ |
3333 | 3392 |
3334 static void | 3393 static void |
3335 build_data_structure (VEC (tree, heap) **unsuitable_types) | 3394 build_data_structure (VEC (tree, heap) **unsuitable_types) |
3336 { | 3395 { |
3337 tree var, type; | 3396 tree var, type; |
3338 tree var_list; | 3397 tree var_list; |
3339 struct varpool_node *current_varpool; | 3398 struct varpool_node *current_varpool; |
3340 struct cgraph_node *c_node; | 3399 struct cgraph_node *c_node; |
3341 | 3400 |
3342 /* Check global variables. */ | 3401 /* Check global variables. */ |
3343 FOR_EACH_STATIC_VARIABLE (current_varpool) | 3402 FOR_EACH_STATIC_VARIABLE (current_varpool) |
3344 { | 3403 { |
3345 var = current_varpool->decl; | 3404 var = current_varpool->decl; |
3346 if (is_candidate (var, &type, unsuitable_types)) | 3405 if (is_candidate (var, &type, unsuitable_types)) |
3347 add_structure (type); | 3406 add_structure (type); |
3348 } | 3407 } |
3349 | 3408 |
3350 /* Now add structures that are types of function parameters and | 3409 /* Now add structures that are types of function parameters and |
3351 local variables. */ | 3410 local variables. */ |
3352 for (c_node = cgraph_nodes; c_node; c_node = c_node->next) | 3411 for (c_node = cgraph_nodes; c_node; c_node = c_node->next) |
3353 { | 3412 { |
3354 enum availability avail = | 3413 enum availability avail = |
3355 cgraph_function_body_availability (c_node); | 3414 cgraph_function_body_availability (c_node); |
3356 | 3415 |
3357 /* We need AVAIL_AVAILABLE for main function. */ | 3416 /* We need AVAIL_AVAILABLE for main function. */ |
3358 if (avail == AVAIL_LOCAL || avail == AVAIL_AVAILABLE) | 3417 if (avail == AVAIL_LOCAL || avail == AVAIL_AVAILABLE) |
3359 { | 3418 { |
3360 struct function *fn = DECL_STRUCT_FUNCTION (c_node->decl); | 3419 struct function *fn = DECL_STRUCT_FUNCTION (c_node->decl); |
3361 | 3420 |
3362 for (var = DECL_ARGUMENTS (c_node->decl); var; | 3421 for (var = DECL_ARGUMENTS (c_node->decl); var; |
3363 var = TREE_CHAIN (var)) | 3422 var = TREE_CHAIN (var)) |
3364 if (is_candidate (var, &type, unsuitable_types)) | 3423 if (is_candidate (var, &type, unsuitable_types)) |
3365 add_structure (type); | 3424 add_structure (type); |
3366 | 3425 |
3426 if (fn == NULL) | |
3427 { | |
3428 /* Skip cones that haven't been materialized yet. */ | |
3429 gcc_assert (c_node->clone_of | |
3430 && c_node->clone_of->decl != c_node->decl); | |
3431 continue; | |
3432 } | |
3433 | |
3367 /* Check function local variables. */ | 3434 /* Check function local variables. */ |
3368 for (var_list = fn->local_decls; var_list; | 3435 for (var_list = fn->local_decls; var_list; |
3369 var_list = TREE_CHAIN (var_list)) | 3436 var_list = TREE_CHAIN (var_list)) |
3370 { | 3437 { |
3371 var = TREE_VALUE (var_list); | 3438 var = TREE_VALUE (var_list); |
3372 | 3439 |
3373 if (is_candidate (var, &type, unsuitable_types)) | 3440 if (is_candidate (var, &type, unsuitable_types)) |
3375 } | 3442 } |
3376 } | 3443 } |
3377 } | 3444 } |
3378 } | 3445 } |
3379 | 3446 |
3380 /* This function returns true if the program contains | 3447 /* This function returns true if the program contains |
3381 a call to user defined allocation function, or other | 3448 a call to user defined allocation function, or other |
3382 functions that can interfere with struct-reorg optimizations. */ | 3449 functions that can interfere with struct-reorg optimizations. */ |
3383 | 3450 |
3384 static bool | 3451 static bool |
3385 program_redefines_malloc_p (void) | 3452 program_redefines_malloc_p (void) |
3386 { | 3453 { |
3387 struct cgraph_node *c_node; | 3454 struct cgraph_node *c_node; |
3388 struct cgraph_node *c_node2; | 3455 struct cgraph_node *c_node2; |
3389 struct cgraph_edge *c_edge; | 3456 struct cgraph_edge *c_edge; |
3390 tree fndecl; | |
3391 tree fndecl2; | 3457 tree fndecl2; |
3392 | 3458 |
3393 for (c_node = cgraph_nodes; c_node; c_node = c_node->next) | 3459 for (c_node = cgraph_nodes; c_node; c_node = c_node->next) |
3394 { | 3460 { |
3395 fndecl = c_node->decl; | |
3396 | |
3397 for (c_edge = c_node->callees; c_edge; c_edge = c_edge->next_callee) | 3461 for (c_edge = c_node->callees; c_edge; c_edge = c_edge->next_callee) |
3398 { | 3462 { |
3399 c_node2 = c_edge->callee; | 3463 c_node2 = c_edge->callee; |
3400 fndecl2 = c_node2->decl; | 3464 fndecl2 = c_node2->decl; |
3401 if (is_gimple_call (c_edge->call_stmt)) | 3465 if (is_gimple_call (c_edge->call_stmt)) |
3411 /* Check that there is no __builtin_object_size, | 3475 /* Check that there is no __builtin_object_size, |
3412 __builtin_offsetof, or realloc's in the program. */ | 3476 __builtin_offsetof, or realloc's in the program. */ |
3413 if (DECL_FUNCTION_CODE (fndecl2) == BUILT_IN_OBJECT_SIZE | 3477 if (DECL_FUNCTION_CODE (fndecl2) == BUILT_IN_OBJECT_SIZE |
3414 || !strcmp (fname, "__builtin_offsetof") | 3478 || !strcmp (fname, "__builtin_offsetof") |
3415 || !strcmp (fname, "realloc")) | 3479 || !strcmp (fname, "realloc")) |
3416 return true; | 3480 return true; |
3417 } | 3481 } |
3418 } | 3482 } |
3419 } | 3483 } |
3420 | 3484 |
3421 return false; | 3485 return false; |
3422 } | 3486 } |
3423 | 3487 |
3424 /* In this function we assume that an allocation statement | 3488 /* In this function we assume that an allocation statement |
3425 | 3489 |
3426 var = (type_cast) malloc (size); | 3490 var = (type_cast) malloc (size); |
3427 | 3491 |
3428 is converted into the following set of statements: | 3492 is converted into the following set of statements: |
3429 | 3493 |
3430 T.1 = size; | 3494 T.1 = size; |
3431 T.2 = malloc (T.1); | 3495 T.2 = malloc (T.1); |
3432 T.3 = (type_cast) T.2; | 3496 T.3 = (type_cast) T.2; |
3433 var = T.3; | 3497 var = T.3; |
3434 | 3498 |
3435 In this function we collect into alloc_sites the allocation | 3499 In this function we collect into alloc_sites the allocation |
3436 sites of variables of structure types that are present | 3500 sites of variables of structure types that are present |
3437 in structures vector. */ | 3501 in structures vector. */ |
3438 | 3502 |
3439 static void | 3503 static void |
3440 collect_alloc_sites (void) | 3504 collect_alloc_sites (void) |
3441 { | 3505 { |
3452 if (stmt) | 3516 if (stmt) |
3453 { | 3517 { |
3454 tree decl; | 3518 tree decl; |
3455 | 3519 |
3456 if (is_gimple_call (stmt) | 3520 if (is_gimple_call (stmt) |
3457 && (decl = gimple_call_fndecl (stmt)) | 3521 && (decl = gimple_call_fndecl (stmt)) |
3458 && gimple_call_lhs (stmt)) | 3522 && gimple_call_lhs (stmt)) |
3459 { | 3523 { |
3460 unsigned i; | 3524 unsigned i; |
3461 | 3525 |
3462 if (is_alloc_of_struct (stmt, &i)) | 3526 if (is_alloc_of_struct (stmt, &i)) |
3463 { | 3527 { |
3464 /* We support only malloc now. */ | 3528 /* We support only malloc now. */ |
3465 if (DECL_FUNCTION_CODE (decl) == BUILT_IN_MALLOC) | 3529 if (DECL_FUNCTION_CODE (decl) == BUILT_IN_MALLOC) |
3466 { | 3530 { |
3467 d_str str; | 3531 d_str str; |
3468 | 3532 |
3469 str = VEC_index (structure, structures, i); | 3533 str = VEC_index (structure, structures, i); |
3470 add_alloc_site (node->decl, stmt, str); | 3534 add_alloc_site (node->decl, stmt, str); |
3471 } | 3535 } |
3472 else | 3536 else |
3473 { | 3537 { |
3474 if (dump_file) | 3538 if (dump_file) |
3475 { | 3539 { |
3476 fprintf (dump_file, | 3540 fprintf (dump_file, |
3477 "\nUnsupported allocation function "); | 3541 "\nUnsupported allocation function "); |
3478 print_gimple_stmt (dump_file, stmt, 0, 0); | 3542 print_gimple_stmt (dump_file, stmt, 0, 0); |
3479 } | 3543 } |
3480 remove_structure (i); | 3544 remove_structure (i); |
3481 } | 3545 } |
3482 } | 3546 } |
3483 } | 3547 } |
3484 } | 3548 } |
3485 } | 3549 } |
3486 } | 3550 } |
3487 } | 3551 } |
3488 | 3552 |
3489 /* Print collected accesses. */ | 3553 /* Print collected accesses. */ |
3499 | 3563 |
3500 for (i = 0; VEC_iterate (structure, structures, i, str); i++) | 3564 for (i = 0; VEC_iterate (structure, structures, i, str); i++) |
3501 dump_accs (str); | 3565 dump_accs (str); |
3502 } | 3566 } |
3503 | 3567 |
3504 /* This function checks whether the accesses of structures in condition | 3568 /* This function checks whether the accesses of structures in condition |
3505 expressions are of the kind we are capable to transform. | 3569 expressions are of the kind we are capable to transform. |
3506 If not, such structures are removed from the vector of structures. */ | 3570 If not, such structures are removed from the vector of structures. */ |
3507 | 3571 |
3508 static void | 3572 static void |
3509 check_cond_exprs (void) | 3573 check_cond_exprs (void) |
3510 { | 3574 { |
3523 else | 3587 else |
3524 i++; | 3588 i++; |
3525 } | 3589 } |
3526 } | 3590 } |
3527 | 3591 |
3528 /* We exclude from non-field accesses of the structure | 3592 /* We exclude from non-field accesses of the structure |
3529 all statements that will be treated as part of the structure | 3593 all statements that will be treated as part of the structure |
3530 allocation sites or field accesses. */ | 3594 allocation sites or field accesses. */ |
3531 | 3595 |
3532 static void | 3596 static void |
3533 exclude_alloc_and_field_accs (struct cgraph_node *node) | 3597 exclude_alloc_and_field_accs (struct cgraph_node *node) |
3534 { | 3598 { |
3537 | 3601 |
3538 for (i = 0; VEC_iterate (structure, structures, i, str); i++) | 3602 for (i = 0; VEC_iterate (structure, structures, i, str); i++) |
3539 exclude_alloc_and_field_accs_1 (str, node); | 3603 exclude_alloc_and_field_accs_1 (str, node); |
3540 } | 3604 } |
3541 | 3605 |
3542 /* This function collects accesses of the fields of the structures | 3606 /* This function collects accesses of the fields of the structures |
3543 that appear at function FN. */ | 3607 that appear at function FN. */ |
3544 | 3608 |
3545 static void | 3609 static void |
3546 collect_accesses_in_func (struct function *fn) | 3610 collect_accesses_in_func (struct function *fn) |
3547 { | 3611 { |
3559 | 3623 |
3560 static void | 3624 static void |
3561 sum_counts (d_str str, gcov_type *hottest) | 3625 sum_counts (d_str str, gcov_type *hottest) |
3562 { | 3626 { |
3563 int i; | 3627 int i; |
3564 | 3628 |
3565 str->count = 0; | 3629 str->count = 0; |
3566 for (i = 0; i < str->num_fields; i++) | 3630 for (i = 0; i < str->num_fields; i++) |
3567 { | 3631 { |
3568 if (dump_file) | 3632 if (dump_file) |
3569 { | 3633 { |
3570 fprintf (dump_file, "\nCounter of field \""); | 3634 fprintf (dump_file, "\nCounter of field \""); |
3571 print_generic_expr (dump_file, str->fields[i].decl, 0); | 3635 print_generic_expr (dump_file, str->fields[i].decl, 0); |
3572 fprintf (dump_file, "\" is " HOST_WIDEST_INT_PRINT_DEC, | 3636 fprintf (dump_file, "\" is " HOST_WIDEST_INT_PRINT_DEC, |
3573 str->fields[i].count); | 3637 str->fields[i].count); |
3574 } | 3638 } |
3575 str->count += str->fields[i].count; | 3639 str->count += str->fields[i].count; |
3576 } | 3640 } |
3577 | 3641 |
3585 if (str->count > *hottest) | 3649 if (str->count > *hottest) |
3586 *hottest = str->count; | 3650 *hottest = str->count; |
3587 } | 3651 } |
3588 | 3652 |
3589 /* This function peels the field into separate structure if it's | 3653 /* This function peels the field into separate structure if it's |
3590 sufficiently hot, i.e. if its count provides at least 90% of | 3654 sufficiently hot, i.e. if its count provides at least 90% of |
3591 the maximum field count in the structure. */ | 3655 the maximum field count in the structure. */ |
3592 | 3656 |
3593 static void | 3657 static void |
3594 peel_hot_fields (d_str str) | 3658 peel_hot_fields (d_str str) |
3595 { | 3659 { |
3596 gcov_type max_field_count; | 3660 gcov_type max_field_count; |
3597 sbitmap fields_left = sbitmap_alloc (str->num_fields); | 3661 sbitmap fields_left = sbitmap_alloc (str->num_fields); |
3598 int i; | 3662 int i; |
3599 | 3663 |
3600 sbitmap_ones (fields_left); | 3664 sbitmap_ones (fields_left); |
3601 max_field_count = | 3665 max_field_count = |
3602 (gcov_type) (get_max_field_count (str)/100)*90; | 3666 (gcov_type) (get_max_field_count (str)/100)*90; |
3603 | 3667 |
3604 str->struct_clustering = NULL; | 3668 str->struct_clustering = NULL; |
3605 | 3669 |
3606 for (i = 0; i < str->num_fields; i++) | 3670 for (i = 0; i < str->num_fields; i++) |
3607 { | 3671 { |
3608 if (str->count >= max_field_count) | 3672 if (str->count >= max_field_count) |
3609 { | 3673 { |
3610 RESET_BIT (fields_left, i); | 3674 RESET_BIT (fields_left, i); |
3611 peel_field (i, str); | 3675 peel_field (i, str); |
3612 } | 3676 } |
3613 } | 3677 } |
3614 | 3678 |
3615 i = sbitmap_first_set_bit (fields_left); | 3679 i = sbitmap_first_set_bit (fields_left); |
3616 if (i != -1) | 3680 if (i != -1) |
3617 gen_cluster (fields_left, str); | 3681 gen_cluster (fields_left, str); |
3618 else | 3682 else |
3619 sbitmap_free (fields_left); | 3683 sbitmap_free (fields_left); |
3620 } | 3684 } |
3621 | 3685 |
3622 /* This function is a helper for do_reorg. It goes over | 3686 /* This function is a helper for do_reorg. It goes over |
3623 functions in call graph and performs actual transformation | 3687 functions in call graph and performs actual transformation |
3624 on them. */ | 3688 on them. */ |
3625 | 3689 |
3626 static void | 3690 static void |
3627 do_reorg_1 (void) | 3691 do_reorg_1 (void) |
3628 { | 3692 { |
3630 | 3694 |
3631 /* Initialize the default bitmap obstack. */ | 3695 /* Initialize the default bitmap obstack. */ |
3632 bitmap_obstack_initialize (NULL); | 3696 bitmap_obstack_initialize (NULL); |
3633 | 3697 |
3634 for (node = cgraph_nodes; node; node = node->next) | 3698 for (node = cgraph_nodes; node; node = node->next) |
3635 if (node->analyzed && node->decl && !node->next_clone) | 3699 if (node->analyzed && node->decl) |
3636 { | 3700 { |
3637 push_cfun (DECL_STRUCT_FUNCTION (node->decl)); | 3701 push_cfun (DECL_STRUCT_FUNCTION (node->decl)); |
3638 current_function_decl = node->decl; | 3702 current_function_decl = node->decl; |
3639 if (dump_file) | 3703 if (dump_file) |
3640 fprintf (dump_file, "\nFunction to do reorg is %s: \n", | 3704 fprintf (dump_file, "\nFunction to do reorg is %s: \n", |
3641 (const char *) IDENTIFIER_POINTER (DECL_NAME (node->decl))); | 3705 (const char *) IDENTIFIER_POINTER (DECL_NAME (node->decl))); |
3642 do_reorg_for_func (node); | 3706 do_reorg_for_func (node); |
3643 free_dominance_info (CDI_DOMINATORS); | 3707 free_dominance_info (CDI_DOMINATORS); |
3644 free_dominance_info (CDI_POST_DOMINATORS); | 3708 free_dominance_info (CDI_POST_DOMINATORS); |
3645 current_function_decl = NULL; | 3709 current_function_decl = NULL; |
3649 set_cfun (NULL); | 3713 set_cfun (NULL); |
3650 bitmap_obstack_release (NULL); | 3714 bitmap_obstack_release (NULL); |
3651 } | 3715 } |
3652 | 3716 |
3653 /* This function creates new global struct variables. | 3717 /* This function creates new global struct variables. |
3654 For each original variable, the set of new variables | 3718 For each original variable, the set of new variables |
3655 is created with the new structure types corresponding | 3719 is created with the new structure types corresponding |
3656 to the structure type of original variable. | 3720 to the structure type of original variable. |
3657 Only VAR_DECL variables are treated by this function. */ | 3721 Only VAR_DECL variables are treated by this function. */ |
3658 | 3722 |
3659 static void | 3723 static void |
3660 create_new_global_vars (void) | 3724 create_new_global_vars (void) |
3661 { | 3725 { |
3662 struct varpool_node *current_varpool; | 3726 struct varpool_node *current_varpool; |
3663 unsigned HOST_WIDE_INT i; | 3727 unsigned HOST_WIDE_INT i; |
3664 unsigned HOST_WIDE_INT varpool_size = 0; | 3728 unsigned HOST_WIDE_INT varpool_size = 0; |
3665 | 3729 |
3666 for (i = 0; i < 2; i++) | 3730 for (i = 0; i < 2; i++) |
3667 { | 3731 { |
3668 if (i) | 3732 if (i) |
3669 new_global_vars = htab_create (varpool_size, | 3733 new_global_vars = htab_create (varpool_size, |
3670 new_var_hash, new_var_eq, NULL); | 3734 new_var_hash, new_var_eq, NULL); |
3671 FOR_EACH_STATIC_VARIABLE(current_varpool) | 3735 FOR_EACH_STATIC_VARIABLE(current_varpool) |
3672 { | 3736 { |
3673 tree var_decl = current_varpool->decl; | 3737 tree var_decl = current_varpool->decl; |
3674 | 3738 |
3706 { | 3770 { |
3707 fprintf (dump_file, "\nFor type "); | 3771 fprintf (dump_file, "\nFor type "); |
3708 dump_struct_type (str->decl, 2, 0); | 3772 dump_struct_type (str->decl, 2, 0); |
3709 fprintf (dump_file, "\nthe number of new types is %d\n", | 3773 fprintf (dump_file, "\nthe number of new types is %d\n", |
3710 VEC_length (tree, str->new_types)); | 3774 VEC_length (tree, str->new_types)); |
3711 } | 3775 } |
3712 for (j = 0; VEC_iterate (tree, str->new_types, j, type); j++) | 3776 for (j = 0; VEC_iterate (tree, str->new_types, j, type); j++) |
3713 dump_struct_type (type, 2, 0); | 3777 dump_struct_type (type, 2, 0); |
3714 } | 3778 } |
3715 } | 3779 } |
3716 | 3780 |
3717 /* This function creates new types to replace old structure types. */ | 3781 /* This function creates new types to replace old structure types. */ |
3718 | 3782 |
3731 | 3795 |
3732 static void | 3796 static void |
3733 free_alloc_sites (void) | 3797 free_alloc_sites (void) |
3734 { | 3798 { |
3735 if (alloc_sites) | 3799 if (alloc_sites) |
3736 htab_traverse (alloc_sites, free_falloc_sites, NULL); | 3800 htab_traverse (alloc_sites, free_falloc_sites, NULL); |
3737 htab_delete (alloc_sites); | 3801 htab_delete (alloc_sites); |
3738 alloc_sites = NULL; | 3802 alloc_sites = NULL; |
3739 } | 3803 } |
3740 | 3804 |
3741 /* This function collects structures potential | 3805 /* This function collects structures potential |
3742 for peeling transformation, and inserts | 3806 for peeling transformation, and inserts |
3743 them into structures hashtable. */ | 3807 them into structures hashtable. */ |
3744 | 3808 |
3745 static void | 3809 static void |
3746 collect_structures (void) | 3810 collect_structures (void) |
3747 { | 3811 { |
3748 VEC (tree, heap) *unsuitable_types = VEC_alloc (tree, heap, 32); | 3812 VEC (tree, heap) *unsuitable_types = VEC_alloc (tree, heap, 32); |
3749 | 3813 |
3750 structures = VEC_alloc (structure, heap, 32); | 3814 structures = VEC_alloc (structure, heap, 32); |
3751 | 3815 |
3752 /* If program contains user defined mallocs, we give up. */ | 3816 /* If program contains user defined mallocs, we give up. */ |
3753 if (program_redefines_malloc_p ()) | 3817 if (program_redefines_malloc_p ()) |
3754 return; | 3818 return; |
3755 | 3819 |
3756 /* Build data structures hashtable of all data structures | 3820 /* Build data structures hashtable of all data structures |
3757 in the program. */ | 3821 in the program. */ |
3758 build_data_structure (&unsuitable_types); | 3822 build_data_structure (&unsuitable_types); |
3759 | 3823 |
3760 /* This function analyzes whether the form of | 3824 /* This function analyzes whether the form of |
3761 structure is such that we are capable to transform it. | 3825 structure is such that we are capable to transform it. |
3762 Nested structures are checked here. */ | 3826 Nested structures are checked here. */ |
3763 analyze_struct_form (&unsuitable_types); | 3827 analyze_struct_form (&unsuitable_types); |
3764 | 3828 |
3765 /* This function excludes those structure types | 3829 /* This function excludes those structure types |
3766 that escape compilation unit. */ | 3830 that escape compilation unit. */ |
3767 exclude_escaping_types (&unsuitable_types); | 3831 exclude_escaping_types (&unsuitable_types); |
3768 | 3832 |
3769 /* We do not want to change data layout of the structures with bitfields. */ | 3833 /* We do not want to change data layout of the structures with bitfields. */ |
3770 exclude_types_with_bit_fields (&unsuitable_types); | 3834 exclude_types_with_bit_fields (&unsuitable_types); |
3781 { | 3845 { |
3782 alloc_sites = htab_create (32, malloc_hash, malloc_eq, NULL); | 3846 alloc_sites = htab_create (32, malloc_hash, malloc_eq, NULL); |
3783 collect_alloc_sites (); | 3847 collect_alloc_sites (); |
3784 } | 3848 } |
3785 | 3849 |
3786 /* This function collects data accesses for the | 3850 /* This function collects data accesses for the |
3787 structures to be transformed. For each structure | 3851 structures to be transformed. For each structure |
3788 field it updates the count field in field_entry. */ | 3852 field it updates the count field in field_entry. */ |
3789 | 3853 |
3790 static void | 3854 static void |
3791 collect_data_accesses (void) | 3855 collect_data_accesses (void) |
3792 { | 3856 { |
3793 struct cgraph_node *c_node; | 3857 struct cgraph_node *c_node; |
3794 | 3858 |
3795 for (c_node = cgraph_nodes; c_node; c_node = c_node->next) | 3859 for (c_node = cgraph_nodes; c_node; c_node = c_node->next) |
3798 | 3862 |
3799 if (avail == AVAIL_LOCAL || avail == AVAIL_AVAILABLE) | 3863 if (avail == AVAIL_LOCAL || avail == AVAIL_AVAILABLE) |
3800 { | 3864 { |
3801 struct function *func = DECL_STRUCT_FUNCTION (c_node->decl); | 3865 struct function *func = DECL_STRUCT_FUNCTION (c_node->decl); |
3802 | 3866 |
3803 if (!c_node->next_clone) | 3867 collect_accesses_in_func (func); |
3804 collect_accesses_in_func (func); | |
3805 exclude_alloc_and_field_accs (c_node); | 3868 exclude_alloc_and_field_accs (c_node); |
3806 } | 3869 } |
3807 } | 3870 } |
3808 | 3871 |
3809 check_cond_exprs (); | 3872 check_cond_exprs (); |
3810 /* Print collected accesses. */ | 3873 /* Print collected accesses. */ |
3811 dump_accesses (); | 3874 dump_accesses (); |
3812 } | 3875 } |
3813 | 3876 |
3814 /* We do not bother to transform cold structures. | 3877 /* We do not bother to transform cold structures. |
3815 Coldness of the structure is defined relatively | 3878 Coldness of the structure is defined relatively |
3816 to the highest structure count among the structures | 3879 to the highest structure count among the structures |
3817 to be transformed. It's triggered by the compiler parameter | 3880 to be transformed. It's triggered by the compiler parameter |
3818 | 3881 |
3819 --param struct-reorg-cold-struct-ratio=<value> | 3882 --param struct-reorg-cold-struct-ratio=<value> |
3820 | 3883 |
3821 where <value> ranges from 0 to 100. Structures with count ratios | 3884 where <value> ranges from 0 to 100. Structures with count ratios |
3847 } | 3910 } |
3848 else | 3911 else |
3849 i++; | 3912 i++; |
3850 } | 3913 } |
3851 | 3914 |
3852 /* This function decomposes original structure into substructures, | 3915 /* This function decomposes original structure into substructures, |
3853 i.e.clusters. */ | 3916 i.e.clusters. */ |
3854 | 3917 |
3855 static void | 3918 static void |
3856 peel_structs (void) | 3919 peel_structs (void) |
3857 { | 3920 { |
3889 create_new_types (); | 3952 create_new_types (); |
3890 dump_new_types (); | 3953 dump_new_types (); |
3891 | 3954 |
3892 /* Create new global variables. */ | 3955 /* Create new global variables. */ |
3893 create_new_global_vars (); | 3956 create_new_global_vars (); |
3894 dump_new_vars (new_global_vars); | 3957 dump_new_vars (new_global_vars); |
3895 | 3958 |
3896 /* Decompose structures for each function separately. */ | 3959 /* Decompose structures for each function separately. */ |
3897 do_reorg_1 (); | 3960 do_reorg_1 (); |
3898 | 3961 |
3899 /* Free auxiliary data collected for global variables. */ | 3962 /* Free auxiliary data collected for global variables. */ |
3900 free_new_vars_htab (new_global_vars); | 3963 free_new_vars_htab (new_global_vars); |
3901 } | 3964 } |
3902 | 3965 |
3903 /* Free all auxiliary data used by this optimization. */ | 3966 /* Free all auxiliary data used by this optimization. */ |
3904 | 3967 |
3905 static void | 3968 static void |
3906 free_data_structs (void) | 3969 free_data_structs (void) |
3907 { | 3970 { |
3908 free_structures (); | 3971 free_structures (); |
3909 free_alloc_sites (); | 3972 free_alloc_sites (); |
3910 } | 3973 } |
3911 | 3974 |
3912 /* Perform structure decomposition (peeling). */ | 3975 /* Perform structure decomposition (peeling). */ |
3913 | 3976 |
3914 static void | 3977 static void |
3915 reorg_structs (void) | 3978 reorg_structs (void) |
3916 { | 3979 { |
3917 | 3980 |
3918 /* Stage1. */ | 3981 /* Stage1. */ |
3919 /* Collect structure types. */ | 3982 /* Collect structure types. */ |
3920 collect_structures (); | 3983 collect_structures (); |
3921 | 3984 |
3922 /* Collect structure allocation sites. */ | 3985 /* Collect structure allocation sites. */ |
3923 collect_allocation_sites (); | 3986 collect_allocation_sites (); |
3924 | 3987 |
3925 /* Collect structure accesses. */ | 3988 /* Collect structure accesses. */ |
3926 collect_data_accesses (); | 3989 collect_data_accesses (); |
3927 | 3990 |
3928 /* We transform only hot structures. */ | 3991 /* We transform only hot structures. */ |
3929 exclude_cold_structs (); | 3992 exclude_cold_structs (); |
3930 | 3993 |
3931 /* Stage2. */ | 3994 /* Stage2. */ |
3932 /* Decompose structures into substructures, i.e. clusters. */ | 3995 /* Decompose structures into substructures, i.e. clusters. */ |
3933 peel_structs (); | 3996 peel_structs (); |
3934 | 3997 |
3935 /* Stage3. */ | 3998 /* Stage3. */ |
3936 /* Do the actual transformation for each structure | 3999 /* Do the actual transformation for each structure |
3937 from the structures hashtable. */ | 4000 from the structures hashtable. */ |
3938 do_reorg (); | 4001 do_reorg (); |
3939 | 4002 |
3940 /* Free all auxiliary data used by this optimization. */ | 4003 /* Free all auxiliary data used by this optimization. */ |
3941 free_data_structs (); | 4004 free_data_structs (); |
3942 } | 4005 } |
3943 | 4006 |
3944 /* Struct-reorg optimization entry point function. */ | 4007 /* Struct-reorg optimization entry point function. */ |
3945 | 4008 |
3946 static unsigned int | 4009 static unsigned int |
3954 | 4017 |
3955 static bool | 4018 static bool |
3956 struct_reorg_gate (void) | 4019 struct_reorg_gate (void) |
3957 { | 4020 { |
3958 return flag_ipa_struct_reorg | 4021 return flag_ipa_struct_reorg |
3959 && flag_whole_program | 4022 && flag_whole_program |
3960 && (optimize > 0); | 4023 && (optimize > 0); |
3961 } | 4024 } |
3962 | 4025 |
3963 struct simple_ipa_opt_pass pass_ipa_struct_reorg = | 4026 struct simple_ipa_opt_pass pass_ipa_struct_reorg = |
3964 { | 4027 { |
3965 { | 4028 { |
3966 SIMPLE_IPA_PASS, | 4029 SIMPLE_IPA_PASS, |
3967 "ipa_struct_reorg", /* name */ | 4030 "ipa_struct_reorg", /* name */ |
3968 struct_reorg_gate, /* gate */ | 4031 struct_reorg_gate, /* gate */ |