gimplify-be.h: New file.
[platform/upstream/gcc.git] / gcc / gimplify-me.c
1 /* Tree lowering to gimple for middle end use only.  
2    This converts the GENERIC functions-as-trees tree representation into
3    the GIMPLE form.
4    Copyright (C) 2013 Free Software Foundation, Inc.
5    Major work done by Sebastian Pop <s.pop@laposte.net>,
6    Diego Novillo <dnovillo@redhat.com> and Jason Merrill <jason@redhat.com>.
7
8 This file is part of GCC.
9
10 GCC is free software; you can redistribute it and/or modify it under
11 the terms of the GNU General Public License as published by the Free
12 Software Foundation; either version 3, or (at your option) any later
13 version.
14
15 GCC is distributed in the hope that it will be useful, but WITHOUT ANY
16 WARRANTY; without even the implied warranty of MERCHANTABILITY or
17 FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
18 for more details.
19
20 You should have received a copy of the GNU General Public License
21 along with GCC; see the file COPYING3.  If not see
22 <http://www.gnu.org/licenses/>.  */
23
24 #include "config.h"
25 #include "system.h"
26 #include "coretypes.h"
27 #include "tree.h"
28 #include "gimple.h"
29 #include "gimple-iterator.h"
30 #include "gimplify.h"
31 #include "gimplify-me.h"
32 #include "gimple-ssa.h"
33 #include "tree-ssanames.h"
34
35
36 /* Expand EXPR to list of gimple statements STMTS.  GIMPLE_TEST_F specifies
37    the predicate that will hold for the result.  If VAR is not NULL, make the
38    base variable of the final destination be VAR if suitable.  */
39
40 tree
41 force_gimple_operand_1 (tree expr, gimple_seq *stmts,
42                         gimple_predicate gimple_test_f, tree var)
43 {
44   enum gimplify_status ret;
45   struct gimplify_ctx gctx;
46   location_t saved_location;
47
48   *stmts = NULL;
49
50   /* gimple_test_f might be more strict than is_gimple_val, make
51      sure we pass both.  Just checking gimple_test_f doesn't work
52      because most gimple predicates do not work recursively.  */
53   if (is_gimple_val (expr)
54       && (*gimple_test_f) (expr))
55     return expr;
56
57   push_gimplify_context (&gctx);
58   gimplify_ctxp->into_ssa = gimple_in_ssa_p (cfun);
59   gimplify_ctxp->allow_rhs_cond_expr = true;
60   saved_location = input_location;
61   input_location = UNKNOWN_LOCATION;
62
63   if (var)
64     {
65       if (gimplify_ctxp->into_ssa
66           && is_gimple_reg (var))
67         var = make_ssa_name (var, NULL);
68       expr = build2 (MODIFY_EXPR, TREE_TYPE (var), var, expr);
69     }
70
71   if (TREE_CODE (expr) != MODIFY_EXPR
72       && TREE_TYPE (expr) == void_type_node)
73     {
74       gimplify_and_add (expr, stmts);
75       expr = NULL_TREE;
76     }
77   else
78     {
79       ret = gimplify_expr (&expr, stmts, NULL, gimple_test_f, fb_rvalue);
80       gcc_assert (ret != GS_ERROR);
81     }
82
83   input_location = saved_location;
84   pop_gimplify_context (NULL);
85
86   return expr;
87 }
88
89 /* Expand EXPR to list of gimple statements STMTS.  If SIMPLE is true,
90    force the result to be either ssa_name or an invariant, otherwise
91    just force it to be a rhs expression.  If VAR is not NULL, make the
92    base variable of the final destination be VAR if suitable.  */
93
94 tree
95 force_gimple_operand (tree expr, gimple_seq *stmts, bool simple, tree var)
96 {
97   return force_gimple_operand_1 (expr, stmts,
98                                  simple ? is_gimple_val : is_gimple_reg_rhs,
99                                  var);
100 }
101
102 /* Invoke force_gimple_operand_1 for EXPR with parameters GIMPLE_TEST_F
103    and VAR.  If some statements are produced, emits them at GSI.
104    If BEFORE is true.  the statements are appended before GSI, otherwise
105    they are appended after it.  M specifies the way GSI moves after
106    insertion (GSI_SAME_STMT or GSI_CONTINUE_LINKING are the usual values).  */
107
108 tree
109 force_gimple_operand_gsi_1 (gimple_stmt_iterator *gsi, tree expr,
110                             gimple_predicate gimple_test_f,
111                             tree var, bool before,
112                             enum gsi_iterator_update m)
113 {
114   gimple_seq stmts;
115
116   expr = force_gimple_operand_1 (expr, &stmts, gimple_test_f, var);
117
118   if (!gimple_seq_empty_p (stmts))
119     {
120       if (before)
121         gsi_insert_seq_before (gsi, stmts, m);
122       else
123         gsi_insert_seq_after (gsi, stmts, m);
124     }
125
126   return expr;
127 }
128
129 /* Invoke force_gimple_operand_1 for EXPR with parameter VAR.
130    If SIMPLE is true, force the result to be either ssa_name or an invariant,
131    otherwise just force it to be a rhs expression.  If some statements are
132    produced, emits them at GSI.  If BEFORE is true, the statements are
133    appended before GSI, otherwise they are appended after it.  M specifies
134    the way GSI moves after insertion (GSI_SAME_STMT or GSI_CONTINUE_LINKING
135    are the usual values).  */
136
137 tree
138 force_gimple_operand_gsi (gimple_stmt_iterator *gsi, tree expr,
139                           bool simple_p, tree var, bool before,
140                           enum gsi_iterator_update m)
141 {
142   return force_gimple_operand_gsi_1 (gsi, expr,
143                                      simple_p
144                                      ? is_gimple_val : is_gimple_reg_rhs,
145                                      var, before, m);
146 }
147
148 /* Some transformations like inlining may invalidate the GIMPLE form
149    for operands.  This function traverses all the operands in STMT and
150    gimplifies anything that is not a valid gimple operand.  Any new
151    GIMPLE statements are inserted before *GSI_P.  */
152
153 void
154 gimple_regimplify_operands (gimple stmt, gimple_stmt_iterator *gsi_p)
155 {
156   size_t i, num_ops;
157   tree lhs;
158   gimple_seq pre = NULL;
159   gimple post_stmt = NULL;
160   struct gimplify_ctx gctx;
161
162   push_gimplify_context (&gctx);
163   gimplify_ctxp->into_ssa = gimple_in_ssa_p (cfun);
164
165   switch (gimple_code (stmt))
166     {
167     case GIMPLE_COND:
168       gimplify_expr (gimple_cond_lhs_ptr (stmt), &pre, NULL,
169                      is_gimple_val, fb_rvalue);
170       gimplify_expr (gimple_cond_rhs_ptr (stmt), &pre, NULL,
171                      is_gimple_val, fb_rvalue);
172       break;
173     case GIMPLE_SWITCH:
174       gimplify_expr (gimple_switch_index_ptr (stmt), &pre, NULL,
175                      is_gimple_val, fb_rvalue);
176       break;
177     case GIMPLE_OMP_ATOMIC_LOAD:
178       gimplify_expr (gimple_omp_atomic_load_rhs_ptr (stmt), &pre, NULL,
179                      is_gimple_val, fb_rvalue);
180       break;
181     case GIMPLE_ASM:
182       {
183         size_t i, noutputs = gimple_asm_noutputs (stmt);
184         const char *constraint, **oconstraints;
185         bool allows_mem, allows_reg, is_inout;
186
187         oconstraints
188           = (const char **) alloca ((noutputs) * sizeof (const char *));
189         for (i = 0; i < noutputs; i++)
190           {
191             tree op = gimple_asm_output_op (stmt, i);
192             constraint = TREE_STRING_POINTER (TREE_VALUE (TREE_PURPOSE (op)));
193             oconstraints[i] = constraint;
194             parse_output_constraint (&constraint, i, 0, 0, &allows_mem,
195                                      &allows_reg, &is_inout);
196             gimplify_expr (&TREE_VALUE (op), &pre, NULL,
197                            is_inout ? is_gimple_min_lval : is_gimple_lvalue,
198                            fb_lvalue | fb_mayfail);
199           }
200         for (i = 0; i < gimple_asm_ninputs (stmt); i++)
201           {
202             tree op = gimple_asm_input_op (stmt, i);
203             constraint = TREE_STRING_POINTER (TREE_VALUE (TREE_PURPOSE (op)));
204             parse_input_constraint (&constraint, 0, 0, noutputs, 0,
205                                     oconstraints, &allows_mem, &allows_reg);
206             if (TREE_ADDRESSABLE (TREE_TYPE (TREE_VALUE (op))) && allows_mem)
207               allows_reg = 0;
208             if (!allows_reg && allows_mem)
209               gimplify_expr (&TREE_VALUE (op), &pre, NULL,
210                              is_gimple_lvalue, fb_lvalue | fb_mayfail);
211             else
212               gimplify_expr (&TREE_VALUE (op), &pre, NULL,
213                              is_gimple_asm_val, fb_rvalue);
214           }
215       }
216       break;
217     default:
218       /* NOTE: We start gimplifying operands from last to first to
219          make sure that side-effects on the RHS of calls, assignments
220          and ASMs are executed before the LHS.  The ordering is not
221          important for other statements.  */
222       num_ops = gimple_num_ops (stmt);
223       for (i = num_ops; i > 0; i--)
224         {
225           tree op = gimple_op (stmt, i - 1);
226           if (op == NULL_TREE)
227             continue;
228           if (i == 1 && (is_gimple_call (stmt) || is_gimple_assign (stmt)))
229             gimplify_expr (&op, &pre, NULL, is_gimple_lvalue, fb_lvalue);
230           else if (i == 2
231                    && is_gimple_assign (stmt)
232                    && num_ops == 2
233                    && get_gimple_rhs_class (gimple_expr_code (stmt))
234                       == GIMPLE_SINGLE_RHS)
235             gimplify_expr (&op, &pre, NULL,
236                            rhs_predicate_for (gimple_assign_lhs (stmt)),
237                            fb_rvalue);
238           else if (i == 2 && is_gimple_call (stmt))
239             {
240               if (TREE_CODE (op) == FUNCTION_DECL)
241                 continue;
242               gimplify_expr (&op, &pre, NULL, is_gimple_call_addr, fb_rvalue);
243             }
244           else
245             gimplify_expr (&op, &pre, NULL, is_gimple_val, fb_rvalue);
246           gimple_set_op (stmt, i - 1, op);
247         }
248
249       lhs = gimple_get_lhs (stmt);
250       /* If the LHS changed it in a way that requires a simple RHS,
251          create temporary.  */
252       if (lhs && !is_gimple_reg (lhs))
253         {
254           bool need_temp = false;
255
256           if (is_gimple_assign (stmt)
257               && num_ops == 2
258               && get_gimple_rhs_class (gimple_expr_code (stmt))
259                  == GIMPLE_SINGLE_RHS)
260             gimplify_expr (gimple_assign_rhs1_ptr (stmt), &pre, NULL,
261                            rhs_predicate_for (gimple_assign_lhs (stmt)),
262                            fb_rvalue);
263           else if (is_gimple_reg (lhs))
264             {
265               if (is_gimple_reg_type (TREE_TYPE (lhs)))
266                 {
267                   if (is_gimple_call (stmt))
268                     {
269                       i = gimple_call_flags (stmt);
270                       if ((i & ECF_LOOPING_CONST_OR_PURE)
271                           || !(i & (ECF_CONST | ECF_PURE)))
272                         need_temp = true;
273                     }
274                   if (stmt_can_throw_internal (stmt))
275                     need_temp = true;
276                 }
277             }
278           else
279             {
280               if (is_gimple_reg_type (TREE_TYPE (lhs)))
281                 need_temp = true;
282               else if (TYPE_MODE (TREE_TYPE (lhs)) != BLKmode)
283                 {
284                   if (is_gimple_call (stmt))
285                     {
286                       tree fndecl = gimple_call_fndecl (stmt);
287
288                       if (!aggregate_value_p (TREE_TYPE (lhs), fndecl)
289                           && !(fndecl && DECL_RESULT (fndecl)
290                                && DECL_BY_REFERENCE (DECL_RESULT (fndecl))))
291                         need_temp = true;
292                     }
293                   else
294                     need_temp = true;
295                 }
296             }
297           if (need_temp)
298             {
299               tree temp = create_tmp_reg (TREE_TYPE (lhs), NULL);
300               if (gimple_in_ssa_p (cfun))
301                 temp = make_ssa_name (temp, NULL);
302               gimple_set_lhs (stmt, temp);
303               post_stmt = gimple_build_assign (lhs, temp);
304             }
305         }
306       break;
307     }
308
309   if (!gimple_seq_empty_p (pre))
310     gsi_insert_seq_before (gsi_p, pre, GSI_SAME_STMT);
311   if (post_stmt)
312     gsi_insert_after (gsi_p, post_stmt, GSI_NEW_STMT);
313
314   pop_gimplify_context (NULL);
315 }
316
317