X-Git-Url: http://git.sourceforge.jp/view?a=blobdiff_plain;f=gcc%2Fstmt.c;h=64e070b5a0a707bf5d578cd0c3a0455500e445a5;hb=e551bd1a627721943b25c270a38b7f3e7df8f647;hp=bb17fa2e4e6551f50d3ed8471f7e176fd3587525;hpb=f28dc0d7c91fb899a94c245007e4482dacd1fcf5;p=pf3gnuchains%2Fgcc-fork.git diff --git a/gcc/stmt.c b/gcc/stmt.c index bb17fa2e4e6..64e070b5a0a 100644 --- a/gcc/stmt.c +++ b/gcc/stmt.c @@ -1,6 +1,7 @@ /* Expands front end tree to back end RTL for GCC Copyright (C) 1987, 1988, 1989, 1992, 1993, 1994, 1995, 1996, 1997, - 1998, 1999, 2000, 2001, 2002, 2003, 2004 Free Software Foundation, Inc. + 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005 + Free Software Foundation, Inc. This file is part of GCC. @@ -110,7 +111,6 @@ static bool check_operand_nalternatives (tree, tree); static bool check_unique_operand_names (tree, tree); static char *resolve_operand_name_1 (char *, tree, tree); static void expand_null_return_1 (void); -static rtx shift_return_value (rtx); static void expand_value_return (rtx); static void do_jump_if_equal (rtx, rtx, rtx, int); static int estimate_case_costs (case_node_ptr); @@ -260,7 +260,7 @@ n_occurrences (int c, const char *s) or an ADDR_EXPR containing a STRING_CST. VOL nonzero means the insn is volatile; don't optimize it. */ -void +static void expand_asm (tree string, int vol) { rtx body; @@ -611,7 +611,7 @@ decl_conflicts_with_clobbers_p (tree decl, const HARD_REG_SET clobbered_regs) VOL nonzero means the insn is volatile; don't optimize it. */ -void +static void expand_asm_operands (tree string, tree outputs, tree inputs, tree clobbers, int vol, location_t locus) { @@ -1500,33 +1500,6 @@ expand_naked_return (void) emit_jump (end_label); } -/* If the current function returns values in the most significant part - of a register, shift return value VAL appropriately. The mode of - the function's return type is known not to be BLKmode. */ - -static rtx -shift_return_value (rtx val) -{ - tree type; - - type = TREE_TYPE (DECL_RESULT (current_function_decl)); - if (targetm.calls.return_in_msb (type)) - { - rtx target; - HOST_WIDE_INT shift; - - target = DECL_RTL (DECL_RESULT (current_function_decl)); - shift = (GET_MODE_BITSIZE (GET_MODE (target)) - - BITS_PER_UNIT * int_size_in_bytes (type)); - if (shift > 0) - val = expand_shift (LSHIFT_EXPR, GET_MODE (target), - gen_lowpart (GET_MODE (target), val), - build_int_cst (NULL_TREE, shift), target, 1); - } - return val; -} - - /* Generate RTL to return from the current function, with value VAL. */ static void @@ -1564,15 +1537,9 @@ expand_value_return (rtx val) static void expand_null_return_1 (void) { - rtx end_label; - clear_pending_stack_adjust (); do_pending_stack_adjust (); - - end_label = return_label; - if (end_label == 0) - end_label = return_label = gen_label_rtx (); - emit_jump (end_label); + emit_jump (return_label); } /* Generate RTL to evaluate the expression RETVAL and return it @@ -1743,7 +1710,7 @@ expand_return (tree retval) val = expand_expr (retval_rhs, val, GET_MODE (val), 0); val = force_not_mem (val); /* Return the calculated value. */ - expand_value_return (shift_return_value (val)); + expand_value_return (val); } else { @@ -2272,8 +2239,8 @@ emit_case_bit_tests (tree index_type, tree index_expr, tree minval, qsort (test, count, sizeof(*test), case_bit_test_cmp); index_expr = fold (build2 (MINUS_EXPR, index_type, - convert (index_type, index_expr), - convert (index_type, minval))); + fold_convert (index_type, index_expr), + fold_convert (index_type, minval))); index = expand_expr (index_expr, NULL_RTX, VOIDmode, 0); do_pending_stack_adjust (); @@ -2317,7 +2284,7 @@ expand_case (tree exp) { tree minval = NULL_TREE, maxval = NULL_TREE, range = NULL_TREE; rtx default_label = 0; - struct case_node *n, *m; + struct case_node *n; unsigned int count, uniq; rtx index; rtx table_label; @@ -2354,6 +2321,11 @@ expand_case (tree exp) if (index_type != error_mark_node) { tree elt; + bitmap label_bitmap; + + /* cleanup_tree_cfg removes all SWITCH_EXPR with their index + expressions being INTEGER_CST. */ + gcc_assert (TREE_CODE (index_expr) != INTEGER_CST); /* The default case is at the end of TREE_VEC. */ elt = TREE_VEC_ELT (vec, TREE_VEC_LENGTH (vec) - 1); @@ -2388,6 +2360,7 @@ expand_case (tree exp) uniq = 0; count = 0; + label_bitmap = BITMAP_ALLOC (NULL); for (n = case_list; n; n = n->right) { /* Count the elements and track the largest and smallest @@ -2408,20 +2381,27 @@ expand_case (tree exp) if (! tree_int_cst_equal (n->low, n->high)) count++; - /* Count the number of unique case node targets. */ - uniq++; + /* If we have not seen this label yet, then increase the + number of unique case node targets seen. */ lab = label_rtx (n->code_label); - for (m = case_list; m != n; m = m->right) - if (label_rtx (m->code_label) == lab) - { - uniq--; - break; - } + if (!bitmap_bit_p (label_bitmap, CODE_LABEL_NUMBER (lab))) + { + bitmap_set_bit (label_bitmap, CODE_LABEL_NUMBER (lab)); + uniq++; + } } + BITMAP_FREE (label_bitmap); + /* cleanup_tree_cfg removes all SWITCH_EXPR with a single - destination, such as one with a default case only. */ - gcc_assert (count != 0); + destination, such as one with a default case only. However, + it doesn't remove cases that are out of range for the switch + type, so we may still get a zero here. */ + if (count == 0) + { + emit_jump (default_label); + return; + } /* Compute span of values. */ range = fold (build2 (MINUS_EXPR, index_type, maxval, minval)); @@ -2494,58 +2474,26 @@ expand_case (tree exp) if (MEM_P (index)) index = copy_to_reg (index); - if (GET_CODE (index) == CONST_INT - || TREE_CODE (index_expr) == INTEGER_CST) - { - /* Make a tree node with the proper constant value - if we don't already have one. */ - if (TREE_CODE (index_expr) != INTEGER_CST) - { - index_expr - = build_int_cst_wide (NULL_TREE, INTVAL (index), - unsignedp || INTVAL (index) >= 0 - ? 0 : -1); - index_expr = convert (index_type, index_expr); - } - /* For constant index expressions we need only - issue an unconditional branch to the appropriate - target code. The job of removing any unreachable - code is left to the optimization phase if the - "-O" option is specified. */ - for (n = case_list; n; n = n->right) - if (! tree_int_cst_lt (index_expr, n->low) - && ! tree_int_cst_lt (n->high, index_expr)) - break; - - if (n) - emit_jump (label_rtx (n->code_label)); - else - emit_jump (default_label); - } - else - { - /* If the index expression is not constant we generate - a binary decision tree to select the appropriate - target code. This is done as follows: + /* We generate a binary decision tree to select the + appropriate target code. This is done as follows: - The list of cases is rearranged into a binary tree, - nearly optimal assuming equal probability for each case. + The list of cases is rearranged into a binary tree, + nearly optimal assuming equal probability for each case. - The tree is transformed into RTL, eliminating - redundant test conditions at the same time. + The tree is transformed into RTL, eliminating + redundant test conditions at the same time. - If program flow could reach the end of the - decision tree an unconditional jump to the - default code is emitted. */ + If program flow could reach the end of the + decision tree an unconditional jump to the + default code is emitted. */ - use_cost_table - = (TREE_CODE (orig_type) != ENUMERAL_TYPE - && estimate_case_costs (case_list)); - balance_case_nodes (&case_list, NULL); - emit_case_nodes (index, case_list, default_label, index_type); - emit_jump (default_label); - } + use_cost_table + = (TREE_CODE (orig_type) != ENUMERAL_TYPE + && estimate_case_costs (case_list)); + balance_case_nodes (&case_list, NULL); + emit_case_nodes (index, case_list, default_label, index_type); + emit_jump (default_label); } else { @@ -2612,14 +2560,8 @@ expand_case (tree exp) emit_jump_insn (gen_rtx_ADDR_VEC (CASE_VECTOR_MODE, gen_rtvec_v (ncases, labelvec))); - /* If the case insn drops through the table, - after the table we must jump to the default-label. - Otherwise record no drop-through after the table. */ -#ifdef CASE_DROPS_THROUGH - emit_jump (default_label); -#else + /* Record no drop-through after the table. */ emit_barrier (); -#endif } before_case = NEXT_INSN (before_case); @@ -2676,8 +2618,7 @@ static int estimate_case_costs (case_node_ptr node) { tree min_ascii = integer_minus_one_node; - tree max_ascii = convert (TREE_TYPE (node->high), - build_int_cst (NULL_TREE, 127)); + tree max_ascii = build_int_cst (TREE_TYPE (node->high), 127); case_node_ptr n; int i; @@ -3106,11 +3047,12 @@ emit_case_nodes (rtx index, case_node_ptr node, rtx default_label, else if (node->right != 0 && node->left == 0) { - /* Here we have a right child but no left so we issue conditional + /* Here we have a right child but no left so we issue a conditional branch to default and process the right child. - Omit the conditional branch to default if we it avoid only one - right child; it costs too much space to save so little time. */ + Omit the conditional branch to default if the right child + does not have any children and is single valued; it would + cost too much space to save so little time. */ if (node->right->right || node->right->left || !tree_int_cst_equal (node->right->low, node->right->high))