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