1 /* Switch Conversion converts variable initializations based on switch
2 statements to initializations from a static array.
3 Copyright (C) 2006, 2008, 2009, 2010 Free Software Foundation, Inc.
4 Contributed by Martin Jambor <jamborm@suse.cz>
6 This file is part of GCC.
8 GCC is free software; you can redistribute it and/or modify it
9 under the terms of the GNU General Public License as published by the
10 Free Software Foundation; either version 3, or (at your option) any
13 GCC is distributed in the hope that it will be useful, but WITHOUT
14 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
15 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
18 You should have received a copy of the GNU General Public License
19 along with GCC; see the file COPYING3. If not, write to the Free
20 Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA
24 Switch initialization conversion
26 The following pass changes simple initializations of scalars in a switch
27 statement into initializations from a static array. Obviously, the values must
28 be constant and known at compile time and a default branch must be
29 provided. For example, the following code:
52 a_5 = PHI <a_1, a_2, a_3, a_4>
53 b_5 = PHI <b_1, b_2, b_3, b_4>
58 static const int = CSWTCH01[] = {6, 6, 5, 1, 1, 1, 1, 1, 1, 1, 1, 4};
59 static const int = CSWTCH02[] = {8, 8, 9, 16, 16, 16, 16, 16, 16, 16,
62 if (((unsigned) argc) - 1 < 11)
64 a_6 = CSWTCH02[argc - 1];
65 b_6 = CSWTCH01[argc - 1];
75 There are further constraints. Specifically, the range of values across all
76 case labels must not be bigger than SWITCH_CONVERSION_BRANCH_RATIO (default
77 eight) times the number of the actual switch branches. */
81 #include "coretypes.h"
87 #include "basic-block.h"
88 #include "tree-flow.h"
89 #include "tree-flow-inline.h"
90 #include "tree-ssa-operands.h"
93 #include "tree-pass.h"
94 #include "gimple-pretty-print.h"
95 #include "tree-dump.h"
97 #include "langhooks.h"
99 /* The main structure of the pass. */
100 struct switch_conv_info
102 /* The expression used to decide the switch branch. (It is subsequently used
103 as the index to the created array.) */
106 /* The following integer constants store the minimum value covered by the
110 /* The difference between the above two numbers, i.e. The size of the array
111 that would have to be created by the transformation. */
114 /* Basic block that contains the actual SWITCH_EXPR. */
115 basic_block switch_bb
;
117 /* All branches of the switch statement must have a single successor stored in
118 the following variable. */
119 basic_block final_bb
;
121 /* Number of phi nodes in the final bb (that we'll be replacing). */
124 /* Array of default values, in the same order as phi nodes. */
125 tree
*default_values
;
127 /* Constructors of new static arrays. */
128 VEC (constructor_elt
, gc
) **constructors
;
130 /* Array of ssa names that are initialized with a value from a new static
132 tree
*target_inbound_names
;
134 /* Array of ssa names that are initialized with the default value if the
135 switch expression is out of range. */
136 tree
*target_outbound_names
;
138 /* The probability of the default edge in the replaced switch. */
141 /* The count of the default edge in the replaced switch. */
142 gcov_type default_count
;
144 /* Combined count of all other (non-default) edges in the replaced switch. */
145 gcov_type other_count
;
147 /* The first load statement that loads a temporary from a new static array.
149 gimple arr_ref_first
;
151 /* The last load statement that loads a temporary from a new static array. */
154 /* String reason why the case wasn't a good candidate that is written to the
155 dump file, if there is one. */
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];
165 /* Global pass info. */
166 static struct switch_conv_info info
;
169 /* Checks whether the range given by individual case statements of the SWTCH
170 switch statement isn't too big and whether the number of branches actually
171 satisfies the size of the new array. */
174 check_range (gimple swtch
)
176 tree min_case
, max_case
;
177 unsigned int branch_num
= gimple_switch_num_labels (swtch
);
180 /* The gimplifier has already sorted the cases by CASE_LOW and ensured there
181 is a default label which is the first in the vector. */
183 min_case
= gimple_switch_label (swtch
, 1);
184 info
.range_min
= CASE_LOW (min_case
);
186 gcc_assert (branch_num
> 1);
187 gcc_assert (CASE_LOW (gimple_switch_label (swtch
, 0)) == NULL_TREE
);
188 max_case
= gimple_switch_label (swtch
, branch_num
- 1);
189 if (CASE_HIGH (max_case
) != NULL_TREE
)
190 range_max
= CASE_HIGH (max_case
);
192 range_max
= CASE_LOW (max_case
);
194 gcc_assert (info
.range_min
);
195 gcc_assert (range_max
);
197 info
.range_size
= int_const_binop (MINUS_EXPR
, range_max
, info
.range_min
, 0);
199 gcc_assert (info
.range_size
);
200 if (!host_integerp (info
.range_size
, 1))
202 info
.reason
= "index range way too large or otherwise unusable.\n";
206 if ((unsigned HOST_WIDE_INT
) tree_low_cst (info
.range_size
, 1)
207 > ((unsigned) branch_num
* SWITCH_CONVERSION_BRANCH_RATIO
))
209 info
.reason
= "the maximum range-branch ratio exceeded.\n";
216 /* Checks the given CS switch case whether it is suitable for conversion
217 (whether all but the default basic blocks are empty and so on). If it is,
218 adds the case to the branch list along with values for the defined variables
219 and returns true. Otherwise returns false. */
222 check_process_case (tree cs
)
225 basic_block label_bb
, following_bb
;
228 ldecl
= CASE_LABEL (cs
);
229 label_bb
= label_to_block (ldecl
);
231 e
= find_edge (info
.switch_bb
, label_bb
);
234 if (CASE_LOW (cs
) == NULL_TREE
)
236 /* Default branch. */
237 info
.default_prob
= e
->probability
;
238 info
.default_count
= e
->count
;
243 info
.other_count
+= e
->count
;
244 for (i
= 0; i
< 2; i
++)
245 if (info
.bit_test_bb
[i
] == label_bb
)
247 else if (info
.bit_test_bb
[i
] == NULL
)
249 info
.bit_test_bb
[i
] = label_bb
;
250 info
.bit_test_uniq
++;
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;
259 info
.bit_test_count
++;
264 info
.reason
= " Bad case - cs BB label is NULL\n";
268 if (!single_pred_p (label_bb
))
270 if (info
.final_bb
&& info
.final_bb
!= label_bb
)
272 info
.reason
= " Bad case - a non-final BB has two predecessors\n";
273 return false; /* sth complex going on in this branch */
276 following_bb
= label_bb
;
280 if (!empty_block_p (label_bb
))
282 info
.reason
= " Bad case - a non-final BB not empty\n";
286 e
= single_succ_edge (label_bb
);
287 following_bb
= single_succ (label_bb
);
291 info
.final_bb
= following_bb
;
292 else if (info
.final_bb
!= following_bb
)
294 info
.reason
= " Bad case - different final BB\n";
295 return false; /* the only successor is not common for all the branches */
301 /* This function checks whether all required values in phi nodes in final_bb
302 are constants. Required values are those that correspond to a basic block
303 which is a part of the examined switch statement. It returns true if the
304 phi nodes are OK, otherwise false. */
307 check_final_bb (void)
309 gimple_stmt_iterator gsi
;
312 for (gsi
= gsi_start_phis (info
.final_bb
); !gsi_end_p (gsi
); gsi_next (&gsi
))
314 gimple phi
= gsi_stmt (gsi
);
319 for (i
= 0; i
< gimple_phi_num_args (phi
); i
++)
321 basic_block bb
= gimple_phi_arg_edge (phi
, i
)->src
;
323 if (bb
== info
.switch_bb
324 || (single_pred_p (bb
) && single_pred (bb
) == info
.switch_bb
))
328 val
= gimple_phi_arg_def (phi
, i
);
329 if (!is_gimple_ip_invariant (val
))
331 info
.reason
= " Non-invariant value from a case\n";
332 return false; /* Non-invariant argument. */
334 reloc
= initializer_constant_valid_p (val
, TREE_TYPE (val
));
335 if ((flag_pic
&& reloc
!= null_pointer_node
)
336 || (!flag_pic
&& reloc
== NULL_TREE
))
340 = " Value from a case would need runtime relocations\n";
343 = " Value from a case is not a valid initializer\n";
353 /* The following function allocates default_values, target_{in,out}_names and
354 constructors arrays. The last one is also populated with pointers to
355 vectors that will become constructors of new arrays. */
358 create_temp_arrays (void)
362 info
.default_values
= XCNEWVEC (tree
, info
.phi_count
* 3);
363 info
.constructors
= XCNEWVEC (VEC (constructor_elt
, gc
) *, info
.phi_count
);
364 info
.target_inbound_names
= info
.default_values
+ info
.phi_count
;
365 info
.target_outbound_names
= info
.target_inbound_names
+ info
.phi_count
;
366 for (i
= 0; i
< info
.phi_count
; i
++)
368 = VEC_alloc (constructor_elt
, gc
, tree_low_cst (info
.range_size
, 1) + 1);
371 /* Free the arrays created by create_temp_arrays(). The vectors that are
372 created by that function are not freed here, however, because they have
373 already become constructors and must be preserved. */
376 free_temp_arrays (void)
378 XDELETEVEC (info
.constructors
);
379 XDELETEVEC (info
.default_values
);
382 /* Populate the array of default values in the order of phi nodes.
383 DEFAULT_CASE is the CASE_LABEL_EXPR for the default switch branch. */
386 gather_default_values (tree default_case
)
388 gimple_stmt_iterator gsi
;
389 basic_block bb
= label_to_block (CASE_LABEL (default_case
));
393 gcc_assert (CASE_LOW (default_case
) == NULL_TREE
);
395 if (bb
== info
.final_bb
)
396 e
= find_edge (info
.switch_bb
, bb
);
398 e
= single_succ_edge (bb
);
400 for (gsi
= gsi_start_phis (info
.final_bb
); !gsi_end_p (gsi
); gsi_next (&gsi
))
402 gimple phi
= gsi_stmt (gsi
);
403 tree val
= PHI_ARG_DEF_FROM_EDGE (phi
, e
);
405 info
.default_values
[i
++] = val
;
409 /* The following function populates the vectors in the constructors array with
410 future contents of the static arrays. The vectors are populated in the
411 order of phi nodes. SWTCH is the switch statement being converted. */
414 build_constructors (gimple swtch
)
416 unsigned i
, branch_num
= gimple_switch_num_labels (swtch
);
417 tree pos
= info
.range_min
;
419 for (i
= 1; i
< branch_num
; i
++)
421 tree cs
= gimple_switch_label (swtch
, i
);
422 basic_block bb
= label_to_block (CASE_LABEL (cs
));
425 gimple_stmt_iterator gsi
;
428 if (bb
== info
.final_bb
)
429 e
= find_edge (info
.switch_bb
, bb
);
431 e
= single_succ_edge (bb
);
434 while (tree_int_cst_lt (pos
, CASE_LOW (cs
)))
437 for (k
= 0; k
< info
.phi_count
; k
++)
439 constructor_elt
*elt
;
441 elt
= VEC_quick_push (constructor_elt
,
442 info
.constructors
[k
], NULL
);
443 elt
->index
= int_const_binop (MINUS_EXPR
, pos
,
445 elt
->value
= info
.default_values
[k
];
448 pos
= int_const_binop (PLUS_EXPR
, pos
, integer_one_node
, 0);
450 gcc_assert (tree_int_cst_equal (pos
, CASE_LOW (cs
)));
454 high
= CASE_HIGH (cs
);
456 high
= CASE_LOW (cs
);
457 for (gsi
= gsi_start_phis (info
.final_bb
);
458 !gsi_end_p (gsi
); gsi_next (&gsi
))
460 gimple phi
= gsi_stmt (gsi
);
461 tree val
= PHI_ARG_DEF_FROM_EDGE (phi
, e
);
462 tree low
= CASE_LOW (cs
);
467 constructor_elt
*elt
;
469 elt
= VEC_quick_push (constructor_elt
,
470 info
.constructors
[j
], NULL
);
471 elt
->index
= int_const_binop (MINUS_EXPR
, pos
, info
.range_min
, 0);
474 pos
= int_const_binop (PLUS_EXPR
, pos
, integer_one_node
, 0);
475 } while (!tree_int_cst_lt (high
, pos
)
476 && tree_int_cst_lt (low
, pos
));
482 /* If all values in the constructor vector are the same, return the value.
483 Otherwise return NULL_TREE. Not supposed to be called for empty
487 constructor_contains_same_values_p (VEC (constructor_elt
, gc
) *vec
)
490 tree prev
= NULL_TREE
;
491 constructor_elt
*elt
;
493 FOR_EACH_VEC_ELT (constructor_elt
, vec
, i
, elt
)
497 else if (!operand_equal_p (elt
->value
, prev
, OEP_ONLY_CONST
))
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. */
508 array_value_type (gimple swtch
, tree type
, int num
)
510 unsigned int i
, len
= VEC_length (constructor_elt
, info
.constructors
[num
]);
511 constructor_elt
*elt
;
512 enum machine_mode mode
;
516 if (!INTEGRAL_TYPE_P (type
))
519 mode
= GET_CLASS_NARROWEST_MODE (GET_MODE_CLASS (TYPE_MODE (type
)));
520 if (GET_MODE_SIZE (TYPE_MODE (type
)) <= GET_MODE_SIZE (mode
))
523 if (len
< (optimize_bb_for_size_p (gimple_bb (swtch
)) ? 2 : 32))
526 FOR_EACH_VEC_ELT (constructor_elt
, info
.constructors
[num
], i
, elt
)
530 if (TREE_CODE (elt
->value
) != INTEGER_CST
)
533 cst
= TREE_INT_CST (elt
->value
);
536 unsigned int prec
= GET_MODE_BITSIZE (mode
);
537 if (prec
> HOST_BITS_PER_WIDE_INT
)
541 && double_int_equal_p (cst
, double_int_zext (cst
, prec
)))
544 && double_int_equal_p (cst
, double_int_sext (cst
, prec
)))
550 && double_int_equal_p (cst
, double_int_sext (cst
, prec
)))
559 mode
= GET_MODE_WIDER_MODE (mode
);
561 || GET_MODE_SIZE (mode
) >= GET_MODE_SIZE (TYPE_MODE (type
)))
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
)))
576 /* Create an appropriate array type and declaration and assemble a static array
577 variable. Also create a load statement that initializes the variable in
578 question with a value from the static array. SWTCH is the switch statement
579 being converted, NUM is the index to arrays of constructors, default values
580 and target SSA names for this particular array. ARR_INDEX_TYPE is the type
581 of the index of the new array, PHI is the phi node of the final BB that
582 corresponds to the value that will be loaded from the created array. TIDX
583 is an ssa name of a temporary variable holding the index for loads from the
587 build_one_array (gimple swtch
, int num
, tree arr_index_type
, gimple phi
,
592 gimple_stmt_iterator gsi
= gsi_for_stmt (swtch
);
593 location_t loc
= gimple_location (swtch
);
595 gcc_assert (info
.default_values
[num
]);
597 name
= make_ssa_name (SSA_NAME_VAR (PHI_RESULT (phi
)), NULL
);
598 info
.target_inbound_names
[num
] = name
;
600 cst
= constructor_contains_same_values_p (info
.constructors
[num
]);
602 load
= gimple_build_assign (name
, cst
);
605 tree array_type
, ctor
, decl
, value_type
, fetch
, default_type
;
607 default_type
= TREE_TYPE (info
.default_values
[num
]);
608 value_type
= array_value_type (swtch
, default_type
, num
);
609 array_type
= build_array_type (value_type
, arr_index_type
);
610 if (default_type
!= value_type
)
613 constructor_elt
*elt
;
615 FOR_EACH_VEC_ELT (constructor_elt
, info
.constructors
[num
], i
, elt
)
616 elt
->value
= fold_convert (value_type
, elt
->value
);
618 ctor
= build_constructor (array_type
, info
.constructors
[num
]);
619 TREE_CONSTANT (ctor
) = true;
620 TREE_STATIC (ctor
) = true;
622 decl
= build_decl (loc
, VAR_DECL
, NULL_TREE
, array_type
);
623 TREE_STATIC (decl
) = 1;
624 DECL_INITIAL (decl
) = ctor
;
626 DECL_NAME (decl
) = create_tmp_var_name ("CSWTCH");
627 DECL_ARTIFICIAL (decl
) = 1;
628 TREE_CONSTANT (decl
) = 1;
629 TREE_READONLY (decl
) = 1;
630 add_referenced_var (decl
);
631 varpool_mark_needed_node (varpool_node (decl
));
632 varpool_finalize_decl (decl
);
634 fetch
= build4 (ARRAY_REF
, value_type
, decl
, tidx
, NULL_TREE
,
636 if (default_type
!= value_type
)
638 fetch
= fold_convert (default_type
, fetch
);
639 fetch
= force_gimple_operand_gsi (&gsi
, fetch
, true, NULL_TREE
,
640 true, GSI_SAME_STMT
);
642 load
= gimple_build_assign (name
, fetch
);
645 SSA_NAME_DEF_STMT (name
) = load
;
646 gsi_insert_before (&gsi
, load
, GSI_SAME_STMT
);
648 info
.arr_ref_last
= load
;
651 /* Builds and initializes static arrays initialized with values gathered from
652 the SWTCH switch statement. Also creates statements that load values from
656 build_arrays (gimple swtch
)
661 gimple_stmt_iterator gsi
;
663 location_t loc
= gimple_location (swtch
);
665 gsi
= gsi_for_stmt (swtch
);
667 arr_index_type
= build_index_type (info
.range_size
);
668 tmp
= create_tmp_var (TREE_TYPE (info
.index_expr
), "csti");
669 add_referenced_var (tmp
);
670 tidx
= make_ssa_name (tmp
, NULL
);
671 sub
= fold_build2_loc (loc
, MINUS_EXPR
,
672 TREE_TYPE (info
.index_expr
), info
.index_expr
,
673 fold_convert_loc (loc
, TREE_TYPE (info
.index_expr
),
675 sub
= force_gimple_operand_gsi (&gsi
, sub
,
676 false, NULL
, true, GSI_SAME_STMT
);
677 stmt
= gimple_build_assign (tidx
, sub
);
678 SSA_NAME_DEF_STMT (tidx
) = stmt
;
680 gsi_insert_before (&gsi
, stmt
, GSI_SAME_STMT
);
682 info
.arr_ref_first
= stmt
;
684 for (gsi
= gsi_start_phis (info
.final_bb
), i
= 0;
685 !gsi_end_p (gsi
); gsi_next (&gsi
), i
++)
686 build_one_array (swtch
, i
, arr_index_type
, gsi_stmt (gsi
), tidx
);
689 /* Generates and appropriately inserts loads of default values at the position
690 given by BSI. Returns the last inserted statement. */
693 gen_def_assigns (gimple_stmt_iterator
*gsi
)
696 gimple assign
= NULL
;
698 for (i
= 0; i
< info
.phi_count
; i
++)
701 = make_ssa_name (SSA_NAME_VAR (info
.target_inbound_names
[i
]), NULL
);
703 info
.target_outbound_names
[i
] = name
;
704 assign
= gimple_build_assign (name
, info
.default_values
[i
]);
705 SSA_NAME_DEF_STMT (name
) = assign
;
706 gsi_insert_before (gsi
, assign
, GSI_SAME_STMT
);
707 update_stmt (assign
);
712 /* Deletes the unused bbs and edges that now contain the switch statement and
713 its empty branch bbs. BBD is the now dead BB containing the original switch
714 statement, FINAL is the last BB of the converted switch statement (in terms
718 prune_bbs (basic_block bbd
, basic_block final
)
723 for (ei
= ei_start (bbd
->succs
); (e
= ei_safe_edge (ei
)); )
729 delete_basic_block (bb
);
731 delete_basic_block (bbd
);
734 /* Add values to phi nodes in final_bb for the two new edges. E1F is the edge
735 from the basic block loading values from an array and E2F from the basic
736 block loading default values. BBF is the last switch basic block (see the
737 bbf description in the comment below). */
740 fix_phi_nodes (edge e1f
, edge e2f
, basic_block bbf
)
742 gimple_stmt_iterator gsi
;
745 for (gsi
= gsi_start_phis (bbf
), i
= 0;
746 !gsi_end_p (gsi
); gsi_next (&gsi
), i
++)
748 gimple phi
= gsi_stmt (gsi
);
749 add_phi_arg (phi
, info
.target_inbound_names
[i
], e1f
, UNKNOWN_LOCATION
);
750 add_phi_arg (phi
, info
.target_outbound_names
[i
], e2f
, UNKNOWN_LOCATION
);
755 /* Creates a check whether the switch expression value actually falls into the
756 range given by all the cases. If it does not, the temporaries are loaded
757 with default values instead. SWTCH is the switch statement being converted.
759 bb0 is the bb with the switch statement, however, we'll end it with a
762 bb1 is the bb to be used when the range check went ok. It is derived from
765 bb2 is the bb taken when the expression evaluated outside of the range
766 covered by the created arrays. It is populated by loads of default
769 bbF is a fall through for both bb1 and bb2 and contains exactly what
770 originally followed the switch statement.
772 bbD contains the switch statement (in the end). It is unreachable but we
773 still need to strip off its edges.
777 gen_inbound_check (gimple swtch
)
779 tree label_decl1
= create_artificial_label (UNKNOWN_LOCATION
);
780 tree label_decl2
= create_artificial_label (UNKNOWN_LOCATION
);
781 tree label_decl3
= create_artificial_label (UNKNOWN_LOCATION
);
782 gimple label1
, label2
, label3
;
785 tree tmp_u_1
, tmp_u_2
, tmp_u_var
;
787 gimple cast_assign
, minus_assign
;
794 gimple_stmt_iterator gsi
;
795 basic_block bb0
, bb1
, bb2
, bbf
, bbd
;
796 edge e01
, e02
, e21
, e1d
, e1f
, e2f
;
797 location_t loc
= gimple_location (swtch
);
799 gcc_assert (info
.default_values
);
800 bb0
= gimple_bb (swtch
);
802 /* Make sure we do not generate arithmetics in a subrange. */
803 if (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);
807 utype
= lang_hooks
.types
.type_for_mode
808 (TYPE_MODE (TREE_TYPE (info
.index_expr
)), 1);
810 /* (end of) block 0 */
811 gsi
= gsi_for_stmt (info
.arr_ref_first
);
812 tmp_u_var
= create_tmp_var (utype
, "csui");
813 add_referenced_var (tmp_u_var
);
814 tmp_u_1
= make_ssa_name (tmp_u_var
, NULL
);
816 cast
= fold_convert_loc (loc
, utype
, info
.index_expr
);
817 cast_assign
= gimple_build_assign (tmp_u_1
, cast
);
818 SSA_NAME_DEF_STMT (tmp_u_1
) = cast_assign
;
819 gsi_insert_before (&gsi
, cast_assign
, GSI_SAME_STMT
);
820 update_stmt (cast_assign
);
822 ulb
= fold_convert_loc (loc
, utype
, info
.range_min
);
823 minus
= fold_build2_loc (loc
, MINUS_EXPR
, utype
, tmp_u_1
, ulb
);
824 minus
= force_gimple_operand_gsi (&gsi
, minus
, false, NULL
, true,
826 tmp_u_2
= make_ssa_name (tmp_u_var
, NULL
);
827 minus_assign
= gimple_build_assign (tmp_u_2
, minus
);
828 SSA_NAME_DEF_STMT (tmp_u_2
) = minus_assign
;
829 gsi_insert_before (&gsi
, minus_assign
, GSI_SAME_STMT
);
830 update_stmt (minus_assign
);
832 bound
= fold_convert_loc (loc
, utype
, info
.range_size
);
833 cond_stmt
= gimple_build_cond (LE_EXPR
, tmp_u_2
, bound
, NULL_TREE
, NULL_TREE
);
834 gsi_insert_before (&gsi
, cond_stmt
, GSI_SAME_STMT
);
835 update_stmt (cond_stmt
);
838 gsi
= gsi_for_stmt (info
.arr_ref_first
);
839 label2
= gimple_build_label (label_decl2
);
840 gsi_insert_before (&gsi
, label2
, GSI_SAME_STMT
);
841 last_assign
= gen_def_assigns (&gsi
);
844 gsi
= gsi_for_stmt (info
.arr_ref_first
);
845 label1
= gimple_build_label (label_decl1
);
846 gsi_insert_before (&gsi
, label1
, GSI_SAME_STMT
);
849 gsi
= gsi_start_bb (info
.final_bb
);
850 label3
= gimple_build_label (label_decl3
);
851 gsi_insert_before (&gsi
, label3
, GSI_SAME_STMT
);
854 e02
= split_block (bb0
, cond_stmt
);
857 e21
= split_block (bb2
, last_assign
);
861 e1d
= split_block (bb1
, info
.arr_ref_last
);
865 /* flags and profiles of the edge for in-range values */
866 e01
= make_edge (bb0
, bb1
, EDGE_TRUE_VALUE
);
867 e01
->probability
= REG_BR_PROB_BASE
- info
.default_prob
;
868 e01
->count
= info
.other_count
;
870 /* flags and profiles of the edge taking care of out-of-range values */
871 e02
->flags
&= ~EDGE_FALLTHRU
;
872 e02
->flags
|= EDGE_FALSE_VALUE
;
873 e02
->probability
= info
.default_prob
;
874 e02
->count
= info
.default_count
;
878 e1f
= make_edge (bb1
, bbf
, EDGE_FALLTHRU
);
879 e1f
->probability
= REG_BR_PROB_BASE
;
880 e1f
->count
= info
.other_count
;
882 e2f
= make_edge (bb2
, bbf
, EDGE_FALLTHRU
);
883 e2f
->probability
= REG_BR_PROB_BASE
;
884 e2f
->count
= info
.default_count
;
886 /* frequencies of the new BBs */
887 bb1
->frequency
= EDGE_FREQUENCY (e01
);
888 bb2
->frequency
= EDGE_FREQUENCY (e02
);
889 bbf
->frequency
= EDGE_FREQUENCY (e1f
) + EDGE_FREQUENCY (e2f
);
891 prune_bbs (bbd
, info
.final_bb
); /* To keep calc_dfs_tree() in dominance.c
894 fix_phi_nodes (e1f
, e2f
, bbf
);
896 free_dominance_info (CDI_DOMINATORS
);
897 free_dominance_info (CDI_POST_DOMINATORS
);
900 /* The following function is invoked on every switch statement (the current one
901 is given in SWTCH) and runs the individual phases of switch conversion on it
902 one after another until one fails or the conversion is completed. */
905 process_switch (gimple swtch
)
907 unsigned int i
, branch_num
= gimple_switch_num_labels (swtch
);
910 /* Operand 2 is either NULL_TREE or a vector of cases (stmt.c). */
913 info
.reason
= "switch has no labels\n";
917 info
.final_bb
= NULL
;
918 info
.switch_bb
= gimple_bb (swtch
);
919 info
.index_expr
= gimple_switch_index (swtch
);
920 index_type
= TREE_TYPE (info
.index_expr
);
921 info
.arr_ref_first
= NULL
;
922 info
.arr_ref_last
= NULL
;
923 info
.default_prob
= 0;
924 info
.default_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
;
931 /* An ERROR_MARK occurs for various reasons including invalid data type.
932 (comment from stmt.c) */
933 if (index_type
== error_mark_node
)
935 info
.reason
= "index error.\n";
939 /* Check the case label values are within reasonable range: */
940 if (!check_range (swtch
))
943 /* For all the cases, see whether they are empty, the assignments they
944 represent constant and so on... */
945 for (i
= 0; i
< branch_num
; i
++)
946 if (!check_process_case (gimple_switch_label (swtch
, i
)))
949 fprintf (dump_file
, "Processing of case %i failed\n", i
);
953 if (info
.bit_test_uniq
<= 2)
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
))
960 info
.reason
= " Expanding as bit test is preferable\n";
965 if (!check_final_bb ())
968 /* At this point all checks have passed and we can proceed with the
971 create_temp_arrays ();
972 gather_default_values (gimple_switch_label (swtch
, 0));
973 build_constructors (swtch
);
975 build_arrays (swtch
); /* Build the static arrays and assignments. */
976 gen_inbound_check (swtch
); /* Build the bounds check. */
983 /* The main function of the pass scans statements for switches and invokes
984 process_switch on them. */
993 gimple stmt
= last_stmt (bb
);
994 if (stmt
&& gimple_code (stmt
) == GIMPLE_SWITCH
)
998 expanded_location loc
= expand_location (gimple_location (stmt
));
1000 fprintf (dump_file
, "beginning to process the following "
1001 "SWITCH statement (%s:%d) : ------- \n",
1002 loc
.file
, loc
.line
);
1003 print_gimple_stmt (dump_file
, stmt
, 0, TDF_SLIM
);
1004 putc ('\n', dump_file
);
1008 if (process_switch (stmt
))
1012 fputs ("Switch converted\n", dump_file
);
1013 fputs ("--------------------------------\n", dump_file
);
1020 gcc_assert (info
.reason
);
1021 fputs ("Bailing out - ", dump_file
);
1022 fputs (info
.reason
, dump_file
);
1023 fputs ("--------------------------------\n", dump_file
);
1032 /* The pass gate. */
1035 switchconv_gate (void)
1037 return flag_tree_switch_conversion
!= 0;
1040 struct gimple_opt_pass pass_convert_switch
=
1044 "switchconv", /* name */
1045 switchconv_gate
, /* gate */
1046 do_switchconv
, /* execute */
1049 0, /* static_pass_number */
1050 TV_TREE_SWITCH_CONVERSION
, /* tv_id */
1051 PROP_cfg
| PROP_ssa
, /* properties_required */
1052 0, /* properties_provided */
1053 0, /* properties_destroyed */
1054 0, /* todo_flags_start */
1055 TODO_update_ssa
| TODO_dump_func
1056 | TODO_ggc_collect
| TODO_verify_ssa
/* todo_flags_finish */