]>
Commit | Line | Data |
---|---|---|
5384b728 | 1 | 2002-08-06 Jason Merrill <jason@redhat.com> |
2 | ||
3 | * c-common.c (c_expand_expr) [STMT_EXPR]: If the last expression is | |
4 | a VAR_DECL with RTL that matches the target, just return that RTL. | |
5 | ||
6 | 2002-06-01 Daniel Berlin <dberlin@dberlin.org> | |
7 | ||
8 | * tree-inline.c (expand_call_inline): Make the statement | |
9 | expression we generate have a COMPOUND_STMT. | |
10 | ||
11 | --- gcc/c-common.c.jj 2002-08-28 11:20:26.000000000 +0200 | |
12 | +++ gcc/c-common.c 2002-08-28 22:49:59.000000000 +0200 | |
13 | @@ -3564,6 +3564,7 @@ c_expand_expr (exp, target, tmode, modif | |
14 | tree rtl_expr; | |
15 | rtx result; | |
16 | bool preserve_result = false; | |
17 | + bool return_target = false; | |
18 | ||
19 | /* Since expand_expr_stmt calls free_temp_slots after every | |
20 | expression statement, we must call push_temp_slots here. | |
21 | @@ -3591,8 +3592,20 @@ c_expand_expr (exp, target, tmode, modif | |
22 | if (TREE_CODE (last) == SCOPE_STMT | |
23 | && TREE_CODE (expr) == EXPR_STMT) | |
24 | { | |
25 | - TREE_ADDRESSABLE (expr) = 1; | |
26 | - preserve_result = true; | |
27 | + if (target && TREE_CODE (EXPR_STMT_EXPR (expr)) == VAR_DECL | |
28 | + && DECL_RTL_IF_SET (EXPR_STMT_EXPR (expr)) == target) | |
29 | + /* If the last expression is a variable whose RTL is the | |
30 | + same as our target, just return the target; if it | |
31 | + isn't valid expanding the decl would produce different | |
32 | + RTL, and store_expr would try to do a copy. */ | |
33 | + return_target = true; | |
34 | + else | |
35 | + { | |
36 | + /* Otherwise, note that we want the value from the last | |
37 | + expression. */ | |
38 | + TREE_ADDRESSABLE (expr) = 1; | |
39 | + preserve_result = true; | |
40 | + } | |
41 | } | |
42 | } | |
43 | ||
44 | @@ -3600,7 +3613,9 @@ c_expand_expr (exp, target, tmode, modif | |
45 | expand_end_stmt_expr (rtl_expr); | |
46 | ||
47 | result = expand_expr (rtl_expr, target, tmode, modifier); | |
48 | - if (preserve_result && GET_CODE (result) == MEM) | |
49 | + if (return_target) | |
50 | + result = target; | |
51 | + else if (preserve_result && GET_CODE (result) == MEM) | |
52 | { | |
53 | if (GET_MODE (result) != BLKmode) | |
54 | result = copy_to_reg (result); | |
55 | --- gcc/tree-inline.c.jj 2002-08-28 11:20:27.000000000 +0200 | |
56 | +++ gcc/tree-inline.c 2002-08-28 22:49:59.000000000 +0200 | |
57 | @@ -773,6 +773,7 @@ expand_call_inline (tp, walk_subtrees, d | |
58 | inline_data *id; | |
59 | tree t; | |
60 | tree expr; | |
61 | + tree stmt; | |
62 | tree chain; | |
63 | tree fn; | |
64 | tree scope_stmt; | |
65 | @@ -864,10 +865,10 @@ expand_call_inline (tp, walk_subtrees, d | |
66 | for the return statements within the function to jump to. The | |
67 | type of the statement expression is the return type of the | |
68 | function call. */ | |
69 | - expr = build1 (STMT_EXPR, TREE_TYPE (TREE_TYPE (fn)), NULL_TREE); | |
70 | + expr = build1 (STMT_EXPR, TREE_TYPE (TREE_TYPE (fn)), make_node (COMPOUND_STMT)); | |
71 | /* There is no scope associated with the statement-expression. */ | |
72 | STMT_EXPR_NO_SCOPE (expr) = 1; | |
73 | - | |
74 | + stmt = STMT_EXPR_STMT (expr); | |
75 | /* Local declarations will be replaced by their equivalents in this | |
76 | map. */ | |
77 | st = id->decl_map; | |
78 | @@ -890,7 +891,7 @@ expand_call_inline (tp, walk_subtrees, d | |
79 | parameters. */ | |
80 | expand_calls_inline (&arg_inits, id); | |
81 | /* And add them to the tree. */ | |
82 | - STMT_EXPR_STMT (expr) = chainon (STMT_EXPR_STMT (expr), arg_inits); | |
83 | + COMPOUND_BODY (stmt) = chainon (COMPOUND_BODY (stmt), arg_inits); | |
84 | ||
85 | /* Record the function we are about to inline so that we can avoid | |
86 | recursing into it. */ | |
87 | @@ -925,8 +926,8 @@ expand_call_inline (tp, walk_subtrees, d | |
88 | SCOPE_BEGIN_P (scope_stmt) = 1; | |
89 | SCOPE_NO_CLEANUPS_P (scope_stmt) = 1; | |
90 | remap_block (scope_stmt, DECL_ARGUMENTS (fn), id); | |
91 | - TREE_CHAIN (scope_stmt) = STMT_EXPR_STMT (expr); | |
92 | - STMT_EXPR_STMT (expr) = scope_stmt; | |
93 | + TREE_CHAIN (scope_stmt) = COMPOUND_BODY (stmt); | |
94 | + COMPOUND_BODY (stmt) = scope_stmt; | |
95 | ||
96 | /* Tell the debugging backends that this block represents the | |
97 | outermost scope of the inlined function. */ | |
98 | @@ -934,34 +935,34 @@ expand_call_inline (tp, walk_subtrees, d | |
99 | BLOCK_ABSTRACT_ORIGIN (SCOPE_STMT_BLOCK (scope_stmt)) = DECL_ORIGIN (fn); | |
100 | ||
101 | /* Declare the return variable for the function. */ | |
102 | - STMT_EXPR_STMT (expr) | |
103 | - = chainon (STMT_EXPR_STMT (expr), | |
104 | + COMPOUND_BODY (stmt) | |
105 | + = chainon (COMPOUND_BODY (stmt), | |
106 | declare_return_variable (id, &use_stmt)); | |
107 | ||
108 | /* After we've initialized the parameters, we insert the body of the | |
109 | function itself. */ | |
110 | - inlined_body = &STMT_EXPR_STMT (expr); | |
111 | + inlined_body = &COMPOUND_BODY (stmt); | |
112 | while (*inlined_body) | |
113 | inlined_body = &TREE_CHAIN (*inlined_body); | |
114 | *inlined_body = copy_body (id); | |
115 | ||
116 | - /* Close the block for the parameters. */ | |
117 | - scope_stmt = build_stmt (SCOPE_STMT, DECL_INITIAL (fn)); | |
118 | - SCOPE_NO_CLEANUPS_P (scope_stmt) = 1; | |
119 | - remap_block (scope_stmt, NULL_TREE, id); | |
120 | - STMT_EXPR_STMT (expr) | |
121 | - = chainon (STMT_EXPR_STMT (expr), scope_stmt); | |
122 | - | |
123 | /* After the body of the function comes the RET_LABEL. This must come | |
124 | before we evaluate the returned value below, because that evalulation | |
125 | may cause RTL to be generated. */ | |
126 | - STMT_EXPR_STMT (expr) | |
127 | - = chainon (STMT_EXPR_STMT (expr), | |
128 | + COMPOUND_BODY (stmt) | |
129 | + = chainon (COMPOUND_BODY (stmt), | |
130 | build_stmt (LABEL_STMT, id->ret_label)); | |
131 | ||
132 | /* Finally, mention the returned value so that the value of the | |
133 | statement-expression is the returned value of the function. */ | |
134 | - STMT_EXPR_STMT (expr) = chainon (STMT_EXPR_STMT (expr), use_stmt); | |
135 | + COMPOUND_BODY (stmt) = chainon (COMPOUND_BODY (stmt), use_stmt); | |
136 | + | |
137 | + /* Close the block for the parameters. */ | |
138 | + scope_stmt = build_stmt (SCOPE_STMT, DECL_INITIAL (fn)); | |
139 | + SCOPE_NO_CLEANUPS_P (scope_stmt) = 1; | |
140 | + remap_block (scope_stmt, NULL_TREE, id); | |
141 | + COMPOUND_BODY (stmt) | |
142 | + = chainon (COMPOUND_BODY (stmt), scope_stmt); | |
143 | ||
144 | /* Clean up. */ | |
145 | splay_tree_delete (id->decl_map); |