aarch64 - Set the mode for the unspec in speculation_tracker insn.
[platform/upstream/linaro-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-2016 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 "backend.h"
28 #include "tree.h"
29 #include "gimple.h"
30 #include "ssa.h"
31 #include "stmt.h"
32 #include "stor-layout.h"
33 #include "tree-eh.h"
34 #include "gimple-iterator.h"
35 #include "gimplify.h"
36 #include "gimplify-me.h"
37
38
39 /* Expand EXPR to list of gimple statements STMTS.  GIMPLE_TEST_F specifies
40    the predicate that will hold for the result.  If VAR is not NULL, make the
41    base variable of the final destination be VAR if suitable.  */
42
43 tree
44 force_gimple_operand_1 (tree expr, gimple_seq *stmts,
45                         gimple_predicate gimple_test_f, tree var)
46 {
47   enum gimplify_status ret;
48   location_t saved_location;
49
50   *stmts = NULL;
51
52   /* gimple_test_f might be more strict than is_gimple_val, make
53      sure we pass both.  Just checking gimple_test_f doesn't work
54      because most gimple predicates do not work recursively.  */
55   if (is_gimple_val (expr)
56       && (*gimple_test_f) (expr))
57     return expr;
58
59   push_gimplify_context (gimple_in_ssa_p (cfun), true);
60   saved_location = input_location;
61   input_location = UNKNOWN_LOCATION;
62
63   if (var)
64     {
65       if (gimple_in_ssa_p (cfun) && is_gimple_reg (var))
66         var = make_ssa_name (var);
67       expr = build2 (MODIFY_EXPR, TREE_TYPE (var), var, expr);
68     }
69
70   if (TREE_CODE (expr) != MODIFY_EXPR
71       && TREE_TYPE (expr) == void_type_node)
72     {
73       gimplify_and_add (expr, stmts);
74       expr = NULL_TREE;
75     }
76   else
77     {
78       ret = gimplify_expr (&expr, stmts, NULL, gimple_test_f, fb_rvalue);
79       gcc_assert (ret != GS_ERROR);
80     }
81
82   input_location = saved_location;
83   pop_gimplify_context (NULL);
84
85   return expr;
86 }
87
88 /* Expand EXPR to list of gimple statements STMTS.  If SIMPLE is true,
89    force the result to be either ssa_name or an invariant, otherwise
90    just force it to be a rhs expression.  If VAR is not NULL, make the
91    base variable of the final destination be VAR if suitable.  */
92
93 tree
94 force_gimple_operand (tree expr, gimple_seq *stmts, bool simple, tree var)
95 {
96   return force_gimple_operand_1 (expr, stmts,
97                                  simple ? is_gimple_val : is_gimple_reg_rhs,
98                                  var);
99 }
100
101 /* Invoke force_gimple_operand_1 for EXPR with parameters GIMPLE_TEST_F
102    and VAR.  If some statements are produced, emits them at GSI.
103    If BEFORE is true.  the statements are appended before GSI, otherwise
104    they are appended after it.  M specifies the way GSI moves after
105    insertion (GSI_SAME_STMT or GSI_CONTINUE_LINKING are the usual values).  */
106
107 tree
108 force_gimple_operand_gsi_1 (gimple_stmt_iterator *gsi, tree expr,
109                             gimple_predicate gimple_test_f,
110                             tree var, bool before,
111                             enum gsi_iterator_update m)
112 {
113   gimple_seq stmts;
114
115   expr = force_gimple_operand_1 (expr, &stmts, gimple_test_f, var);
116
117   if (!gimple_seq_empty_p (stmts))
118     {
119       if (before)
120         gsi_insert_seq_before (gsi, stmts, m);
121       else
122         gsi_insert_seq_after (gsi, stmts, m);
123     }
124
125   return expr;
126 }
127
128 /* Invoke force_gimple_operand_1 for EXPR with parameter VAR.
129    If SIMPLE is true, force the result to be either ssa_name or an invariant,
130    otherwise just force it to be a rhs expression.  If some statements are
131    produced, emits them at GSI.  If BEFORE is true, the statements are
132    appended before GSI, otherwise they are appended after it.  M specifies
133    the way GSI moves after insertion (GSI_SAME_STMT or GSI_CONTINUE_LINKING
134    are the usual values).  */
135
136 tree
137 force_gimple_operand_gsi (gimple_stmt_iterator *gsi, tree expr,
138                           bool simple_p, tree var, bool before,
139                           enum gsi_iterator_update m)
140 {
141   return force_gimple_operand_gsi_1 (gsi, expr,
142                                      simple_p
143                                      ? is_gimple_val : is_gimple_reg_rhs,
144                                      var, before, m);
145 }
146
147 /* Some transformations like inlining may invalidate the GIMPLE form
148    for operands.  This function traverses all the operands in STMT and
149    gimplifies anything that is not a valid gimple operand.  Any new
150    GIMPLE statements are inserted before *GSI_P.  */
151
152 void
153 gimple_regimplify_operands (gimple *stmt, gimple_stmt_iterator *gsi_p)
154 {
155   size_t i, num_ops;
156   tree lhs;
157   gimple_seq pre = NULL;
158   gimple *post_stmt = NULL;
159
160   push_gimplify_context (gimple_in_ssa_p (cfun));
161
162   switch (gimple_code (stmt))
163     {
164     case GIMPLE_COND:
165       {
166         gcond *cond_stmt = as_a <gcond *> (stmt);
167         gimplify_expr (gimple_cond_lhs_ptr (cond_stmt), &pre, NULL,
168                        is_gimple_val, fb_rvalue);
169         gimplify_expr (gimple_cond_rhs_ptr (cond_stmt), &pre, NULL,
170                        is_gimple_val, fb_rvalue);
171       }
172       break;
173     case GIMPLE_SWITCH:
174       gimplify_expr (gimple_switch_index_ptr (as_a <gswitch *> (stmt)),
175                      &pre, NULL, is_gimple_val, fb_rvalue);
176       break;
177     case GIMPLE_OMP_ATOMIC_LOAD:
178       gimplify_expr (gimple_omp_atomic_load_rhs_ptr (
179                        as_a <gomp_atomic_load *> (stmt)),
180                      &pre, NULL, is_gimple_val, fb_rvalue);
181       break;
182     case GIMPLE_ASM:
183       {
184         gasm *asm_stmt = as_a <gasm *> (stmt);
185         size_t i, noutputs = gimple_asm_noutputs (asm_stmt);
186         const char *constraint, **oconstraints;
187         bool allows_mem, allows_reg, is_inout;
188
189         oconstraints
190           = (const char **) alloca ((noutputs) * sizeof (const char *));
191         for (i = 0; i < noutputs; i++)
192           {
193             tree op = gimple_asm_output_op (asm_stmt, i);
194             constraint = TREE_STRING_POINTER (TREE_VALUE (TREE_PURPOSE (op)));
195             oconstraints[i] = constraint;
196             parse_output_constraint (&constraint, i, 0, 0, &allows_mem,
197                                      &allows_reg, &is_inout);
198             gimplify_expr (&TREE_VALUE (op), &pre, NULL,
199                            is_inout ? is_gimple_min_lval : is_gimple_lvalue,
200                            fb_lvalue | fb_mayfail);
201           }
202         for (i = 0; i < gimple_asm_ninputs (asm_stmt); i++)
203           {
204             tree op = gimple_asm_input_op (asm_stmt, i);
205             constraint = TREE_STRING_POINTER (TREE_VALUE (TREE_PURPOSE (op)));
206             parse_input_constraint (&constraint, 0, 0, noutputs, 0,
207                                     oconstraints, &allows_mem, &allows_reg);
208             if (TREE_ADDRESSABLE (TREE_TYPE (TREE_VALUE (op))) && allows_mem)
209               allows_reg = 0;
210             if (!allows_reg && allows_mem)
211               gimplify_expr (&TREE_VALUE (op), &pre, NULL,
212                              is_gimple_lvalue, fb_lvalue | fb_mayfail);
213             else
214               gimplify_expr (&TREE_VALUE (op), &pre, NULL,
215                              is_gimple_asm_val, fb_rvalue);
216           }
217       }
218       break;
219     default:
220       /* NOTE: We start gimplifying operands from last to first to
221          make sure that side-effects on the RHS of calls, assignments
222          and ASMs are executed before the LHS.  The ordering is not
223          important for other statements.  */
224       num_ops = gimple_num_ops (stmt);
225       for (i = num_ops; i > 0; i--)
226         {
227           tree op = gimple_op (stmt, i - 1);
228           if (op == NULL_TREE)
229             continue;
230           if (i == 1 && (is_gimple_call (stmt) || is_gimple_assign (stmt)))
231             gimplify_expr (&op, &pre, NULL, is_gimple_lvalue, fb_lvalue);
232           else if (i == 2
233                    && is_gimple_assign (stmt)
234                    && num_ops == 2
235                    && get_gimple_rhs_class (gimple_expr_code (stmt))
236                       == GIMPLE_SINGLE_RHS)
237             gimplify_expr (&op, &pre, NULL,
238                            rhs_predicate_for (gimple_assign_lhs (stmt)),
239                            fb_rvalue);
240           else if (i == 2 && is_gimple_call (stmt))
241             {
242               if (TREE_CODE (op) == FUNCTION_DECL)
243                 continue;
244               gimplify_expr (&op, &pre, NULL, is_gimple_call_addr, fb_rvalue);
245             }
246           else
247             gimplify_expr (&op, &pre, NULL, is_gimple_val, fb_rvalue);
248           gimple_set_op (stmt, i - 1, op);
249         }
250
251       lhs = gimple_get_lhs (stmt);
252       /* If the LHS changed it in a way that requires a simple RHS,
253          create temporary.  */
254       if (lhs && !is_gimple_reg (lhs))
255         {
256           bool need_temp = false;
257
258           if (is_gimple_assign (stmt)
259               && num_ops == 2
260               && get_gimple_rhs_class (gimple_expr_code (stmt))
261                  == GIMPLE_SINGLE_RHS)
262             gimplify_expr (gimple_assign_rhs1_ptr (stmt), &pre, NULL,
263                            rhs_predicate_for (gimple_assign_lhs (stmt)),
264                            fb_rvalue);
265           else if (is_gimple_reg (lhs))
266             {
267               if (is_gimple_reg_type (TREE_TYPE (lhs)))
268                 {
269                   if (is_gimple_call (stmt))
270                     {
271                       i = gimple_call_flags (stmt);
272                       if ((i & ECF_LOOPING_CONST_OR_PURE)
273                           || !(i & (ECF_CONST | ECF_PURE)))
274                         need_temp = true;
275                     }
276                   if (stmt_can_throw_internal (stmt))
277                     need_temp = true;
278                 }
279             }
280           else
281             {
282               if (is_gimple_reg_type (TREE_TYPE (lhs)))
283                 need_temp = true;
284               else if (TYPE_MODE (TREE_TYPE (lhs)) != BLKmode)
285                 {
286                   if (is_gimple_call (stmt))
287                     {
288                       tree fndecl = gimple_call_fndecl (stmt);
289
290                       if (!aggregate_value_p (TREE_TYPE (lhs), fndecl)
291                           && !(fndecl && DECL_RESULT (fndecl)
292                                && DECL_BY_REFERENCE (DECL_RESULT (fndecl))))
293                         need_temp = true;
294                     }
295                   else
296                     need_temp = true;
297                 }
298             }
299           if (need_temp)
300             {
301               tree temp = create_tmp_reg (TREE_TYPE (lhs));
302               if (gimple_in_ssa_p (cfun)
303                   && is_gimple_reg_type (TREE_TYPE (lhs)))
304                 temp = make_ssa_name (temp);
305               gimple_set_lhs (stmt, temp);
306               post_stmt = gimple_build_assign (lhs, temp);
307             }
308         }
309       break;
310     }
311
312   if (!gimple_seq_empty_p (pre))
313     gsi_insert_seq_before (gsi_p, pre, GSI_SAME_STMT);
314   if (post_stmt)
315     gsi_insert_after (gsi_p, post_stmt, GSI_NEW_STMT);
316
317   pop_gimplify_context (NULL);
318
319   update_stmt (stmt);
320 }
321
322