summaryrefslogtreecommitdiff
path: root/gcc/cp
diff options
context:
space:
mode:
Diffstat (limited to 'gcc/cp')
-rw-r--r--gcc/cp/ChangeLog140
-rw-r--r--gcc/cp/Make-lang.in8
-rw-r--r--gcc/cp/cp-gimplify.c243
-rw-r--r--gcc/cp/cp-tree.h5
-rw-r--r--gcc/cp/decl.c2
-rw-r--r--gcc/cp/decl2.c3
-rw-r--r--gcc/cp/except.c7
-rw-r--r--gcc/cp/init.c5
-rw-r--r--gcc/cp/optimize.c28
-rw-r--r--gcc/cp/semantics.c3
10 files changed, 318 insertions, 126 deletions
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog
index 6a13613d860..ad2964cf403 100644
--- a/gcc/cp/ChangeLog
+++ b/gcc/cp/ChangeLog
@@ -1,3 +1,143 @@
+2008-07-28 Richard Guenther <rguenther@suse.de>
+
+ Merge from gimple-tuples-branch.
+
+ 2008-07-22 Aldy Hernandez <aldyh@redhat.com>
+
+ * cp-gimplify.c (gimplify_if_stmt): Set location on newly created
+ COND_EXPR.
+
+ 2008-07-18 Jakub Jelinek <jakub@redhat.com>
+
+ * decl.c (finish_function): Call gimple_body after cp_genericize.
+
+ 2008-07-18 Aldy Hernandez <aldyh@redhat.com>
+
+ * optimize.c: Include gimple.h instead of tree-gimple.h.
+ * Make-lang.in (cp-gimplify.o): Depend on tree-iterator.h.
+ * cp-gimplify.c: Rename tree-gimple.h to gimple.h. Include
+ tree-iterator.h.
+
+ 2008-07-16 Jakub Jelinek <jakub@redhat.com>
+
+ * optimize.c (maybe_clone_body): Clear DECL_SAVED_TREE for the clone.
+
+ 2008-07-14 Jakub Jelinek <jakub@redhat.com>
+
+ * cp-gimplify.c (cp_gimplify_expr): Update comment.
+
+ 2008-07-14 Aldy Hernandez <aldyh@redhat.com>
+
+ * cp-tree.h (union lang_tree_node): Rename GENERIC_NEXT to
+ TREE_CHAIN.
+ * cp-gimplify.c (cxx_omp_clause_apply_fn): Rename
+ GIMPLE_MODIFY_STMT to MODIFY_EXPR.
+ (cxx_omp_clause_copy_ctor): Same.
+ (cxx_omp_clause_assign_op): Same.
+
+ 2008-05-28 Jakub Jelinek <jakub@redhat.com>
+
+ * cp-gimplify.c (cp_gimplify_omp_for): Add pre_p argument. Tuplify.
+ (cp_gimplify_expr): Adjust caller.
+
+ 2008-05-11 Doug Kwan <dougkwan@google.com>
+
+ * init.c (build_vec_delete): Add type conversion for argument
+ 0 of POINTER_PLUS_EXPR.
+
+ 2008-04-29 Doug Kwan <dougkwan@google.com>
+
+ * decl2 (File): Include "gimple.h"
+ (cp_write_global_declarations): Use gimple_body instead of
+ DECL_SAVED_TREE.
+ * Make-lang.in (cp/decl2.o): Add $(GIMPLE_H)
+
+ 2008-04-10 Diego Novillo <dnovillo@google.com>
+
+ http://gcc.gnu.org/ml/gcc-patches/2008-04/msg00913.html
+
+ * optimize.c (maybe_clone_body): Re-enable call to
+ clone_body.
+ * cp-gimplify.c (cp_gimplify_omp_for): Mark disabled
+ code with call to gimple_unreachable.
+ (cp_genericize): Fix handling of clone bodies.
+
+ 2008-04-04 Diego Novillo <dnovillo@google.com>
+
+ http://gcc.gnu.org/ml/gcc-patches/2008-04/msg00413.html
+
+ * optimize.c (maybe_clone_body): Re-enable.
+
+ 2008-02-19 Diego Novillo <dnovillo@google.com>
+ Oleg Ryjkov <olegr@google.com>
+
+ http://gcc.gnu.org/ml/gcc-patches/2008-02/msg00804.html
+
+ * cp-gimplify.c (gimplify_for_stmt): Change gimple_seq
+ argument to gimple_seq *. Update all users.
+ (gimplify_must_not_throw_expr): Likewise.
+
+ 2008-02-04 Oleg Ryjkov <olegr@google.com>
+
+ * except.c: Include gimple.h
+ (cp_protect_cleanup_actions): Convert to tuples.
+ * Make-lang.in (cp/except.o): Add dependency on gimple.h
+
+ 2007-11-10 Aldy Hernandez <aldyh@redhat.com>
+
+ * cp-gimplify.c (gimplify_cp_loop): Call tree_annotate_all_with_locus
+ instead of annotating each block manually.
+
+ 2007-10-30 Aldy Hernandez <aldyh@redhat.com>
+
+ * cp-gimplify.c (gimplify_cp_loop): Tuplify.
+ (gimplify_for_stmt): Same.
+ (gimplify_switch_stmt): Same.
+ (cp_gimplify_expr): [FOR_STMT]: Do not call gimplify_for_stmt. Return
+ GS_OK.
+ [WHILE_STMT]: Return GS_OK.
+ [SWITCH_STMT]: Same.
+ [CONTINUE_STMT]: Same.
+ [BREAK_STMT]: Same.
+ (cp_genericize): Set gimple_body() of cloned functions when needed.
+
+ 2007-10-29 Aldy Hernandez <aldy@quesejoda.com>
+
+ * cp-gimplify.c: Move build_gimple_eh_filter_tree here.
+ (cp_gimplify_init_expr): Convert to tuples.
+ (gimplify_must_not_throw_expr): Make function return a
+ gimplify_status and convert to tuples.
+
+ 2007-10-18 Aldy Hernandez <aldy@quesejoda.com>
+
+ * cp-gimplify.c (genericize_try_block): Enable and do not call
+ gimplify_stmt.
+ (genericize_catch_block): Same.
+ (genericize_eh_spec_block): Same.
+ Rename gimple_build_eh_filter_tree to build_gimple_eh_filter_tree.
+ (cp_gimplify_expr): Enable TRY_BLOCK, HANDLER, and EH_SPEC_BLOCK.
+
+ 2007-10-16 Aldy Hernandez <aldy@quesejoda.com>
+
+ * optimize.c (maybe_clone_body): Comment out call to clone_body.
+ * decl.c (finish_function): Use gimple_body instead of
+ DECL_SAVED_TREE.
+ * cp-tree.h (cp_gimplify_expr): Last 2 arguments are sequences.
+ * cp-gimplify.c (genericize_try_block): Comment out.
+ (genericize_catch_block): Same.
+ (genericize_eh_spec_block): Same.
+ (gimplify_cp_loop): Comment out calls to gimplify_stmt.
+ (gimplify_for_stmt): Comment out.
+ (gimplify_switch_stmt): Comment out call to gimplify_stmt.
+ (cp_gimplify_omp_for): Same.
+ (gimplify_must_not_throw_expr): Argument pre_p is a sequence.
+ Comment out call to gimplify_stmt and append_to_statement_list.
+ Rename gimple_build_eh_filter_tree to build_gimple_eh_filter_tree.
+ (cp_gimplify_init_expr): Arguments pre_p and post_p are sequences.
+ (cp_gimplify_expr): Same.
+ Comment out calls to genericize_*_block. Comment out call to
+ gimplify_for_stmt.
+
2008-07-27 H.J. Lu <hongjiu.lu@intel.com>
PR c++/36944
diff --git a/gcc/cp/Make-lang.in b/gcc/cp/Make-lang.in
index c7877205f25..03963446251 100644
--- a/gcc/cp/Make-lang.in
+++ b/gcc/cp/Make-lang.in
@@ -239,7 +239,7 @@ cp/decl.o: cp/decl.c $(CXX_TREE_H) $(TM_H) $(FLAGS_H) cp/decl.h \
debug.h gt-cp-decl.h $(TIMEVAR_H) $(TREE_FLOW_H) $(TARGET_H)
cp/decl2.o: cp/decl2.c $(CXX_TREE_H) $(TM_H) $(FLAGS_H) cp/decl.h $(EXPR_H) \
output.h except.h toplev.h $(RTL_H) $(C_COMMON_H) gt-cp-decl2.h $(CGRAPH_H) \
- $(C_PRAGMA_H) $(TREE_DUMP_H) intl.h $(TARGET_H)
+ $(C_PRAGMA_H) $(TREE_DUMP_H) intl.h $(TARGET_H) $(GIMPLE_H)
cp/cp-objcp-common.o : cp/cp-objcp-common.c $(CONFIG_H) $(SYSTEM_H) \
coretypes.h $(TM_H) $(TREE_H) $(CXX_TREE_H) $(C_COMMON_H) toplev.h \
langhooks.h $(LANGHOOKS_DEF_H) $(DIAGNOSTIC_H) debug.h \
@@ -280,17 +280,17 @@ cp/repo.o: cp/repo.c $(CXX_TREE_H) $(TM_H) toplev.h $(DIAGNOSTIC_H) \
gt-cp-repo.h
cp/semantics.o: cp/semantics.c $(CXX_TREE_H) $(TM_H) except.h toplev.h \
$(FLAGS_H) debug.h output.h $(RTL_H) $(TIMEVAR_H) $(EXPR_H) \
- $(TREE_INLINE_H) $(CGRAPH_H) $(TARGET_H) $(C_COMMON_H)
+ $(TREE_INLINE_H) $(CGRAPH_H) $(TARGET_H) $(C_COMMON_H) $(GIMPLE_H)
cp/dump.o: cp/dump.c $(CXX_TREE_H) $(TM_H) $(TREE_DUMP_H)
cp/optimize.o: cp/optimize.c $(CXX_TREE_H) $(TM_H) rtl.h $(INTEGRATE_H) \
- insn-config.h input.h $(PARAMS_H) debug.h $(TREE_INLINE_H) $(TREE_GIMPLE_H) \
+ insn-config.h input.h $(PARAMS_H) debug.h $(TREE_INLINE_H) $(GIMPLE_H) \
$(TARGET_H)
cp/mangle.o: cp/mangle.c $(CXX_TREE_H) $(TM_H) toplev.h $(REAL_H) \
gt-cp-mangle.h $(TARGET_H) $(TM_P_H)
cp/parser.o: cp/parser.c $(CXX_TREE_H) $(TM_H) $(DIAGNOSTIC_H) gt-cp-parser.h \
output.h $(TARGET_H)
cp/cp-gimplify.o: cp/cp-gimplify.c $(CXX_TREE_H) toplev.h $(C_COMMON_H) \
- $(TM_H) coretypes.h pointer-set.h
+ $(TM_H) coretypes.h pointer-set.h tree-iterator.h
cp/name-lookup.o: cp/name-lookup.c $(CONFIG_H) $(SYSTEM_H) coretypes.h \
$(TM_H) $(CXX_TREE_H) $(TIMEVAR_H) gt-cp-name-lookup.h toplev.h \
diff --git a/gcc/cp/cp-gimplify.c b/gcc/cp/cp-gimplify.c
index c6d64dfbb75..8dda74d3cbe 100644
--- a/gcc/cp/cp-gimplify.c
+++ b/gcc/cp/cp-gimplify.c
@@ -28,7 +28,8 @@ along with GCC; see the file COPYING3. If not see
#include "cp-tree.h"
#include "c-common.h"
#include "toplev.h"
-#include "tree-gimple.h"
+#include "tree-iterator.h"
+#include "gimple.h"
#include "hashtab.h"
#include "pointer-set.h"
#include "flags.h"
@@ -62,20 +63,14 @@ begin_bc_block (enum bc_t bc)
If we saw a break (or continue) in the scope, append a LABEL_EXPR to
body. Otherwise, just forget the label. */
-static tree
-finish_bc_block (enum bc_t bc, tree label, tree body)
+static gimple_seq
+finish_bc_block (enum bc_t bc, tree label, gimple_seq body)
{
gcc_assert (label == bc_label[bc]);
if (TREE_USED (label))
{
- tree t, sl = NULL;
-
- t = build1 (LABEL_EXPR, void_type_node, label);
-
- append_to_statement_list (body, &sl);
- append_to_statement_list (t, &sl);
- body = sl;
+ gimple_seq_add_stmt (&body, gimple_build_label (label));
}
bc_label[bc] = TREE_CHAIN (label);
@@ -83,11 +78,11 @@ finish_bc_block (enum bc_t bc, tree label, tree body)
return body;
}
-/* Build a GOTO_EXPR to represent a break or continue statement. BC
- indicates which. */
+/* Get the LABEL_EXPR to represent a break or continue statement
+ in the current block scope. BC indicates which. */
static tree
-build_bc_goto (enum bc_t bc)
+get_bc_label (enum bc_t bc)
{
tree label = bc_label[bc];
@@ -103,7 +98,7 @@ build_bc_goto (enum bc_t bc)
/* Mark the label used for finish_bc_block. */
TREE_USED (label) = 1;
- return build1 (GOTO_EXPR, void_type_node, label);
+ return label;
}
/* Genericize a TRY_BLOCK. */
@@ -114,13 +109,6 @@ genericize_try_block (tree *stmt_p)
tree body = TRY_STMTS (*stmt_p);
tree cleanup = TRY_HANDLERS (*stmt_p);
- gimplify_stmt (&body);
-
- if (CLEANUP_P (*stmt_p))
- /* A cleanup is an expression, so it doesn't need to be genericized. */;
- else
- gimplify_stmt (&cleanup);
-
*stmt_p = build2 (TRY_CATCH_EXPR, void_type_node, body, cleanup);
}
@@ -132,12 +120,28 @@ genericize_catch_block (tree *stmt_p)
tree type = HANDLER_TYPE (*stmt_p);
tree body = HANDLER_BODY (*stmt_p);
- gimplify_stmt (&body);
-
/* FIXME should the caught type go in TREE_TYPE? */
*stmt_p = build2 (CATCH_EXPR, void_type_node, type, body);
}
+/* A terser interface for building a representation of an exception
+ specification. */
+
+static tree
+build_gimple_eh_filter_tree (tree body, tree allowed, tree failure)
+{
+ tree t;
+
+ /* FIXME should the allowed types go in TREE_TYPE? */
+ t = build2 (EH_FILTER_EXPR, void_type_node, allowed, NULL_TREE);
+ append_to_statement_list (failure, &EH_FILTER_FAILURE (t));
+
+ t = build2 (TRY_CATCH_EXPR, void_type_node, NULL_TREE, t);
+ append_to_statement_list (body, &TREE_OPERAND (t, 0));
+
+ return t;
+}
+
/* Genericize an EH_SPEC_BLOCK by converting it to a
TRY_CATCH_EXPR/EH_FILTER_EXPR pair. */
@@ -147,9 +151,8 @@ genericize_eh_spec_block (tree *stmt_p)
tree body = EH_SPEC_STMTS (*stmt_p);
tree allowed = EH_SPEC_RAISES (*stmt_p);
tree failure = build_call_n (call_unexpected_node, 1, build_exc_ptr ());
- gimplify_stmt (&body);
- *stmt_p = gimple_build_eh_filter (body, allowed, failure);
+ *stmt_p = build_gimple_eh_filter_tree (body, allowed, failure);
}
/* Genericize an IF_STMT by turning it into a COND_EXPR. */
@@ -158,6 +161,7 @@ static void
gimplify_if_stmt (tree *stmt_p)
{
tree stmt, cond, then_, else_;
+ location_t locus = EXPR_LOCATION (*stmt_p);
stmt = *stmt_p;
cond = IF_COND (stmt);
@@ -175,6 +179,8 @@ gimplify_if_stmt (tree *stmt_p)
stmt = else_;
else
stmt = build3 (COND_EXPR, void_type_node, cond, then_, else_);
+ if (CAN_HAVE_LOCATION_P (stmt) && !EXPR_HAS_LOCATION (stmt))
+ SET_EXPR_LOCATION (stmt, locus);
*stmt_p = stmt;
}
@@ -185,15 +191,20 @@ gimplify_if_stmt (tree *stmt_p)
evaluated before the loop body as in while and for loops, or after the
loop body as in do-while loops. */
-static tree
+static gimple_seq
gimplify_cp_loop (tree cond, tree body, tree incr, bool cond_is_first)
{
- tree top, entry, exit, cont_block, break_block, stmt_list, t;
+ gimple top, entry, stmt;
+ gimple_seq stmt_list, body_seq, incr_seq, exit_seq;
+ tree cont_block, break_block;
location_t stmt_locus;
stmt_locus = input_location;
- stmt_list = NULL_TREE;
- entry = NULL_TREE;
+ stmt_list = NULL;
+ body_seq = NULL;
+ incr_seq = NULL;
+ exit_seq = NULL;
+ entry = NULL;
break_block = begin_bc_block (bc_break);
cont_block = begin_bc_block (bc_continue);
@@ -201,12 +212,12 @@ gimplify_cp_loop (tree cond, tree body, tree incr, bool cond_is_first)
/* If condition is zero don't generate a loop construct. */
if (cond && integer_zerop (cond))
{
- top = NULL_TREE;
- exit = NULL_TREE;
+ top = NULL;
if (cond_is_first)
{
- t = build_bc_goto (bc_break);
- append_to_statement_list (t, &stmt_list);
+ stmt = gimple_build_goto (get_bc_label (bc_break));
+ gimple_set_location (stmt, stmt_locus);
+ gimple_seq_add_stmt (&stmt_list, stmt);
}
}
else
@@ -215,44 +226,55 @@ gimplify_cp_loop (tree cond, tree body, tree incr, bool cond_is_first)
back through the main gimplifier to lower it. Given that we
have to gimplify the loop body NOW so that we can resolve
break/continue stmts, seems easier to just expand to gotos. */
- top = build1 (LABEL_EXPR, void_type_node, NULL_TREE);
+ top = gimple_build_label (create_artificial_label ());
/* If we have an exit condition, then we build an IF with gotos either
out of the loop, or to the top of it. If there's no exit condition,
then we just build a jump back to the top. */
- exit = build_and_jump (&LABEL_EXPR_LABEL (top));
if (cond && !integer_nonzerop (cond))
{
- t = build_bc_goto (bc_break);
- exit = fold_build3 (COND_EXPR, void_type_node, cond, exit, t);
- gimplify_stmt (&exit);
+ if (cond != error_mark_node)
+ {
+ gimplify_expr (&cond, &exit_seq, NULL, is_gimple_val, fb_rvalue);
+ stmt = gimple_build_cond (NE_EXPR, cond,
+ build_int_cst (TREE_TYPE (cond), 0),
+ gimple_label_label (top),
+ get_bc_label (bc_break));
+ gimple_seq_add_stmt (&exit_seq, stmt);
+ }
if (cond_is_first)
{
if (incr)
{
- entry = build1 (LABEL_EXPR, void_type_node, NULL_TREE);
- t = build_and_jump (&LABEL_EXPR_LABEL (entry));
+ entry = gimple_build_label (create_artificial_label ());
+ stmt = gimple_build_goto (gimple_label_label (entry));
}
else
- t = build_bc_goto (bc_continue);
- append_to_statement_list (t, &stmt_list);
+ stmt = gimple_build_goto (get_bc_label (bc_continue));
+ gimple_set_location (stmt, stmt_locus);
+ gimple_seq_add_stmt (&stmt_list, stmt);
}
}
+ else
+ {
+ stmt = gimple_build_goto (gimple_label_label (top));
+ gimple_seq_add_stmt (&exit_seq, stmt);
+ }
}
- gimplify_stmt (&body);
- gimplify_stmt (&incr);
+ gimplify_stmt (&body, &body_seq);
+ gimplify_stmt (&incr, &incr_seq);
- body = finish_bc_block (bc_continue, cont_block, body);
+ body_seq = finish_bc_block (bc_continue, cont_block, body_seq);
- append_to_statement_list (top, &stmt_list);
- append_to_statement_list (body, &stmt_list);
- append_to_statement_list (incr, &stmt_list);
- append_to_statement_list (entry, &stmt_list);
- append_to_statement_list (exit, &stmt_list);
+ gimple_seq_add_stmt (&stmt_list, top);
+ gimple_seq_add_seq (&stmt_list, body_seq);
+ gimple_seq_add_seq (&stmt_list, incr_seq);
+ gimple_seq_add_stmt (&stmt_list, entry);
+ gimple_seq_add_seq (&stmt_list, exit_seq);
- annotate_all_with_locus (&stmt_list, stmt_locus);
+ annotate_all_with_location (stmt_list, stmt_locus);
return finish_bc_block (bc_break, break_block, stmt_list);
}
@@ -261,45 +283,52 @@ gimplify_cp_loop (tree cond, tree body, tree incr, bool cond_is_first)
prequeue and hand off to gimplify_cp_loop. */
static void
-gimplify_for_stmt (tree *stmt_p, tree *pre_p)
+gimplify_for_stmt (tree *stmt_p, gimple_seq *pre_p)
{
tree stmt = *stmt_p;
if (FOR_INIT_STMT (stmt))
gimplify_and_add (FOR_INIT_STMT (stmt), pre_p);
- *stmt_p = gimplify_cp_loop (FOR_COND (stmt), FOR_BODY (stmt),
- FOR_EXPR (stmt), 1);
+ gimple_seq_add_seq (pre_p,
+ gimplify_cp_loop (FOR_COND (stmt), FOR_BODY (stmt),
+ FOR_EXPR (stmt), 1));
+ *stmt_p = NULL_TREE;
}
/* Gimplify a WHILE_STMT node. */
static void
-gimplify_while_stmt (tree *stmt_p)
+gimplify_while_stmt (tree *stmt_p, gimple_seq *pre_p)
{
tree stmt = *stmt_p;
- *stmt_p = gimplify_cp_loop (WHILE_COND (stmt), WHILE_BODY (stmt),
- NULL_TREE, 1);
+ gimple_seq_add_seq (pre_p,
+ gimplify_cp_loop (WHILE_COND (stmt), WHILE_BODY (stmt),
+ NULL_TREE, 1));
+ *stmt_p = NULL_TREE;
}
/* Gimplify a DO_STMT node. */
static void
-gimplify_do_stmt (tree *stmt_p)
+gimplify_do_stmt (tree *stmt_p, gimple_seq *pre_p)
{
tree stmt = *stmt_p;
- *stmt_p = gimplify_cp_loop (DO_COND (stmt), DO_BODY (stmt),
- NULL_TREE, 0);
+ gimple_seq_add_seq (pre_p,
+ gimplify_cp_loop (DO_COND (stmt), DO_BODY (stmt),
+ NULL_TREE, 0));
+ *stmt_p = NULL_TREE;
}
/* Genericize a SWITCH_STMT by turning it into a SWITCH_EXPR. */
static void
-gimplify_switch_stmt (tree *stmt_p)
+gimplify_switch_stmt (tree *stmt_p, gimple_seq *pre_p)
{
tree stmt = *stmt_p;
- tree break_block, body;
+ tree break_block, body, t;
location_t stmt_locus = input_location;
+ gimple_seq seq = NULL;
break_block = begin_bc_block (bc_break);
@@ -307,12 +336,14 @@ gimplify_switch_stmt (tree *stmt_p)
if (!body)
body = build_empty_stmt ();
- *stmt_p = build3 (SWITCH_EXPR, SWITCH_STMT_TYPE (stmt),
- SWITCH_STMT_COND (stmt), body, NULL_TREE);
- SET_EXPR_LOCATION (*stmt_p, stmt_locus);
- gimplify_stmt (stmt_p);
+ t = build3 (SWITCH_EXPR, SWITCH_STMT_TYPE (stmt),
+ SWITCH_STMT_COND (stmt), body, NULL_TREE);
+ SET_EXPR_LOCATION (t, stmt_locus);
+ gimplify_and_add (t, &seq);
- *stmt_p = finish_bc_block (bc_break, break_block, *stmt_p);
+ seq = finish_bc_block (bc_break, break_block, seq);
+ gimple_seq_add_seq (pre_p, seq);
+ *stmt_p = NULL_TREE;
}
/* Hook into the middle of gimplifying an OMP_FOR node. This is required
@@ -321,10 +352,12 @@ gimplify_switch_stmt (tree *stmt_p)
regular gimplifier. */
static enum gimplify_status
-cp_gimplify_omp_for (tree *expr_p)
+cp_gimplify_omp_for (tree *expr_p, gimple_seq *pre_p)
{
tree for_stmt = *expr_p;
tree cont_block;
+ gimple stmt;
+ gimple_seq seq = NULL;
/* Protect ourselves from recursion. */
if (OMP_FOR_GIMPLIFYING_P (for_stmt))
@@ -336,10 +369,15 @@ cp_gimplify_omp_for (tree *expr_p)
statement expressions within the INIT, COND, or INCR expressions. */
cont_block = begin_bc_block (bc_continue);
- gimplify_stmt (expr_p);
+ gimplify_and_add (for_stmt, &seq);
+ stmt = gimple_seq_last_stmt (seq);
+ if (gimple_code (stmt) == GIMPLE_OMP_FOR)
+ gimple_omp_set_body (stmt, finish_bc_block (bc_continue, cont_block,
+ gimple_omp_body (stmt)));
+ else
+ seq = finish_bc_block (bc_continue, cont_block, seq);
+ gimple_seq_add_seq (pre_p, seq);
- OMP_FOR_BODY (for_stmt)
- = finish_bc_block (bc_continue, cont_block, OMP_FOR_BODY (for_stmt));
OMP_FOR_GIMPLIFYING_P (for_stmt) = 0;
return GS_ALL_DONE;
@@ -383,7 +421,7 @@ gimplify_expr_stmt (tree *stmt_p)
/* Gimplify initialization from an AGGR_INIT_EXPR. */
static void
-cp_gimplify_init_expr (tree *expr_p, tree *pre_p, tree *post_p)
+cp_gimplify_init_expr (tree *expr_p, gimple_seq *pre_p, gimple_seq *post_p)
{
tree from = TREE_OPERAND (*expr_p, 1);
tree to = TREE_OPERAND (*expr_p, 0);
@@ -441,31 +479,31 @@ cp_gimplify_init_expr (tree *expr_p, tree *pre_p, tree *post_p)
/* Gimplify a MUST_NOT_THROW_EXPR. */
-static void
-gimplify_must_not_throw_expr (tree *expr_p, tree *pre_p)
+static enum gimplify_status
+gimplify_must_not_throw_expr (tree *expr_p, gimple_seq *pre_p)
{
tree stmt = *expr_p;
tree temp = voidify_wrapper_expr (stmt, NULL);
tree body = TREE_OPERAND (stmt, 0);
- gimplify_stmt (&body);
-
- stmt = gimple_build_eh_filter (body, NULL_TREE,
- build_call_n (terminate_node, 0));
+ stmt = build_gimple_eh_filter_tree (body, NULL_TREE,
+ build_call_n (terminate_node, 0));
+ gimplify_and_add (stmt, pre_p);
if (temp)
{
- append_to_statement_list (stmt, pre_p);
*expr_p = temp;
+ return GS_OK;
}
- else
- *expr_p = stmt;
+
+ *expr_p = NULL;
+ return GS_ALL_DONE;
}
/* Do C++-specific gimplification. Args are as for gimplify_expr. */
int
-cp_gimplify_expr (tree *expr_p, tree *pre_p, tree *post_p)
+cp_gimplify_expr (tree *expr_p, gimple_seq *pre_p, gimple_seq *post_p)
{
int saved_stmts_are_full_exprs_p = 0;
enum tree_code code = TREE_CODE (*expr_p);
@@ -498,11 +536,10 @@ cp_gimplify_expr (tree *expr_p, tree *pre_p, tree *post_p)
break;
case MUST_NOT_THROW_EXPR:
- gimplify_must_not_throw_expr (expr_p, pre_p);
- ret = GS_OK;
+ ret = gimplify_must_not_throw_expr (expr_p, pre_p);
break;
- /* We used to do this for GIMPLE_MODIFY_STMT as well, but that's unsafe; the
+ /* We used to do this for MODIFY_EXPR as well, but that's unsafe; the
LHS of an assignment might also be involved in the RHS, as in bug
25979. */
case INIT_EXPR:
@@ -539,7 +576,7 @@ cp_gimplify_expr (tree *expr_p, tree *pre_p, tree *post_p)
case USING_STMT:
/* Just ignore for now. Eventually we will want to pass this on to
the debugger. */
- *expr_p = build_empty_stmt ();
+ *expr_p = NULL;
ret = GS_ALL_DONE;
break;
@@ -550,35 +587,37 @@ cp_gimplify_expr (tree *expr_p, tree *pre_p, tree *post_p)
case FOR_STMT:
gimplify_for_stmt (expr_p, pre_p);
- ret = GS_ALL_DONE;
+ ret = GS_OK;
break;
case WHILE_STMT:
- gimplify_while_stmt (expr_p);
- ret = GS_ALL_DONE;
+ gimplify_while_stmt (expr_p, pre_p);
+ ret = GS_OK;
break;
case DO_STMT:
- gimplify_do_stmt (expr_p);
- ret = GS_ALL_DONE;
+ gimplify_do_stmt (expr_p, pre_p);
+ ret = GS_OK;
break;
case SWITCH_STMT:
- gimplify_switch_stmt (expr_p);
- ret = GS_ALL_DONE;
+ gimplify_switch_stmt (expr_p, pre_p);
+ ret = GS_OK;
break;
case OMP_FOR:
- ret = cp_gimplify_omp_for (expr_p);
+ ret = cp_gimplify_omp_for (expr_p, pre_p);
break;
case CONTINUE_STMT:
- *expr_p = build_bc_goto (bc_continue);
+ gimple_seq_add_stmt (pre_p, gimple_build_goto (get_bc_label (bc_continue)));
+ *expr_p = NULL_TREE;
ret = GS_ALL_DONE;
break;
case BREAK_STMT:
- *expr_p = build_bc_goto (bc_break);
+ gimple_seq_add_stmt (pre_p, gimple_build_goto (get_bc_label (bc_break)));
+ *expr_p = NULL_TREE;
ret = GS_ALL_DONE;
break;
@@ -835,13 +874,13 @@ cxx_omp_clause_apply_fn (tree fn, tree arg1, tree arg2)
end1 = build2 (POINTER_PLUS_EXPR, TREE_TYPE (start1), start1, end1);
p1 = create_tmp_var (TREE_TYPE (start1), NULL);
- t = build2 (GIMPLE_MODIFY_STMT, void_type_node, p1, start1);
+ t = build2 (MODIFY_EXPR, TREE_TYPE (p1), p1, start1);
append_to_statement_list (t, &ret);
if (arg2)
{
p2 = create_tmp_var (TREE_TYPE (start2), NULL);
- t = build2 (GIMPLE_MODIFY_STMT, void_type_node, p2, start2);
+ t = build2 (MODIFY_EXPR, TREE_TYPE (p2), p2, start2);
append_to_statement_list (t, &ret);
}
@@ -864,14 +903,14 @@ cxx_omp_clause_apply_fn (tree fn, tree arg1, tree arg2)
t = TYPE_SIZE_UNIT (inner_type);
t = build2 (POINTER_PLUS_EXPR, TREE_TYPE (p1), p1, t);
- t = build2 (GIMPLE_MODIFY_STMT, void_type_node, p1, t);
+ t = build2 (MODIFY_EXPR, TREE_TYPE (p1), p1, t);
append_to_statement_list (t, &ret);
if (arg2)
{
t = TYPE_SIZE_UNIT (inner_type);
t = build2 (POINTER_PLUS_EXPR, TREE_TYPE (p2), p2, t);
- t = build2 (GIMPLE_MODIFY_STMT, void_type_node, p2, t);
+ t = build2 (MODIFY_EXPR, TREE_TYPE (p2), p2, t);
append_to_statement_list (t, &ret);
}
@@ -925,7 +964,7 @@ cxx_omp_clause_copy_ctor (tree clause, tree dst, tree src)
if (info)
ret = cxx_omp_clause_apply_fn (TREE_VEC_ELT (info, 0), dst, src);
if (ret == NULL)
- ret = build2 (GIMPLE_MODIFY_STMT, void_type_node, dst, src);
+ ret = build2 (MODIFY_EXPR, TREE_TYPE (dst), dst, src);
return ret;
}
@@ -941,7 +980,7 @@ cxx_omp_clause_assign_op (tree clause, tree dst, tree src)
if (info)
ret = cxx_omp_clause_apply_fn (TREE_VEC_ELT (info, 2), dst, src);
if (ret == NULL)
- ret = build2 (GIMPLE_MODIFY_STMT, void_type_node, dst, src);
+ ret = build2 (MODIFY_EXPR, TREE_TYPE (dst), dst, src);
return ret;
}
diff --git a/gcc/cp/cp-tree.h b/gcc/cp/cp-tree.h
index 67f15e55219..f9a2af8bb01 100644
--- a/gcc/cp/cp-tree.h
+++ b/gcc/cp/cp-tree.h
@@ -534,7 +534,7 @@ enum cp_tree_node_structure_enum {
/* The resulting tree type. */
union lang_tree_node GTY((desc ("cp_tree_node_structure (&%h)"),
- chain_next ("(union lang_tree_node *)GENERIC_NEXT (&%h.generic)")))
+ chain_next ("(union lang_tree_node *)TREE_CHAIN (&%h.generic)")))
{
union tree_node GTY ((tag ("TS_CP_GENERIC"),
desc ("tree_node_structure (&%h)"))) generic;
@@ -4938,7 +4938,8 @@ extern void init_shadowed_var_for_decl (void);
extern tree cxx_staticp (tree);
/* in cp-gimplify.c */
-extern int cp_gimplify_expr (tree *, tree *, tree *);
+extern int cp_gimplify_expr (tree *, gimple_seq *,
+ gimple_seq *);
extern void cp_genericize (tree);
/* -- end of C++ */
diff --git a/gcc/cp/decl.c b/gcc/cp/decl.c
index 0cc17a484f6..630faacb354 100644
--- a/gcc/cp/decl.c
+++ b/gcc/cp/decl.c
@@ -12038,7 +12038,7 @@ finish_function (int flags)
f->extern_decl_map = NULL;
/* Handle attribute((warn_unused_result)). Relies on gimple input. */
- c_warn_unused_result (&DECL_SAVED_TREE (fndecl));
+ c_warn_unused_result (gimple_body (fndecl));
}
/* Clear out the bits we don't need. */
local_names = NULL;
diff --git a/gcc/cp/decl2.c b/gcc/cp/decl2.c
index a156e32dcdb..20b0826faf2 100644
--- a/gcc/cp/decl2.c
+++ b/gcc/cp/decl2.c
@@ -51,6 +51,7 @@ along with GCC; see the file COPYING3. If not see
#include "c-pragma.h"
#include "tree-dump.h"
#include "intl.h"
+#include "gimple.h"
extern cpp_reader *parse_in;
@@ -3439,7 +3440,7 @@ cp_write_global_declarations (void)
reconsider = true;
}
- if (!DECL_SAVED_TREE (decl))
+ if (!gimple_body (decl))
continue;
/* We lie to the back end, pretending that some functions
diff --git a/gcc/cp/except.c b/gcc/cp/except.c
index adb1b97928f..56a551212fe 100644
--- a/gcc/cp/except.c
+++ b/gcc/cp/except.c
@@ -39,6 +39,7 @@ along with GCC; see the file COPYING3. If not see
#include "tree-inline.h"
#include "tree-iterator.h"
#include "target.h"
+#include "gimple.h"
static void push_eh_cleanup (tree);
static tree prepare_eh_type (tree);
@@ -53,7 +54,7 @@ static tree wrap_cleanups_r (tree *, int *, void *);
static int complete_ptr_ref_or_void_ptr_p (tree, tree);
static bool is_admissible_throw_operand (tree);
static int can_convert_eh (tree, tree);
-static tree cp_protect_cleanup_actions (void);
+static gimple cp_protect_cleanup_actions (void);
/* Sets up all the global eh stuff that needs to be initialized at the
start of compilation. */
@@ -92,14 +93,14 @@ init_exception_processing (void)
/* Returns an expression to be executed if an unhandled exception is
propagated out of a cleanup region. */
-static tree
+static gimple
cp_protect_cleanup_actions (void)
{
/* [except.terminate]
When the destruction of an object during stack unwinding exits
using an exception ... void terminate(); is called. */
- return build_call_n (terminate_node, 0);
+ return gimple_build_call (terminate_node, 0);
}
static tree
diff --git a/gcc/cp/init.c b/gcc/cp/init.c
index 3dd6c4e328b..3deb85d432b 100644
--- a/gcc/cp/init.c
+++ b/gcc/cp/init.c
@@ -3275,6 +3275,7 @@ build_vec_delete (tree base, tree maxindex,
{
/* Step back one from start of vector, and read dimension. */
tree cookie_addr;
+ tree size_ptr_type = build_pointer_type (sizetype);
if (TREE_SIDE_EFFECTS (base))
{
@@ -3284,8 +3285,8 @@ build_vec_delete (tree base, tree maxindex,
type = strip_array_types (TREE_TYPE (type));
cookie_addr = fold_build1 (NEGATE_EXPR, sizetype, TYPE_SIZE_UNIT (sizetype));
cookie_addr = build2 (POINTER_PLUS_EXPR,
- build_pointer_type (sizetype),
- base,
+ size_ptr_type,
+ fold_convert (size_ptr_type, base),
cookie_addr);
maxindex = cp_build_indirect_ref (cookie_addr, NULL, tf_warning_or_error);
}
diff --git a/gcc/cp/optimize.c b/gcc/cp/optimize.c
index a91f8d5f564..ed43b435831 100644
--- a/gcc/cp/optimize.c
+++ b/gcc/cp/optimize.c
@@ -1,5 +1,5 @@
/* Perform optimizations on tree structure.
- Copyright (C) 1998, 1999, 2000, 2001, 2002, 2004, 2005, 2007
+ Copyright (C) 1998, 1999, 2000, 2001, 2002, 2004, 2005, 2007, 2008
Free Software Foundation, Inc.
Written by Mark Michell (mark@codesourcery.com).
@@ -40,7 +40,7 @@ along with GCC; see the file COPYING3. If not see
#include "langhooks.h"
#include "diagnostic.h"
#include "tree-dump.h"
-#include "tree-gimple.h"
+#include "gimple.h"
/* Prototypes. */
@@ -72,35 +72,40 @@ update_cloned_parm (tree parm, tree cloned_parm, bool first)
DECL_GIMPLE_REG_P (cloned_parm) = DECL_GIMPLE_REG_P (parm);
}
-/* FN is a function that has a complete body, and CLONE is a function whose
- body is to be set to a copy of FN, mapping argument declarations according
- to the ARG_MAP splay_tree. */
+
+/* FN is a function in High GIMPLE form that has a complete body and no
+ CFG. CLONE is a function whose body is to be set to a copy of FN,
+ mapping argument declarations according to the ARG_MAP splay_tree. */
static void
clone_body (tree clone, tree fn, void *arg_map)
{
copy_body_data id;
+ gimple_seq new_body;
+
+ /* FN must already be in GIMPLE form. */
+ gcc_assert (gimple_body (fn));
- /* Clone the body, as if we were making an inline call. But, remap the
- parameters in the callee to the parameters of caller. */
+ /* Clone the body, as if we were making an inline call. But, remap
+ the parameters in the callee to the parameters of caller. */
memset (&id, 0, sizeof (id));
id.src_fn = fn;
id.dst_fn = clone;
id.src_cfun = DECL_STRUCT_FUNCTION (fn);
- id.decl_map = (struct pointer_map_t *)arg_map;
+ id.decl_map = (struct pointer_map_t *) arg_map;
id.copy_decl = copy_decl_no_change;
id.transform_call_graph_edges = CB_CGE_DUPLICATE;
id.transform_new_cfg = true;
id.transform_return_to_modify = false;
- id.transform_lang_insert_block = insert_block;
+ id.transform_lang_insert_block = NULL;
/* We're not inside any EH region. */
id.eh_region = -1;
/* Actually copy the body. */
- append_to_statement_list_force (copy_generic_body (&id),
- &DECL_SAVED_TREE (clone));
+ new_body = remap_gimple_seq (gimple_body (fn), &id);
+ gimple_set_body (clone, new_body);
}
/* FN is a function that has a complete body. Clone the body as
@@ -228,6 +233,7 @@ maybe_clone_body (tree fn)
/* Now, expand this function into RTL, if appropriate. */
finish_function (0);
BLOCK_ABSTRACT_ORIGIN (DECL_INITIAL (clone)) = DECL_INITIAL (fn);
+ DECL_SAVED_TREE (clone) = NULL;
expand_or_defer_fn (clone);
first = false;
}
diff --git a/gcc/cp/semantics.c b/gcc/cp/semantics.c
index ffa6493ced4..5ada42241fb 100644
--- a/gcc/cp/semantics.c
+++ b/gcc/cp/semantics.c
@@ -46,6 +46,7 @@ along with GCC; see the file COPYING3. If not see
#include "tree-iterator.h"
#include "vec.h"
#include "target.h"
+#include "gimple.h"
/* There routines provide a modular interface to perform many parsing
operations. They may therefore be used during actual parsing, or
@@ -3201,6 +3202,8 @@ expand_or_defer_fn (tree fn)
return;
}
+ gcc_assert (gimple_body (fn));
+
/* Replace AGGR_INIT_EXPRs with appropriate CALL_EXPRs. */
cp_walk_tree_without_duplicates (&DECL_SAVED_TREE (fn),
simplify_aggr_init_exprs_r,