Mercurial > hg > CbC > CbC_gcc
comparison gcc/tree-switch-conversion.c @ 67:f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
author | nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp> |
---|---|
date | Tue, 22 Mar 2011 17:18:12 +0900 |
parents | b7f97abdc517 |
children | 04ced10e8804 |
comparison
equal
deleted
inserted
replaced
65:65488c3d617d | 67:f6334be47118 |
---|---|
78 | 78 |
79 #include "config.h" | 79 #include "config.h" |
80 #include "system.h" | 80 #include "system.h" |
81 #include "coretypes.h" | 81 #include "coretypes.h" |
82 #include "tm.h" | 82 #include "tm.h" |
83 #include <signal.h> | |
84 | |
85 #include "line-map.h" | 83 #include "line-map.h" |
86 #include "params.h" | 84 #include "params.h" |
87 #include "flags.h" | 85 #include "flags.h" |
88 #include "tree.h" | 86 #include "tree.h" |
89 #include "basic-block.h" | 87 #include "basic-block.h" |
91 #include "tree-flow-inline.h" | 89 #include "tree-flow-inline.h" |
92 #include "tree-ssa-operands.h" | 90 #include "tree-ssa-operands.h" |
93 #include "output.h" | 91 #include "output.h" |
94 #include "input.h" | 92 #include "input.h" |
95 #include "tree-pass.h" | 93 #include "tree-pass.h" |
96 #include "diagnostic.h" | |
97 #include "gimple-pretty-print.h" | 94 #include "gimple-pretty-print.h" |
98 #include "tree-dump.h" | 95 #include "tree-dump.h" |
99 #include "timevar.h" | 96 #include "timevar.h" |
97 #include "langhooks.h" | |
100 | 98 |
101 /* The main structure of the pass. */ | 99 /* The main structure of the pass. */ |
102 struct switch_conv_info | 100 struct switch_conv_info |
103 { | 101 { |
104 /* The expression used to decide the switch branch. (It is subsequently used | 102 /* The expression used to decide the switch branch. (It is subsequently used |
154 gimple arr_ref_last; | 152 gimple arr_ref_last; |
155 | 153 |
156 /* String reason why the case wasn't a good candidate that is written to the | 154 /* String reason why the case wasn't a good candidate that is written to the |
157 dump file, if there is one. */ | 155 dump file, if there is one. */ |
158 const char *reason; | 156 const char *reason; |
157 | |
158 /* Parameters for expand_switch_using_bit_tests. Should be computed | |
159 the same way as in expand_case. */ | |
160 unsigned int bit_test_uniq; | |
161 unsigned int bit_test_count; | |
162 basic_block bit_test_bb[2]; | |
159 }; | 163 }; |
160 | 164 |
161 /* Global pass info. */ | 165 /* Global pass info. */ |
162 static struct switch_conv_info info; | 166 static struct switch_conv_info info; |
163 | 167 |
172 tree min_case, max_case; | 176 tree min_case, max_case; |
173 unsigned int branch_num = gimple_switch_num_labels (swtch); | 177 unsigned int branch_num = gimple_switch_num_labels (swtch); |
174 tree range_max; | 178 tree range_max; |
175 | 179 |
176 /* The gimplifier has already sorted the cases by CASE_LOW and ensured there | 180 /* The gimplifier has already sorted the cases by CASE_LOW and ensured there |
177 is a default label which is the last in the vector. */ | 181 is a default label which is the first in the vector. */ |
178 | 182 |
179 min_case = gimple_switch_label (swtch, 1); | 183 min_case = gimple_switch_label (swtch, 1); |
180 info.range_min = CASE_LOW (min_case); | 184 info.range_min = CASE_LOW (min_case); |
181 | 185 |
182 gcc_assert (branch_num > 1); | 186 gcc_assert (branch_num > 1); |
232 /* Default branch. */ | 236 /* Default branch. */ |
233 info.default_prob = e->probability; | 237 info.default_prob = e->probability; |
234 info.default_count = e->count; | 238 info.default_count = e->count; |
235 } | 239 } |
236 else | 240 else |
237 info.other_count += e->count; | 241 { |
242 int i; | |
243 info.other_count += e->count; | |
244 for (i = 0; i < 2; i++) | |
245 if (info.bit_test_bb[i] == label_bb) | |
246 break; | |
247 else if (info.bit_test_bb[i] == NULL) | |
248 { | |
249 info.bit_test_bb[i] = label_bb; | |
250 info.bit_test_uniq++; | |
251 break; | |
252 } | |
253 if (i == 2) | |
254 info.bit_test_uniq = 3; | |
255 if (CASE_HIGH (cs) != NULL_TREE | |
256 && ! tree_int_cst_equal (CASE_LOW (cs), CASE_HIGH (cs))) | |
257 info.bit_test_count += 2; | |
258 else | |
259 info.bit_test_count++; | |
260 } | |
238 | 261 |
239 if (!label_bb) | 262 if (!label_bb) |
240 { | 263 { |
241 info.reason = " Bad case - cs BB label is NULL\n"; | 264 info.reason = " Bad case - cs BB label is NULL\n"; |
242 return false; | 265 return false; |
334 static void | 357 static void |
335 create_temp_arrays (void) | 358 create_temp_arrays (void) |
336 { | 359 { |
337 int i; | 360 int i; |
338 | 361 |
339 info.default_values = (tree *) xcalloc (info.phi_count, sizeof (tree)); | 362 info.default_values = XCNEWVEC (tree, info.phi_count * 3); |
340 info.constructors = (VEC (constructor_elt, gc) **) xcalloc (info.phi_count, | 363 info.constructors = XCNEWVEC (VEC (constructor_elt, gc) *, info.phi_count); |
341 sizeof (tree)); | 364 info.target_inbound_names = info.default_values + info.phi_count; |
342 info.target_inbound_names = (tree *) xcalloc (info.phi_count, sizeof (tree)); | 365 info.target_outbound_names = info.target_inbound_names + info.phi_count; |
343 info.target_outbound_names = (tree *) xcalloc (info.phi_count, | |
344 sizeof (tree)); | |
345 | |
346 for (i = 0; i < info.phi_count; i++) | 366 for (i = 0; i < info.phi_count; i++) |
347 info.constructors[i] | 367 info.constructors[i] |
348 = VEC_alloc (constructor_elt, gc, tree_low_cst (info.range_size, 1) + 1); | 368 = VEC_alloc (constructor_elt, gc, tree_low_cst (info.range_size, 1) + 1); |
349 } | 369 } |
350 | 370 |
353 already become constructors and must be preserved. */ | 373 already become constructors and must be preserved. */ |
354 | 374 |
355 static void | 375 static void |
356 free_temp_arrays (void) | 376 free_temp_arrays (void) |
357 { | 377 { |
358 free (info.constructors); | 378 XDELETEVEC (info.constructors); |
359 free (info.default_values); | 379 XDELETEVEC (info.default_values); |
360 free (info.target_inbound_names); | |
361 free (info.target_outbound_names); | |
362 } | 380 } |
363 | 381 |
364 /* Populate the array of default values in the order of phi nodes. | 382 /* Populate the array of default values in the order of phi nodes. |
365 DEFAULT_CASE is the CASE_LABEL_EXPR for the default switch branch. */ | 383 DEFAULT_CASE is the CASE_LABEL_EXPR for the default switch branch. */ |
366 | 384 |
466 vectors. */ | 484 vectors. */ |
467 | 485 |
468 static tree | 486 static tree |
469 constructor_contains_same_values_p (VEC (constructor_elt, gc) *vec) | 487 constructor_contains_same_values_p (VEC (constructor_elt, gc) *vec) |
470 { | 488 { |
471 int i, len = VEC_length (constructor_elt, vec); | 489 unsigned int i; |
472 tree prev = NULL_TREE; | 490 tree prev = NULL_TREE; |
473 | 491 constructor_elt *elt; |
474 for (i = 0; i < len; i++) | 492 |
475 { | 493 FOR_EACH_VEC_ELT (constructor_elt, vec, i, elt) |
476 constructor_elt *elt = VEC_index (constructor_elt, vec, i); | 494 { |
477 | |
478 if (!prev) | 495 if (!prev) |
479 prev = elt->value; | 496 prev = elt->value; |
480 else if (!operand_equal_p (elt->value, prev, OEP_ONLY_CONST)) | 497 else if (!operand_equal_p (elt->value, prev, OEP_ONLY_CONST)) |
481 return NULL_TREE; | 498 return NULL_TREE; |
482 } | 499 } |
483 return prev; | 500 return prev; |
501 } | |
502 | |
503 /* Return type which should be used for array elements, either TYPE, | |
504 or for integral type some smaller integral type that can still hold | |
505 all the constants. */ | |
506 | |
507 static tree | |
508 array_value_type (gimple swtch, tree type, int num) | |
509 { | |
510 unsigned int i, len = VEC_length (constructor_elt, info.constructors[num]); | |
511 constructor_elt *elt; | |
512 enum machine_mode mode; | |
513 int sign = 0; | |
514 tree smaller_type; | |
515 | |
516 if (!INTEGRAL_TYPE_P (type)) | |
517 return type; | |
518 | |
519 mode = GET_CLASS_NARROWEST_MODE (GET_MODE_CLASS (TYPE_MODE (type))); | |
520 if (GET_MODE_SIZE (TYPE_MODE (type)) <= GET_MODE_SIZE (mode)) | |
521 return type; | |
522 | |
523 if (len < (optimize_bb_for_size_p (gimple_bb (swtch)) ? 2 : 32)) | |
524 return type; | |
525 | |
526 FOR_EACH_VEC_ELT (constructor_elt, info.constructors[num], i, elt) | |
527 { | |
528 double_int cst; | |
529 | |
530 if (TREE_CODE (elt->value) != INTEGER_CST) | |
531 return type; | |
532 | |
533 cst = TREE_INT_CST (elt->value); | |
534 while (1) | |
535 { | |
536 unsigned int prec = GET_MODE_BITSIZE (mode); | |
537 if (prec > HOST_BITS_PER_WIDE_INT) | |
538 return type; | |
539 | |
540 if (sign >= 0 | |
541 && double_int_equal_p (cst, double_int_zext (cst, prec))) | |
542 { | |
543 if (sign == 0 | |
544 && double_int_equal_p (cst, double_int_sext (cst, prec))) | |
545 break; | |
546 sign = 1; | |
547 break; | |
548 } | |
549 if (sign <= 0 | |
550 && double_int_equal_p (cst, double_int_sext (cst, prec))) | |
551 { | |
552 sign = -1; | |
553 break; | |
554 } | |
555 | |
556 if (sign == 1) | |
557 sign = 0; | |
558 | |
559 mode = GET_MODE_WIDER_MODE (mode); | |
560 if (mode == VOIDmode | |
561 || GET_MODE_SIZE (mode) >= GET_MODE_SIZE (TYPE_MODE (type))) | |
562 return type; | |
563 } | |
564 } | |
565 | |
566 if (sign == 0) | |
567 sign = TYPE_UNSIGNED (type) ? 1 : -1; | |
568 smaller_type = lang_hooks.types.type_for_mode (mode, sign >= 0); | |
569 if (GET_MODE_SIZE (TYPE_MODE (type)) | |
570 <= GET_MODE_SIZE (TYPE_MODE (smaller_type))) | |
571 return type; | |
572 | |
573 return smaller_type; | |
484 } | 574 } |
485 | 575 |
486 /* Create an appropriate array type and declaration and assemble a static array | 576 /* Create an appropriate array type and declaration and assemble a static array |
487 variable. Also create a load statement that initializes the variable in | 577 variable. Also create a load statement that initializes the variable in |
488 question with a value from the static array. SWTCH is the switch statement | 578 question with a value from the static array. SWTCH is the switch statement |
510 cst = constructor_contains_same_values_p (info.constructors[num]); | 600 cst = constructor_contains_same_values_p (info.constructors[num]); |
511 if (cst) | 601 if (cst) |
512 load = gimple_build_assign (name, cst); | 602 load = gimple_build_assign (name, cst); |
513 else | 603 else |
514 { | 604 { |
515 tree array_type, ctor, decl, value_type, fetch; | 605 tree array_type, ctor, decl, value_type, fetch, default_type; |
516 | 606 |
517 value_type = TREE_TYPE (info.default_values[num]); | 607 default_type = TREE_TYPE (info.default_values[num]); |
608 value_type = array_value_type (swtch, default_type, num); | |
518 array_type = build_array_type (value_type, arr_index_type); | 609 array_type = build_array_type (value_type, arr_index_type); |
610 if (default_type != value_type) | |
611 { | |
612 unsigned int i; | |
613 constructor_elt *elt; | |
614 | |
615 FOR_EACH_VEC_ELT (constructor_elt, info.constructors[num], i, elt) | |
616 elt->value = fold_convert (value_type, elt->value); | |
617 } | |
519 ctor = build_constructor (array_type, info.constructors[num]); | 618 ctor = build_constructor (array_type, info.constructors[num]); |
520 TREE_CONSTANT (ctor) = true; | 619 TREE_CONSTANT (ctor) = true; |
620 TREE_STATIC (ctor) = true; | |
521 | 621 |
522 decl = build_decl (loc, VAR_DECL, NULL_TREE, array_type); | 622 decl = build_decl (loc, VAR_DECL, NULL_TREE, array_type); |
523 TREE_STATIC (decl) = 1; | 623 TREE_STATIC (decl) = 1; |
524 DECL_INITIAL (decl) = ctor; | 624 DECL_INITIAL (decl) = ctor; |
525 | 625 |
526 DECL_NAME (decl) = create_tmp_var_name ("CSWTCH"); | 626 DECL_NAME (decl) = create_tmp_var_name ("CSWTCH"); |
527 DECL_ARTIFICIAL (decl) = 1; | 627 DECL_ARTIFICIAL (decl) = 1; |
528 TREE_CONSTANT (decl) = 1; | 628 TREE_CONSTANT (decl) = 1; |
629 TREE_READONLY (decl) = 1; | |
529 add_referenced_var (decl); | 630 add_referenced_var (decl); |
530 varpool_mark_needed_node (varpool_node (decl)); | 631 varpool_mark_needed_node (varpool_node (decl)); |
531 varpool_finalize_decl (decl); | 632 varpool_finalize_decl (decl); |
532 | 633 |
533 fetch = build4 (ARRAY_REF, value_type, decl, tidx, NULL_TREE, | 634 fetch = build4 (ARRAY_REF, value_type, decl, tidx, NULL_TREE, |
534 NULL_TREE); | 635 NULL_TREE); |
636 if (default_type != value_type) | |
637 { | |
638 fetch = fold_convert (default_type, fetch); | |
639 fetch = force_gimple_operand_gsi (&gsi, fetch, true, NULL_TREE, | |
640 true, GSI_SAME_STMT); | |
641 } | |
535 load = gimple_build_assign (name, fetch); | 642 load = gimple_build_assign (name, fetch); |
536 } | 643 } |
537 | 644 |
538 SSA_NAME_DEF_STMT (name) = load; | 645 SSA_NAME_DEF_STMT (name) = load; |
539 gsi_insert_before (&gsi, load, GSI_SAME_STMT); | 646 gsi_insert_before (&gsi, load, GSI_SAME_STMT); |
692 gcc_assert (info.default_values); | 799 gcc_assert (info.default_values); |
693 bb0 = gimple_bb (swtch); | 800 bb0 = gimple_bb (swtch); |
694 | 801 |
695 /* Make sure we do not generate arithmetics in a subrange. */ | 802 /* Make sure we do not generate arithmetics in a subrange. */ |
696 if (TREE_TYPE (TREE_TYPE (info.index_expr))) | 803 if (TREE_TYPE (TREE_TYPE (info.index_expr))) |
697 utype = unsigned_type_for (TREE_TYPE (TREE_TYPE (info.index_expr))); | 804 utype = lang_hooks.types.type_for_mode |
805 (TYPE_MODE (TREE_TYPE (TREE_TYPE (info.index_expr))), 1); | |
698 else | 806 else |
699 utype = unsigned_type_for (TREE_TYPE (info.index_expr)); | 807 utype = lang_hooks.types.type_for_mode |
808 (TYPE_MODE (TREE_TYPE (info.index_expr)), 1); | |
700 | 809 |
701 /* (end of) block 0 */ | 810 /* (end of) block 0 */ |
702 gsi = gsi_for_stmt (info.arr_ref_first); | 811 gsi = gsi_for_stmt (info.arr_ref_first); |
703 tmp_u_var = create_tmp_var (utype, "csui"); | 812 tmp_u_var = create_tmp_var (utype, "csui"); |
704 add_referenced_var (tmp_u_var); | 813 add_referenced_var (tmp_u_var); |
812 info.arr_ref_first = NULL; | 921 info.arr_ref_first = NULL; |
813 info.arr_ref_last = NULL; | 922 info.arr_ref_last = NULL; |
814 info.default_prob = 0; | 923 info.default_prob = 0; |
815 info.default_count = 0; | 924 info.default_count = 0; |
816 info.other_count = 0; | 925 info.other_count = 0; |
926 info.bit_test_uniq = 0; | |
927 info.bit_test_count = 0; | |
928 info.bit_test_bb[0] = NULL; | |
929 info.bit_test_bb[1] = NULL; | |
817 | 930 |
818 /* An ERROR_MARK occurs for various reasons including invalid data type. | 931 /* An ERROR_MARK occurs for various reasons including invalid data type. |
819 (comment from stmt.c) */ | 932 (comment from stmt.c) */ |
820 if (index_type == error_mark_node) | 933 if (index_type == error_mark_node) |
821 { | 934 { |
834 { | 947 { |
835 if (dump_file) | 948 if (dump_file) |
836 fprintf (dump_file, "Processing of case %i failed\n", i); | 949 fprintf (dump_file, "Processing of case %i failed\n", i); |
837 return false; | 950 return false; |
838 } | 951 } |
952 | |
953 if (info.bit_test_uniq <= 2) | |
954 { | |
955 rtl_profile_for_bb (gimple_bb (swtch)); | |
956 if (expand_switch_using_bit_tests_p (gimple_switch_index (swtch), | |
957 info.range_size, info.bit_test_uniq, | |
958 info.bit_test_count)) | |
959 { | |
960 info.reason = " Expanding as bit test is preferable\n"; | |
961 return false; | |
962 } | |
963 } | |
839 | 964 |
840 if (!check_final_bb ()) | 965 if (!check_final_bb ()) |
841 return false; | 966 return false; |
842 | 967 |
843 /* At this point all checks have passed and we can proceed with the | 968 /* At this point all checks have passed and we can proceed with the |