diff options
author | Jason Merrill <jason@redhat.com> | 2002-09-04 15:15:28 +0000 |
---|---|---|
committer | Jason Merrill <jason@redhat.com> | 2002-09-04 15:15:28 +0000 |
commit | d32d494b33941b24431f0422e8ddc0937ea41426 (patch) | |
tree | a6949a2f7286373de0bb29aabf32406b529f6b3b | |
parent | aa49d98c742631847566b755f25893498663e98b (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.in | 4 | ||||
-rw-r--r-- | gcc/c-common.def | 2 | ||||
-rw-r--r-- | gcc/c-common.h | 6 | ||||
-rw-r--r-- | gcc/c-decl.c | 8 | ||||
-rw-r--r-- | gcc/c-lang.c | 2 | ||||
-rw-r--r-- | gcc/c-objc-common.c | 2 | ||||
-rw-r--r-- | gcc/c-pretty-print.c | 2 | ||||
-rw-r--r-- | gcc/c-semantics.c | 28 | ||||
-rw-r--r-- | gcc/c-simplify.c | 323 | ||||
-rw-r--r-- | gcc/c-tree.h | 2 | ||||
-rw-r--r-- | gcc/c-typeck.c | 7 | ||||
-rw-r--r-- | gcc/expr.c | 13 | ||||
-rw-r--r-- | gcc/langhooks-def.h | 3 | ||||
-rw-r--r-- | gcc/langhooks.c | 14 | ||||
-rw-r--r-- | gcc/langhooks.h | 3 | ||||
-rw-r--r-- | gcc/tree-inline.c | 6 | ||||
-rw-r--r-- | gcc/tree-simple.c | 40 | ||||
-rw-r--r-- | gcc/tree.def | 2 | ||||
-rw-r--r-- | gcc/tree.h | 18 |
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(()) { |