2008-07-01 10:54:18 +02:00
|
|
|
/* Switch Conversion converts variable initializations based on switch
|
|
|
|
statements to initializations from a static array.
|
2011-04-30 08:54:02 +02:00
|
|
|
Copyright (C) 2006, 2008, 2009, 2010, 2011 Free Software Foundation, Inc.
|
2008-07-01 10:54:18 +02:00
|
|
|
Contributed by Martin Jambor <jamborm@suse.cz>
|
|
|
|
|
|
|
|
This file is part of GCC.
|
|
|
|
|
|
|
|
GCC is free software; you can redistribute it and/or modify it
|
|
|
|
under the terms of the GNU General Public License as published by the
|
|
|
|
Free Software Foundation; either version 3, or (at your option) any
|
|
|
|
later version.
|
|
|
|
|
|
|
|
GCC is distributed in the hope that it will be useful, but WITHOUT
|
|
|
|
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
|
|
|
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
|
|
|
for more details.
|
|
|
|
|
|
|
|
You should have received a copy of the GNU General Public License
|
|
|
|
along with GCC; see the file COPYING3. If not, write to the Free
|
|
|
|
Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA
|
|
|
|
02110-1301, USA. */
|
|
|
|
|
|
|
|
/*
|
|
|
|
Switch initialization conversion
|
|
|
|
|
|
|
|
The following pass changes simple initializations of scalars in a switch
|
|
|
|
statement into initializations from a static array. Obviously, the values must
|
|
|
|
be constant and known at compile time and a default branch must be
|
|
|
|
provided. For example, the following code:
|
|
|
|
|
|
|
|
int a,b;
|
|
|
|
|
|
|
|
switch (argc)
|
|
|
|
{
|
|
|
|
case 1:
|
|
|
|
case 2:
|
|
|
|
a_1 = 8;
|
|
|
|
b_1 = 6;
|
|
|
|
break;
|
|
|
|
case 3:
|
|
|
|
a_2 = 9;
|
|
|
|
b_2 = 5;
|
|
|
|
break;
|
|
|
|
case 12:
|
|
|
|
a_3 = 10;
|
|
|
|
b_3 = 4;
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
a_4 = 16;
|
|
|
|
b_4 = 1;
|
|
|
|
}
|
|
|
|
a_5 = PHI <a_1, a_2, a_3, a_4>
|
|
|
|
b_5 = PHI <b_1, b_2, b_3, b_4>
|
|
|
|
|
|
|
|
|
|
|
|
is changed into:
|
|
|
|
|
|
|
|
static const int = CSWTCH01[] = {6, 6, 5, 1, 1, 1, 1, 1, 1, 1, 1, 4};
|
|
|
|
static const int = CSWTCH02[] = {8, 8, 9, 16, 16, 16, 16, 16, 16, 16,
|
|
|
|
16, 16, 10};
|
|
|
|
|
|
|
|
if (((unsigned) argc) - 1 < 11)
|
|
|
|
{
|
|
|
|
a_6 = CSWTCH02[argc - 1];
|
|
|
|
b_6 = CSWTCH01[argc - 1];
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
a_7 = 16;
|
|
|
|
b_7 = 1;
|
|
|
|
}
|
|
|
|
a_5 = PHI <a_6, a_7>
|
|
|
|
b_b = PHI <b_6, b_7>
|
|
|
|
|
|
|
|
There are further constraints. Specifically, the range of values across all
|
|
|
|
case labels must not be bigger than SWITCH_CONVERSION_BRANCH_RATIO (default
|
|
|
|
eight) times the number of the actual switch branches. */
|
|
|
|
|
|
|
|
#include "config.h"
|
|
|
|
#include "system.h"
|
|
|
|
#include "coretypes.h"
|
|
|
|
#include "tm.h"
|
|
|
|
#include "line-map.h"
|
|
|
|
#include "params.h"
|
|
|
|
#include "flags.h"
|
|
|
|
#include "tree.h"
|
|
|
|
#include "basic-block.h"
|
|
|
|
#include "tree-flow.h"
|
|
|
|
#include "tree-flow-inline.h"
|
|
|
|
#include "tree-ssa-operands.h"
|
|
|
|
#include "output.h"
|
|
|
|
#include "input.h"
|
|
|
|
#include "tree-pass.h"
|
diagnostic.c: Don't include tm.h, tree.h, tm_p.h, langhooks.h or langhooks-def.h.
* diagnostic.c: Don't include tm.h, tree.h, tm_p.h, langhooks.h or
langhooks-def.h.
(diagnostic_initialize): Initialize x_data not last_function.
(diagnostic_report_current_function): Move to tree-diagnostic.c.
(default_diagnostic_starter): Call
diagnostic_report_current_module not
diagnostic_report_current_function.
(diagnostic_report_diagnostic): Initialize x_data not
abstract_origin.
(verbatim): Likewise.
* diagnostic.h (struct diagnostic_info): Change abstract_origin to
x_data.
(struct diagnostic_context): Change last_function to x_data.
(diagnostic_auxiliary_data): Replace with
diagnostic_context_auxiliary_data and
diagnostic_info_auxiliary_data.
(diagnostic_last_function_changed, diagnostic_set_last_function,
diagnostic_report_current_function): Move to tree-diagnostic.h.
(print_declaration, dump_generic_node, print_generic_stmt,
print_generic_stmt_indented, print_generic_expr,
print_generic_decl, debug_c_tree, dump_omp_clauses,
print_call_name, debug_generic_expr, debug_generic_stmt,
debug_tree_chain, default_tree_printer): Move to
tree-pretty-print.h.
(debug_gimple_stmt, debug_gimple_seq, print_gimple_seq,
print_gimple_stmt, print_gimple_expr, dump_gimple_stmt): Move to
gimple-pretty-print.h.
* pretty-print.c: Don't include tree.h
(pp_base_format): Don't handle %K here.
(pp_base_tree_identifier): Move to tree-pretty-print.c.
* pretty-print.h (text_info): Change abstract_origin to x_data.
(pp_tree_identifier, pp_unsupported_tree,
pp_base_tree_identifier): Move to tree-pretty-print.h.
* gimple-pretty-print.h, tree-diagnostic.c, tree-diagnostic.h,
tree-pretty-print.h: New files.
* tree-pretty-print.c: Include tree-pretty-print.h.
(percent_K_format): New. Moved from pretty-print.c.
(pp_base_tree_identifier): Move from pretty-print.c.
* c-objc-common.c: Include tree-pretty-print.h.
(c_tree_printer): Handle %K here.
* langhooks.c: Include tree-diagnostic.h.
(lhd_print_error_function): Use diagnostic_abstract_origin macro.
* toplev.c: Include tree-diagnostic.h and tree-pretty-print.h.
(default_tree_printer): Handle %K using percent_K_format.
(general_init): Use default_tree_diagnostic_starter.
* tree.c: Include tree-diagnostic.h and tree-pretty-print.h.
(free_lang_data): Use default_tree_diagnostic_starter.
* c-pretty-print.c: Include tree-pretty-print.h.
* cfgexpand.c: Include tree-pretty-print.h and
gimple-pretty-print.h.
* cgraphunit.c: Include tree-pretty-print.h and
gimple-pretty-print.h.
* dwarf2out.c: Include tree-pretty-print.h.
* except.c: Include tree-pretty-print.h.
* gimple-pretty-print.c: Include tree-pretty-print.h and
gimple-pretty-print.h.
* gimplify.c: Include tree-pretty-print.h.
* graphite-poly.c: Include tree-pretty-print.h and
gimple-pretty-print.h.
* ipa-cp.c: Include tree-pretty-print.h.
* ipa-inline.c: Include gimple-pretty-print.h.
* ipa-prop.c: Include tree-pretty-print.h and
gimple-pretty-print.h.
* ipa-pure-const.c: Include gimple-pretty-print.h.
* ipa-struct-reorg.c: Include tree-pretty-print.h and
gimple-pretty-print.h.
* ipa-type-escape.c: Include tree-pretty-print.h.
* print-rtl.c: Include tree-pretty-print.h.
* print-tree.c: Include gimple-pretty-print.h.
* sese.c: Include tree-pretty-print.h.
* tree-affine.c: Include tree-pretty-print.h.
* tree-browser.c: Include tree-pretty-print.h.
* tree-call-cdce.c: Include gimple-pretty-print.h.
* tree-cfg.c: Include tree-pretty-print.h and
gimple-pretty-print.h.
* tree-chrec.c: Include tree-pretty-print.h.
* tree-data-ref.c: Include tree-pretty-print.h and
gimple-pretty-print.h.
* tree-dfa.c: Include tree-pretty-print.h.
* tree-if-conv.c: Include tree-pretty-print.h and
gimple-pretty-print.h.
* tree-inline.c: Include tree-pretty-print.h.
* tree-into-ssa.c: Include tree-pretty-print.h and
gimple-pretty-print.h.
* tree-nrv.c: Include tree-pretty-print.h.
* tree-object-size.c: Include tree-pretty-print.h and
gimple-pretty-print.h.
* tree-outof-ssa.c: Include tree-pretty-print.h and
gimple-pretty-print.h.
* tree-parloops.c: Include tree-pretty-print.h and
gimple-pretty-print.h.
* tree-predcom.c: Include tree-pretty-print.h and
gimple-pretty-print.h.
* tree-scalar-evolution.c: Include tree-pretty-print.h and
gimple-pretty-print.h.
* tree-sra.c: Include tree-pretty-print.h.
* tree-ssa-address.c: Include tree-pretty-print.h.
* tree-ssa-alias.c: Include tree-pretty-print.h.
* tree-ssa-ccp.c: Include tree-pretty-print.h and
gimple-pretty-print.h.
* tree-ssa-coalesce.c: Include tree-pretty-print.h.
* tree-ssa-copy.c: Include tree-pretty-print.h and
gimple-pretty-print.h.
* tree-ssa-copyrename.c: Include tree-pretty-print.h.
* tree-ssa-dce.c: Include tree-pretty-print.h and
gimple-pretty-print.h.
* tree-ssa-dom.c: Include tree-pretty-print.h and
gimple-pretty-print.h.
* tree-ssa-dse.c: Include gimple-pretty-print.h.
* tree-ssa-forwprop.c: Include tree-pretty-print.h.
* tree-ssa-ifcombine.c: Include tree-pretty-print.h.
* tree-ssa-live.c: Include tree-pretty-print.h and
gimple-pretty-print.h.
* tree-ssa-loop-im.c: Include tree-pretty-print.h and
gimple-pretty-print.h.
* tree-ssa-loop-ivcanon.c: Include tree-pretty-print.h and
gimple-pretty-print.h.
* tree-ssa-loop-ivopts.c: Include tree-pretty-print.h and
gimple-pretty-print.h.
* tree-ssa-loop-niter.c: Include tree-pretty-print.h and
gimple-pretty-print.h.
* tree-ssa-loop-prefetch.c: Include tree-pretty-print.h.
* tree-ssa-math-opts.c: Include gimple-pretty-print.h.
* tree-ssa-operands.c: Include tree-pretty-print.h and
gimple-pretty-print.h.
* tree-ssa-phiprop.c: Include tree-pretty-print.h and
gimple-pretty-print.h.
* tree-ssa-pre.c: Include tree-pretty-print.h and
gimple-pretty-print.h.
* tree-ssa-propagate.c: Include gimple-pretty-print.h.
* tree-ssa-reassoc.c: Include tree-pretty-print.h and
gimple-pretty-print.h.
* tree-ssa-sccvn.c: Include tree-pretty-print.h and
gimple-pretty-print.h.
* tree-ssa-sink.c: Include gimple-pretty-print.h.
* tree-ssa-ter.c: Include tree-pretty-print.h and
gimple-pretty-print.h.
* tree-ssa-uninit.c: Include gimple-pretty-print.h.
* tree-ssa.c: Include tree-pretty-print.h and
gimple-pretty-print.h.
* tree-stdarg.c: Include gimple-pretty-print.h.
* tree-switch-conversion.c: Include gimple-pretty-print.h.
* tree-tailcall.c: Include tree-pretty-print.h and
gimple-pretty-print.h.
* tree-vect-data-refs.c: Include tree-pretty-print.h and
gimple-pretty-print.h.
* tree-vect-loop-manip.c: Include tree-pretty-print.h and
gimple-pretty-print.h.
* tree-vect-loop.c: Include tree-pretty-print.h and
gimple-pretty-print.h.
* tree-vect-patterns.c: Include gimple-pretty-print.h.
* tree-vect-slp.c: Include tree-pretty-print.h and
gimple-pretty-print.h.
* tree-vect-stmts.c: Include tree-pretty-print.h and
gimple-pretty-print.h.
* tree-vectorizer.c: Include tree-pretty-print.h.
* tree-vrp.c: Include tree-pretty-print.h and
gimple-pretty-print.h.
* value-prof.c: Include tree-pretty-print.h and
gimple-pretty-print.h.
* var-tracking.c: Include tree-pretty-print.h.
* Makefile.in (OBJS-common): Add tree-diagnostic.o.
(tree-diagnostic.o): New dependencies.
(c-objc-common.o, c-pretty-print.o, langhooks.o, tree.o,
tree-inline.o, print-tree.o, stor-layout.o, tree-ssa-uninit.o,
tree-ssa.o, tree-into-ssa.o, tree-ssa-ter.o, tree-ssa-coalesce.o,
tree-outof-ssa.o, tree-ssa-forwprop.o, tree-ssa-phiprop.o,
tree-ssa-ifcombine.o, tree-nrv.o, tree-ssa-copy.o,
tree-ssa-propagate.o, tree-ssa-dom.o, tree-ssa-uncprop.o,
tree-ssa-live.o, tree-ssa-copyrename.o, tree-ssa-pre.o,
tree-ssa-sccvn.o, tree-vrp.o, tree-cfg.o, tree-tailcall.o,
tree-ssa-sink.o, tree-if-conv.o, tree-dfa.o, tree-ssa-operands.o,
tree-ssa-address.o, tree-ssa-loop-niter.o,
tree-ssa-loop-ivcanon.o, tree-ssa-loop-prefetch.o, tree-predcom.o,
tree-ssa-loop-ivopts.o, tree-affine.o, tree-ssa-loop-im.o,
tree-ssa-math-opts.o, tree-ssa-alias.o, tree-ssa-reassoc.o,
gimplify.o, tree-browser.o, tree-chrec.o, tree-scalar-evolution.o,
tree-data-ref.o, sese.o, graphite-poly.o, tree-vect-loop.o,
tree-vect-loop-manip.o, tree-vect-patterns.o, tree-vect-slp.o,
tree-vect-stmts.o, tree-vect-data-refs.o, tree-vectorizer.o,
tree-parloops.o, tree-stdarg.o, tree-object-size.o,
gimple-pretty-print.o, tree-pretty-print.o, diagnostic.o,
toplev.o, print-rtl.o, except.o, dwarf2out.o, cgraphunit.o,
ipa-prop.o, ipa-cp.o, ipa-inline.o, ipa-pure-const.o,
ipa-type-escape.o, ipa-struct-reorg.o, tree-ssa-dce.o,
tree-call-cdce.o, tree-ssa-ccp.o, tree-sra.o,
tree-switch-conversion.o, var-tracking.o, value-prof.o,
cfgexpand.o, pretty-print.o): Update dependencies.
cp:
* error.c: Include tree-diagnostic.h and tree-pretty-print.h.
(cp_print_error_function): Use diagnostic_abstract_origin macro.
(cp_printer): Handle %K here using percent_K_format.
* cxx-pretty-print.c: Include tree-pretty-print.h.
* Make-lang.in (cp/error.o, cp/cxx-pretty-print.o): Update
dependencies.
From-SVN: r159685
2010-05-22 00:34:26 +02:00
|
|
|
#include "gimple-pretty-print.h"
|
2008-07-01 10:54:18 +02:00
|
|
|
#include "tree-dump.h"
|
2008-07-02 12:37:02 +02:00
|
|
|
#include "timevar.h"
|
2010-08-19 10:12:31 +02:00
|
|
|
#include "langhooks.h"
|
2008-07-01 10:54:18 +02:00
|
|
|
|
|
|
|
/* The main structure of the pass. */
|
|
|
|
struct switch_conv_info
|
|
|
|
{
|
|
|
|
/* The expression used to decide the switch branch. (It is subsequently used
|
|
|
|
as the index to the created array.) */
|
|
|
|
tree index_expr;
|
|
|
|
|
|
|
|
/* The following integer constants store the minimum value covered by the
|
|
|
|
cases. */
|
|
|
|
tree range_min;
|
|
|
|
|
2008-07-02 11:47:09 +02:00
|
|
|
/* The difference between the above two numbers, i.e. The size of the array
|
2008-07-01 10:54:18 +02:00
|
|
|
that would have to be created by the transformation. */
|
|
|
|
tree range_size;
|
|
|
|
|
|
|
|
/* Basic block that contains the actual SWITCH_EXPR. */
|
|
|
|
basic_block switch_bb;
|
|
|
|
|
|
|
|
/* All branches of the switch statement must have a single successor stored in
|
|
|
|
the following variable. */
|
|
|
|
basic_block final_bb;
|
|
|
|
|
|
|
|
/* Number of phi nodes in the final bb (that we'll be replacing). */
|
|
|
|
int phi_count;
|
|
|
|
|
2008-07-02 11:47:09 +02:00
|
|
|
/* Array of default values, in the same order as phi nodes. */
|
2008-07-01 10:54:18 +02:00
|
|
|
tree *default_values;
|
|
|
|
|
|
|
|
/* Constructors of new static arrays. */
|
|
|
|
VEC (constructor_elt, gc) **constructors;
|
|
|
|
|
|
|
|
/* Array of ssa names that are initialized with a value from a new static
|
|
|
|
array. */
|
|
|
|
tree *target_inbound_names;
|
|
|
|
|
|
|
|
/* Array of ssa names that are initialized with the default value if the
|
|
|
|
switch expression is out of range. */
|
|
|
|
tree *target_outbound_names;
|
|
|
|
|
|
|
|
/* The probability of the default edge in the replaced switch. */
|
|
|
|
int default_prob;
|
|
|
|
|
|
|
|
/* The count of the default edge in the replaced switch. */
|
|
|
|
gcov_type default_count;
|
|
|
|
|
|
|
|
/* Combined count of all other (non-default) edges in the replaced switch. */
|
|
|
|
gcov_type other_count;
|
|
|
|
|
2008-07-02 11:47:09 +02:00
|
|
|
/* The first load statement that loads a temporary from a new static array.
|
|
|
|
*/
|
2008-07-28 16:33:56 +02:00
|
|
|
gimple arr_ref_first;
|
2008-07-01 10:54:18 +02:00
|
|
|
|
|
|
|
/* The last load statement that loads a temporary from a new static array. */
|
2008-07-28 16:33:56 +02:00
|
|
|
gimple arr_ref_last;
|
2008-07-01 10:54:18 +02:00
|
|
|
|
|
|
|
/* String reason why the case wasn't a good candidate that is written to the
|
|
|
|
dump file, if there is one. */
|
|
|
|
const char *reason;
|
2010-11-20 00:48:57 +01:00
|
|
|
|
|
|
|
/* Parameters for expand_switch_using_bit_tests. Should be computed
|
|
|
|
the same way as in expand_case. */
|
|
|
|
unsigned int bit_test_uniq;
|
|
|
|
unsigned int bit_test_count;
|
|
|
|
basic_block bit_test_bb[2];
|
2008-07-01 10:54:18 +02:00
|
|
|
};
|
|
|
|
|
|
|
|
/* Global pass info. */
|
|
|
|
static struct switch_conv_info info;
|
|
|
|
|
|
|
|
|
|
|
|
/* Checks whether the range given by individual case statements of the SWTCH
|
|
|
|
switch statement isn't too big and whether the number of branches actually
|
|
|
|
satisfies the size of the new array. */
|
|
|
|
|
|
|
|
static bool
|
2008-07-28 16:33:56 +02:00
|
|
|
check_range (gimple swtch)
|
2008-07-01 10:54:18 +02:00
|
|
|
{
|
|
|
|
tree min_case, max_case;
|
2008-07-28 16:33:56 +02:00
|
|
|
unsigned int branch_num = gimple_switch_num_labels (swtch);
|
2008-07-01 10:54:18 +02:00
|
|
|
tree range_max;
|
|
|
|
|
|
|
|
/* The gimplifier has already sorted the cases by CASE_LOW and ensured there
|
2010-11-20 00:48:57 +01:00
|
|
|
is a default label which is the first in the vector. */
|
2008-07-01 10:54:18 +02:00
|
|
|
|
2008-07-28 16:33:56 +02:00
|
|
|
min_case = gimple_switch_label (swtch, 1);
|
2008-07-01 10:54:18 +02:00
|
|
|
info.range_min = CASE_LOW (min_case);
|
|
|
|
|
|
|
|
gcc_assert (branch_num > 1);
|
2008-07-28 16:33:56 +02:00
|
|
|
gcc_assert (CASE_LOW (gimple_switch_label (swtch, 0)) == NULL_TREE);
|
|
|
|
max_case = gimple_switch_label (swtch, branch_num - 1);
|
2008-07-01 10:54:18 +02:00
|
|
|
if (CASE_HIGH (max_case) != NULL_TREE)
|
|
|
|
range_max = CASE_HIGH (max_case);
|
|
|
|
else
|
|
|
|
range_max = CASE_LOW (max_case);
|
|
|
|
|
|
|
|
gcc_assert (info.range_min);
|
|
|
|
gcc_assert (range_max);
|
|
|
|
|
2011-05-04 11:04:53 +02:00
|
|
|
info.range_size = int_const_binop (MINUS_EXPR, range_max, info.range_min);
|
2008-07-01 10:54:18 +02:00
|
|
|
|
|
|
|
gcc_assert (info.range_size);
|
|
|
|
if (!host_integerp (info.range_size, 1))
|
|
|
|
{
|
|
|
|
info.reason = "index range way too large or otherwise unusable.\n";
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
if ((unsigned HOST_WIDE_INT) tree_low_cst (info.range_size, 1)
|
|
|
|
> ((unsigned) branch_num * SWITCH_CONVERSION_BRANCH_RATIO))
|
|
|
|
{
|
|
|
|
info.reason = "the maximum range-branch ratio exceeded.\n";
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Checks the given CS switch case whether it is suitable for conversion
|
|
|
|
(whether all but the default basic blocks are empty and so on). If it is,
|
|
|
|
adds the case to the branch list along with values for the defined variables
|
|
|
|
and returns true. Otherwise returns false. */
|
|
|
|
|
|
|
|
static bool
|
|
|
|
check_process_case (tree cs)
|
|
|
|
{
|
|
|
|
tree ldecl;
|
|
|
|
basic_block label_bb, following_bb;
|
|
|
|
edge e;
|
|
|
|
|
|
|
|
ldecl = CASE_LABEL (cs);
|
|
|
|
label_bb = label_to_block (ldecl);
|
|
|
|
|
|
|
|
e = find_edge (info.switch_bb, label_bb);
|
|
|
|
gcc_assert (e);
|
|
|
|
|
|
|
|
if (CASE_LOW (cs) == NULL_TREE)
|
|
|
|
{
|
|
|
|
/* Default branch. */
|
|
|
|
info.default_prob = e->probability;
|
|
|
|
info.default_count = e->count;
|
|
|
|
}
|
|
|
|
else
|
2010-11-20 00:48:57 +01:00
|
|
|
{
|
|
|
|
int i;
|
|
|
|
info.other_count += e->count;
|
|
|
|
for (i = 0; i < 2; i++)
|
|
|
|
if (info.bit_test_bb[i] == label_bb)
|
|
|
|
break;
|
|
|
|
else if (info.bit_test_bb[i] == NULL)
|
|
|
|
{
|
|
|
|
info.bit_test_bb[i] = label_bb;
|
|
|
|
info.bit_test_uniq++;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
if (i == 2)
|
|
|
|
info.bit_test_uniq = 3;
|
|
|
|
if (CASE_HIGH (cs) != NULL_TREE
|
|
|
|
&& ! tree_int_cst_equal (CASE_LOW (cs), CASE_HIGH (cs)))
|
|
|
|
info.bit_test_count += 2;
|
|
|
|
else
|
|
|
|
info.bit_test_count++;
|
|
|
|
}
|
2008-07-01 10:54:18 +02:00
|
|
|
|
|
|
|
if (!label_bb)
|
|
|
|
{
|
|
|
|
info.reason = " Bad case - cs BB label is NULL\n";
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (!single_pred_p (label_bb))
|
|
|
|
{
|
|
|
|
if (info.final_bb && info.final_bb != label_bb)
|
|
|
|
{
|
|
|
|
info.reason = " Bad case - a non-final BB has two predecessors\n";
|
|
|
|
return false; /* sth complex going on in this branch */
|
|
|
|
}
|
|
|
|
|
|
|
|
following_bb = label_bb;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
if (!empty_block_p (label_bb))
|
|
|
|
{
|
|
|
|
info.reason = " Bad case - a non-final BB not empty\n";
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
e = single_succ_edge (label_bb);
|
|
|
|
following_bb = single_succ (label_bb);
|
|
|
|
}
|
|
|
|
|
|
|
|
if (!info.final_bb)
|
|
|
|
info.final_bb = following_bb;
|
|
|
|
else if (info.final_bb != following_bb)
|
|
|
|
{
|
|
|
|
info.reason = " Bad case - different final BB\n";
|
|
|
|
return false; /* the only successor is not common for all the branches */
|
|
|
|
}
|
|
|
|
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* This function checks whether all required values in phi nodes in final_bb
|
|
|
|
are constants. Required values are those that correspond to a basic block
|
|
|
|
which is a part of the examined switch statement. It returns true if the
|
|
|
|
phi nodes are OK, otherwise false. */
|
|
|
|
|
|
|
|
static bool
|
|
|
|
check_final_bb (void)
|
|
|
|
{
|
2008-07-28 16:33:56 +02:00
|
|
|
gimple_stmt_iterator gsi;
|
2008-07-01 10:54:18 +02:00
|
|
|
|
|
|
|
info.phi_count = 0;
|
2008-07-28 16:33:56 +02:00
|
|
|
for (gsi = gsi_start_phis (info.final_bb); !gsi_end_p (gsi); gsi_next (&gsi))
|
2008-07-01 10:54:18 +02:00
|
|
|
{
|
2008-07-28 16:33:56 +02:00
|
|
|
gimple phi = gsi_stmt (gsi);
|
|
|
|
unsigned int i;
|
2008-07-01 10:54:18 +02:00
|
|
|
|
|
|
|
info.phi_count++;
|
|
|
|
|
2008-07-28 16:33:56 +02:00
|
|
|
for (i = 0; i < gimple_phi_num_args (phi); i++)
|
2008-07-01 10:54:18 +02:00
|
|
|
{
|
2008-07-28 16:33:56 +02:00
|
|
|
basic_block bb = gimple_phi_arg_edge (phi, i)->src;
|
2008-07-01 10:54:18 +02:00
|
|
|
|
2008-10-15 08:43:19 +02:00
|
|
|
if (bb == info.switch_bb
|
|
|
|
|| (single_pred_p (bb) && single_pred (bb) == info.switch_bb))
|
2008-07-01 10:54:18 +02:00
|
|
|
{
|
2008-10-15 08:43:19 +02:00
|
|
|
tree reloc, val;
|
|
|
|
|
|
|
|
val = gimple_phi_arg_def (phi, i);
|
|
|
|
if (!is_gimple_ip_invariant (val))
|
|
|
|
{
|
|
|
|
info.reason = " Non-invariant value from a case\n";
|
|
|
|
return false; /* Non-invariant argument. */
|
|
|
|
}
|
|
|
|
reloc = initializer_constant_valid_p (val, TREE_TYPE (val));
|
|
|
|
if ((flag_pic && reloc != null_pointer_node)
|
|
|
|
|| (!flag_pic && reloc == NULL_TREE))
|
|
|
|
{
|
|
|
|
if (reloc)
|
|
|
|
info.reason
|
|
|
|
= " Value from a case would need runtime relocations\n";
|
|
|
|
else
|
|
|
|
info.reason
|
|
|
|
= " Value from a case is not a valid initializer\n";
|
|
|
|
return false;
|
|
|
|
}
|
2008-07-01 10:54:18 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* The following function allocates default_values, target_{in,out}_names and
|
|
|
|
constructors arrays. The last one is also populated with pointers to
|
|
|
|
vectors that will become constructors of new arrays. */
|
|
|
|
|
|
|
|
static void
|
|
|
|
create_temp_arrays (void)
|
|
|
|
{
|
|
|
|
int i;
|
|
|
|
|
2010-11-20 00:48:57 +01:00
|
|
|
info.default_values = XCNEWVEC (tree, info.phi_count * 3);
|
|
|
|
info.constructors = XCNEWVEC (VEC (constructor_elt, gc) *, info.phi_count);
|
|
|
|
info.target_inbound_names = info.default_values + info.phi_count;
|
|
|
|
info.target_outbound_names = info.target_inbound_names + info.phi_count;
|
2008-07-01 10:54:18 +02:00
|
|
|
for (i = 0; i < info.phi_count; i++)
|
2008-07-28 16:33:56 +02:00
|
|
|
info.constructors[i]
|
|
|
|
= VEC_alloc (constructor_elt, gc, tree_low_cst (info.range_size, 1) + 1);
|
2008-07-01 10:54:18 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
/* Free the arrays created by create_temp_arrays(). The vectors that are
|
|
|
|
created by that function are not freed here, however, because they have
|
|
|
|
already become constructors and must be preserved. */
|
|
|
|
|
|
|
|
static void
|
|
|
|
free_temp_arrays (void)
|
|
|
|
{
|
2010-11-20 00:48:57 +01:00
|
|
|
XDELETEVEC (info.constructors);
|
|
|
|
XDELETEVEC (info.default_values);
|
2008-07-01 10:54:18 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
/* Populate the array of default values in the order of phi nodes.
|
|
|
|
DEFAULT_CASE is the CASE_LABEL_EXPR for the default switch branch. */
|
|
|
|
|
|
|
|
static void
|
|
|
|
gather_default_values (tree default_case)
|
|
|
|
{
|
2008-07-28 16:33:56 +02:00
|
|
|
gimple_stmt_iterator gsi;
|
2008-07-01 10:54:18 +02:00
|
|
|
basic_block bb = label_to_block (CASE_LABEL (default_case));
|
|
|
|
edge e;
|
2008-07-28 16:33:56 +02:00
|
|
|
int i = 0;
|
2008-07-01 10:54:18 +02:00
|
|
|
|
|
|
|
gcc_assert (CASE_LOW (default_case) == NULL_TREE);
|
|
|
|
|
|
|
|
if (bb == info.final_bb)
|
|
|
|
e = find_edge (info.switch_bb, bb);
|
|
|
|
else
|
|
|
|
e = single_succ_edge (bb);
|
|
|
|
|
2008-07-28 16:33:56 +02:00
|
|
|
for (gsi = gsi_start_phis (info.final_bb); !gsi_end_p (gsi); gsi_next (&gsi))
|
2008-07-01 10:54:18 +02:00
|
|
|
{
|
2008-07-28 16:33:56 +02:00
|
|
|
gimple phi = gsi_stmt (gsi);
|
2008-07-01 10:54:18 +02:00
|
|
|
tree val = PHI_ARG_DEF_FROM_EDGE (phi, e);
|
|
|
|
gcc_assert (val);
|
2008-07-28 16:33:56 +02:00
|
|
|
info.default_values[i++] = val;
|
2008-07-01 10:54:18 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/* The following function populates the vectors in the constructors array with
|
|
|
|
future contents of the static arrays. The vectors are populated in the
|
|
|
|
order of phi nodes. SWTCH is the switch statement being converted. */
|
|
|
|
|
|
|
|
static void
|
2008-07-28 16:33:56 +02:00
|
|
|
build_constructors (gimple swtch)
|
2008-07-01 10:54:18 +02:00
|
|
|
{
|
2008-07-28 16:33:56 +02:00
|
|
|
unsigned i, branch_num = gimple_switch_num_labels (swtch);
|
2008-07-01 10:54:18 +02:00
|
|
|
tree pos = info.range_min;
|
|
|
|
|
2008-07-28 16:33:56 +02:00
|
|
|
for (i = 1; i < branch_num; i++)
|
2008-07-01 10:54:18 +02:00
|
|
|
{
|
2008-07-28 16:33:56 +02:00
|
|
|
tree cs = gimple_switch_label (swtch, i);
|
2008-07-01 10:54:18 +02:00
|
|
|
basic_block bb = label_to_block (CASE_LABEL (cs));
|
|
|
|
edge e;
|
2008-07-28 16:33:56 +02:00
|
|
|
tree high;
|
|
|
|
gimple_stmt_iterator gsi;
|
2008-07-01 10:54:18 +02:00
|
|
|
int j;
|
|
|
|
|
|
|
|
if (bb == info.final_bb)
|
|
|
|
e = find_edge (info.switch_bb, bb);
|
|
|
|
else
|
|
|
|
e = single_succ_edge (bb);
|
|
|
|
gcc_assert (e);
|
|
|
|
|
|
|
|
while (tree_int_cst_lt (pos, CASE_LOW (cs)))
|
|
|
|
{
|
|
|
|
int k;
|
|
|
|
for (k = 0; k < info.phi_count; k++)
|
|
|
|
{
|
|
|
|
constructor_elt *elt;
|
|
|
|
|
|
|
|
elt = VEC_quick_push (constructor_elt,
|
|
|
|
info.constructors[k], NULL);
|
2008-07-28 16:33:56 +02:00
|
|
|
elt->index = int_const_binop (MINUS_EXPR, pos,
|
2011-05-04 11:04:53 +02:00
|
|
|
info.range_min);
|
2008-07-01 10:54:18 +02:00
|
|
|
elt->value = info.default_values[k];
|
|
|
|
}
|
|
|
|
|
2011-05-04 11:04:53 +02:00
|
|
|
pos = int_const_binop (PLUS_EXPR, pos, integer_one_node);
|
2008-07-01 10:54:18 +02:00
|
|
|
}
|
2008-07-02 11:47:09 +02:00
|
|
|
gcc_assert (tree_int_cst_equal (pos, CASE_LOW (cs)));
|
2008-07-01 10:54:18 +02:00
|
|
|
|
|
|
|
j = 0;
|
|
|
|
if (CASE_HIGH (cs))
|
|
|
|
high = CASE_HIGH (cs);
|
|
|
|
else
|
2008-07-02 11:47:09 +02:00
|
|
|
high = CASE_LOW (cs);
|
2008-07-28 16:33:56 +02:00
|
|
|
for (gsi = gsi_start_phis (info.final_bb);
|
|
|
|
!gsi_end_p (gsi); gsi_next (&gsi))
|
2008-07-01 10:54:18 +02:00
|
|
|
{
|
2008-07-28 16:33:56 +02:00
|
|
|
gimple phi = gsi_stmt (gsi);
|
2008-07-01 10:54:18 +02:00
|
|
|
tree val = PHI_ARG_DEF_FROM_EDGE (phi, e);
|
2008-12-30 17:27:29 +01:00
|
|
|
tree low = CASE_LOW (cs);
|
2008-07-01 10:54:18 +02:00
|
|
|
pos = CASE_LOW (cs);
|
|
|
|
|
2009-11-25 11:55:54 +01:00
|
|
|
do
|
2008-07-01 10:54:18 +02:00
|
|
|
{
|
|
|
|
constructor_elt *elt;
|
|
|
|
|
|
|
|
elt = VEC_quick_push (constructor_elt,
|
|
|
|
info.constructors[j], NULL);
|
2011-05-04 11:04:53 +02:00
|
|
|
elt->index = int_const_binop (MINUS_EXPR, pos, info.range_min);
|
2008-07-01 10:54:18 +02:00
|
|
|
elt->value = val;
|
|
|
|
|
2011-05-04 11:04:53 +02:00
|
|
|
pos = int_const_binop (PLUS_EXPR, pos, integer_one_node);
|
2009-04-21 13:55:41 +02:00
|
|
|
} while (!tree_int_cst_lt (high, pos)
|
|
|
|
&& tree_int_cst_lt (low, pos));
|
2008-07-01 10:54:18 +02:00
|
|
|
j++;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2009-04-21 13:55:41 +02:00
|
|
|
/* If all values in the constructor vector are the same, return the value.
|
|
|
|
Otherwise return NULL_TREE. Not supposed to be called for empty
|
|
|
|
vectors. */
|
|
|
|
|
|
|
|
static tree
|
|
|
|
constructor_contains_same_values_p (VEC (constructor_elt, gc) *vec)
|
|
|
|
{
|
2010-11-20 00:48:57 +01:00
|
|
|
unsigned int i;
|
2009-04-21 13:55:41 +02:00
|
|
|
tree prev = NULL_TREE;
|
2010-11-20 00:48:57 +01:00
|
|
|
constructor_elt *elt;
|
2009-04-21 13:55:41 +02:00
|
|
|
|
2010-11-20 00:48:57 +01:00
|
|
|
FOR_EACH_VEC_ELT (constructor_elt, vec, i, elt)
|
2009-04-21 13:55:41 +02:00
|
|
|
{
|
|
|
|
if (!prev)
|
|
|
|
prev = elt->value;
|
|
|
|
else if (!operand_equal_p (elt->value, prev, OEP_ONLY_CONST))
|
|
|
|
return NULL_TREE;
|
|
|
|
}
|
|
|
|
return prev;
|
|
|
|
}
|
|
|
|
|
2010-11-20 00:48:57 +01:00
|
|
|
/* Return type which should be used for array elements, either TYPE,
|
|
|
|
or for integral type some smaller integral type that can still hold
|
|
|
|
all the constants. */
|
|
|
|
|
|
|
|
static tree
|
|
|
|
array_value_type (gimple swtch, tree type, int num)
|
|
|
|
{
|
|
|
|
unsigned int i, len = VEC_length (constructor_elt, info.constructors[num]);
|
|
|
|
constructor_elt *elt;
|
|
|
|
enum machine_mode mode;
|
|
|
|
int sign = 0;
|
|
|
|
tree smaller_type;
|
|
|
|
|
|
|
|
if (!INTEGRAL_TYPE_P (type))
|
|
|
|
return type;
|
|
|
|
|
|
|
|
mode = GET_CLASS_NARROWEST_MODE (GET_MODE_CLASS (TYPE_MODE (type)));
|
|
|
|
if (GET_MODE_SIZE (TYPE_MODE (type)) <= GET_MODE_SIZE (mode))
|
|
|
|
return type;
|
|
|
|
|
|
|
|
if (len < (optimize_bb_for_size_p (gimple_bb (swtch)) ? 2 : 32))
|
|
|
|
return type;
|
|
|
|
|
|
|
|
FOR_EACH_VEC_ELT (constructor_elt, info.constructors[num], i, elt)
|
|
|
|
{
|
|
|
|
double_int cst;
|
|
|
|
|
|
|
|
if (TREE_CODE (elt->value) != INTEGER_CST)
|
|
|
|
return type;
|
|
|
|
|
|
|
|
cst = TREE_INT_CST (elt->value);
|
|
|
|
while (1)
|
|
|
|
{
|
|
|
|
unsigned int prec = GET_MODE_BITSIZE (mode);
|
|
|
|
if (prec > HOST_BITS_PER_WIDE_INT)
|
|
|
|
return type;
|
|
|
|
|
|
|
|
if (sign >= 0
|
|
|
|
&& double_int_equal_p (cst, double_int_zext (cst, prec)))
|
|
|
|
{
|
|
|
|
if (sign == 0
|
|
|
|
&& double_int_equal_p (cst, double_int_sext (cst, prec)))
|
|
|
|
break;
|
|
|
|
sign = 1;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
if (sign <= 0
|
|
|
|
&& double_int_equal_p (cst, double_int_sext (cst, prec)))
|
|
|
|
{
|
|
|
|
sign = -1;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (sign == 1)
|
|
|
|
sign = 0;
|
|
|
|
|
|
|
|
mode = GET_MODE_WIDER_MODE (mode);
|
|
|
|
if (mode == VOIDmode
|
|
|
|
|| GET_MODE_SIZE (mode) >= GET_MODE_SIZE (TYPE_MODE (type)))
|
|
|
|
return type;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if (sign == 0)
|
|
|
|
sign = TYPE_UNSIGNED (type) ? 1 : -1;
|
|
|
|
smaller_type = lang_hooks.types.type_for_mode (mode, sign >= 0);
|
|
|
|
if (GET_MODE_SIZE (TYPE_MODE (type))
|
|
|
|
<= GET_MODE_SIZE (TYPE_MODE (smaller_type)))
|
|
|
|
return type;
|
|
|
|
|
|
|
|
return smaller_type;
|
|
|
|
}
|
|
|
|
|
2008-07-01 10:54:18 +02:00
|
|
|
/* Create an appropriate array type and declaration and assemble a static array
|
|
|
|
variable. Also create a load statement that initializes the variable in
|
|
|
|
question with a value from the static array. SWTCH is the switch statement
|
|
|
|
being converted, NUM is the index to arrays of constructors, default values
|
|
|
|
and target SSA names for this particular array. ARR_INDEX_TYPE is the type
|
|
|
|
of the index of the new array, PHI is the phi node of the final BB that
|
|
|
|
corresponds to the value that will be loaded from the created array. TIDX
|
2009-04-21 13:55:41 +02:00
|
|
|
is an ssa name of a temporary variable holding the index for loads from the
|
|
|
|
new array. */
|
2008-07-01 10:54:18 +02:00
|
|
|
|
|
|
|
static void
|
2008-07-28 16:33:56 +02:00
|
|
|
build_one_array (gimple swtch, int num, tree arr_index_type, gimple phi,
|
|
|
|
tree tidx)
|
2008-07-01 10:54:18 +02:00
|
|
|
{
|
2009-04-21 13:55:41 +02:00
|
|
|
tree name, cst;
|
2008-07-28 16:33:56 +02:00
|
|
|
gimple load;
|
2009-04-21 13:55:41 +02:00
|
|
|
gimple_stmt_iterator gsi = gsi_for_stmt (swtch);
|
java-gimplify.c (java_gimplify_block): New argument to build_empty_stmt.
gcc/java/
* java-gimplify.c (java_gimplify_block): New argument to
build_empty_stmt.
* expr.c (force_evaluation_order): Same.
* typeck.c: Add location to build_decl or PUSH_FIELD calls.
* class.c: Same.
* decl.c: Same.
* jcf-parse.c: Same.
* constants.c: Same.
* resource.c: Same.
* except.c: Same.
* builtins.c: Same.
* expr.c: Same.
* java-tree.h (PUSH_FIELD): Add location field.
gcc/objc/
* objc-act.c (finish_var_decl): Pass location to finish_decl.
(objc_get_parm_info): Same.
(get_super_receiver): Same.
* objc-act.c (objc_build_component_ref): Pass location to
build_compound_ref.
(build_module_initializer_routine): Pass location to
c_end_compound_stmt.
(objc_generate_static_init_call): Pass location to build_stmt.
(build_typed_selector_reference): New location argument.
(build_selector_reference): Same.
(objc_substitute_decl): Pass location to build_array_ref.
(next_sjlj_build_try_catch_finally): Pass location to build_stmt.
(objc_begin_catch_clause): Same.
(objc_finish_try_stmt): Same.
(objc_finish_catch_clause): Pass location to c_end_compound_stmt.
(objc_build_throw_stmt): New argument.
(generate_shared_structures): Pass location to build_c_cast.
(objc_build_message_expr): Use local location.
(objc_finish_message_expr): Use input_location.
(build_objc_method_call): New argument.
(objc_build_selector_expr): Same.
(get_super_receiver): Pass location to build_c_cast,
build_modify_expr, build_compound_expr.
* objc-act.c: Add location to all calls to start_struct, build_decl,
finish_struct.
gcc/
* tree-pretty-print.c (dump_generic_node): Dump column numbers.
* gimple-pretty-print.c (dump_gimple_stmt): Same.
* gimplify.c (gimplify_modify_expr): Set location for GIMPLE_ASSIGNs
created.
* c-parser.c (c_parser_binary_expression): Use current column while
building binary operations.
* common.opt (fshow-column): Enable by default.
* tree-vrp.c (check_array_ref): Use warning_at.
(check_array_bounds): Use location from call back if expr has no
location.
* tree.h: Add location argument to maybe_fold_*.
* tree-ssa-ccp.c (ccp_fold): Pass location to maybe_fold_*.
(maybe_fold_offset_to_array_ref): Add location argument and use it.
(maybe_fold_offset_to_component_ref): Same.
(maybe_fold_offset_to_reference): Same.
(maybe_fold_offset_to_address): Same.
(maybe_fold_stmt_indirect): Same.
(maybe_fold_stmt_addition): Same.
(fold_stmt_r): Pass location to maybe_fold_*.
(fold_gimple_assign): Same.
* c-tree.h: Add location argument to finish_decl,
default_function_array_conversion, store_init_value.
* c-decl.c (define_label): Use error_at.
(c_make_fname_decl): Pass location to finish_decl.
(finish_decl): New location argument.
(build_compound_literal): Pass location to store_init_value.
(grokdeclarator): Pass location to finish_decl.
(grokfield): Same.
* c-typeck.c (array_to_pointer_conversion): New location argument.
(function_to_pointer_conversion): Same.
(default_function_array_conversion): Same.
(parser_build_unary_op): Pass location to overflow_warning.
(parser_build_binary_op): Same. Use warning_at.
(build_unary_op): Pass location to array_to_pointer_conversion.
(build_c_cast): Pass location to digest_init.
(build_modify_expr): New location argument.
(convert_for_assignment): Same.
(store_init_value): Same.
(digest_init): Same.
(output_init_element): Pass location to digest_init and
array_to_pointer_conversion.
(c_finish_return): Pass location to convert_for_assignment.
* gimplify.c (gimplify_conversion): Pass location to
maybe_fold_offset_to_address.
* tree-ssa-forwprop.c (forward_propagate_addr_expr_1): Pass location
to maybe_fold_stmt_addition.
* c-omp.c (c_finish_omp_atomic): Pass new location to
build_modify_expr.
(c_finish_omp_for): Same.
* c-common.c (overflow_warning): New argument.
* c-common.h: New argument to build_modify_expr, overflow_warning.
* c-parser.c (c_parser_declaration_or_fndef): Pass location to
finish_decl.
(c_parser_initializer): Pass location to
default_function_array_conversion.
(c_parser_initelt): Same.
(c_parser_initval): Same.
(c_parser_asm_operands): Same.
(c_parser_expr_no_commas): Same. Pass location to build_modify_expr.
(c_parser_conditional_expression): Same.
(c_parser_binary_expression): Add location info to stack. Use it.
(c_parser_unary_expression): Pass location to
default_function_array_conversion, parser_build_unary_op,
build_indirect_ref, c_parser_postfix_expression_after_primary.
(c_parser_postfix_expression_after_primary): New location argument.
Use it.
(c_parser_expression_conv): Pass location to
default_function_array_conversion.
(c_parser_expr_list): Same.
(c_parser_omp_atomic): Same.
(c_parser_omp_for_loop): Same.
* c-tree.h: (struct c_declarator): Add comment to id_loc.
(build_array_declarator): New argument.
* c-decl.c (build_array_declarator): Add location argument.
(grokdeclarator): Set id_loc for cdk_array.
* c-parser.c (c_parser_direct_declarator_inner): Pass location to
build_array_declarator.
* tree.c (build_omp_clause): Add location argument.
* tree.h (OMP_CLAUSE_HAS_LOCATION): New macro.
(OMP_CLAUSE_LOCATION): New macro.
(struct tree_omp_clause): Add location field.
(build_omp_clause): Add argument.
* testsuite/gcc.dg/gomp/for-1.c: Fix column.
* cp/pt.c (tsubst_omp_for_iterator): Pass location to
build_omp_clause.
* cp/parser.c (cp_parser_omp_var_list_no_open): Same.
(cp_parser_omp_clause_collapse): Same.
(cp_parser_omp_clause_default): Same.
(cp_parser_omp_clause_if): Same.
(cp_parser_omp_clause_nowait): Same.
(cp_parser_omp_clause_num_threads): Same.
(cp_parser_omp_clause_ordered): Same.
(cp_parser_omp_clause_schedule): Same.
(cp_parser_omp_clause_untied): Same.
(cp_parser_omp_for_loop): Same.
(cp_parser_omp_parallel): Pass location to c_split_parallel_clauses.
* c-tree.h (c_start_case): Add location argument.
(c_process_expr_stmt): Same.
(c_finish_goto_*): Same.
* tree-parloops.c (initialize_reductions): Pass location to
build_omp_clause.
(create_parallel_loop): Same.
* fortran/trans-openmp.c (gfc_trans_omp_variable_list): Same.
(gfc_trans_omp_reduction_list): Same.
(gfc_trans_omp_clauses): Same.
(gfc_trans_omp_do): Same.
* c-typeck.c (c_finish_goto_label): Same.
(c_finish_goto_ptr): New location argument.
(c_start_case): Same.
(emit_side_effect_warnings): Same.
(c_process_expr_stmt): Same.
(c_finish_stmt_expr): Same.
(c_finish_omp_clauses): Use error_at instead of error.
* gimplify.c (gimplify_adjust_omp_clauses_1): Pass location to
build_omp_clause.
* c-omp.c (c_split_parallel_clauses): New location argument.
* tree-nested.c (convert_nonlocal_reference_stmt): Pass location
to build_omp_clause.
(convert_local_reference_stmt): Same.
(convert_gimple_call): Same.
* c-common.h (c_split_parallel_clauses): New argument.
* c-parser.c (c_parser_statement_after_labels): Pass location to
c_finish_goto_label.
(c_parser_switch_statement): Pass location to c_start_case.
(c_parser_for_statement): Pass location to c_finish_expr_stmt,
and c_process_expr_stmt.
(c_parser_omp_variable_list): Add location argument.
(c_parser_omp_clause_collapse): Pass location to
build_omp_clause.
(c_parser_omp_clause_default): Same.
(c_parser_omp_clause_if): Same.
(c_parser_omp_clause_num_threads): Same.
(-c_parser_omp_clause_ordered): Same.
(c_parser_omp_clause_reduction): Pass location to
c_parser_omp_variable_list.
(c_parser_omp_clause_schedule): Pass location to build_omp_clause.
(c_parser_omp_clause_untied): Same.
(c_parser_omp_for_loop): Pass location to c_process_expr_stmt.
(c_parser_omp_parallel): Pass location to
c_split_parallel_clauses.
* c-tree.h (check_for_loop_decls, undeclared_variable,
build_component_ref, build_array_ref, build_external_ref,
c_expr_sizeof_expr, c_expr_sizeof_type, parser_build_unary_op,
build_conditional_expr, build_compound_expr, c_cast_expr,
build_c_cast, build_asm_expr, c_end_compound_stmt, c_finish_stmt_expr,
c_finish_return, c_finish_omp_parallel, c_finish_omp_task): New
argument.
* c-semantics.c (build_stmt): Same.
(build_case_label): Same.
* c-decl.c (c_finish_incomplete_decl): Pass location on down.
(undeclared_variable): New argument.
(make_label): Same.
(lookup_label): Pass location on down.
(define_label): Same.
(finish_decl): Same.
(build_compound_literal): Same.
(finish_struct): Same.
(finish_function): Do not set location here.
(check_for_loop_decls): New argument.
* tree.c (save_expr): Set location.
(build_empty_stmt): New argument.
* tree.h (build_empty_stmt): New argument to build_empty_stmt.
(CAN_HAVE_LOCATION_P): Make sure we have a non empty node.
* builtins.c (gimplify_va_arg_expr): Use locations.
(expand_builtin_sync_operation): Same.
* c-typeck.c (build_component_ref): New argument.
(build_array_ref): Same.
(build_external_ref): Same.
(c_expr_sizeof_expr): Same.
(c_expr_sizeof_type): Same.
(parser_build_unary_op): Same.
(build_conditional_expr): Same.
(build_compound_expr): Pass location on down.
(build_compound_expr): New argument.
(build_c_cast): Same.
(c_cast_expr): Same.
(build_asm_expr): Same.
(c_finish_return): Same.
(c_process_expr_stmt): Pass location on down.
(c_finish_stmt_expr): New argument.
(push_clenaup): Same.
(c_finish_omp_parallel): Same.
(c_finish_omp_task): Same.
* gimplify.c (gimplify_call_expr): Pass location on down.
* c-omp.c (c_finish_omp_master): New argument.
(c_finish_omp_critical): Same.
(c_finish_omp_ordered): Same.
(c_finish_omp_barrier): Same.
(-c_finish_omp_taskwait): Same.
(c_finish_omp_atomic): Same.
(c_finish_omp_flush): Same.
* tree-inline.c (copy_tree_body_r): Pass location on down.
(inline_forbidden_p): Remove use of input_location.
* c-gimplify.c (c_build_bind_expr): New argument.
* c-common.c (c_common_truthvalue_conversion): Pass location on down.
(c_sizeof_or_alignof_type): New argument.
(c_alignof_expr): Same.
(build_va_arg): Same.
(c_add_case_label): Same.
* c-common.h (c_sizeof_or_alignof_type, c_alignof_expr,
c_sizeof, c_alignof, build_va_arg, build_stmt, build_case_label,
c_build_bind_expr, objc_build_selector_expr, objc_build_throw_stmt,
c_finish_omp_master, c_finish_omp_critical, c_finish_omp_ordered,
c_finish_omp_barrier, c_finish_omp_atomic, c_finish_omp_flush,
c_finish_omp_taskwait, c_finish_omp_for, c_split_parallel_clauses):
New argument.
* stub-objc.c (objc_build_selector_expr): Same.
(objc_build_throw_stmt): Same.
* c-parser.c (c_parser_declaration_or_fndef): Pass location on down.
(c_parser_initelt): Same.
(c_parser_compound_statement): Same.
(c_parser_compound_statement_nostart): Same.
(c_parser_label): Same.
(c_parser_statement_after_labels): Same.
(c_parser_if_body): Same.
(c_parser_else_body): Same.
(c_parser_if_statement): Same.
(c_parser_switch_statement): Same.
(c_parser_while_statement): Same.
(c_parser_do_statement): Same.
(c_parser_for_statement): Same.
(c_parser_asm_statement): Same.
(c_parser_conditional_expression): Same.
(c_parser_binary_expression): Same.
(c_parser_cast_expression): Same.
(c_parser_unary_expression): Same.
(c_parser_sizeof_expression): Same.
(c_parser_alignof_expression): Same.
(c_parser_postfix_expression): Same.
(c_parser_expression): Same.
(c_parser_objc_receiver): Same.
(c_parser_omp_variable_list): Same.
(c_parser_omp_structured_block): Same.
(c_parser_omp_atomic): New argument.
(c_parser_omp_barrier): Same.
(c_parser_omp_critical): Same.
(c_parser_omp_flush): Pass location on down.
(c_parser_omp_for_loop): New argument.
(c_parser_omp_for): Same.
(c_parser_omp_master): Same.
(c_parser_omp_ordered): Same.
(c_parser_omp_sections_scope): Same.
(c_parser_omp_sections): Same.
(c_parser_omp_parallel): Same.
(c_parser_omp_single): Same.
(c_parser_omp_task): Same.
(c_parser_omp_taskwait): Pass location on down.
(c_parser_omp_construct): Same.
(c_parser_omp_threadprivate): Same.
* dwarf2asm.c, targhooks.c, optabs.c, tree.c, tree.h, target.h,
builtins.c, omp-low.c, cgraphunit.c, tree-call-cdce.c,
tree-ssa-alias.c, gimple-low.c, c-tree.h, expr.c, tree-parloops.c,
c-decl.c, tree-eh.c, langhooks.c, function.c, stor-layout.c,
c-typeck.c, gimplify.c, c-pragma.c, expmed.c, except.c, coverage.c,
emit-rtl.c, cfgexpand.c, tree-mudflap.c, varasm.c, tree-nested.c,
rtl.h, tree-inline.c, tree-profile.c, c-common.c, c-common.h,
tree-switch-conversion.c, tree-cfg.c, ipa-struct-reorg.c, c-parser.c,
config/i386/i386.c, stmt.c:
Add location argument to the following function definitions and/or
function calls: build_decl, objcp_start_struct, objcp_finish_struct,
start_struct, finish_struct, PUSH_FIELD, create_artificial_label,
cp_make_fname_decl, pushtag, implicitly_declare, c_make_fname_decl,
build_compound_literal, parser_xref_tag, resolve_overloaded_builtin,
do_case, c_finish_bc_stmt, build_compound_literal,
build_function_call.
* c-decl.c (build_compound_literal): Add location argument.
Make all diagnostic calls use location.
(start_struct): Same.
(finish_struct): Same.
(start_enum): Same.
(build_enumerator): Same.
(start_function): Same.
(grokdeclarator): Make all diagnostic calls use location.
(store_parm_decls_oldstyle): Same.
* c-typeck.c (build_function_call): Add location argument.
Make all diagnostic calls use location.
(do_case): Same.
(c_finish_bc_stmt): Same.
* tree-nested.c (get_trampoline_type): Add argument.
Pass location to build_decl.
(lookup_tramp_for_decl): Pass location to get_trampoline_type.
* rtl.h (RTL_LOCATION): New.
* c-common.c (c_add_case_label): Add location argument.
Make all diagnostic calls use location.
* c-common.h: Add location argument to make_fname_decl, do_case,
c_add_case_label, build_function_call, resolve_overloaded_builtin.
* c-parser.c (c_parser_enum_specifier): Rename ident_loc to enum_loc.
Set it appropriately for every case. Pass enum_loc to start_enum
call. Pass value_loc first to build_enumerator. Pass enum_loc to
parser_xref_tag.
(c_parser_struct_or_union_specifier): Save location. Use it for
start_struct, finish_struct, and parser_xref_tag.
gcc/testsuite/
* gcc.dg/old-style-prom-3.c: Add column info.
* gcc.dg/overflow-warn-1.c
* gcc.dg/gomp/pr27415.c
* gcc.dg/gomp/for-1.c: Same.
* gcc.dg/enum-compat-1.c: Same.
* gcc.dg/c99-tag-3.c: Same.
* gcc.dg/Wredundant-decls-2.c: Same.
* gcc.dg/func-ptr-conv-1.c: Same.
* gcc.dg/asm-wide-1.c: Same.
* gcc.dg/nofixed-point-2.c: Same.
* gcc.dg/cpp/line3.c: Same.
* gcc.dg/array-10.c: Same.
* gcc.dg/c99-vla-jump-1.c: Same.
* gcc.dg/pr20368-1.c: Same.
* gcc.dg/Wshadow-3.c: Same.
* gcc.dg/c90-const-expr-8.c: Same.
* gcc.dg/label-decl-2.c: Same.
* gcc.dg/dremf-type-compat-2.c: Same.
* gcc.dg/c90-const-expr-5.c: Same.
* gcc.dg/builtins-30.c: Same.
* gcc.dg/Warray-bounds.c: Same.
* gcc.dg/Wcxx-compat-2.c: Same.
* gcc.dg/tree-ssa/col-1.c: Same.
* gcc.dg/old-style-prom-2.c: Same.
* gcc.dg/cast-function-1.c: Same.
* gcc.dg/pr15698-1.c: Same.
* gcc.dg/dremf-type-compat-3.c: Same.
* gcc.dg/vla-8.c: Same.
* gcc.dg/gomp/pr27415.c: Move firstprivate diagnostics to correct
line.
* gcc.dg/label-decl-2.c: Move label diagnostic to correct line.
* gcc.dg/old-style-prom-3.c: Check for error on the correct line.
* gcc.dg/enum-compat-1.c: Same.
* gcc.dg/dremf-type-compat-2.c: Same.
* gcc.dg/old-style-prom-2.c: Same.
* gcc.dg/pr15698-1.c: Same.
* gcc.dg/pr20368-1.c: Same.
* gcc.dg/dremf-type-compat-3.c: Same.
* gcc.dg/builtins-30.c: Same. Test for columns.
gcc/objcp/
* objcp-decl.h (c_end_compound_stmt): New argument.
* objcp-decl.c (objcp_start_struct): Add argument.
(objcp_finish_struct): Same.
gcc/cp/
* typeck.c (cp_build_binary_op): Pass location to overflow_warning.
(build_modify_expr): New arg.
* semantics.c (finish_unary_op_expr): Pass location to
overflow_warning.
(handle_omp_for_class_iterator): Pass location to build_modify_expr.
* typeck.c (cxx_sizeof_or_alignof_type): Pass location to
c_sizeof_or_alignof_type.
(build_array_ref): New argument.
(build_compound_expr): Same.
(build_const_cast): Same.
(build_ptrmemfunc): Pass location to build_c_cast.
* init.c (avoid_placement_new_aliasing): Pass location to
build_stmt.
(build_vec_delete_1): Pass location to cp_build_modify_expr,
build_compound_expr.
* class.c (build_vtbl_ref_1): Pass location to build_array_ref.
* decl.c (poplevel): Pass location to c_build_bind_expr.
(finish_case_label): Pass location to build_case_label.
(finish_constructor_body): Same.
(finish_destructor_body): Pass location to build_stmt.
(cxx_maybe_build_cleanup): Same, but to build_compound_expr.
* call.c (build_new_op): Pass location to build_array_ref.
(build_x_va_arg): Pass location to build_va_arg.
* except.c (expand_end_catch_block): Pass location to
build_stmt.
* cp-tree.h (build_array_ref): New argument.
(build_compound_expr): Same.
(build_c_cast): Same.
* cp-gimplify.c (gimplify_if_stmt): Pass location on down.
(gimplify_switch_stmt): Same.
* typeck2.c (split_nonconstant_init_1): Same.
* pt.c (tsubst_copy): Same.
* semantics.c (add_decl_expr): Same.
(do_poplevel): Same.
(push_cleanup): Same.
(finish_goto_stmt): Same.
(finish_expr_stmt): Same.
(begin_if_stmt): Same.
(begin_while_stmt): Same.
(begin_do_stmt): Same.
(finish_return_stmt): Same.
(begin_for_stmt): Same.
(finish_break_stmt): Same.
(finish_continue_stmt): Same.
(begin_switch_stmt): Same.
(begin_try_block): Same.
(begin_handler): Same.
(finish_asm_stmt): Same.
(finish_label_stmt): Same.
(finish_stmt_expr_expr): Same.
(finalize_nrv_r): Same.
(finish_omp_atomic): Same.
* name-lookup.c (do_using_directive): Same.
* decl2.c (grok_array_decl): Same.
* parser.c (cp_parser_cast_expression): Same.
(cp_parser_selection_statement): Same.
(cp_parser_implicitly_scoped_statement): Same.
(cp_parser_objc_selector_expression): Same.
(cp_parser_objc_synchronized_statement): Same.
(cp_parser_objc_throw_statement): Same.
(cp_parser_omp_critical): Same.
(cp_parser_omp_master): Same.
* typeck.c (build_function_call): Add location argument.
* init.c: Add location argument to all build_decl calls.
* class.c: Same.
* method.c: Same.
* rtti.c: Same.
* tree.c: Same.
* pt.c: Same.
* semantics.c: Same.
* lex.c: Same.
* decl2.c: Same.
* cp-gimplify.c: Same.
* decl.c: Same.
(cp_make_fname_decl): Add location argument. Pass location ot
build_decl.
(finish_case_label): Same.
* cp-tree.h (finish_case_label): Add location argument.
* parser.c (cp_parser_label_for_labeled_statement): Pass location to
finish_case_label.
gcc/fortran/
* trans-array.c (gfc_trans_allocate_array_storage): Pass
location on down.
(gfc_trans_array_constructor_value): Same.
(gfc_trans_scalarized_loop_end): Same.
(gfc_conv_ss_startstride): Same.
(gfc_trans_g77_array): Same.
(gfc_trans_dummy_array_bias): Same.
(gfc_conv_array_parameter): Same.
(structure_alloc_comps): Same.
* trans-expr.c (gfc_conv_function_call): Same.
(fill_with_spaces): Same.
(gfc_trans_string_copy): Same.
(gfc_trans_scalar_assign): Same.
* trans-stmt.c (gfc_trans_goto): Same.
(gfc_trans_if_1): Same.
(gfc_trans_simple_do): Same.
(gfc_trans_do): Same.
(gfc_trans_do_while): Same.
(gfc_trans_logical_select): Same.
(gfc_trans_select): Same.
(gfc_trans_forall_loop): Same.
(gfc_trans_nested_forall_loop): Same.
(generate_loop_for_temp_to_lhs): Same.
(generate_loop_for_rhs_to_temp): Same.
(gfc_trans_forall_1): Same.
(gfc_trans_where_assign): Same.
(gfc_trans_where_3): Same.
(gfc_trans_allocate): Same.
* trans.c (gfc_finish_block): Same.
(gfc_trans_runtime_check): Same.
(gfc_call_malloc): Same.
(gfc_allocate_with_status): Same.
(gfc_call_free): Same.
(gfc_deallocate_with_status): Same.
(gfc_call_realloc): Same.
(gfc_trans_code): Same.
* trans-decl.c (gfc_init_default_dt): Same.
(gfc_generate_constructors): Same.
* trans-io.c (gfc_trans_io_runtime_check): Same.
* trans-intrinsic.c (gfc_conv_intrinsic_ctime): Same.
(gfc_conv_intrinsic_fdate): Same.
(gfc_conv_intrinsic_ttynam): Same.
(gfc_conv_intrinsic_minmax): Same.
(gfc_conv_intrinsic_minmax_char): Same.
(gfc_conv_intrinsic_anyall): Same.
(gfc_conv_intrinsic_count): Same.
(gfc_conv_intrinsic_arith): Same.
(gfc_conv_intrinsic_minmaxloc): Same.
(gfc_conv_intrinsic_minmaxval): Same.
(gfc_conv_intrinsic_rrspacing): Same.
(gfc_conv_intrinsic_array_transfer): Same.
(gfc_conv_intrinsic_trim): Same.
(gfc_conv_intrinsic_repeat): Same.
From-SVN: r148442
2009-06-13 00:06:47 +02:00
|
|
|
location_t loc = gimple_location (swtch);
|
2008-07-01 10:54:18 +02:00
|
|
|
|
|
|
|
gcc_assert (info.default_values[num]);
|
|
|
|
|
2008-07-28 16:33:56 +02:00
|
|
|
name = make_ssa_name (SSA_NAME_VAR (PHI_RESULT (phi)), NULL);
|
2008-07-01 10:54:18 +02:00
|
|
|
info.target_inbound_names[num] = name;
|
|
|
|
|
2009-04-21 13:55:41 +02:00
|
|
|
cst = constructor_contains_same_values_p (info.constructors[num]);
|
|
|
|
if (cst)
|
|
|
|
load = gimple_build_assign (name, cst);
|
|
|
|
else
|
|
|
|
{
|
2010-11-20 00:48:57 +01:00
|
|
|
tree array_type, ctor, decl, value_type, fetch, default_type;
|
2009-04-21 13:55:41 +02:00
|
|
|
|
2010-11-20 00:48:57 +01:00
|
|
|
default_type = TREE_TYPE (info.default_values[num]);
|
|
|
|
value_type = array_value_type (swtch, default_type, num);
|
2009-04-21 13:55:41 +02:00
|
|
|
array_type = build_array_type (value_type, arr_index_type);
|
2010-11-20 00:48:57 +01:00
|
|
|
if (default_type != value_type)
|
|
|
|
{
|
|
|
|
unsigned int i;
|
|
|
|
constructor_elt *elt;
|
|
|
|
|
|
|
|
FOR_EACH_VEC_ELT (constructor_elt, info.constructors[num], i, elt)
|
|
|
|
elt->value = fold_convert (value_type, elt->value);
|
|
|
|
}
|
2009-04-21 13:55:41 +02:00
|
|
|
ctor = build_constructor (array_type, info.constructors[num]);
|
|
|
|
TREE_CONSTANT (ctor) = true;
|
2010-09-04 18:02:38 +02:00
|
|
|
TREE_STATIC (ctor) = true;
|
2009-04-21 13:55:41 +02:00
|
|
|
|
java-gimplify.c (java_gimplify_block): New argument to build_empty_stmt.
gcc/java/
* java-gimplify.c (java_gimplify_block): New argument to
build_empty_stmt.
* expr.c (force_evaluation_order): Same.
* typeck.c: Add location to build_decl or PUSH_FIELD calls.
* class.c: Same.
* decl.c: Same.
* jcf-parse.c: Same.
* constants.c: Same.
* resource.c: Same.
* except.c: Same.
* builtins.c: Same.
* expr.c: Same.
* java-tree.h (PUSH_FIELD): Add location field.
gcc/objc/
* objc-act.c (finish_var_decl): Pass location to finish_decl.
(objc_get_parm_info): Same.
(get_super_receiver): Same.
* objc-act.c (objc_build_component_ref): Pass location to
build_compound_ref.
(build_module_initializer_routine): Pass location to
c_end_compound_stmt.
(objc_generate_static_init_call): Pass location to build_stmt.
(build_typed_selector_reference): New location argument.
(build_selector_reference): Same.
(objc_substitute_decl): Pass location to build_array_ref.
(next_sjlj_build_try_catch_finally): Pass location to build_stmt.
(objc_begin_catch_clause): Same.
(objc_finish_try_stmt): Same.
(objc_finish_catch_clause): Pass location to c_end_compound_stmt.
(objc_build_throw_stmt): New argument.
(generate_shared_structures): Pass location to build_c_cast.
(objc_build_message_expr): Use local location.
(objc_finish_message_expr): Use input_location.
(build_objc_method_call): New argument.
(objc_build_selector_expr): Same.
(get_super_receiver): Pass location to build_c_cast,
build_modify_expr, build_compound_expr.
* objc-act.c: Add location to all calls to start_struct, build_decl,
finish_struct.
gcc/
* tree-pretty-print.c (dump_generic_node): Dump column numbers.
* gimple-pretty-print.c (dump_gimple_stmt): Same.
* gimplify.c (gimplify_modify_expr): Set location for GIMPLE_ASSIGNs
created.
* c-parser.c (c_parser_binary_expression): Use current column while
building binary operations.
* common.opt (fshow-column): Enable by default.
* tree-vrp.c (check_array_ref): Use warning_at.
(check_array_bounds): Use location from call back if expr has no
location.
* tree.h: Add location argument to maybe_fold_*.
* tree-ssa-ccp.c (ccp_fold): Pass location to maybe_fold_*.
(maybe_fold_offset_to_array_ref): Add location argument and use it.
(maybe_fold_offset_to_component_ref): Same.
(maybe_fold_offset_to_reference): Same.
(maybe_fold_offset_to_address): Same.
(maybe_fold_stmt_indirect): Same.
(maybe_fold_stmt_addition): Same.
(fold_stmt_r): Pass location to maybe_fold_*.
(fold_gimple_assign): Same.
* c-tree.h: Add location argument to finish_decl,
default_function_array_conversion, store_init_value.
* c-decl.c (define_label): Use error_at.
(c_make_fname_decl): Pass location to finish_decl.
(finish_decl): New location argument.
(build_compound_literal): Pass location to store_init_value.
(grokdeclarator): Pass location to finish_decl.
(grokfield): Same.
* c-typeck.c (array_to_pointer_conversion): New location argument.
(function_to_pointer_conversion): Same.
(default_function_array_conversion): Same.
(parser_build_unary_op): Pass location to overflow_warning.
(parser_build_binary_op): Same. Use warning_at.
(build_unary_op): Pass location to array_to_pointer_conversion.
(build_c_cast): Pass location to digest_init.
(build_modify_expr): New location argument.
(convert_for_assignment): Same.
(store_init_value): Same.
(digest_init): Same.
(output_init_element): Pass location to digest_init and
array_to_pointer_conversion.
(c_finish_return): Pass location to convert_for_assignment.
* gimplify.c (gimplify_conversion): Pass location to
maybe_fold_offset_to_address.
* tree-ssa-forwprop.c (forward_propagate_addr_expr_1): Pass location
to maybe_fold_stmt_addition.
* c-omp.c (c_finish_omp_atomic): Pass new location to
build_modify_expr.
(c_finish_omp_for): Same.
* c-common.c (overflow_warning): New argument.
* c-common.h: New argument to build_modify_expr, overflow_warning.
* c-parser.c (c_parser_declaration_or_fndef): Pass location to
finish_decl.
(c_parser_initializer): Pass location to
default_function_array_conversion.
(c_parser_initelt): Same.
(c_parser_initval): Same.
(c_parser_asm_operands): Same.
(c_parser_expr_no_commas): Same. Pass location to build_modify_expr.
(c_parser_conditional_expression): Same.
(c_parser_binary_expression): Add location info to stack. Use it.
(c_parser_unary_expression): Pass location to
default_function_array_conversion, parser_build_unary_op,
build_indirect_ref, c_parser_postfix_expression_after_primary.
(c_parser_postfix_expression_after_primary): New location argument.
Use it.
(c_parser_expression_conv): Pass location to
default_function_array_conversion.
(c_parser_expr_list): Same.
(c_parser_omp_atomic): Same.
(c_parser_omp_for_loop): Same.
* c-tree.h: (struct c_declarator): Add comment to id_loc.
(build_array_declarator): New argument.
* c-decl.c (build_array_declarator): Add location argument.
(grokdeclarator): Set id_loc for cdk_array.
* c-parser.c (c_parser_direct_declarator_inner): Pass location to
build_array_declarator.
* tree.c (build_omp_clause): Add location argument.
* tree.h (OMP_CLAUSE_HAS_LOCATION): New macro.
(OMP_CLAUSE_LOCATION): New macro.
(struct tree_omp_clause): Add location field.
(build_omp_clause): Add argument.
* testsuite/gcc.dg/gomp/for-1.c: Fix column.
* cp/pt.c (tsubst_omp_for_iterator): Pass location to
build_omp_clause.
* cp/parser.c (cp_parser_omp_var_list_no_open): Same.
(cp_parser_omp_clause_collapse): Same.
(cp_parser_omp_clause_default): Same.
(cp_parser_omp_clause_if): Same.
(cp_parser_omp_clause_nowait): Same.
(cp_parser_omp_clause_num_threads): Same.
(cp_parser_omp_clause_ordered): Same.
(cp_parser_omp_clause_schedule): Same.
(cp_parser_omp_clause_untied): Same.
(cp_parser_omp_for_loop): Same.
(cp_parser_omp_parallel): Pass location to c_split_parallel_clauses.
* c-tree.h (c_start_case): Add location argument.
(c_process_expr_stmt): Same.
(c_finish_goto_*): Same.
* tree-parloops.c (initialize_reductions): Pass location to
build_omp_clause.
(create_parallel_loop): Same.
* fortran/trans-openmp.c (gfc_trans_omp_variable_list): Same.
(gfc_trans_omp_reduction_list): Same.
(gfc_trans_omp_clauses): Same.
(gfc_trans_omp_do): Same.
* c-typeck.c (c_finish_goto_label): Same.
(c_finish_goto_ptr): New location argument.
(c_start_case): Same.
(emit_side_effect_warnings): Same.
(c_process_expr_stmt): Same.
(c_finish_stmt_expr): Same.
(c_finish_omp_clauses): Use error_at instead of error.
* gimplify.c (gimplify_adjust_omp_clauses_1): Pass location to
build_omp_clause.
* c-omp.c (c_split_parallel_clauses): New location argument.
* tree-nested.c (convert_nonlocal_reference_stmt): Pass location
to build_omp_clause.
(convert_local_reference_stmt): Same.
(convert_gimple_call): Same.
* c-common.h (c_split_parallel_clauses): New argument.
* c-parser.c (c_parser_statement_after_labels): Pass location to
c_finish_goto_label.
(c_parser_switch_statement): Pass location to c_start_case.
(c_parser_for_statement): Pass location to c_finish_expr_stmt,
and c_process_expr_stmt.
(c_parser_omp_variable_list): Add location argument.
(c_parser_omp_clause_collapse): Pass location to
build_omp_clause.
(c_parser_omp_clause_default): Same.
(c_parser_omp_clause_if): Same.
(c_parser_omp_clause_num_threads): Same.
(-c_parser_omp_clause_ordered): Same.
(c_parser_omp_clause_reduction): Pass location to
c_parser_omp_variable_list.
(c_parser_omp_clause_schedule): Pass location to build_omp_clause.
(c_parser_omp_clause_untied): Same.
(c_parser_omp_for_loop): Pass location to c_process_expr_stmt.
(c_parser_omp_parallel): Pass location to
c_split_parallel_clauses.
* c-tree.h (check_for_loop_decls, undeclared_variable,
build_component_ref, build_array_ref, build_external_ref,
c_expr_sizeof_expr, c_expr_sizeof_type, parser_build_unary_op,
build_conditional_expr, build_compound_expr, c_cast_expr,
build_c_cast, build_asm_expr, c_end_compound_stmt, c_finish_stmt_expr,
c_finish_return, c_finish_omp_parallel, c_finish_omp_task): New
argument.
* c-semantics.c (build_stmt): Same.
(build_case_label): Same.
* c-decl.c (c_finish_incomplete_decl): Pass location on down.
(undeclared_variable): New argument.
(make_label): Same.
(lookup_label): Pass location on down.
(define_label): Same.
(finish_decl): Same.
(build_compound_literal): Same.
(finish_struct): Same.
(finish_function): Do not set location here.
(check_for_loop_decls): New argument.
* tree.c (save_expr): Set location.
(build_empty_stmt): New argument.
* tree.h (build_empty_stmt): New argument to build_empty_stmt.
(CAN_HAVE_LOCATION_P): Make sure we have a non empty node.
* builtins.c (gimplify_va_arg_expr): Use locations.
(expand_builtin_sync_operation): Same.
* c-typeck.c (build_component_ref): New argument.
(build_array_ref): Same.
(build_external_ref): Same.
(c_expr_sizeof_expr): Same.
(c_expr_sizeof_type): Same.
(parser_build_unary_op): Same.
(build_conditional_expr): Same.
(build_compound_expr): Pass location on down.
(build_compound_expr): New argument.
(build_c_cast): Same.
(c_cast_expr): Same.
(build_asm_expr): Same.
(c_finish_return): Same.
(c_process_expr_stmt): Pass location on down.
(c_finish_stmt_expr): New argument.
(push_clenaup): Same.
(c_finish_omp_parallel): Same.
(c_finish_omp_task): Same.
* gimplify.c (gimplify_call_expr): Pass location on down.
* c-omp.c (c_finish_omp_master): New argument.
(c_finish_omp_critical): Same.
(c_finish_omp_ordered): Same.
(c_finish_omp_barrier): Same.
(-c_finish_omp_taskwait): Same.
(c_finish_omp_atomic): Same.
(c_finish_omp_flush): Same.
* tree-inline.c (copy_tree_body_r): Pass location on down.
(inline_forbidden_p): Remove use of input_location.
* c-gimplify.c (c_build_bind_expr): New argument.
* c-common.c (c_common_truthvalue_conversion): Pass location on down.
(c_sizeof_or_alignof_type): New argument.
(c_alignof_expr): Same.
(build_va_arg): Same.
(c_add_case_label): Same.
* c-common.h (c_sizeof_or_alignof_type, c_alignof_expr,
c_sizeof, c_alignof, build_va_arg, build_stmt, build_case_label,
c_build_bind_expr, objc_build_selector_expr, objc_build_throw_stmt,
c_finish_omp_master, c_finish_omp_critical, c_finish_omp_ordered,
c_finish_omp_barrier, c_finish_omp_atomic, c_finish_omp_flush,
c_finish_omp_taskwait, c_finish_omp_for, c_split_parallel_clauses):
New argument.
* stub-objc.c (objc_build_selector_expr): Same.
(objc_build_throw_stmt): Same.
* c-parser.c (c_parser_declaration_or_fndef): Pass location on down.
(c_parser_initelt): Same.
(c_parser_compound_statement): Same.
(c_parser_compound_statement_nostart): Same.
(c_parser_label): Same.
(c_parser_statement_after_labels): Same.
(c_parser_if_body): Same.
(c_parser_else_body): Same.
(c_parser_if_statement): Same.
(c_parser_switch_statement): Same.
(c_parser_while_statement): Same.
(c_parser_do_statement): Same.
(c_parser_for_statement): Same.
(c_parser_asm_statement): Same.
(c_parser_conditional_expression): Same.
(c_parser_binary_expression): Same.
(c_parser_cast_expression): Same.
(c_parser_unary_expression): Same.
(c_parser_sizeof_expression): Same.
(c_parser_alignof_expression): Same.
(c_parser_postfix_expression): Same.
(c_parser_expression): Same.
(c_parser_objc_receiver): Same.
(c_parser_omp_variable_list): Same.
(c_parser_omp_structured_block): Same.
(c_parser_omp_atomic): New argument.
(c_parser_omp_barrier): Same.
(c_parser_omp_critical): Same.
(c_parser_omp_flush): Pass location on down.
(c_parser_omp_for_loop): New argument.
(c_parser_omp_for): Same.
(c_parser_omp_master): Same.
(c_parser_omp_ordered): Same.
(c_parser_omp_sections_scope): Same.
(c_parser_omp_sections): Same.
(c_parser_omp_parallel): Same.
(c_parser_omp_single): Same.
(c_parser_omp_task): Same.
(c_parser_omp_taskwait): Pass location on down.
(c_parser_omp_construct): Same.
(c_parser_omp_threadprivate): Same.
* dwarf2asm.c, targhooks.c, optabs.c, tree.c, tree.h, target.h,
builtins.c, omp-low.c, cgraphunit.c, tree-call-cdce.c,
tree-ssa-alias.c, gimple-low.c, c-tree.h, expr.c, tree-parloops.c,
c-decl.c, tree-eh.c, langhooks.c, function.c, stor-layout.c,
c-typeck.c, gimplify.c, c-pragma.c, expmed.c, except.c, coverage.c,
emit-rtl.c, cfgexpand.c, tree-mudflap.c, varasm.c, tree-nested.c,
rtl.h, tree-inline.c, tree-profile.c, c-common.c, c-common.h,
tree-switch-conversion.c, tree-cfg.c, ipa-struct-reorg.c, c-parser.c,
config/i386/i386.c, stmt.c:
Add location argument to the following function definitions and/or
function calls: build_decl, objcp_start_struct, objcp_finish_struct,
start_struct, finish_struct, PUSH_FIELD, create_artificial_label,
cp_make_fname_decl, pushtag, implicitly_declare, c_make_fname_decl,
build_compound_literal, parser_xref_tag, resolve_overloaded_builtin,
do_case, c_finish_bc_stmt, build_compound_literal,
build_function_call.
* c-decl.c (build_compound_literal): Add location argument.
Make all diagnostic calls use location.
(start_struct): Same.
(finish_struct): Same.
(start_enum): Same.
(build_enumerator): Same.
(start_function): Same.
(grokdeclarator): Make all diagnostic calls use location.
(store_parm_decls_oldstyle): Same.
* c-typeck.c (build_function_call): Add location argument.
Make all diagnostic calls use location.
(do_case): Same.
(c_finish_bc_stmt): Same.
* tree-nested.c (get_trampoline_type): Add argument.
Pass location to build_decl.
(lookup_tramp_for_decl): Pass location to get_trampoline_type.
* rtl.h (RTL_LOCATION): New.
* c-common.c (c_add_case_label): Add location argument.
Make all diagnostic calls use location.
* c-common.h: Add location argument to make_fname_decl, do_case,
c_add_case_label, build_function_call, resolve_overloaded_builtin.
* c-parser.c (c_parser_enum_specifier): Rename ident_loc to enum_loc.
Set it appropriately for every case. Pass enum_loc to start_enum
call. Pass value_loc first to build_enumerator. Pass enum_loc to
parser_xref_tag.
(c_parser_struct_or_union_specifier): Save location. Use it for
start_struct, finish_struct, and parser_xref_tag.
gcc/testsuite/
* gcc.dg/old-style-prom-3.c: Add column info.
* gcc.dg/overflow-warn-1.c
* gcc.dg/gomp/pr27415.c
* gcc.dg/gomp/for-1.c: Same.
* gcc.dg/enum-compat-1.c: Same.
* gcc.dg/c99-tag-3.c: Same.
* gcc.dg/Wredundant-decls-2.c: Same.
* gcc.dg/func-ptr-conv-1.c: Same.
* gcc.dg/asm-wide-1.c: Same.
* gcc.dg/nofixed-point-2.c: Same.
* gcc.dg/cpp/line3.c: Same.
* gcc.dg/array-10.c: Same.
* gcc.dg/c99-vla-jump-1.c: Same.
* gcc.dg/pr20368-1.c: Same.
* gcc.dg/Wshadow-3.c: Same.
* gcc.dg/c90-const-expr-8.c: Same.
* gcc.dg/label-decl-2.c: Same.
* gcc.dg/dremf-type-compat-2.c: Same.
* gcc.dg/c90-const-expr-5.c: Same.
* gcc.dg/builtins-30.c: Same.
* gcc.dg/Warray-bounds.c: Same.
* gcc.dg/Wcxx-compat-2.c: Same.
* gcc.dg/tree-ssa/col-1.c: Same.
* gcc.dg/old-style-prom-2.c: Same.
* gcc.dg/cast-function-1.c: Same.
* gcc.dg/pr15698-1.c: Same.
* gcc.dg/dremf-type-compat-3.c: Same.
* gcc.dg/vla-8.c: Same.
* gcc.dg/gomp/pr27415.c: Move firstprivate diagnostics to correct
line.
* gcc.dg/label-decl-2.c: Move label diagnostic to correct line.
* gcc.dg/old-style-prom-3.c: Check for error on the correct line.
* gcc.dg/enum-compat-1.c: Same.
* gcc.dg/dremf-type-compat-2.c: Same.
* gcc.dg/old-style-prom-2.c: Same.
* gcc.dg/pr15698-1.c: Same.
* gcc.dg/pr20368-1.c: Same.
* gcc.dg/dremf-type-compat-3.c: Same.
* gcc.dg/builtins-30.c: Same. Test for columns.
gcc/objcp/
* objcp-decl.h (c_end_compound_stmt): New argument.
* objcp-decl.c (objcp_start_struct): Add argument.
(objcp_finish_struct): Same.
gcc/cp/
* typeck.c (cp_build_binary_op): Pass location to overflow_warning.
(build_modify_expr): New arg.
* semantics.c (finish_unary_op_expr): Pass location to
overflow_warning.
(handle_omp_for_class_iterator): Pass location to build_modify_expr.
* typeck.c (cxx_sizeof_or_alignof_type): Pass location to
c_sizeof_or_alignof_type.
(build_array_ref): New argument.
(build_compound_expr): Same.
(build_const_cast): Same.
(build_ptrmemfunc): Pass location to build_c_cast.
* init.c (avoid_placement_new_aliasing): Pass location to
build_stmt.
(build_vec_delete_1): Pass location to cp_build_modify_expr,
build_compound_expr.
* class.c (build_vtbl_ref_1): Pass location to build_array_ref.
* decl.c (poplevel): Pass location to c_build_bind_expr.
(finish_case_label): Pass location to build_case_label.
(finish_constructor_body): Same.
(finish_destructor_body): Pass location to build_stmt.
(cxx_maybe_build_cleanup): Same, but to build_compound_expr.
* call.c (build_new_op): Pass location to build_array_ref.
(build_x_va_arg): Pass location to build_va_arg.
* except.c (expand_end_catch_block): Pass location to
build_stmt.
* cp-tree.h (build_array_ref): New argument.
(build_compound_expr): Same.
(build_c_cast): Same.
* cp-gimplify.c (gimplify_if_stmt): Pass location on down.
(gimplify_switch_stmt): Same.
* typeck2.c (split_nonconstant_init_1): Same.
* pt.c (tsubst_copy): Same.
* semantics.c (add_decl_expr): Same.
(do_poplevel): Same.
(push_cleanup): Same.
(finish_goto_stmt): Same.
(finish_expr_stmt): Same.
(begin_if_stmt): Same.
(begin_while_stmt): Same.
(begin_do_stmt): Same.
(finish_return_stmt): Same.
(begin_for_stmt): Same.
(finish_break_stmt): Same.
(finish_continue_stmt): Same.
(begin_switch_stmt): Same.
(begin_try_block): Same.
(begin_handler): Same.
(finish_asm_stmt): Same.
(finish_label_stmt): Same.
(finish_stmt_expr_expr): Same.
(finalize_nrv_r): Same.
(finish_omp_atomic): Same.
* name-lookup.c (do_using_directive): Same.
* decl2.c (grok_array_decl): Same.
* parser.c (cp_parser_cast_expression): Same.
(cp_parser_selection_statement): Same.
(cp_parser_implicitly_scoped_statement): Same.
(cp_parser_objc_selector_expression): Same.
(cp_parser_objc_synchronized_statement): Same.
(cp_parser_objc_throw_statement): Same.
(cp_parser_omp_critical): Same.
(cp_parser_omp_master): Same.
* typeck.c (build_function_call): Add location argument.
* init.c: Add location argument to all build_decl calls.
* class.c: Same.
* method.c: Same.
* rtti.c: Same.
* tree.c: Same.
* pt.c: Same.
* semantics.c: Same.
* lex.c: Same.
* decl2.c: Same.
* cp-gimplify.c: Same.
* decl.c: Same.
(cp_make_fname_decl): Add location argument. Pass location ot
build_decl.
(finish_case_label): Same.
* cp-tree.h (finish_case_label): Add location argument.
* parser.c (cp_parser_label_for_labeled_statement): Pass location to
finish_case_label.
gcc/fortran/
* trans-array.c (gfc_trans_allocate_array_storage): Pass
location on down.
(gfc_trans_array_constructor_value): Same.
(gfc_trans_scalarized_loop_end): Same.
(gfc_conv_ss_startstride): Same.
(gfc_trans_g77_array): Same.
(gfc_trans_dummy_array_bias): Same.
(gfc_conv_array_parameter): Same.
(structure_alloc_comps): Same.
* trans-expr.c (gfc_conv_function_call): Same.
(fill_with_spaces): Same.
(gfc_trans_string_copy): Same.
(gfc_trans_scalar_assign): Same.
* trans-stmt.c (gfc_trans_goto): Same.
(gfc_trans_if_1): Same.
(gfc_trans_simple_do): Same.
(gfc_trans_do): Same.
(gfc_trans_do_while): Same.
(gfc_trans_logical_select): Same.
(gfc_trans_select): Same.
(gfc_trans_forall_loop): Same.
(gfc_trans_nested_forall_loop): Same.
(generate_loop_for_temp_to_lhs): Same.
(generate_loop_for_rhs_to_temp): Same.
(gfc_trans_forall_1): Same.
(gfc_trans_where_assign): Same.
(gfc_trans_where_3): Same.
(gfc_trans_allocate): Same.
* trans.c (gfc_finish_block): Same.
(gfc_trans_runtime_check): Same.
(gfc_call_malloc): Same.
(gfc_allocate_with_status): Same.
(gfc_call_free): Same.
(gfc_deallocate_with_status): Same.
(gfc_call_realloc): Same.
(gfc_trans_code): Same.
* trans-decl.c (gfc_init_default_dt): Same.
(gfc_generate_constructors): Same.
* trans-io.c (gfc_trans_io_runtime_check): Same.
* trans-intrinsic.c (gfc_conv_intrinsic_ctime): Same.
(gfc_conv_intrinsic_fdate): Same.
(gfc_conv_intrinsic_ttynam): Same.
(gfc_conv_intrinsic_minmax): Same.
(gfc_conv_intrinsic_minmax_char): Same.
(gfc_conv_intrinsic_anyall): Same.
(gfc_conv_intrinsic_count): Same.
(gfc_conv_intrinsic_arith): Same.
(gfc_conv_intrinsic_minmaxloc): Same.
(gfc_conv_intrinsic_minmaxval): Same.
(gfc_conv_intrinsic_rrspacing): Same.
(gfc_conv_intrinsic_array_transfer): Same.
(gfc_conv_intrinsic_trim): Same.
(gfc_conv_intrinsic_repeat): Same.
From-SVN: r148442
2009-06-13 00:06:47 +02:00
|
|
|
decl = build_decl (loc, VAR_DECL, NULL_TREE, array_type);
|
2009-04-21 13:55:41 +02:00
|
|
|
TREE_STATIC (decl) = 1;
|
|
|
|
DECL_INITIAL (decl) = ctor;
|
|
|
|
|
|
|
|
DECL_NAME (decl) = create_tmp_var_name ("CSWTCH");
|
|
|
|
DECL_ARTIFICIAL (decl) = 1;
|
|
|
|
TREE_CONSTANT (decl) = 1;
|
2010-06-01 16:15:42 +02:00
|
|
|
TREE_READONLY (decl) = 1;
|
2009-04-21 13:55:41 +02:00
|
|
|
add_referenced_var (decl);
|
|
|
|
varpool_mark_needed_node (varpool_node (decl));
|
|
|
|
varpool_finalize_decl (decl);
|
|
|
|
|
|
|
|
fetch = build4 (ARRAY_REF, value_type, decl, tidx, NULL_TREE,
|
|
|
|
NULL_TREE);
|
2010-11-20 00:48:57 +01:00
|
|
|
if (default_type != value_type)
|
|
|
|
{
|
|
|
|
fetch = fold_convert (default_type, fetch);
|
|
|
|
fetch = force_gimple_operand_gsi (&gsi, fetch, true, NULL_TREE,
|
|
|
|
true, GSI_SAME_STMT);
|
|
|
|
}
|
2009-04-21 13:55:41 +02:00
|
|
|
load = gimple_build_assign (name, fetch);
|
|
|
|
}
|
2008-07-01 10:54:18 +02:00
|
|
|
|
2009-04-21 13:55:41 +02:00
|
|
|
SSA_NAME_DEF_STMT (name) = load;
|
2008-07-28 16:33:56 +02:00
|
|
|
gsi_insert_before (&gsi, load, GSI_SAME_STMT);
|
2009-04-21 13:55:41 +02:00
|
|
|
update_stmt (load);
|
2008-07-01 10:54:18 +02:00
|
|
|
info.arr_ref_last = load;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Builds and initializes static arrays initialized with values gathered from
|
|
|
|
the SWTCH switch statement. Also creates statements that load values from
|
|
|
|
them. */
|
|
|
|
|
|
|
|
static void
|
2008-07-28 16:33:56 +02:00
|
|
|
build_arrays (gimple swtch)
|
2008-07-01 10:54:18 +02:00
|
|
|
{
|
|
|
|
tree arr_index_type;
|
2011-04-30 08:54:02 +02:00
|
|
|
tree tidx, sub, tmp, utype;
|
2008-07-28 16:33:56 +02:00
|
|
|
gimple stmt;
|
|
|
|
gimple_stmt_iterator gsi;
|
2008-07-01 10:54:18 +02:00
|
|
|
int i;
|
re PR c/40435 (Revision 148442 caused many regressions on trunk)
2009-07-17 Aldy Hernandez <aldyh@redhat.com>
Manuel López-Ibáñez <manu@gcc.gnu.org>
PR 40435
* tree-complex.c, tree-loop-distribution.c,
tree.c, tree.h, builtins.c, fold-const.c, omp-low.c,
cgraphunit.c, tree-ssa-ccp.c, tree-ssa-dom.c,
gimple-low.c, expr.c, tree-ssa-ifcombine.c, c-decl.c,
stor-layout.c, tree-if-conv.c, c-typeck.c,
gimplify.c, calls.c, tree-sra.c, tree-mudflap.c,
tree-ssa-copy.c, tree-ssa-forwprop.c, c-convert.c, c-omp.c,
varasm.c, tree-inline.c, c-common.c,
c-common.h, gimple.c, tree-switch-conversion.c, gimple.h,
tree-cfg.c, c-parser.c, convert.c: Add location
argument to fold_{unary,binary,ternary}, fold_build[123],
build_call_expr, build_size_arg, build_fold_addr_expr,
build_call_array, non_lvalue, size_diffop,
fold_build1_initializer, fold_build2_initializer,
fold_build3_initializer, fold_build_call_array,
fold_build_call_array_initializer, fold_single_bit_test,
omit_one_operand, omit_two_operands, invert_truthvalue,
fold_truth_not_expr, build_fold_indirect_ref, fold_indirect_ref,
combine_comparisons, fold_builtin_*, fold_call_expr,
build_range_check, maybe_fold_offset_to_address, round_up,
round_down.
objc/
* objc-act.c: Add location argument to all calls to
build_fold_addr_expr.
testsuite/
* gcc.dg/pr36902.c: Add column info.
* g++.dg/gcov/gcov-2.C: Change count for definition.
cp/
* typeck.c, init.c, class.c, method.c, rtti.c, except.c, error.c,
tree.c, cp-gimplify.c, cxx-pretty-print.c, pt.c, semantics.c,
call.c, cvt.c, mangle.c: Add location argument to
fold_{unary,binary,ternary}, fold_build[123], build_call_expr,
build_size_arg, build_fold_addr_expr, build_call_array,
non_lvalue, size_diffop, fold_build1_initializer,
fold_build2_initializer, fold_build3_initializer,
fold_build_call_array, fold_build_call_array_initializer,
fold_single_bit_test, omit_one_operand, omit_two_operands,
invert_truthvalue, fold_truth_not_expr, build_fold_indirect_ref,
fold_indirect_ref, combine_comparisons, fold_builtin_*,
fold_call_expr, build_range_check, maybe_fold_offset_to_address,
round_up, round_down.
fortran/
* trans-expr.c, trans-array.c, trans-openmp.c, trans-stmt.c,
trans.c, trans-io.c, trans-decl.c, trans-intrinsic.c: Add location
argument to fold_{unary,binary,ternary}, fold_build[123],
build_call_expr, build_size_arg, build_fold_addr_expr,
build_call_array, non_lvalue, size_diffop,
fold_build1_initializer, fold_build2_initializer,
fold_build3_initializer, fold_build_call_array,
fold_build_call_array_initializer, fold_single_bit_test,
omit_one_operand, omit_two_operands, invert_truthvalue,
fold_truth_not_expr, build_fold_indirect_ref, fold_indirect_ref,
combine_comparisons, fold_builtin_*, fold_call_expr,
build_range_check, maybe_fold_offset_to_address, round_up,
round_down.
Co-Authored-By: Manuel López-Ibáñez <manu@gcc.gnu.org>
From-SVN: r149722
2009-07-17 00:29:52 +02:00
|
|
|
location_t loc = gimple_location (swtch);
|
2008-07-01 10:54:18 +02:00
|
|
|
|
2008-07-28 16:33:56 +02:00
|
|
|
gsi = gsi_for_stmt (swtch);
|
2008-07-04 11:57:59 +02:00
|
|
|
|
2011-04-30 08:54:02 +02:00
|
|
|
/* Make sure we do not generate arithmetics in a subrange. */
|
|
|
|
utype = TREE_TYPE (info.index_expr);
|
|
|
|
if (TREE_TYPE (utype))
|
|
|
|
utype = lang_hooks.types.type_for_mode (TYPE_MODE (TREE_TYPE (utype)), 1);
|
|
|
|
else
|
|
|
|
utype = lang_hooks.types.type_for_mode (TYPE_MODE (utype), 1);
|
|
|
|
|
2008-07-01 10:54:18 +02:00
|
|
|
arr_index_type = build_index_type (info.range_size);
|
2011-04-30 08:54:02 +02:00
|
|
|
tmp = create_tmp_var (utype, "csui");
|
2009-04-22 13:30:04 +02:00
|
|
|
add_referenced_var (tmp);
|
|
|
|
tidx = make_ssa_name (tmp, NULL);
|
2011-04-30 08:54:02 +02:00
|
|
|
sub = fold_build2_loc (loc, MINUS_EXPR, utype,
|
|
|
|
fold_convert_loc (loc, utype, info.index_expr),
|
|
|
|
fold_convert_loc (loc, utype, info.range_min));
|
2009-07-04 00:09:12 +02:00
|
|
|
sub = force_gimple_operand_gsi (&gsi, sub,
|
2008-07-28 16:33:56 +02:00
|
|
|
false, NULL, true, GSI_SAME_STMT);
|
|
|
|
stmt = gimple_build_assign (tidx, sub);
|
2009-04-21 13:55:41 +02:00
|
|
|
SSA_NAME_DEF_STMT (tidx) = stmt;
|
2008-07-01 10:54:18 +02:00
|
|
|
|
2008-07-28 16:33:56 +02:00
|
|
|
gsi_insert_before (&gsi, stmt, GSI_SAME_STMT);
|
2009-04-21 13:55:41 +02:00
|
|
|
update_stmt (stmt);
|
2008-07-28 16:33:56 +02:00
|
|
|
info.arr_ref_first = stmt;
|
2008-07-01 10:54:18 +02:00
|
|
|
|
2008-07-28 16:33:56 +02:00
|
|
|
for (gsi = gsi_start_phis (info.final_bb), i = 0;
|
|
|
|
!gsi_end_p (gsi); gsi_next (&gsi), i++)
|
|
|
|
build_one_array (swtch, i, arr_index_type, gsi_stmt (gsi), tidx);
|
2008-07-01 10:54:18 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
/* Generates and appropriately inserts loads of default values at the position
|
|
|
|
given by BSI. Returns the last inserted statement. */
|
|
|
|
|
2008-07-28 16:33:56 +02:00
|
|
|
static gimple
|
|
|
|
gen_def_assigns (gimple_stmt_iterator *gsi)
|
2008-07-01 10:54:18 +02:00
|
|
|
{
|
|
|
|
int i;
|
2008-07-28 16:33:56 +02:00
|
|
|
gimple assign = NULL;
|
2008-07-01 10:54:18 +02:00
|
|
|
|
|
|
|
for (i = 0; i < info.phi_count; i++)
|
|
|
|
{
|
2008-07-28 16:33:56 +02:00
|
|
|
tree name
|
|
|
|
= make_ssa_name (SSA_NAME_VAR (info.target_inbound_names[i]), NULL);
|
2008-07-01 10:54:18 +02:00
|
|
|
|
|
|
|
info.target_outbound_names[i] = name;
|
2008-07-28 16:33:56 +02:00
|
|
|
assign = gimple_build_assign (name, info.default_values[i]);
|
2008-07-01 10:54:18 +02:00
|
|
|
SSA_NAME_DEF_STMT (name) = assign;
|
2008-07-28 16:33:56 +02:00
|
|
|
gsi_insert_before (gsi, assign, GSI_SAME_STMT);
|
2009-04-21 13:55:41 +02:00
|
|
|
update_stmt (assign);
|
2008-07-01 10:54:18 +02:00
|
|
|
}
|
|
|
|
return assign;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Deletes the unused bbs and edges that now contain the switch statement and
|
|
|
|
its empty branch bbs. BBD is the now dead BB containing the original switch
|
|
|
|
statement, FINAL is the last BB of the converted switch statement (in terms
|
|
|
|
of succession). */
|
|
|
|
|
|
|
|
static void
|
|
|
|
prune_bbs (basic_block bbd, basic_block final)
|
|
|
|
{
|
|
|
|
edge_iterator ei;
|
|
|
|
edge e;
|
|
|
|
|
|
|
|
for (ei = ei_start (bbd->succs); (e = ei_safe_edge (ei)); )
|
|
|
|
{
|
|
|
|
basic_block bb;
|
|
|
|
bb = e->dest;
|
|
|
|
remove_edge (e);
|
|
|
|
if (bb != final)
|
|
|
|
delete_basic_block (bb);
|
|
|
|
}
|
|
|
|
delete_basic_block (bbd);
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Add values to phi nodes in final_bb for the two new edges. E1F is the edge
|
|
|
|
from the basic block loading values from an array and E2F from the basic
|
|
|
|
block loading default values. BBF is the last switch basic block (see the
|
|
|
|
bbf description in the comment below). */
|
|
|
|
|
|
|
|
static void
|
|
|
|
fix_phi_nodes (edge e1f, edge e2f, basic_block bbf)
|
|
|
|
{
|
2008-07-28 16:33:56 +02:00
|
|
|
gimple_stmt_iterator gsi;
|
2008-07-01 10:54:18 +02:00
|
|
|
int i;
|
|
|
|
|
2008-07-28 16:33:56 +02:00
|
|
|
for (gsi = gsi_start_phis (bbf), i = 0;
|
|
|
|
!gsi_end_p (gsi); gsi_next (&gsi), i++)
|
2008-07-01 10:54:18 +02:00
|
|
|
{
|
2008-07-28 16:33:56 +02:00
|
|
|
gimple phi = gsi_stmt (gsi);
|
Add source_location support to PHI arguments.
2009-07-29 Andrew MacLeod <amacleod@redhat.com>
PR debug 26475
* tree-into-ssa.c (insert_phi_nodes_for, rewrite_add_phi_arguments): Set
location for phi arguments.
(rewrite_update_phi_arguments): Find locations for reaching defs.
* tree-ssa-threadupdate.c (create_edge_and_update_destination_phis):
Add location to add_phi_arg calls.
* tree-loop-districbution.c (update_phis_for_loop_copy): Add locations.
* tree-ssa-loop-manip.c (create_iv, add_exit_phis_edge,
split_loop_exit_edge, tree_transform_and_unroll_loop): Add locations.
* tree-tailcall.c (add_successor_phi_arg, eliminate_tail_call,
create_tailcall_accumulator, tree_optimize_tail_calls_1): Add locations.
* tree.h (struct phi_arg_d): Add location_t to PHI arguments.
* tree-phinodes.c (make_phi_node): Initialize location.
(resize_phi_node): Initialize location to UNKNOWN_LOCATION.
(add_phi_arg): Add location parameter.
(remove_phi_arg_num): Move location when moving phi argument.
* omp-low.c (expand_parallel_call, expand_omp_for_static_chunk): Set
location.
* tree-vect-loop-manip.c (slpeel_update_phis_for_duplicate_loop,
slpeel_update_phi_nodes_for_guard1,
slpeel_update_phi_nodes_for_guard2,
slpeel_tree_duplicate_loop_to_edge_cfg, set_prologue_iterations,
vect_loop_versioning): Set locations.
* tree-parloops.c (create_phi_for_local_result,
transform_to_exit_first_loop, create_parallel_loop): Add locations.
* gimple-pretty-print.c (dump_gimple_phi): Dump lineno's if present.
* tree-vect-loop.c (get_initial_def_for_induction,
vect_create_epilog_for_reduction, vect_finalize_reduction): Add
locations.
* tree-flow-inline.h (gimple_phi_arg_location): New. Return locus.
(gimple_phi_arg_location_from_edge): New. Return locus from an edge.
(gimple_phi_arg_set_location): New. Set locus.
(gimple_phi_arg_has_location): New. Check for locus.
(redirect_edge_var_map_location): New. Return locus from var_map.
* tree-vect-data-refs.c (vect_setup_realignment): Set location.
* tree-ssa-phiopt.c (conditional_replacement): Set locus when
combining PHI arguments.
(cond_store_replacement): Set location.
* cfgexpand.c (gimple_assign_rhs_to_tree): Transfer locus if possible.
* grpahite.c (add_loop_exit_phis, add_guard_exit_phis,
scop_add_exit_phis_edge): Add locations.
* tree-cfgcleanup.c (remove_forwarder_block,
remove_forwarder_block_with_phi): Add locations.
* tree-ssa-pre.c (insert_into_preds_of_block): Add locations.
* tree-predcom.c (initialize_root_vars, initialize_root_vars_lm): Add
locations.
* tree-ssa-dce.c (forward_edge_to_pdom): Add locations.
* tree-ssa.c (redirect_edge_var_map_add, ssa_redirect_edge,
flush_pending_stmts): Add source location.
* lambda-code.c (perfect_nestify): Maintain location stack with argument
stack to preserve locations.
* tree-vect-stmts.c (vectorizable_load): Add location.
* tree-inline.c (copy_phis_for_bb): Copy locus.
(setup_one_parameter): Add call locus to inlined parameter stmts.
(initialize_inlined_parameters): Pass in call location as parameter
assignment locus.
(tree_function_versioning): Pass location to setup_one_parameter.
* tree-ssa-phiprop.c (phiprop_insert_phi): Set locations.
* tree-outof-ssa.c (struct _elim_graph): Add source_location vecs for
copy and edge lists.
(insert_partition_copy_on_edge, insert_value_copy_on_edge,
insert_rtx_to_part_on_edge, insert_part_to_rtx_on_edge): Provide a
locus parameter and override the stmt default if provided.
(new_elim_graph, clear_elim_graph, delete_elim_graph,
elim_graph_add_edge, elim_graph_remove_succ_edge,
FOR_EACH_ELIM_GRAPH_SUCC, FOR_EACH_ELIM_GRAPH_PRED, eliminate_build,
elim_forward, elim_unvisited_predecessor, elim_backward, elim_create,
eliminate_phi): Add locus info in elimination graph for each edge and
value copy.
(insert_backedge_copies): Copy locus if present.
* tree-flow.h (struct _edge_var_map): Add locus field.
* tree-switch_conversions.c (fix_phi_nodes): Add locations.
* tree-cfg.c (reinstall_phi_args, gimple_make_forwarder_block,
add_phi_args_after_copy_edge, gimple_lv_adjust_loop_header_phi): Add
locations.
* ipa-struct-reorg.c (make_edge_and_fix_phis_of_dest): Add locations.
From-SVN: r150267
2009-07-30 20:36:30 +02:00
|
|
|
add_phi_arg (phi, info.target_inbound_names[i], e1f, UNKNOWN_LOCATION);
|
|
|
|
add_phi_arg (phi, info.target_outbound_names[i], e2f, UNKNOWN_LOCATION);
|
2008-07-01 10:54:18 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Creates a check whether the switch expression value actually falls into the
|
|
|
|
range given by all the cases. If it does not, the temporaries are loaded
|
|
|
|
with default values instead. SWTCH is the switch statement being converted.
|
|
|
|
|
|
|
|
bb0 is the bb with the switch statement, however, we'll end it with a
|
|
|
|
condition instead.
|
|
|
|
|
|
|
|
bb1 is the bb to be used when the range check went ok. It is derived from
|
|
|
|
the switch BB
|
|
|
|
|
|
|
|
bb2 is the bb taken when the expression evaluated outside of the range
|
|
|
|
covered by the created arrays. It is populated by loads of default
|
|
|
|
values.
|
|
|
|
|
|
|
|
bbF is a fall through for both bb1 and bb2 and contains exactly what
|
|
|
|
originally followed the switch statement.
|
|
|
|
|
|
|
|
bbD contains the switch statement (in the end). It is unreachable but we
|
|
|
|
still need to strip off its edges.
|
|
|
|
*/
|
|
|
|
|
|
|
|
static void
|
2008-07-28 16:33:56 +02:00
|
|
|
gen_inbound_check (gimple swtch)
|
2008-07-01 10:54:18 +02:00
|
|
|
{
|
java-gimplify.c (java_gimplify_block): New argument to build_empty_stmt.
gcc/java/
* java-gimplify.c (java_gimplify_block): New argument to
build_empty_stmt.
* expr.c (force_evaluation_order): Same.
* typeck.c: Add location to build_decl or PUSH_FIELD calls.
* class.c: Same.
* decl.c: Same.
* jcf-parse.c: Same.
* constants.c: Same.
* resource.c: Same.
* except.c: Same.
* builtins.c: Same.
* expr.c: Same.
* java-tree.h (PUSH_FIELD): Add location field.
gcc/objc/
* objc-act.c (finish_var_decl): Pass location to finish_decl.
(objc_get_parm_info): Same.
(get_super_receiver): Same.
* objc-act.c (objc_build_component_ref): Pass location to
build_compound_ref.
(build_module_initializer_routine): Pass location to
c_end_compound_stmt.
(objc_generate_static_init_call): Pass location to build_stmt.
(build_typed_selector_reference): New location argument.
(build_selector_reference): Same.
(objc_substitute_decl): Pass location to build_array_ref.
(next_sjlj_build_try_catch_finally): Pass location to build_stmt.
(objc_begin_catch_clause): Same.
(objc_finish_try_stmt): Same.
(objc_finish_catch_clause): Pass location to c_end_compound_stmt.
(objc_build_throw_stmt): New argument.
(generate_shared_structures): Pass location to build_c_cast.
(objc_build_message_expr): Use local location.
(objc_finish_message_expr): Use input_location.
(build_objc_method_call): New argument.
(objc_build_selector_expr): Same.
(get_super_receiver): Pass location to build_c_cast,
build_modify_expr, build_compound_expr.
* objc-act.c: Add location to all calls to start_struct, build_decl,
finish_struct.
gcc/
* tree-pretty-print.c (dump_generic_node): Dump column numbers.
* gimple-pretty-print.c (dump_gimple_stmt): Same.
* gimplify.c (gimplify_modify_expr): Set location for GIMPLE_ASSIGNs
created.
* c-parser.c (c_parser_binary_expression): Use current column while
building binary operations.
* common.opt (fshow-column): Enable by default.
* tree-vrp.c (check_array_ref): Use warning_at.
(check_array_bounds): Use location from call back if expr has no
location.
* tree.h: Add location argument to maybe_fold_*.
* tree-ssa-ccp.c (ccp_fold): Pass location to maybe_fold_*.
(maybe_fold_offset_to_array_ref): Add location argument and use it.
(maybe_fold_offset_to_component_ref): Same.
(maybe_fold_offset_to_reference): Same.
(maybe_fold_offset_to_address): Same.
(maybe_fold_stmt_indirect): Same.
(maybe_fold_stmt_addition): Same.
(fold_stmt_r): Pass location to maybe_fold_*.
(fold_gimple_assign): Same.
* c-tree.h: Add location argument to finish_decl,
default_function_array_conversion, store_init_value.
* c-decl.c (define_label): Use error_at.
(c_make_fname_decl): Pass location to finish_decl.
(finish_decl): New location argument.
(build_compound_literal): Pass location to store_init_value.
(grokdeclarator): Pass location to finish_decl.
(grokfield): Same.
* c-typeck.c (array_to_pointer_conversion): New location argument.
(function_to_pointer_conversion): Same.
(default_function_array_conversion): Same.
(parser_build_unary_op): Pass location to overflow_warning.
(parser_build_binary_op): Same. Use warning_at.
(build_unary_op): Pass location to array_to_pointer_conversion.
(build_c_cast): Pass location to digest_init.
(build_modify_expr): New location argument.
(convert_for_assignment): Same.
(store_init_value): Same.
(digest_init): Same.
(output_init_element): Pass location to digest_init and
array_to_pointer_conversion.
(c_finish_return): Pass location to convert_for_assignment.
* gimplify.c (gimplify_conversion): Pass location to
maybe_fold_offset_to_address.
* tree-ssa-forwprop.c (forward_propagate_addr_expr_1): Pass location
to maybe_fold_stmt_addition.
* c-omp.c (c_finish_omp_atomic): Pass new location to
build_modify_expr.
(c_finish_omp_for): Same.
* c-common.c (overflow_warning): New argument.
* c-common.h: New argument to build_modify_expr, overflow_warning.
* c-parser.c (c_parser_declaration_or_fndef): Pass location to
finish_decl.
(c_parser_initializer): Pass location to
default_function_array_conversion.
(c_parser_initelt): Same.
(c_parser_initval): Same.
(c_parser_asm_operands): Same.
(c_parser_expr_no_commas): Same. Pass location to build_modify_expr.
(c_parser_conditional_expression): Same.
(c_parser_binary_expression): Add location info to stack. Use it.
(c_parser_unary_expression): Pass location to
default_function_array_conversion, parser_build_unary_op,
build_indirect_ref, c_parser_postfix_expression_after_primary.
(c_parser_postfix_expression_after_primary): New location argument.
Use it.
(c_parser_expression_conv): Pass location to
default_function_array_conversion.
(c_parser_expr_list): Same.
(c_parser_omp_atomic): Same.
(c_parser_omp_for_loop): Same.
* c-tree.h: (struct c_declarator): Add comment to id_loc.
(build_array_declarator): New argument.
* c-decl.c (build_array_declarator): Add location argument.
(grokdeclarator): Set id_loc for cdk_array.
* c-parser.c (c_parser_direct_declarator_inner): Pass location to
build_array_declarator.
* tree.c (build_omp_clause): Add location argument.
* tree.h (OMP_CLAUSE_HAS_LOCATION): New macro.
(OMP_CLAUSE_LOCATION): New macro.
(struct tree_omp_clause): Add location field.
(build_omp_clause): Add argument.
* testsuite/gcc.dg/gomp/for-1.c: Fix column.
* cp/pt.c (tsubst_omp_for_iterator): Pass location to
build_omp_clause.
* cp/parser.c (cp_parser_omp_var_list_no_open): Same.
(cp_parser_omp_clause_collapse): Same.
(cp_parser_omp_clause_default): Same.
(cp_parser_omp_clause_if): Same.
(cp_parser_omp_clause_nowait): Same.
(cp_parser_omp_clause_num_threads): Same.
(cp_parser_omp_clause_ordered): Same.
(cp_parser_omp_clause_schedule): Same.
(cp_parser_omp_clause_untied): Same.
(cp_parser_omp_for_loop): Same.
(cp_parser_omp_parallel): Pass location to c_split_parallel_clauses.
* c-tree.h (c_start_case): Add location argument.
(c_process_expr_stmt): Same.
(c_finish_goto_*): Same.
* tree-parloops.c (initialize_reductions): Pass location to
build_omp_clause.
(create_parallel_loop): Same.
* fortran/trans-openmp.c (gfc_trans_omp_variable_list): Same.
(gfc_trans_omp_reduction_list): Same.
(gfc_trans_omp_clauses): Same.
(gfc_trans_omp_do): Same.
* c-typeck.c (c_finish_goto_label): Same.
(c_finish_goto_ptr): New location argument.
(c_start_case): Same.
(emit_side_effect_warnings): Same.
(c_process_expr_stmt): Same.
(c_finish_stmt_expr): Same.
(c_finish_omp_clauses): Use error_at instead of error.
* gimplify.c (gimplify_adjust_omp_clauses_1): Pass location to
build_omp_clause.
* c-omp.c (c_split_parallel_clauses): New location argument.
* tree-nested.c (convert_nonlocal_reference_stmt): Pass location
to build_omp_clause.
(convert_local_reference_stmt): Same.
(convert_gimple_call): Same.
* c-common.h (c_split_parallel_clauses): New argument.
* c-parser.c (c_parser_statement_after_labels): Pass location to
c_finish_goto_label.
(c_parser_switch_statement): Pass location to c_start_case.
(c_parser_for_statement): Pass location to c_finish_expr_stmt,
and c_process_expr_stmt.
(c_parser_omp_variable_list): Add location argument.
(c_parser_omp_clause_collapse): Pass location to
build_omp_clause.
(c_parser_omp_clause_default): Same.
(c_parser_omp_clause_if): Same.
(c_parser_omp_clause_num_threads): Same.
(-c_parser_omp_clause_ordered): Same.
(c_parser_omp_clause_reduction): Pass location to
c_parser_omp_variable_list.
(c_parser_omp_clause_schedule): Pass location to build_omp_clause.
(c_parser_omp_clause_untied): Same.
(c_parser_omp_for_loop): Pass location to c_process_expr_stmt.
(c_parser_omp_parallel): Pass location to
c_split_parallel_clauses.
* c-tree.h (check_for_loop_decls, undeclared_variable,
build_component_ref, build_array_ref, build_external_ref,
c_expr_sizeof_expr, c_expr_sizeof_type, parser_build_unary_op,
build_conditional_expr, build_compound_expr, c_cast_expr,
build_c_cast, build_asm_expr, c_end_compound_stmt, c_finish_stmt_expr,
c_finish_return, c_finish_omp_parallel, c_finish_omp_task): New
argument.
* c-semantics.c (build_stmt): Same.
(build_case_label): Same.
* c-decl.c (c_finish_incomplete_decl): Pass location on down.
(undeclared_variable): New argument.
(make_label): Same.
(lookup_label): Pass location on down.
(define_label): Same.
(finish_decl): Same.
(build_compound_literal): Same.
(finish_struct): Same.
(finish_function): Do not set location here.
(check_for_loop_decls): New argument.
* tree.c (save_expr): Set location.
(build_empty_stmt): New argument.
* tree.h (build_empty_stmt): New argument to build_empty_stmt.
(CAN_HAVE_LOCATION_P): Make sure we have a non empty node.
* builtins.c (gimplify_va_arg_expr): Use locations.
(expand_builtin_sync_operation): Same.
* c-typeck.c (build_component_ref): New argument.
(build_array_ref): Same.
(build_external_ref): Same.
(c_expr_sizeof_expr): Same.
(c_expr_sizeof_type): Same.
(parser_build_unary_op): Same.
(build_conditional_expr): Same.
(build_compound_expr): Pass location on down.
(build_compound_expr): New argument.
(build_c_cast): Same.
(c_cast_expr): Same.
(build_asm_expr): Same.
(c_finish_return): Same.
(c_process_expr_stmt): Pass location on down.
(c_finish_stmt_expr): New argument.
(push_clenaup): Same.
(c_finish_omp_parallel): Same.
(c_finish_omp_task): Same.
* gimplify.c (gimplify_call_expr): Pass location on down.
* c-omp.c (c_finish_omp_master): New argument.
(c_finish_omp_critical): Same.
(c_finish_omp_ordered): Same.
(c_finish_omp_barrier): Same.
(-c_finish_omp_taskwait): Same.
(c_finish_omp_atomic): Same.
(c_finish_omp_flush): Same.
* tree-inline.c (copy_tree_body_r): Pass location on down.
(inline_forbidden_p): Remove use of input_location.
* c-gimplify.c (c_build_bind_expr): New argument.
* c-common.c (c_common_truthvalue_conversion): Pass location on down.
(c_sizeof_or_alignof_type): New argument.
(c_alignof_expr): Same.
(build_va_arg): Same.
(c_add_case_label): Same.
* c-common.h (c_sizeof_or_alignof_type, c_alignof_expr,
c_sizeof, c_alignof, build_va_arg, build_stmt, build_case_label,
c_build_bind_expr, objc_build_selector_expr, objc_build_throw_stmt,
c_finish_omp_master, c_finish_omp_critical, c_finish_omp_ordered,
c_finish_omp_barrier, c_finish_omp_atomic, c_finish_omp_flush,
c_finish_omp_taskwait, c_finish_omp_for, c_split_parallel_clauses):
New argument.
* stub-objc.c (objc_build_selector_expr): Same.
(objc_build_throw_stmt): Same.
* c-parser.c (c_parser_declaration_or_fndef): Pass location on down.
(c_parser_initelt): Same.
(c_parser_compound_statement): Same.
(c_parser_compound_statement_nostart): Same.
(c_parser_label): Same.
(c_parser_statement_after_labels): Same.
(c_parser_if_body): Same.
(c_parser_else_body): Same.
(c_parser_if_statement): Same.
(c_parser_switch_statement): Same.
(c_parser_while_statement): Same.
(c_parser_do_statement): Same.
(c_parser_for_statement): Same.
(c_parser_asm_statement): Same.
(c_parser_conditional_expression): Same.
(c_parser_binary_expression): Same.
(c_parser_cast_expression): Same.
(c_parser_unary_expression): Same.
(c_parser_sizeof_expression): Same.
(c_parser_alignof_expression): Same.
(c_parser_postfix_expression): Same.
(c_parser_expression): Same.
(c_parser_objc_receiver): Same.
(c_parser_omp_variable_list): Same.
(c_parser_omp_structured_block): Same.
(c_parser_omp_atomic): New argument.
(c_parser_omp_barrier): Same.
(c_parser_omp_critical): Same.
(c_parser_omp_flush): Pass location on down.
(c_parser_omp_for_loop): New argument.
(c_parser_omp_for): Same.
(c_parser_omp_master): Same.
(c_parser_omp_ordered): Same.
(c_parser_omp_sections_scope): Same.
(c_parser_omp_sections): Same.
(c_parser_omp_parallel): Same.
(c_parser_omp_single): Same.
(c_parser_omp_task): Same.
(c_parser_omp_taskwait): Pass location on down.
(c_parser_omp_construct): Same.
(c_parser_omp_threadprivate): Same.
* dwarf2asm.c, targhooks.c, optabs.c, tree.c, tree.h, target.h,
builtins.c, omp-low.c, cgraphunit.c, tree-call-cdce.c,
tree-ssa-alias.c, gimple-low.c, c-tree.h, expr.c, tree-parloops.c,
c-decl.c, tree-eh.c, langhooks.c, function.c, stor-layout.c,
c-typeck.c, gimplify.c, c-pragma.c, expmed.c, except.c, coverage.c,
emit-rtl.c, cfgexpand.c, tree-mudflap.c, varasm.c, tree-nested.c,
rtl.h, tree-inline.c, tree-profile.c, c-common.c, c-common.h,
tree-switch-conversion.c, tree-cfg.c, ipa-struct-reorg.c, c-parser.c,
config/i386/i386.c, stmt.c:
Add location argument to the following function definitions and/or
function calls: build_decl, objcp_start_struct, objcp_finish_struct,
start_struct, finish_struct, PUSH_FIELD, create_artificial_label,
cp_make_fname_decl, pushtag, implicitly_declare, c_make_fname_decl,
build_compound_literal, parser_xref_tag, resolve_overloaded_builtin,
do_case, c_finish_bc_stmt, build_compound_literal,
build_function_call.
* c-decl.c (build_compound_literal): Add location argument.
Make all diagnostic calls use location.
(start_struct): Same.
(finish_struct): Same.
(start_enum): Same.
(build_enumerator): Same.
(start_function): Same.
(grokdeclarator): Make all diagnostic calls use location.
(store_parm_decls_oldstyle): Same.
* c-typeck.c (build_function_call): Add location argument.
Make all diagnostic calls use location.
(do_case): Same.
(c_finish_bc_stmt): Same.
* tree-nested.c (get_trampoline_type): Add argument.
Pass location to build_decl.
(lookup_tramp_for_decl): Pass location to get_trampoline_type.
* rtl.h (RTL_LOCATION): New.
* c-common.c (c_add_case_label): Add location argument.
Make all diagnostic calls use location.
* c-common.h: Add location argument to make_fname_decl, do_case,
c_add_case_label, build_function_call, resolve_overloaded_builtin.
* c-parser.c (c_parser_enum_specifier): Rename ident_loc to enum_loc.
Set it appropriately for every case. Pass enum_loc to start_enum
call. Pass value_loc first to build_enumerator. Pass enum_loc to
parser_xref_tag.
(c_parser_struct_or_union_specifier): Save location. Use it for
start_struct, finish_struct, and parser_xref_tag.
gcc/testsuite/
* gcc.dg/old-style-prom-3.c: Add column info.
* gcc.dg/overflow-warn-1.c
* gcc.dg/gomp/pr27415.c
* gcc.dg/gomp/for-1.c: Same.
* gcc.dg/enum-compat-1.c: Same.
* gcc.dg/c99-tag-3.c: Same.
* gcc.dg/Wredundant-decls-2.c: Same.
* gcc.dg/func-ptr-conv-1.c: Same.
* gcc.dg/asm-wide-1.c: Same.
* gcc.dg/nofixed-point-2.c: Same.
* gcc.dg/cpp/line3.c: Same.
* gcc.dg/array-10.c: Same.
* gcc.dg/c99-vla-jump-1.c: Same.
* gcc.dg/pr20368-1.c: Same.
* gcc.dg/Wshadow-3.c: Same.
* gcc.dg/c90-const-expr-8.c: Same.
* gcc.dg/label-decl-2.c: Same.
* gcc.dg/dremf-type-compat-2.c: Same.
* gcc.dg/c90-const-expr-5.c: Same.
* gcc.dg/builtins-30.c: Same.
* gcc.dg/Warray-bounds.c: Same.
* gcc.dg/Wcxx-compat-2.c: Same.
* gcc.dg/tree-ssa/col-1.c: Same.
* gcc.dg/old-style-prom-2.c: Same.
* gcc.dg/cast-function-1.c: Same.
* gcc.dg/pr15698-1.c: Same.
* gcc.dg/dremf-type-compat-3.c: Same.
* gcc.dg/vla-8.c: Same.
* gcc.dg/gomp/pr27415.c: Move firstprivate diagnostics to correct
line.
* gcc.dg/label-decl-2.c: Move label diagnostic to correct line.
* gcc.dg/old-style-prom-3.c: Check for error on the correct line.
* gcc.dg/enum-compat-1.c: Same.
* gcc.dg/dremf-type-compat-2.c: Same.
* gcc.dg/old-style-prom-2.c: Same.
* gcc.dg/pr15698-1.c: Same.
* gcc.dg/pr20368-1.c: Same.
* gcc.dg/dremf-type-compat-3.c: Same.
* gcc.dg/builtins-30.c: Same. Test for columns.
gcc/objcp/
* objcp-decl.h (c_end_compound_stmt): New argument.
* objcp-decl.c (objcp_start_struct): Add argument.
(objcp_finish_struct): Same.
gcc/cp/
* typeck.c (cp_build_binary_op): Pass location to overflow_warning.
(build_modify_expr): New arg.
* semantics.c (finish_unary_op_expr): Pass location to
overflow_warning.
(handle_omp_for_class_iterator): Pass location to build_modify_expr.
* typeck.c (cxx_sizeof_or_alignof_type): Pass location to
c_sizeof_or_alignof_type.
(build_array_ref): New argument.
(build_compound_expr): Same.
(build_const_cast): Same.
(build_ptrmemfunc): Pass location to build_c_cast.
* init.c (avoid_placement_new_aliasing): Pass location to
build_stmt.
(build_vec_delete_1): Pass location to cp_build_modify_expr,
build_compound_expr.
* class.c (build_vtbl_ref_1): Pass location to build_array_ref.
* decl.c (poplevel): Pass location to c_build_bind_expr.
(finish_case_label): Pass location to build_case_label.
(finish_constructor_body): Same.
(finish_destructor_body): Pass location to build_stmt.
(cxx_maybe_build_cleanup): Same, but to build_compound_expr.
* call.c (build_new_op): Pass location to build_array_ref.
(build_x_va_arg): Pass location to build_va_arg.
* except.c (expand_end_catch_block): Pass location to
build_stmt.
* cp-tree.h (build_array_ref): New argument.
(build_compound_expr): Same.
(build_c_cast): Same.
* cp-gimplify.c (gimplify_if_stmt): Pass location on down.
(gimplify_switch_stmt): Same.
* typeck2.c (split_nonconstant_init_1): Same.
* pt.c (tsubst_copy): Same.
* semantics.c (add_decl_expr): Same.
(do_poplevel): Same.
(push_cleanup): Same.
(finish_goto_stmt): Same.
(finish_expr_stmt): Same.
(begin_if_stmt): Same.
(begin_while_stmt): Same.
(begin_do_stmt): Same.
(finish_return_stmt): Same.
(begin_for_stmt): Same.
(finish_break_stmt): Same.
(finish_continue_stmt): Same.
(begin_switch_stmt): Same.
(begin_try_block): Same.
(begin_handler): Same.
(finish_asm_stmt): Same.
(finish_label_stmt): Same.
(finish_stmt_expr_expr): Same.
(finalize_nrv_r): Same.
(finish_omp_atomic): Same.
* name-lookup.c (do_using_directive): Same.
* decl2.c (grok_array_decl): Same.
* parser.c (cp_parser_cast_expression): Same.
(cp_parser_selection_statement): Same.
(cp_parser_implicitly_scoped_statement): Same.
(cp_parser_objc_selector_expression): Same.
(cp_parser_objc_synchronized_statement): Same.
(cp_parser_objc_throw_statement): Same.
(cp_parser_omp_critical): Same.
(cp_parser_omp_master): Same.
* typeck.c (build_function_call): Add location argument.
* init.c: Add location argument to all build_decl calls.
* class.c: Same.
* method.c: Same.
* rtti.c: Same.
* tree.c: Same.
* pt.c: Same.
* semantics.c: Same.
* lex.c: Same.
* decl2.c: Same.
* cp-gimplify.c: Same.
* decl.c: Same.
(cp_make_fname_decl): Add location argument. Pass location ot
build_decl.
(finish_case_label): Same.
* cp-tree.h (finish_case_label): Add location argument.
* parser.c (cp_parser_label_for_labeled_statement): Pass location to
finish_case_label.
gcc/fortran/
* trans-array.c (gfc_trans_allocate_array_storage): Pass
location on down.
(gfc_trans_array_constructor_value): Same.
(gfc_trans_scalarized_loop_end): Same.
(gfc_conv_ss_startstride): Same.
(gfc_trans_g77_array): Same.
(gfc_trans_dummy_array_bias): Same.
(gfc_conv_array_parameter): Same.
(structure_alloc_comps): Same.
* trans-expr.c (gfc_conv_function_call): Same.
(fill_with_spaces): Same.
(gfc_trans_string_copy): Same.
(gfc_trans_scalar_assign): Same.
* trans-stmt.c (gfc_trans_goto): Same.
(gfc_trans_if_1): Same.
(gfc_trans_simple_do): Same.
(gfc_trans_do): Same.
(gfc_trans_do_while): Same.
(gfc_trans_logical_select): Same.
(gfc_trans_select): Same.
(gfc_trans_forall_loop): Same.
(gfc_trans_nested_forall_loop): Same.
(generate_loop_for_temp_to_lhs): Same.
(generate_loop_for_rhs_to_temp): Same.
(gfc_trans_forall_1): Same.
(gfc_trans_where_assign): Same.
(gfc_trans_where_3): Same.
(gfc_trans_allocate): Same.
* trans.c (gfc_finish_block): Same.
(gfc_trans_runtime_check): Same.
(gfc_call_malloc): Same.
(gfc_allocate_with_status): Same.
(gfc_call_free): Same.
(gfc_deallocate_with_status): Same.
(gfc_call_realloc): Same.
(gfc_trans_code): Same.
* trans-decl.c (gfc_init_default_dt): Same.
(gfc_generate_constructors): Same.
* trans-io.c (gfc_trans_io_runtime_check): Same.
* trans-intrinsic.c (gfc_conv_intrinsic_ctime): Same.
(gfc_conv_intrinsic_fdate): Same.
(gfc_conv_intrinsic_ttynam): Same.
(gfc_conv_intrinsic_minmax): Same.
(gfc_conv_intrinsic_minmax_char): Same.
(gfc_conv_intrinsic_anyall): Same.
(gfc_conv_intrinsic_count): Same.
(gfc_conv_intrinsic_arith): Same.
(gfc_conv_intrinsic_minmaxloc): Same.
(gfc_conv_intrinsic_minmaxval): Same.
(gfc_conv_intrinsic_rrspacing): Same.
(gfc_conv_intrinsic_array_transfer): Same.
(gfc_conv_intrinsic_trim): Same.
(gfc_conv_intrinsic_repeat): Same.
From-SVN: r148442
2009-06-13 00:06:47 +02:00
|
|
|
tree label_decl1 = create_artificial_label (UNKNOWN_LOCATION);
|
|
|
|
tree label_decl2 = create_artificial_label (UNKNOWN_LOCATION);
|
|
|
|
tree label_decl3 = create_artificial_label (UNKNOWN_LOCATION);
|
2008-07-28 16:33:56 +02:00
|
|
|
gimple label1, label2, label3;
|
2011-04-30 08:54:02 +02:00
|
|
|
tree utype, tidx;
|
2008-07-01 10:54:18 +02:00
|
|
|
tree bound;
|
|
|
|
|
2008-07-28 16:33:56 +02:00
|
|
|
gimple cond_stmt;
|
2008-07-01 10:54:18 +02:00
|
|
|
|
2008-07-28 16:33:56 +02:00
|
|
|
gimple last_assign;
|
|
|
|
gimple_stmt_iterator gsi;
|
2008-07-01 10:54:18 +02:00
|
|
|
basic_block bb0, bb1, bb2, bbf, bbd;
|
|
|
|
edge e01, e02, e21, e1d, e1f, e2f;
|
re PR c/40435 (Revision 148442 caused many regressions on trunk)
2009-07-17 Aldy Hernandez <aldyh@redhat.com>
Manuel López-Ibáñez <manu@gcc.gnu.org>
PR 40435
* tree-complex.c, tree-loop-distribution.c,
tree.c, tree.h, builtins.c, fold-const.c, omp-low.c,
cgraphunit.c, tree-ssa-ccp.c, tree-ssa-dom.c,
gimple-low.c, expr.c, tree-ssa-ifcombine.c, c-decl.c,
stor-layout.c, tree-if-conv.c, c-typeck.c,
gimplify.c, calls.c, tree-sra.c, tree-mudflap.c,
tree-ssa-copy.c, tree-ssa-forwprop.c, c-convert.c, c-omp.c,
varasm.c, tree-inline.c, c-common.c,
c-common.h, gimple.c, tree-switch-conversion.c, gimple.h,
tree-cfg.c, c-parser.c, convert.c: Add location
argument to fold_{unary,binary,ternary}, fold_build[123],
build_call_expr, build_size_arg, build_fold_addr_expr,
build_call_array, non_lvalue, size_diffop,
fold_build1_initializer, fold_build2_initializer,
fold_build3_initializer, fold_build_call_array,
fold_build_call_array_initializer, fold_single_bit_test,
omit_one_operand, omit_two_operands, invert_truthvalue,
fold_truth_not_expr, build_fold_indirect_ref, fold_indirect_ref,
combine_comparisons, fold_builtin_*, fold_call_expr,
build_range_check, maybe_fold_offset_to_address, round_up,
round_down.
objc/
* objc-act.c: Add location argument to all calls to
build_fold_addr_expr.
testsuite/
* gcc.dg/pr36902.c: Add column info.
* g++.dg/gcov/gcov-2.C: Change count for definition.
cp/
* typeck.c, init.c, class.c, method.c, rtti.c, except.c, error.c,
tree.c, cp-gimplify.c, cxx-pretty-print.c, pt.c, semantics.c,
call.c, cvt.c, mangle.c: Add location argument to
fold_{unary,binary,ternary}, fold_build[123], build_call_expr,
build_size_arg, build_fold_addr_expr, build_call_array,
non_lvalue, size_diffop, fold_build1_initializer,
fold_build2_initializer, fold_build3_initializer,
fold_build_call_array, fold_build_call_array_initializer,
fold_single_bit_test, omit_one_operand, omit_two_operands,
invert_truthvalue, fold_truth_not_expr, build_fold_indirect_ref,
fold_indirect_ref, combine_comparisons, fold_builtin_*,
fold_call_expr, build_range_check, maybe_fold_offset_to_address,
round_up, round_down.
fortran/
* trans-expr.c, trans-array.c, trans-openmp.c, trans-stmt.c,
trans.c, trans-io.c, trans-decl.c, trans-intrinsic.c: Add location
argument to fold_{unary,binary,ternary}, fold_build[123],
build_call_expr, build_size_arg, build_fold_addr_expr,
build_call_array, non_lvalue, size_diffop,
fold_build1_initializer, fold_build2_initializer,
fold_build3_initializer, fold_build_call_array,
fold_build_call_array_initializer, fold_single_bit_test,
omit_one_operand, omit_two_operands, invert_truthvalue,
fold_truth_not_expr, build_fold_indirect_ref, fold_indirect_ref,
combine_comparisons, fold_builtin_*, fold_call_expr,
build_range_check, maybe_fold_offset_to_address, round_up,
round_down.
Co-Authored-By: Manuel López-Ibáñez <manu@gcc.gnu.org>
From-SVN: r149722
2009-07-17 00:29:52 +02:00
|
|
|
location_t loc = gimple_location (swtch);
|
2008-07-01 10:54:18 +02:00
|
|
|
|
|
|
|
gcc_assert (info.default_values);
|
2008-07-28 16:33:56 +02:00
|
|
|
bb0 = gimple_bb (swtch);
|
2008-07-01 10:54:18 +02:00
|
|
|
|
2011-04-30 08:54:02 +02:00
|
|
|
tidx = gimple_assign_lhs (info.arr_ref_first);
|
|
|
|
utype = TREE_TYPE (tidx);
|
2008-07-14 13:28:39 +02:00
|
|
|
|
2008-07-01 10:54:18 +02:00
|
|
|
/* (end of) block 0 */
|
2008-07-28 16:33:56 +02:00
|
|
|
gsi = gsi_for_stmt (info.arr_ref_first);
|
2011-04-30 08:54:02 +02:00
|
|
|
gsi_next (&gsi);
|
2008-07-01 10:54:18 +02:00
|
|
|
|
re PR c/40435 (Revision 148442 caused many regressions on trunk)
2009-07-17 Aldy Hernandez <aldyh@redhat.com>
Manuel López-Ibáñez <manu@gcc.gnu.org>
PR 40435
* tree-complex.c, tree-loop-distribution.c,
tree.c, tree.h, builtins.c, fold-const.c, omp-low.c,
cgraphunit.c, tree-ssa-ccp.c, tree-ssa-dom.c,
gimple-low.c, expr.c, tree-ssa-ifcombine.c, c-decl.c,
stor-layout.c, tree-if-conv.c, c-typeck.c,
gimplify.c, calls.c, tree-sra.c, tree-mudflap.c,
tree-ssa-copy.c, tree-ssa-forwprop.c, c-convert.c, c-omp.c,
varasm.c, tree-inline.c, c-common.c,
c-common.h, gimple.c, tree-switch-conversion.c, gimple.h,
tree-cfg.c, c-parser.c, convert.c: Add location
argument to fold_{unary,binary,ternary}, fold_build[123],
build_call_expr, build_size_arg, build_fold_addr_expr,
build_call_array, non_lvalue, size_diffop,
fold_build1_initializer, fold_build2_initializer,
fold_build3_initializer, fold_build_call_array,
fold_build_call_array_initializer, fold_single_bit_test,
omit_one_operand, omit_two_operands, invert_truthvalue,
fold_truth_not_expr, build_fold_indirect_ref, fold_indirect_ref,
combine_comparisons, fold_builtin_*, fold_call_expr,
build_range_check, maybe_fold_offset_to_address, round_up,
round_down.
objc/
* objc-act.c: Add location argument to all calls to
build_fold_addr_expr.
testsuite/
* gcc.dg/pr36902.c: Add column info.
* g++.dg/gcov/gcov-2.C: Change count for definition.
cp/
* typeck.c, init.c, class.c, method.c, rtti.c, except.c, error.c,
tree.c, cp-gimplify.c, cxx-pretty-print.c, pt.c, semantics.c,
call.c, cvt.c, mangle.c: Add location argument to
fold_{unary,binary,ternary}, fold_build[123], build_call_expr,
build_size_arg, build_fold_addr_expr, build_call_array,
non_lvalue, size_diffop, fold_build1_initializer,
fold_build2_initializer, fold_build3_initializer,
fold_build_call_array, fold_build_call_array_initializer,
fold_single_bit_test, omit_one_operand, omit_two_operands,
invert_truthvalue, fold_truth_not_expr, build_fold_indirect_ref,
fold_indirect_ref, combine_comparisons, fold_builtin_*,
fold_call_expr, build_range_check, maybe_fold_offset_to_address,
round_up, round_down.
fortran/
* trans-expr.c, trans-array.c, trans-openmp.c, trans-stmt.c,
trans.c, trans-io.c, trans-decl.c, trans-intrinsic.c: Add location
argument to fold_{unary,binary,ternary}, fold_build[123],
build_call_expr, build_size_arg, build_fold_addr_expr,
build_call_array, non_lvalue, size_diffop,
fold_build1_initializer, fold_build2_initializer,
fold_build3_initializer, fold_build_call_array,
fold_build_call_array_initializer, fold_single_bit_test,
omit_one_operand, omit_two_operands, invert_truthvalue,
fold_truth_not_expr, build_fold_indirect_ref, fold_indirect_ref,
combine_comparisons, fold_builtin_*, fold_call_expr,
build_range_check, maybe_fold_offset_to_address, round_up,
round_down.
Co-Authored-By: Manuel López-Ibáñez <manu@gcc.gnu.org>
From-SVN: r149722
2009-07-17 00:29:52 +02:00
|
|
|
bound = fold_convert_loc (loc, utype, info.range_size);
|
2011-04-30 08:54:02 +02:00
|
|
|
cond_stmt = gimple_build_cond (LE_EXPR, tidx, bound, NULL_TREE, NULL_TREE);
|
2008-07-28 16:33:56 +02:00
|
|
|
gsi_insert_before (&gsi, cond_stmt, GSI_SAME_STMT);
|
2009-04-21 13:55:41 +02:00
|
|
|
update_stmt (cond_stmt);
|
2008-07-01 10:54:18 +02:00
|
|
|
|
|
|
|
/* block 2 */
|
2008-07-28 16:33:56 +02:00
|
|
|
label2 = gimple_build_label (label_decl2);
|
|
|
|
gsi_insert_before (&gsi, label2, GSI_SAME_STMT);
|
|
|
|
last_assign = gen_def_assigns (&gsi);
|
2008-07-01 10:54:18 +02:00
|
|
|
|
|
|
|
/* block 1 */
|
2008-07-28 16:33:56 +02:00
|
|
|
label1 = gimple_build_label (label_decl1);
|
|
|
|
gsi_insert_before (&gsi, label1, GSI_SAME_STMT);
|
2008-07-01 10:54:18 +02:00
|
|
|
|
|
|
|
/* block F */
|
2008-07-28 16:33:56 +02:00
|
|
|
gsi = gsi_start_bb (info.final_bb);
|
|
|
|
label3 = gimple_build_label (label_decl3);
|
|
|
|
gsi_insert_before (&gsi, label3, GSI_SAME_STMT);
|
2008-07-01 10:54:18 +02:00
|
|
|
|
|
|
|
/* cfg fix */
|
2008-07-28 16:33:56 +02:00
|
|
|
e02 = split_block (bb0, cond_stmt);
|
2008-07-01 10:54:18 +02:00
|
|
|
bb2 = e02->dest;
|
|
|
|
|
|
|
|
e21 = split_block (bb2, last_assign);
|
|
|
|
bb1 = e21->dest;
|
|
|
|
remove_edge (e21);
|
|
|
|
|
|
|
|
e1d = split_block (bb1, info.arr_ref_last);
|
|
|
|
bbd = e1d->dest;
|
|
|
|
remove_edge (e1d);
|
|
|
|
|
|
|
|
/* flags and profiles of the edge for in-range values */
|
|
|
|
e01 = make_edge (bb0, bb1, EDGE_TRUE_VALUE);
|
|
|
|
e01->probability = REG_BR_PROB_BASE - info.default_prob;
|
|
|
|
e01->count = info.other_count;
|
|
|
|
|
|
|
|
/* flags and profiles of the edge taking care of out-of-range values */
|
|
|
|
e02->flags &= ~EDGE_FALLTHRU;
|
|
|
|
e02->flags |= EDGE_FALSE_VALUE;
|
|
|
|
e02->probability = info.default_prob;
|
|
|
|
e02->count = info.default_count;
|
|
|
|
|
|
|
|
bbf = info.final_bb;
|
|
|
|
|
|
|
|
e1f = make_edge (bb1, bbf, EDGE_FALLTHRU);
|
|
|
|
e1f->probability = REG_BR_PROB_BASE;
|
|
|
|
e1f->count = info.other_count;
|
|
|
|
|
|
|
|
e2f = make_edge (bb2, bbf, EDGE_FALLTHRU);
|
|
|
|
e2f->probability = REG_BR_PROB_BASE;
|
|
|
|
e2f->count = info.default_count;
|
|
|
|
|
|
|
|
/* frequencies of the new BBs */
|
|
|
|
bb1->frequency = EDGE_FREQUENCY (e01);
|
|
|
|
bb2->frequency = EDGE_FREQUENCY (e02);
|
|
|
|
bbf->frequency = EDGE_FREQUENCY (e1f) + EDGE_FREQUENCY (e2f);
|
|
|
|
|
2008-07-28 16:33:56 +02:00
|
|
|
prune_bbs (bbd, info.final_bb); /* To keep calc_dfs_tree() in dominance.c
|
|
|
|
happy. */
|
2008-07-01 10:54:18 +02:00
|
|
|
|
|
|
|
fix_phi_nodes (e1f, e2f, bbf);
|
|
|
|
|
|
|
|
free_dominance_info (CDI_DOMINATORS);
|
|
|
|
free_dominance_info (CDI_POST_DOMINATORS);
|
|
|
|
}
|
|
|
|
|
|
|
|
/* The following function is invoked on every switch statement (the current one
|
|
|
|
is given in SWTCH) and runs the individual phases of switch conversion on it
|
|
|
|
one after another until one fails or the conversion is completed. */
|
|
|
|
|
|
|
|
static bool
|
2008-07-28 16:33:56 +02:00
|
|
|
process_switch (gimple swtch)
|
2008-07-01 10:54:18 +02:00
|
|
|
{
|
2008-07-28 16:33:56 +02:00
|
|
|
unsigned int i, branch_num = gimple_switch_num_labels (swtch);
|
2008-07-01 10:54:18 +02:00
|
|
|
tree index_type;
|
|
|
|
|
|
|
|
/* Operand 2 is either NULL_TREE or a vector of cases (stmt.c). */
|
2008-07-28 16:33:56 +02:00
|
|
|
if (branch_num < 2)
|
2008-07-01 10:54:18 +02:00
|
|
|
{
|
2008-07-28 16:33:56 +02:00
|
|
|
info.reason = "switch has no labels\n";
|
2008-07-01 10:54:18 +02:00
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
info.final_bb = NULL;
|
2008-07-28 16:33:56 +02:00
|
|
|
info.switch_bb = gimple_bb (swtch);
|
|
|
|
info.index_expr = gimple_switch_index (swtch);
|
2008-07-01 10:54:18 +02:00
|
|
|
index_type = TREE_TYPE (info.index_expr);
|
2008-07-28 16:33:56 +02:00
|
|
|
info.arr_ref_first = NULL;
|
|
|
|
info.arr_ref_last = NULL;
|
2008-07-01 10:54:18 +02:00
|
|
|
info.default_prob = 0;
|
|
|
|
info.default_count = 0;
|
|
|
|
info.other_count = 0;
|
2010-11-20 00:48:57 +01:00
|
|
|
info.bit_test_uniq = 0;
|
|
|
|
info.bit_test_count = 0;
|
|
|
|
info.bit_test_bb[0] = NULL;
|
|
|
|
info.bit_test_bb[1] = NULL;
|
2008-07-01 10:54:18 +02:00
|
|
|
|
|
|
|
/* An ERROR_MARK occurs for various reasons including invalid data type.
|
|
|
|
(comment from stmt.c) */
|
|
|
|
if (index_type == error_mark_node)
|
|
|
|
{
|
|
|
|
info.reason = "index error.\n";
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Check the case label values are within reasonable range: */
|
|
|
|
if (!check_range (swtch))
|
|
|
|
return false;
|
|
|
|
|
|
|
|
/* For all the cases, see whether they are empty, the assignments they
|
|
|
|
represent constant and so on... */
|
2008-07-28 16:33:56 +02:00
|
|
|
for (i = 0; i < branch_num; i++)
|
|
|
|
if (!check_process_case (gimple_switch_label (swtch, i)))
|
|
|
|
{
|
|
|
|
if (dump_file)
|
|
|
|
fprintf (dump_file, "Processing of case %i failed\n", i);
|
|
|
|
return false;
|
|
|
|
}
|
2008-07-01 10:54:18 +02:00
|
|
|
|
2010-11-20 00:48:57 +01:00
|
|
|
if (info.bit_test_uniq <= 2)
|
|
|
|
{
|
|
|
|
rtl_profile_for_bb (gimple_bb (swtch));
|
|
|
|
if (expand_switch_using_bit_tests_p (gimple_switch_index (swtch),
|
|
|
|
info.range_size, info.bit_test_uniq,
|
|
|
|
info.bit_test_count))
|
|
|
|
{
|
|
|
|
info.reason = " Expanding as bit test is preferable\n";
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2008-07-01 10:54:18 +02:00
|
|
|
if (!check_final_bb ())
|
|
|
|
return false;
|
|
|
|
|
|
|
|
/* At this point all checks have passed and we can proceed with the
|
|
|
|
transformation. */
|
|
|
|
|
|
|
|
create_temp_arrays ();
|
2008-07-28 16:33:56 +02:00
|
|
|
gather_default_values (gimple_switch_label (swtch, 0));
|
2008-07-01 10:54:18 +02:00
|
|
|
build_constructors (swtch);
|
|
|
|
|
|
|
|
build_arrays (swtch); /* Build the static arrays and assignments. */
|
2008-07-02 11:47:09 +02:00
|
|
|
gen_inbound_check (swtch); /* Build the bounds check. */
|
2008-07-01 10:54:18 +02:00
|
|
|
|
|
|
|
/* Cleanup: */
|
|
|
|
free_temp_arrays ();
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* The main function of the pass scans statements for switches and invokes
|
|
|
|
process_switch on them. */
|
|
|
|
|
|
|
|
static unsigned int
|
|
|
|
do_switchconv (void)
|
|
|
|
{
|
|
|
|
basic_block bb;
|
|
|
|
|
|
|
|
FOR_EACH_BB (bb)
|
|
|
|
{
|
2008-07-28 16:33:56 +02:00
|
|
|
gimple stmt = last_stmt (bb);
|
|
|
|
if (stmt && gimple_code (stmt) == GIMPLE_SWITCH)
|
2008-07-01 10:54:18 +02:00
|
|
|
{
|
|
|
|
if (dump_file)
|
|
|
|
{
|
2008-07-28 16:33:56 +02:00
|
|
|
expanded_location loc = expand_location (gimple_location (stmt));
|
|
|
|
|
2008-07-01 10:54:18 +02:00
|
|
|
fprintf (dump_file, "beginning to process the following "
|
|
|
|
"SWITCH statement (%s:%d) : ------- \n",
|
|
|
|
loc.file, loc.line);
|
2008-07-28 16:33:56 +02:00
|
|
|
print_gimple_stmt (dump_file, stmt, 0, TDF_SLIM);
|
2009-09-10 18:21:45 +02:00
|
|
|
putc ('\n', dump_file);
|
2008-07-01 10:54:18 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
info.reason = NULL;
|
|
|
|
if (process_switch (stmt))
|
|
|
|
{
|
|
|
|
if (dump_file)
|
|
|
|
{
|
2009-09-10 18:21:45 +02:00
|
|
|
fputs ("Switch converted\n", dump_file);
|
|
|
|
fputs ("--------------------------------\n", dump_file);
|
2008-07-01 10:54:18 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
if (dump_file)
|
|
|
|
{
|
|
|
|
gcc_assert (info.reason);
|
2009-09-10 18:21:45 +02:00
|
|
|
fputs ("Bailing out - ", dump_file);
|
|
|
|
fputs (info.reason, dump_file);
|
|
|
|
fputs ("--------------------------------\n", dump_file);
|
2008-07-01 10:54:18 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* The pass gate. */
|
|
|
|
|
|
|
|
static bool
|
|
|
|
switchconv_gate (void)
|
|
|
|
{
|
|
|
|
return flag_tree_switch_conversion != 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
struct gimple_opt_pass pass_convert_switch =
|
|
|
|
{
|
|
|
|
{
|
|
|
|
GIMPLE_PASS,
|
|
|
|
"switchconv", /* name */
|
2008-07-02 11:47:09 +02:00
|
|
|
switchconv_gate, /* gate */
|
2008-07-01 10:54:18 +02:00
|
|
|
do_switchconv, /* execute */
|
|
|
|
NULL, /* sub */
|
|
|
|
NULL, /* next */
|
|
|
|
0, /* static_pass_number */
|
2008-07-02 11:59:34 +02:00
|
|
|
TV_TREE_SWITCH_CONVERSION, /* tv_id */
|
2008-07-01 10:54:18 +02:00
|
|
|
PROP_cfg | PROP_ssa, /* properties_required */
|
|
|
|
0, /* properties_provided */
|
|
|
|
0, /* properties_destroyed */
|
|
|
|
0, /* todo_flags_start */
|
2011-06-14 21:39:36 +02:00
|
|
|
TODO_update_ssa
|
2008-07-01 10:54:18 +02:00
|
|
|
| TODO_ggc_collect | TODO_verify_ssa /* todo_flags_finish */
|
|
|
|
}
|
|
|
|
};
|