aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJason Merrill <jason@redhat.com>2002-09-04 15:15:28 +0000
committerJason Merrill <jason@redhat.com>2002-09-04 15:15:28 +0000
commitd32d494b33941b24431f0422e8ddc0937ea41426 (patch)
treea6949a2f7286373de0bb29aabf32406b529f6b3b
parentaa49d98c742631847566b755f25893498663e98b (diff)
latest drop
git-svn-id: https://gcc.gnu.org/svn/gcc/branches/bnw-simple-branch@56794 138bc75d-0d04-0410-961f-82ee72b054a4
-rw-r--r--gcc/Makefile.in4
-rw-r--r--gcc/c-common.def2
-rw-r--r--gcc/c-common.h6
-rw-r--r--gcc/c-decl.c8
-rw-r--r--gcc/c-lang.c2
-rw-r--r--gcc/c-objc-common.c2
-rw-r--r--gcc/c-pretty-print.c2
-rw-r--r--gcc/c-semantics.c28
-rw-r--r--gcc/c-simplify.c323
-rw-r--r--gcc/c-tree.h2
-rw-r--r--gcc/c-typeck.c7
-rw-r--r--gcc/expr.c13
-rw-r--r--gcc/langhooks-def.h3
-rw-r--r--gcc/langhooks.c14
-rw-r--r--gcc/langhooks.h3
-rw-r--r--gcc/tree-inline.c6
-rw-r--r--gcc/tree-simple.c40
-rw-r--r--gcc/tree.def2
-rw-r--r--gcc/tree.h18
19 files changed, 231 insertions, 254 deletions
diff --git a/gcc/Makefile.in b/gcc/Makefile.in
index 47d078354fb..78d109d7384 100644
--- a/gcc/Makefile.in
+++ b/gcc/Makefile.in
@@ -1263,7 +1263,7 @@ c-format.o : c-format.c $(CONFIG_H) $(SYSTEM_H) $(TREE_H) langhooks.h \
c-semantics.o : c-semantics.c $(CONFIG_H) $(SYSTEM_H) $(TREE_H) $(C_TREE_H) \
flags.h toplev.h output.h c-pragma.h $(RTL_H) $(GGC_H) \
- $(EXPR_H) $(PREDICT_H)
+ $(EXPR_H) $(PREDICT_H) langhooks.h
c-dump.o : c-dump.c $(CONFIG_H) $(SYSTEM_H) $(TREE_H) $(C_TREE_H) tree-dump.h
@@ -1497,7 +1497,7 @@ expmed.o : expmed.c $(CONFIG_H) $(SYSTEM_H) $(RTL_H) $(TREE_H) flags.h \
toplev.h $(TM_P_H) langhooks.h
explow.o : explow.c $(CONFIG_H) $(SYSTEM_H) $(RTL_H) $(TREE_H) flags.h \
hard-reg-set.h insn-config.h $(EXPR_H) $(OPTABS_H) $(RECOG_H) \
- toplev.h function.h ggc.h $(TM_P_H) gt-explow.h
+ toplev.h function.h ggc.h $(TM_P_H) gt-explow.h langhooks.h
optabs.o : optabs.c $(CONFIG_H) $(SYSTEM_H) $(RTL_H) $(TREE_H) flags.h \
insn-config.h $(EXPR_H) $(OPTABS_H) libfuncs.h $(RECOG_H) reload.h \
toplev.h $(GGC_H) real.h $(TM_P_H) except.h gt-optabs.h
diff --git a/gcc/c-common.def b/gcc/c-common.def
index efcd2568cab..a94e85d660c 100644
--- a/gcc/c-common.def
+++ b/gcc/c-common.def
@@ -82,7 +82,7 @@ DEFTREECODE (GOTO_STMT, "goto_stmt", 'e', 1)
DEFTREECODE (LABEL_STMT, "label_stmt", 'e', 1)
/* Used to represent an inline assembly statement. */
-DEFTREECODE (ASM_STMT, "asm_stmt", 'e', 5)
+DEFTREECODE (ASM_STMT, "asm_stmt", 'e', 4)
/* A SCOPE_STMT marks the beginning or end of a scope. If
SCOPE_BEGIN_P holds, then this is the start of a scope. If
diff --git a/gcc/c-common.h b/gcc/c-common.h
index bfd81791b8b..5779862ef80 100644
--- a/gcc/c-common.h
+++ b/gcc/c-common.h
@@ -1029,10 +1029,6 @@ extern tree strip_array_types PARAMS ((tree));
#define SCOPE_PARTIAL_P(NODE) \
(TREE_LANG_FLAG_4 (SCOPE_STMT_CHECK (NODE)))
-/* Nonzero for an ASM_STMT if the assembly statement is volatile. */
-#define ASM_VOLATILE_P(NODE) \
- (ASM_CV_QUAL (ASM_STMT_CHECK (NODE)) != NULL_TREE)
-
/* The VAR_DECL to clean up in a CLEANUP_STMT. */
#define CLEANUP_DECL(NODE) \
TREE_OPERAND (CLEANUP_STMT_CHECK (NODE), 0)
@@ -1087,7 +1083,7 @@ extern void genrtl_scope_stmt PARAMS ((tree));
extern void genrtl_switch_stmt PARAMS ((tree));
extern void genrtl_case_label PARAMS ((tree));
extern void genrtl_compound_stmt PARAMS ((tree));
-extern void genrtl_asm_stmt PARAMS ((tree, tree,
+extern void genrtl_asm_stmt PARAMS ((int, tree,
tree, tree,
tree, int));
extern void genrtl_decl_cleanup PARAMS ((tree));
diff --git a/gcc/c-decl.c b/gcc/c-decl.c
index 5d712b2ec4b..5c6959b5f6b 100644
--- a/gcc/c-decl.c
+++ b/gcc/c-decl.c
@@ -6873,15 +6873,13 @@ c_begin_compound_stmt ()
return stmt;
}
-/* Expand T (a DECL_STMT) if it declares an entity not handled by the
+/* Expand DECL if it declares an entity not handled by the
common code. */
void
-c_expand_decl_stmt (t)
- tree t;
+c_expand_decl (decl)
+ tree decl;
{
- tree decl = DECL_STMT_DECL (t);
-
/* Expand nested functions. */
if (TREE_CODE (decl) == FUNCTION_DECL
&& DECL_CONTEXT (decl) == current_function_decl
diff --git a/gcc/c-lang.c b/gcc/c-lang.c
index cb15f215f5e..f3fdaaa5e78 100644
--- a/gcc/c-lang.c
+++ b/gcc/c-lang.c
@@ -51,6 +51,8 @@ static void c_init_options PARAMS ((void));
#define LANG_HOOKS_SAFE_FROM_P c_safe_from_p
#undef LANG_HOOKS_EXPAND_EXPR
#define LANG_HOOKS_EXPAND_EXPR c_expand_expr
+#undef LANG_HOOKS_EXPAND_DECL
+#define LANG_HOOKS_EXPAND_DECL c_expand_decl
#undef LANG_HOOKS_MARK_ADDRESSABLE
#define LANG_HOOKS_MARK_ADDRESSABLE c_mark_addressable
#undef LANG_HOOKS_PARSE_FILE
diff --git a/gcc/c-objc-common.c b/gcc/c-objc-common.c
index 58ea14b9e6b..9be1bbf8bce 100644
--- a/gcc/c-objc-common.c
+++ b/gcc/c-objc-common.c
@@ -235,8 +235,6 @@ c_objc_common_init (filename)
if (filename == NULL)
return NULL;
- lang_expand_decl_stmt = c_expand_decl_stmt;
-
/* These were not defined in the Objective-C front end, but I'm
putting them here anyway. The diagnostic format decoder might
want an enhanced ObjC implementation. */
diff --git a/gcc/c-pretty-print.c b/gcc/c-pretty-print.c
index 0c8e777310d..2e0853f1c1b 100644
--- a/gcc/c-pretty-print.c
+++ b/gcc/c-pretty-print.c
@@ -1394,6 +1394,8 @@ print_declaration (buffer, t, spc, brief_dump)
if (TREE_PUBLIC (t) && DECL_EXTERNAL (t))
output_add_string (buffer, "extern ");
+ else if (TREE_STATIC (t))
+ output_add_string (buffer, "static ");
/* Print the type and name. */
if (TREE_CODE (TREE_TYPE (t)) == ARRAY_TYPE)
diff --git a/gcc/c-semantics.c b/gcc/c-semantics.c
index 35cb559e6f8..c22d7bc63f8 100644
--- a/gcc/c-semantics.c
+++ b/gcc/c-semantics.c
@@ -37,18 +37,12 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
#include "output.h"
#include "timevar.h"
#include "predict.h"
+#include "langhooks.h"
/* If non-NULL, the address of a language-specific function for
expanding statements. */
void (*lang_expand_stmt) PARAMS ((tree));
-/* If non-NULL, the address of a language-specific function for
- expanding a DECL_STMT. After the language-independent cases are
- handled, this function will be called. If this function is not
- defined, it is assumed that declarations other than those for
- variables and labels do not require any RTL generation. */
-void (*lang_expand_decl_stmt) PARAMS ((tree));
-
/* Create an empty statement tree rooted at T. */
void
@@ -389,8 +383,8 @@ genrtl_decl_stmt (t)
else if (TREE_CODE (decl) == LABEL_DECL
&& C_DECLARED_LABEL_FLAG (decl))
declare_nonlocal_label (decl);
- else if (lang_expand_decl_stmt)
- (*lang_expand_decl_stmt) (t);
+ else
+ (*lang_hooks.expand_decl) (decl);
}
/* Generate the RTL for T, which is an IF_STMT. */
@@ -708,29 +702,21 @@ genrtl_compound_stmt (t)
/* Generate the RTL for an ASM_STMT. */
void
-genrtl_asm_stmt (cv_qualifier, string, output_operands,
+genrtl_asm_stmt (volatile_p, string, output_operands,
input_operands, clobbers, asm_input_p)
- tree cv_qualifier;
+ int volatile_p;
tree string;
tree output_operands;
tree input_operands;
tree clobbers;
int asm_input_p;
{
- if (cv_qualifier != NULL_TREE
- && cv_qualifier != ridpointers[(int) RID_VOLATILE])
- {
- warning ("%s qualifier ignored on asm",
- IDENTIFIER_POINTER (cv_qualifier));
- cv_qualifier = NULL_TREE;
- }
-
emit_line_note (input_filename, lineno);
if (asm_input_p)
expand_asm (string);
else
c_expand_asm_operands (string, output_operands, input_operands,
- clobbers, cv_qualifier != NULL_TREE,
+ clobbers, volatile_p,
input_filename, lineno);
}
@@ -846,7 +832,7 @@ expand_stmt (t)
break;
case ASM_STMT:
- genrtl_asm_stmt (ASM_CV_QUAL (t), ASM_STRING (t),
+ genrtl_asm_stmt (ASM_VOLATILE_P (t), ASM_STRING (t),
ASM_OUTPUTS (t), ASM_INPUTS (t),
ASM_CLOBBERS (t), ASM_INPUT_P (t));
break;
diff --git a/gcc/c-simplify.c b/gcc/c-simplify.c
index 2a362f4e124..92ef834f178 100644
--- a/gcc/c-simplify.c
+++ b/gcc/c-simplify.c
@@ -79,7 +79,6 @@ static void simplify_stmt_expr PARAMS ((tree *, tree *));
static void simplify_compound_literal_expr PARAMS ((tree *, tree *));
static void make_type_writable PARAMS ((tree));
static int expr_has_effect PARAMS ((tree));
-static tree mostly_copy_tree_r PARAMS ((tree *, int *, void *));
static tree copy_if_shared_r PARAMS ((tree *, int *, void *));
static tree unmark_visited_r PARAMS ((tree *, int *, void *));
static void unshare_all_trees PARAMS ((tree));
@@ -91,7 +90,6 @@ static void simplify_block PARAMS ((tree *, tree *));
static tree simplify_c_loop PARAMS ((tree, tree, tree, int));
static void push_context PARAMS ((void));
static void pop_context PARAMS ((void));
-static void simplify_break_or_continue PARAMS ((tree *));
/* Should move to tree-simple.c when the target language loses the C-isms. */
static void simplify_constructor PARAMS ((tree, tree *, tree *));
@@ -240,6 +238,9 @@ simplify_function_tree (fndecl)
return done;
}
+/* Simplify an expression which appears at statement context; usually, this
+ means replacing it with a suitably simple COMPOUND_EXPR. */
+
int
simplify_stmt (stmt_p)
tree *stmt_p;
@@ -247,6 +248,9 @@ simplify_stmt (stmt_p)
return simplify_expr (stmt_p, NULL, NULL, is_simple_stmt, fb_rvalue);
}
+/* Apply FN to each statement under *STMT_P, which may be a COMPOUND_EXPR
+ or a single statement expr. */
+
void
foreach_stmt (stmt_p, fn)
tree *stmt_p;
@@ -387,15 +391,22 @@ c_simplify_stmt (stmt_p)
break;
case CONTINUE_STMT:
+ stmt = build_bc_goto (bc_continue);
+ break;
+
case BREAK_STMT:
- simplify_break_or_continue (&stmt);
+ stmt = build_bc_goto (bc_break);
break;
case CLEANUP_STMT:
- case ASM_STMT:
abort ();
goto cont;
+ case ASM_STMT:
+ stmt = copy_node (stmt);
+ TREE_CODE (stmt) = ASM_EXPR;
+ break;
+
case FILE_STMT:
input_filename = FILE_STMT_FILENAME (stmt);
goto cont;
@@ -426,11 +437,6 @@ c_simplify_stmt (stmt_p)
fprintf (dump_file, "\n");
}
- /* Before re-chaining the side effects, determine if we are going to
- keep the original statement or not. If the statement had no
- effect before simplification, we emit it anyway to avoid changing
- the semantics of the original program. */
-
add_tree (stmt, &pre);
add_tree (post, &pre);
pre = rationalize_compound_expr (pre);
@@ -446,6 +452,11 @@ c_simplify_stmt (stmt_p)
*stmt_p = rationalize_compound_expr (outer_pre);
}
+/* Genericize a syntactic block by removing the bracketing SCOPE_STMTs and
+ wrapping the intervening code in a BIND_EXPR. This function assumes
+ that matching SCOPE_STMTs will always appear in the same statement
+ sequence. */
+
static void
simplify_block (stmt_p, next_p)
tree *stmt_p;
@@ -522,6 +533,11 @@ simplify_expr_stmt (stmt_p)
*stmt_p = stmt;
}
+/* Begin a scope which can be exited by a break or continue statement. BC
+ indicates which.
+
+ Just creates a label and pushes it into the current context. */
+
static tree
begin_bc_block (bc)
enum bc_t bc;
@@ -532,6 +548,13 @@ begin_bc_block (bc)
return label;
}
+/* Finish a scope which can be exited by a break or continue statement.
+ LABEL was returned from the most recent call to begin_bc_block. BODY is
+ an expression for the contents of the scope.
+
+ 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 (label, body)
tree label, body;
@@ -550,6 +573,9 @@ finish_bc_block (label, body)
return body;
}
+/* Build a GOTO_EXPR to represent a break or continue statement. BC
+ indicates which. */
+
static tree
build_bc_goto (bc)
enum bc_t bc;
@@ -557,26 +583,23 @@ build_bc_goto (bc)
tree label;
tree target_name = ctxp->bc_id[bc];
+ /* Look for the appropriate type of label. */
for (label = ctxp->current_bc_label; ;
label = TREE_CHAIN (label))
if (DECL_NAME (label) == target_name)
break;
+ /* Mark the label used for finish_bc_block. */
TREE_USED (label) = 1;
return build1 (GOTO_EXPR, void_type_node, label);
}
-static void
-simplify_break_or_continue (stmt_p)
- tree *stmt_p;
-{
- enum bc_t bc;
- if (TREE_CODE (*stmt_p) == BREAK_STMT)
- bc = bc_break;
- else
- bc = bc_continue;
- *stmt_p = build_bc_goto (bc);
-}
+/* Build a generic representation of one of the C loop forms. COND is the
+ loop condition or NULL_TREE. BODY is the (possibly compound) statement
+ controlled by the loop. INCR is the increment expression of a for-loop,
+ or NULL_TREE. COND_IS_FIRST indicates whether the condition is
+ evaluated before the loop body as in while and for loops, or after the
+ loop body as in do-while loops. */
static tree
simplify_c_loop (cond, body, incr, cond_is_first)
@@ -623,28 +646,8 @@ simplify_c_loop (cond, body, incr, cond_is_first)
return loop;
}
-/* Simplify a FOR_STMT node. This will convert:
-
- for (init; cond; expr)
- {
- body;
- }
-
- into
-
- init
- LOOP_EXPR
- COMPOUND_EXPR
- EXIT_EXPR
- cond
- COMPOUND_EXPR
- LABELED_BLOCK_EXPR
- body
- expr
-
- PRE_P points to the list where side effects that must happen before
- STMT should be store. These are all the expressions in
- FOR_INIT_STMT and the pre side-effects of the loop conditional. */
+/* Simplify a FOR_STMT node. Move the stuff in the for-init-stmt into the
+ prequeue and hand off to simplify_c_loop. */
static void
simplify_for_stmt (stmt_p, pre_p)
@@ -662,26 +665,7 @@ simplify_for_stmt (stmt_p, pre_p)
}
-/* Simplify a WHILE_STMT node. This will convert:
-
- while (cond)
- {
- body;
- }
-
- into
-
- LOOP_EXPR
- COMPOUND_EXPR
- EXIT_EXPR
- cond
- LABELED_BLOCK_EXPR
- body
-
- STMT is the statement to simplify.
-
- PRE_P points to the list where side effects that must happen before
- STMT should be stored. */
+/* Simplify a WHILE_STMT node. */
static void
simplify_while_stmt (stmt_p)
@@ -692,24 +676,7 @@ simplify_while_stmt (stmt_p)
NULL_TREE, 1);
}
-/* Simplify a DO_STMT node. This will convert:
-
- do
- {
- body;
- }
- while (cond);
-
- into
-
- LOOP_EXPR
- COMPOUND_EXPR
- LABELED_BLOCK_EXPR
- body
- EXIT_EXPR
- cond
-
- STMT is the statement to simplify. */
+/* Simplify a DO_STMT node. */
static void
simplify_do_stmt (stmt_p)
@@ -720,40 +687,7 @@ simplify_do_stmt (stmt_p)
NULL_TREE, 0);
}
-/* Simplify an IF_STMT. This will convert:
-
- if (cond)
- {
- then_clause;
- }
- else
- {
- else_clause;
- }
-
- into
-
- pre_cond_s;
- if (cond_s)
- {
- then_clause;
- }
- else
- {
- else_clause;
- }
-
- where COND_S is the simplified version of the predicate. PRE_COND_S are
- the pre side-effects produced by the simplification of the conditional.
-
- The order in which the different pieces are simplified is also
- important. Simplification should be done in the same order in which
- the loop will execute at runtime.
-
- STMT is the statement to simplify.
-
- PRE_P points to the list where side effects that must happen before
- STMT should be stored. */
+/* Genericize an IF_STMT by turning it into a COND_EXPR. */
static void
simplify_if_stmt (stmt_p)
@@ -769,32 +703,7 @@ simplify_if_stmt (stmt_p)
*stmt_p = build (COND_EXPR, void_type_node, IF_COND (stmt), then_, else_);
}
-/* Simplify a SWITCH_STMT. This will convert:
-
- switch (cond)
- {
- body;
- }
-
- into
-
- pre_cond_s;
- switch (cond_s)
- {
- body;
- }
-
- where COND_S is the simplified version of the predicate. PRE_COND_S are
- the pre side-effects produced by the simplification of the conditional.
-
- The order in which the different pieces are simplified is also
- important. Simplification should be done in the same order in which
- the loop will execute at runtime.
-
- STMT is the statement to simplify.
-
- PRE_P points to the list where side effects that must happen before
- STMT should be stored. */
+/* Genericize a SWITCH_STMT by turning it into a SWITCH_EXPR. */
static void
simplify_switch_stmt (stmt_p)
@@ -816,12 +725,7 @@ simplify_switch_stmt (stmt_p)
*stmt_p = switch_;
}
-/* Simplify a RETURN_STMT. If the expression to be returned is not a
- SIMPLE value, it is assigned to a new temporary and the statement is
- re-written to return the temporary.
-
- PRE_P points to the list where side effects that must happen before
- STMT should be stored. */
+/* Genericize a RETURN_STMT by turning it into a RETURN_EXPR. */
static void
simplify_return_stmt (stmt_p)
@@ -831,6 +735,13 @@ simplify_return_stmt (stmt_p)
*stmt_p = build (RETURN_EXPR, void_type_node, RETURN_STMT_EXPR (stmt));
}
+/* Simplify a RETURN_EXPR. If the expression to be returned is not a
+ SIMPLE value, it is assigned to a new temporary and the statement is
+ re-written to return the temporary.
+
+ PRE_P points to the list where side effects that must happen before
+ STMT should be stored. */
+
static void
simplify_return_expr (stmt, pre_p)
tree stmt;
@@ -931,6 +842,10 @@ simplify_compound_literal_expr (expr_p, pre_p)
tree decl_s = COMPOUND_LITERAL_EXPR_DECL_STMT (*expr_p);
tree decl = DECL_STMT_DECL (decl_s);
+ /* This decl isn't mentioned in the enclosing block, so add it to
+ the list of temps. */
+ pushdecl (decl);
+ simplify_decl_stmt (&decl_s);
add_tree (decl_s, pre_p);
*expr_p = decl;
}
@@ -1055,8 +970,7 @@ simplify_expr (expr_p, pre_p, post_p, simple_test_f, fallback)
tmp = TREE_OPERAND (*expr_p, 0);
simplify_expr (&tmp, pre_p, post_p, is_simple_id, fb_rvalue);
*expr_p = build (EQ_EXPR, TREE_TYPE (*expr_p), tmp, integer_zero_node);
- TREE_SIDE_EFFECTS (*expr_p)
- = TREE_SIDE_EFFECTS (TREE_OPERAND (*expr_p, 0));
+ recalculate_side_effects (*expr_p);
break;
case ADDR_EXPR:
@@ -1083,8 +997,7 @@ simplify_expr (expr_p, pre_p, post_p, simple_test_f, fallback)
case FIX_ROUND_EXPR:
simplify_expr (&TREE_OPERAND (*expr_p, 0), pre_p, post_p,
is_simple_varname, fb_rvalue);
- TREE_SIDE_EFFECTS (*expr_p)
- = TREE_SIDE_EFFECTS (TREE_OPERAND (*expr_p, 0));
+ recalculate_side_effects (*expr_p);
break;
case INDIRECT_REF:
@@ -1101,8 +1014,7 @@ simplify_expr (expr_p, pre_p, post_p, simple_test_f, fallback)
case BIND_EXPR:
simplify_stmt (&BIND_EXPR_BODY (*expr_p));
- TREE_SIDE_EFFECTS (*expr_p)
- = TREE_SIDE_EFFECTS (BIND_EXPR_BODY (*expr_p));
+ recalculate_side_effects (*expr_p);
break;
case LOOP_EXPR:
@@ -1117,8 +1029,7 @@ simplify_expr (expr_p, pre_p, post_p, simple_test_f, fallback)
case LABELED_BLOCK_EXPR:
simplify_stmt (&LABELED_BLOCK_BODY (*expr_p));
- TREE_SIDE_EFFECTS (*expr_p)
- = TREE_SIDE_EFFECTS (LABELED_BLOCK_BODY (*expr_p));
+ recalculate_side_effects (*expr_p);
break;
case EXIT_EXPR:
@@ -1126,6 +1037,16 @@ simplify_expr (expr_p, pre_p, post_p, simple_test_f, fallback)
is_simple_condexpr, fb_rvalue);
break;
+ case GOTO_EXPR:
+ if (TREE_CODE (GOTO_DESTINATION (*expr_p)) != LABEL_DECL)
+ simplify_expr (&GOTO_DESTINATION (*expr_p), pre_p, NULL,
+ is_simple_val, fb_rvalue);
+ break;
+
+ case LABEL_EXPR:
+ case CASE_LABEL_EXPR:
+ break;
+
case RETURN_EXPR:
simplify_return_expr (*expr_p, pre_p);
break;
@@ -1134,8 +1055,8 @@ simplify_expr (expr_p, pre_p, post_p, simple_test_f, fallback)
simplify_constructor (*expr_p, pre_p, post_p);
break;
- /* The following are special cases that are not handled by the original
- SIMPLE grammar. */
+ /* The following are special cases that are not handled by the
+ original SIMPLE grammar. */
/* SAVE_EXPR nodes are converted into a SIMPLE identifier and
eliminated. */
@@ -1163,20 +1084,18 @@ simplify_expr (expr_p, pre_p, post_p, simple_test_f, fallback)
case NON_LVALUE_EXPR:
simplify_expr (&TREE_OPERAND (*expr_p, 0), pre_p, post_p, simple_test_f,
fb_rvalue);
- TREE_SIDE_EFFECTS (*expr_p)
- = TREE_SIDE_EFFECTS (TREE_OPERAND (*expr_p, 0));
+ recalculate_side_effects (*expr_p);
break;
- /* If *EXPR_P does not need to be special-cased, handle it according to
- its class. */
+ /* If *EXPR_P does not need to be special-cased, handle it
+ according to its class. */
default:
{
if (TREE_CODE_CLASS (TREE_CODE (*expr_p)) == '1')
{
simplify_expr (&TREE_OPERAND (*expr_p, 0), pre_p, post_p,
is_simple_val, fb_rvalue);
- TREE_SIDE_EFFECTS (*expr_p)
- = TREE_SIDE_EFFECTS (TREE_OPERAND (*expr_p, 0));
+ recalculate_side_effects (*expr_p);
}
else if (TREE_CODE_CLASS (TREE_CODE (*expr_p)) == '2'
|| TREE_CODE_CLASS (TREE_CODE (*expr_p)) == '<'
@@ -1189,10 +1108,14 @@ simplify_expr (expr_p, pre_p, post_p, simple_test_f, fallback)
simplify_expr (&TREE_OPERAND (*expr_p, 1), pre_p, post_p,
is_simple_val, fb_rvalue);
- TREE_SIDE_EFFECTS (*expr_p)
- = (TREE_SIDE_EFFECTS (TREE_OPERAND (*expr_p, 0))
- || TREE_SIDE_EFFECTS (TREE_OPERAND (*expr_p, 1)));
+ recalculate_side_effects (*expr_p);
}
+ else if (TREE_CODE_CLASS (TREE_CODE (*expr_p)) == 'd'
+ || TREE_CODE_CLASS (TREE_CODE (*expr_p)) == 'c')
+ /* OK */;
+ else
+ /* Fail if we don't know how to handle this tree code. */
+ abort ();
}
}
}
@@ -1599,14 +1522,11 @@ simplify_tree_list (expr_p, pre_p, post_p)
t1 = a; a;
else or else
t1 = b; b;
- t1; (void)0;
+ t1;
The second form is used when *EXPR_P is of type void.
PRE_P points to the list where side effects that must happen before
- *EXPR_P should be stored.
-
- POST_P points to the list where side effects that must happen after
*EXPR_P should be stored. */
static void
@@ -1614,46 +1534,45 @@ simplify_cond_expr (expr_p, pre_p)
tree *expr_p;
tree *pre_p;
{
- tree t_then, t_else, tmp, pred, tval, fval, new_if, expr_type;
-
#if defined ENABLE_CHECKING
if (TREE_CODE (*expr_p) != COND_EXPR)
abort ();
#endif
- expr_type = TREE_TYPE (*expr_p);
-
- if (!VOID_TYPE_P (expr_type))
- tmp = create_tmp_var (TREE_TYPE (*expr_p), "iftmp");
+ if (VOID_TYPE_P (TREE_TYPE (*expr_p)))
+ {
+ /* If this is already void, just make sure it's simple. */
+ simplify_expr (&TREE_OPERAND (*expr_p, 0), pre_p, NULL,
+ is_simple_condexpr, fb_rvalue);
+ simplify_stmt (&TREE_OPERAND (*expr_p, 1));
+ simplify_stmt (&TREE_OPERAND (*expr_p, 2));
+ }
else
- tmp = NULL_TREE;
+ {
+ tree t_then, t_else, tmp, pred, new_if;
- pred = TREE_OPERAND (*expr_p, 0);
- tval = TREE_OPERAND (*expr_p, 1);
- fval = TREE_OPERAND (*expr_p, 2);
+ /* Otherwise, we need to copy the values into a temporary. */
+ tmp = create_tmp_var (TREE_TYPE (*expr_p), "iftmp");
- /* Build the THEN_CLAUSE 't1 = a;' or 'a;'. */
- if (tmp)
- t_then = build_modify_expr (tmp, NOP_EXPR, tval);
- else
- t_then = tval;
+ /* Simplify the condition. */
+ pred = TREE_OPERAND (*expr_p, 0);
+ simplify_expr (&pred, pre_p, NULL, is_simple_condexpr, fb_rvalue);
- /* Build the ELSE_CLAUSE 't1 = b;' or 'b;'. */
- if (tmp)
- t_else = build_modify_expr (tmp, NOP_EXPR, fval);
- else
- t_else = fval;
+ /* Build the then clause, 't1 = a;'. */
+ t_then = build_modify_expr (tmp, NOP_EXPR, TREE_OPERAND (*expr_p, 1));
+ simplify_stmt (&t_then);
- simplify_expr (&pred, pre_p, NULL, is_simple_condexpr, fb_rvalue);
- simplify_stmt (&t_then);
- simplify_stmt (&t_else);
+ /* Build the else clause, 't1 = b;'. */
+ t_else = build_modify_expr (tmp, NOP_EXPR, TREE_OPERAND (*expr_p, 2));
+ simplify_stmt (&t_else);
- /* Build a new IF_STMT, simplify it and insert it in the PRE_P chain. */
- new_if = build (COND_EXPR, void_type_node, pred, t_then, t_else);
- add_tree (new_if, pre_p);
+ /* Build a new COND_EXPR and insert it in the PRE_P chain. */
+ new_if = build (COND_EXPR, void_type_node, pred, t_then, t_else);
+ add_tree (new_if, pre_p);
- /* Replace the original expression with the new temporary. */
- *expr_p = tmp;
+ /* Replace the original expression with the new temporary. */
+ *expr_p = tmp;
+ }
}
@@ -1751,10 +1670,10 @@ simplify_boolean_expr (expr_p, pre_p)
else
if_cond = build (EQ_EXPR, TREE_TYPE (t), t, integer_zero_node);
- if_stmt = build (COND_EXPR, void_type_node, if_cond, if_body, empty_stmt_node);
- simplify_stmt (&if_stmt);
-
+ if_stmt = build (COND_EXPR, void_type_node, if_cond, if_body,
+ empty_stmt_node);
/* Simplify the IF_STMT and insert it in the PRE_P chain. */
+ simplify_stmt (&if_stmt);
add_tree (if_stmt, pre_p);
/* If we're not actually looking for a boolean result, convert now. */
@@ -2476,12 +2395,13 @@ expr_has_effect (expr)
&& VOID_TYPE_P (TREE_TYPE (expr))));
}
-
+#if 0
/* Similar to copy_tree_r() but do not copy SAVE_EXPR nodes. These nodes
model computations that should only be done once. If we were to unshare
something like SAVE_EXPR(i++), the simplification process would create
wrong code. */
+static tree mostly_copy_tree_r PARAMS ((tree *, int *, void *));
static tree
mostly_copy_tree_r (tp, walk_subtrees, data)
tree *tp;
@@ -2495,6 +2415,7 @@ mostly_copy_tree_r (tp, walk_subtrees, data)
return NULL_TREE;
}
+#endif
/* Callback for walk_tree to unshare most of the shared trees rooted at
*TP. If *TP has been visited already (i.e., TREE_VISITED (*TP) == 1),
diff --git a/gcc/c-tree.h b/gcc/c-tree.h
index 104a6d0c883..a67822db4df 100644
--- a/gcc/c-tree.h
+++ b/gcc/c-tree.h
@@ -237,7 +237,7 @@ extern void store_parm_decls PARAMS ((void));
extern tree xref_tag PARAMS ((enum tree_code, tree));
extern tree c_begin_compound_stmt PARAMS ((void));
extern void c_expand_deferred_function PARAMS ((tree));
-extern void c_expand_decl_stmt PARAMS ((tree));
+extern void c_expand_decl PARAMS ((tree));
extern tree make_pointer_declarator PARAMS ((tree, tree));
/* in c-objc-common.c */
diff --git a/gcc/c-typeck.c b/gcc/c-typeck.c
index 2f7eb1fd942..c2c849c5f94 100644
--- a/gcc/c-typeck.c
+++ b/gcc/c-typeck.c
@@ -6811,6 +6811,7 @@ build_asm_stmt (cv_qualifier, string, outputs, inputs, clobbers)
tree clobbers;
{
tree tail;
+ tree stmt;
if (TREE_CODE (string) != STRING_CST)
{
@@ -6863,8 +6864,10 @@ build_asm_stmt (cv_qualifier, string, outputs, inputs, clobbers)
for (tail = inputs; tail; tail = TREE_CHAIN (tail))
TREE_VALUE (tail) = default_function_array_conversion (TREE_VALUE (tail));
- return add_stmt (build_stmt (ASM_STMT, cv_qualifier, string,
- outputs, inputs, clobbers));
+ stmt = build_stmt (ASM_STMT, string, outputs, inputs, clobbers);
+ if (cv_qualifier)
+ ASM_VOLATILE_P (stmt) = 1;
+ return add_stmt (stmt);
}
/* Expand an ASM statement with operands, handling output operands
diff --git a/gcc/expr.c b/gcc/expr.c
index d579dcab377..99ecbadba55 100644
--- a/gcc/expr.c
+++ b/gcc/expr.c
@@ -5238,7 +5238,7 @@ store_field (target, bitsize, bitpos, mode, exp, value_mode, unsignedp, type,
if (bitpos != 0)
abort ();
- return store_expr (exp, target, 0);
+ return store_expr (exp, target, value_mode != VOIDmode);
}
/* If the structure is in a register or if the component
@@ -6760,7 +6760,14 @@ expand_expr (exp, target, tmode, modifier)
if (!DECL_RTL_SET_P (vars))
{
vars_need_expansion = 1;
- expand_decl (vars);
+ if (DECL_EXTERNAL (vars))
+ /* Do nothing. */;
+ else if (TREE_CODE (vars) == VAR_DECL && !TREE_STATIC (vars))
+ expand_decl (vars);
+ else if (TREE_CODE (vars) == VAR_DECL && TREE_STATIC (vars))
+ rest_of_decl_compilation (vars, NULL, 0, 0);
+ else
+ (*lang_hooks.expand_decl) (vars);
}
expand_decl_init (vars);
vars = TREE_CHAIN (vars);
@@ -9091,7 +9098,7 @@ expand_expr (exp, target, tmode, modifier)
else
expand_asm_operands (ASM_STRING (exp), ASM_OUTPUTS (exp),
ASM_INPUTS (exp), ASM_CLOBBERS (exp),
- ASM_CV_QUAL (exp) != NULL_TREE,
+ ASM_VOLATILE_P (exp),
input_filename, lineno);
/* FIXME copy outputs into proper locations? */
return const0_rtx;
diff --git a/gcc/langhooks-def.h b/gcc/langhooks-def.h
index ad52831d7ea..4e13e972b83 100644
--- a/gcc/langhooks-def.h
+++ b/gcc/langhooks-def.h
@@ -56,6 +56,7 @@ extern void lhd_clear_binding_stack PARAMS ((void));
extern void lhd_print_tree_nothing PARAMS ((FILE *, tree, int));
extern const char *lhd_decl_printable_name PARAMS ((tree, int));
extern rtx lhd_expand_expr PARAMS ((tree, rtx, enum machine_mode, int));
+extern void lhd_expand_decl PARAMS ((tree));
extern void lhd_print_error_function PARAMS ((struct diagnostic_context *,
const char *));
extern void lhd_set_decl_assembler_name PARAMS ((tree));
@@ -97,6 +98,7 @@ int lhd_simplify_expr PARAMS ((tree *, tree *, tree *));
#define LANG_HOOKS_GET_ALIAS_SET lhd_get_alias_set
#define LANG_HOOKS_EXPAND_CONSTANT lhd_return_tree
#define LANG_HOOKS_EXPAND_EXPR lhd_expand_expr
+#define LANG_HOOKS_EXPAND_DECL lhd_expand_decl
#define LANG_HOOKS_SAFE_FROM_P lhd_safe_from_p
#define LANG_HOOKS_FINISH_INCOMPLETE_DECL lhd_do_nothing_t
#define LANG_HOOKS_UNSAFE_FOR_REEVAL lhd_unsafe_for_reeval
@@ -238,6 +240,7 @@ int lhd_tree_dump_type_quals PARAMS ((tree));
LANG_HOOKS_GET_ALIAS_SET, \
LANG_HOOKS_EXPAND_CONSTANT, \
LANG_HOOKS_EXPAND_EXPR, \
+ LANG_HOOKS_EXPAND_DECL, \
LANG_HOOKS_TRUTHVALUE_CONVERSION, \
LANG_HOOKS_INSERT_DEFAULT_ATTRIBUTES, \
LANG_HOOKS_SAFE_FROM_P, \
diff --git a/gcc/langhooks.c b/gcc/langhooks.c
index 893a6a948f0..3d6fe8cf7ab 100644
--- a/gcc/langhooks.c
+++ b/gcc/langhooks.c
@@ -242,6 +242,20 @@ lhd_expand_expr (t, r, mm, em)
abort ();
}
+/* This is the default expand_decl function. */
+/* If non-NULL, the address of a language-specific function for
+ expanding a DECL_STMT. After the language-independent cases are
+ handled, this function will be called. If this function is not
+ defined, it is assumed that declarations other than those for
+ variables and labels do not require any RTL generation. */
+
+void
+lhd_expand_decl (t)
+ tree t;
+{
+ abort ();
+}
+
/* This is the default decl_printable_name function. */
const char *
diff --git a/gcc/langhooks.h b/gcc/langhooks.h
index 1292ef7d1b0..08206fe219b 100644
--- a/gcc/langhooks.h
+++ b/gcc/langhooks.h
@@ -236,6 +236,9 @@ struct lang_hooks
Fourth argument is actually an enum expand_modifier. */
rtx (*expand_expr) PARAMS ((tree, rtx, enum machine_mode, int));
+ /* Called by expand_expr to generate the definition of a decl. */
+ void (*expand_decl) PARAMS ((tree));
+
/* Prepare expr to be an argument of a TRUTH_NOT_EXPR or other logical
operation.
diff --git a/gcc/tree-inline.c b/gcc/tree-inline.c
index b16835250de..711e5f357d3 100644
--- a/gcc/tree-inline.c
+++ b/gcc/tree-inline.c
@@ -855,6 +855,8 @@ inlinable_function_p (fn, id)
int inlinable;
int currfn_insns;
+ return 0;
+
/* If we've already decided this function shouldn't be inlined,
there's no need to check again. */
if (DECL_UNINLINABLE (fn))
@@ -1160,7 +1162,9 @@ expand_call_inline (tp, walk_subtrees, data)
/* Declare the return variable for the function. */
decl = declare_return_variable (id, &use_stmt);
COMPOUND_BODY (stmt) = chainon (COMPOUND_BODY (stmt), decl);
- if (TREE_CODE (decl) == DECL_STMT)
+ if (!decl)
+ /* OK */;
+ else if (TREE_CODE (decl) == DECL_STMT)
BLOCK_VARS (SCOPE_STMT_BLOCK (scope_stmt))
= chainon (BLOCK_VARS (SCOPE_STMT_BLOCK (scope_stmt)),
DECL_STMT_DECL (decl));
diff --git a/gcc/tree-simple.c b/gcc/tree-simple.c
index 2d9a1bc1e3b..24b746b2105 100644
--- a/gcc/tree-simple.c
+++ b/gcc/tree-simple.c
@@ -980,5 +980,43 @@ void
recalculate_side_effects (t)
tree t;
{
-
+ enum tree_code code = TREE_CODE (t);
+ int fro = first_rtl_op (code);
+ int i;
+
+ switch (TREE_CODE_CLASS (code))
+ {
+ case 'e':
+ switch (code)
+ {
+ case INIT_EXPR:
+ case MODIFY_EXPR:
+ case VA_ARG_EXPR:
+ case RTL_EXPR:
+ case PREDECREMENT_EXPR:
+ case PREINCREMENT_EXPR:
+ case POSTDECREMENT_EXPR:
+ case POSTINCREMENT_EXPR:
+ /* All of these have side-effects, no matter what their
+ operands are. */
+ return;
+
+ default:
+ break;
+ }
+ /* Fall through. */
+
+ case '<': /* a comparison expression */
+ case '1': /* a unary arithmetic expression */
+ case '2': /* a binary arithmetic expression */
+ case 'r': /* a reference */
+ TREE_SIDE_EFFECTS (t) = 0;
+ for (i = 0; i < fro; ++i)
+ {
+ tree op = TREE_OPERAND (t, i);
+ if (op && TREE_SIDE_EFFECTS (op))
+ TREE_SIDE_EFFECTS (t) = 1;
+ }
+ break;
+ }
}
diff --git a/gcc/tree.def b/gcc/tree.def
index 0cec1b9ee31..3514fb16260 100644
--- a/gcc/tree.def
+++ b/gcc/tree.def
@@ -863,7 +863,7 @@ DEFTREECODE (CASE_LABEL_EXPR, "case_label_expr", 's', 2)
STRING_CST for the instruction (e.g., "mov x, y"). ASM_OUTPUTS,
ASM_INPUTS, and ASM_CLOBBERS represent the outputs, inputs, and clobbers
for the statement. */
-DEFTREECODE (ASM_EXPR, "asm_expr", 's', 1)
+DEFTREECODE (ASM_EXPR, "asm_expr", 's', 4)
/*
Local variables:
mode:c
diff --git a/gcc/tree.h b/gcc/tree.h
index a6007353fd1..5a431ba98c4 100644
--- a/gcc/tree.h
+++ b/gcc/tree.h
@@ -187,7 +187,7 @@ struct tree_common GTY(())
TREE_LIST elements of a block's cleanup list.
EXIT_EXPR_IS_LOOP_COND in
EXIT_EXPR
- ASM_EXPR_INPUT_P in
+ ASM_INPUT_P in
ASM_EXPR
public_flag:
@@ -200,6 +200,8 @@ struct tree_common GTY(())
TREE_LIST or TREE_VEC
EXPR_WFL_EMIT_LINE_NOTE in
EXPR_WITH_FILE_LOCATION
+ ASM_VOLATILE_P in
+ ASM_EXPR
private_flag:
@@ -896,7 +898,7 @@ struct tree_vec GTY(())
#define EXIT_EXPR_IS_LOOP_COND(NODE) TREE_STATIC (NODE)
#define EXIT_EXPR_COND(NODE) TREE_OPERAND (EXIT_EXPR_CHECK (NODE), 0)
-/* SWITCH_STMT accessors. These give access to the condition, body and
+/* SWITCH_EXPR accessors. These give access to the condition, body and
original condition type (before any compiler conversions)
of the switch statement, respectively. */
#define SWITCH_COND(NODE) TREE_OPERAND ((NODE), 0)
@@ -912,7 +914,7 @@ struct tree_vec GTY(())
#define BIND_EXPR_BODY(NODE) (TREE_OPERAND (BIND_EXPR_CHECK (NODE), 1))
#define BIND_EXPR_BLOCK(NODE) (TREE_OPERAND (BIND_EXPR_CHECK (NODE), 2))
-/* GOTO_STMT accessor. This gives access to the label associated with
+/* GOTO_EXPR accessor. This gives access to the label associated with
a goto statement. */
#define GOTO_DESTINATION(NODE) TREE_OPERAND ((NODE), 0)
@@ -920,14 +922,14 @@ struct tree_vec GTY(())
instruction (e.g., "mov x, y"). ASM_OUTPUTS, ASM_INPUTS, and
ASM_CLOBBERS represent the outputs, inputs, and clobbers for the
statement. */
-#define ASM_CV_QUAL(NODE) TREE_OPERAND ((NODE), 0)
-#define ASM_STRING(NODE) TREE_OPERAND ((NODE), 1)
-#define ASM_OUTPUTS(NODE) TREE_OPERAND ((NODE), 2)
-#define ASM_INPUTS(NODE) TREE_OPERAND ((NODE), 3)
-#define ASM_CLOBBERS(NODE) TREE_OPERAND ((NODE), 4)
+#define ASM_STRING(NODE) TREE_OPERAND ((NODE), 0)
+#define ASM_OUTPUTS(NODE) TREE_OPERAND ((NODE), 1)
+#define ASM_INPUTS(NODE) TREE_OPERAND ((NODE), 2)
+#define ASM_CLOBBERS(NODE) TREE_OPERAND ((NODE), 3)
/* Nonzero if we want to create an ASM_INPUT instead of an
ASM_OPERAND with no operands. */
#define ASM_INPUT_P(NODE) (TREE_STATIC (NODE))
+#define ASM_VOLATILE_P(NODE) (TREE_PUBLIC (NODE))
struct tree_exp GTY(())
{