xref: /dragonfly/contrib/gcc-8.0/gcc/gimple.c (revision 38fd1498)
1*38fd1498Szrj /* Gimple IR support functions.
2*38fd1498Szrj 
3*38fd1498Szrj    Copyright (C) 2007-2018 Free Software Foundation, Inc.
4*38fd1498Szrj    Contributed by Aldy Hernandez <aldyh@redhat.com>
5*38fd1498Szrj 
6*38fd1498Szrj This file is part of GCC.
7*38fd1498Szrj 
8*38fd1498Szrj GCC is free software; you can redistribute it and/or modify it under
9*38fd1498Szrj the terms of the GNU General Public License as published by the Free
10*38fd1498Szrj Software Foundation; either version 3, or (at your option) any later
11*38fd1498Szrj version.
12*38fd1498Szrj 
13*38fd1498Szrj GCC is distributed in the hope that it will be useful, but WITHOUT ANY
14*38fd1498Szrj WARRANTY; without even the implied warranty of MERCHANTABILITY or
15*38fd1498Szrj FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
16*38fd1498Szrj for more details.
17*38fd1498Szrj 
18*38fd1498Szrj You should have received a copy of the GNU General Public License
19*38fd1498Szrj along with GCC; see the file COPYING3.  If not see
20*38fd1498Szrj <http://www.gnu.org/licenses/>.  */
21*38fd1498Szrj 
22*38fd1498Szrj #include "config.h"
23*38fd1498Szrj #include "system.h"
24*38fd1498Szrj #include "coretypes.h"
25*38fd1498Szrj #include "backend.h"
26*38fd1498Szrj #include "tree.h"
27*38fd1498Szrj #include "gimple.h"
28*38fd1498Szrj #include "ssa.h"
29*38fd1498Szrj #include "cgraph.h"
30*38fd1498Szrj #include "diagnostic.h"
31*38fd1498Szrj #include "alias.h"
32*38fd1498Szrj #include "fold-const.h"
33*38fd1498Szrj #include "calls.h"
34*38fd1498Szrj #include "stor-layout.h"
35*38fd1498Szrj #include "internal-fn.h"
36*38fd1498Szrj #include "tree-eh.h"
37*38fd1498Szrj #include "gimple-iterator.h"
38*38fd1498Szrj #include "gimple-walk.h"
39*38fd1498Szrj #include "gimplify.h"
40*38fd1498Szrj #include "target.h"
41*38fd1498Szrj #include "builtins.h"
42*38fd1498Szrj #include "selftest.h"
43*38fd1498Szrj #include "gimple-pretty-print.h"
44*38fd1498Szrj #include "stringpool.h"
45*38fd1498Szrj #include "attribs.h"
46*38fd1498Szrj #include "asan.h"
47*38fd1498Szrj 
48*38fd1498Szrj 
49*38fd1498Szrj /* All the tuples have their operand vector (if present) at the very bottom
50*38fd1498Szrj    of the structure.  Therefore, the offset required to find the
51*38fd1498Szrj    operands vector the size of the structure minus the size of the 1
52*38fd1498Szrj    element tree array at the end (see gimple_ops).  */
53*38fd1498Szrj #define DEFGSSTRUCT(SYM, STRUCT, HAS_TREE_OP) \
54*38fd1498Szrj 	(HAS_TREE_OP ? sizeof (struct STRUCT) - sizeof (tree) : 0),
55*38fd1498Szrj EXPORTED_CONST size_t gimple_ops_offset_[] = {
56*38fd1498Szrj #include "gsstruct.def"
57*38fd1498Szrj };
58*38fd1498Szrj #undef DEFGSSTRUCT
59*38fd1498Szrj 
60*38fd1498Szrj #define DEFGSSTRUCT(SYM, STRUCT, HAS_TREE_OP) sizeof (struct STRUCT),
61*38fd1498Szrj static const size_t gsstruct_code_size[] = {
62*38fd1498Szrj #include "gsstruct.def"
63*38fd1498Szrj };
64*38fd1498Szrj #undef DEFGSSTRUCT
65*38fd1498Szrj 
66*38fd1498Szrj #define DEFGSCODE(SYM, NAME, GSSCODE)	NAME,
67*38fd1498Szrj const char *const gimple_code_name[] = {
68*38fd1498Szrj #include "gimple.def"
69*38fd1498Szrj };
70*38fd1498Szrj #undef DEFGSCODE
71*38fd1498Szrj 
72*38fd1498Szrj #define DEFGSCODE(SYM, NAME, GSSCODE)	GSSCODE,
73*38fd1498Szrj EXPORTED_CONST enum gimple_statement_structure_enum gss_for_code_[] = {
74*38fd1498Szrj #include "gimple.def"
75*38fd1498Szrj };
76*38fd1498Szrj #undef DEFGSCODE
77*38fd1498Szrj 
78*38fd1498Szrj /* Gimple stats.  */
79*38fd1498Szrj 
80*38fd1498Szrj uint64_t gimple_alloc_counts[(int) gimple_alloc_kind_all];
81*38fd1498Szrj uint64_t gimple_alloc_sizes[(int) gimple_alloc_kind_all];
82*38fd1498Szrj 
83*38fd1498Szrj /* Keep in sync with gimple.h:enum gimple_alloc_kind.  */
84*38fd1498Szrj static const char * const gimple_alloc_kind_names[] = {
85*38fd1498Szrj     "assignments",
86*38fd1498Szrj     "phi nodes",
87*38fd1498Szrj     "conditionals",
88*38fd1498Szrj     "everything else"
89*38fd1498Szrj };
90*38fd1498Szrj 
91*38fd1498Szrj /* Static gimple tuple members.  */
92*38fd1498Szrj const enum gimple_code gassign::code_;
93*38fd1498Szrj const enum gimple_code gcall::code_;
94*38fd1498Szrj const enum gimple_code gcond::code_;
95*38fd1498Szrj 
96*38fd1498Szrj 
97*38fd1498Szrj /* Gimple tuple constructors.
98*38fd1498Szrj    Note: Any constructor taking a ``gimple_seq'' as a parameter, can
99*38fd1498Szrj    be passed a NULL to start with an empty sequence.  */
100*38fd1498Szrj 
101*38fd1498Szrj /* Set the code for statement G to CODE.  */
102*38fd1498Szrj 
103*38fd1498Szrj static inline void
gimple_set_code(gimple * g,enum gimple_code code)104*38fd1498Szrj gimple_set_code (gimple *g, enum gimple_code code)
105*38fd1498Szrj {
106*38fd1498Szrj   g->code = code;
107*38fd1498Szrj }
108*38fd1498Szrj 
109*38fd1498Szrj /* Return the number of bytes needed to hold a GIMPLE statement with
110*38fd1498Szrj    code CODE.  */
111*38fd1498Szrj 
112*38fd1498Szrj static inline size_t
gimple_size(enum gimple_code code)113*38fd1498Szrj gimple_size (enum gimple_code code)
114*38fd1498Szrj {
115*38fd1498Szrj   return gsstruct_code_size[gss_for_code (code)];
116*38fd1498Szrj }
117*38fd1498Szrj 
118*38fd1498Szrj /* Allocate memory for a GIMPLE statement with code CODE and NUM_OPS
119*38fd1498Szrj    operands.  */
120*38fd1498Szrj 
121*38fd1498Szrj gimple *
gimple_alloc(enum gimple_code code,unsigned num_ops MEM_STAT_DECL)122*38fd1498Szrj gimple_alloc (enum gimple_code code, unsigned num_ops MEM_STAT_DECL)
123*38fd1498Szrj {
124*38fd1498Szrj   size_t size;
125*38fd1498Szrj   gimple *stmt;
126*38fd1498Szrj 
127*38fd1498Szrj   size = gimple_size (code);
128*38fd1498Szrj   if (num_ops > 0)
129*38fd1498Szrj     size += sizeof (tree) * (num_ops - 1);
130*38fd1498Szrj 
131*38fd1498Szrj   if (GATHER_STATISTICS)
132*38fd1498Szrj     {
133*38fd1498Szrj       enum gimple_alloc_kind kind = gimple_alloc_kind (code);
134*38fd1498Szrj       gimple_alloc_counts[(int) kind]++;
135*38fd1498Szrj       gimple_alloc_sizes[(int) kind] += size;
136*38fd1498Szrj     }
137*38fd1498Szrj 
138*38fd1498Szrj   stmt = ggc_alloc_cleared_gimple_statement_stat (size PASS_MEM_STAT);
139*38fd1498Szrj   gimple_set_code (stmt, code);
140*38fd1498Szrj   gimple_set_num_ops (stmt, num_ops);
141*38fd1498Szrj 
142*38fd1498Szrj   /* Do not call gimple_set_modified here as it has other side
143*38fd1498Szrj      effects and this tuple is still not completely built.  */
144*38fd1498Szrj   stmt->modified = 1;
145*38fd1498Szrj   gimple_init_singleton (stmt);
146*38fd1498Szrj 
147*38fd1498Szrj   return stmt;
148*38fd1498Szrj }
149*38fd1498Szrj 
150*38fd1498Szrj /* Set SUBCODE to be the code of the expression computed by statement G.  */
151*38fd1498Szrj 
152*38fd1498Szrj static inline void
gimple_set_subcode(gimple * g,unsigned subcode)153*38fd1498Szrj gimple_set_subcode (gimple *g, unsigned subcode)
154*38fd1498Szrj {
155*38fd1498Szrj   /* We only have 16 bits for the RHS code.  Assert that we are not
156*38fd1498Szrj      overflowing it.  */
157*38fd1498Szrj   gcc_assert (subcode < (1 << 16));
158*38fd1498Szrj   g->subcode = subcode;
159*38fd1498Szrj }
160*38fd1498Szrj 
161*38fd1498Szrj 
162*38fd1498Szrj 
163*38fd1498Szrj /* Build a tuple with operands.  CODE is the statement to build (which
164*38fd1498Szrj    must be one of the GIMPLE_WITH_OPS tuples).  SUBCODE is the subcode
165*38fd1498Szrj    for the new tuple.  NUM_OPS is the number of operands to allocate.  */
166*38fd1498Szrj 
167*38fd1498Szrj #define gimple_build_with_ops(c, s, n) \
168*38fd1498Szrj   gimple_build_with_ops_stat (c, s, n MEM_STAT_INFO)
169*38fd1498Szrj 
170*38fd1498Szrj static gimple *
gimple_build_with_ops_stat(enum gimple_code code,unsigned subcode,unsigned num_ops MEM_STAT_DECL)171*38fd1498Szrj gimple_build_with_ops_stat (enum gimple_code code, unsigned subcode,
172*38fd1498Szrj 		            unsigned num_ops MEM_STAT_DECL)
173*38fd1498Szrj {
174*38fd1498Szrj   gimple *s = gimple_alloc (code, num_ops PASS_MEM_STAT);
175*38fd1498Szrj   gimple_set_subcode (s, subcode);
176*38fd1498Szrj 
177*38fd1498Szrj   return s;
178*38fd1498Szrj }
179*38fd1498Szrj 
180*38fd1498Szrj 
181*38fd1498Szrj /* Build a GIMPLE_RETURN statement returning RETVAL.  */
182*38fd1498Szrj 
183*38fd1498Szrj greturn *
gimple_build_return(tree retval)184*38fd1498Szrj gimple_build_return (tree retval)
185*38fd1498Szrj {
186*38fd1498Szrj   greturn *s
187*38fd1498Szrj     = as_a <greturn *> (gimple_build_with_ops (GIMPLE_RETURN, ERROR_MARK,
188*38fd1498Szrj 					       2));
189*38fd1498Szrj   if (retval)
190*38fd1498Szrj     gimple_return_set_retval (s, retval);
191*38fd1498Szrj   return s;
192*38fd1498Szrj }
193*38fd1498Szrj 
194*38fd1498Szrj /* Reset alias information on call S.  */
195*38fd1498Szrj 
196*38fd1498Szrj void
gimple_call_reset_alias_info(gcall * s)197*38fd1498Szrj gimple_call_reset_alias_info (gcall *s)
198*38fd1498Szrj {
199*38fd1498Szrj   if (gimple_call_flags (s) & ECF_CONST)
200*38fd1498Szrj     memset (gimple_call_use_set (s), 0, sizeof (struct pt_solution));
201*38fd1498Szrj   else
202*38fd1498Szrj     pt_solution_reset (gimple_call_use_set (s));
203*38fd1498Szrj   if (gimple_call_flags (s) & (ECF_CONST|ECF_PURE|ECF_NOVOPS))
204*38fd1498Szrj     memset (gimple_call_clobber_set (s), 0, sizeof (struct pt_solution));
205*38fd1498Szrj   else
206*38fd1498Szrj     pt_solution_reset (gimple_call_clobber_set (s));
207*38fd1498Szrj }
208*38fd1498Szrj 
209*38fd1498Szrj /* Helper for gimple_build_call, gimple_build_call_valist,
210*38fd1498Szrj    gimple_build_call_vec and gimple_build_call_from_tree.  Build the basic
211*38fd1498Szrj    components of a GIMPLE_CALL statement to function FN with NARGS
212*38fd1498Szrj    arguments.  */
213*38fd1498Szrj 
214*38fd1498Szrj static inline gcall *
gimple_build_call_1(tree fn,unsigned nargs)215*38fd1498Szrj gimple_build_call_1 (tree fn, unsigned nargs)
216*38fd1498Szrj {
217*38fd1498Szrj   gcall *s
218*38fd1498Szrj     = as_a <gcall *> (gimple_build_with_ops (GIMPLE_CALL, ERROR_MARK,
219*38fd1498Szrj 					     nargs + 3));
220*38fd1498Szrj   if (TREE_CODE (fn) == FUNCTION_DECL)
221*38fd1498Szrj     fn = build_fold_addr_expr (fn);
222*38fd1498Szrj   gimple_set_op (s, 1, fn);
223*38fd1498Szrj   gimple_call_set_fntype (s, TREE_TYPE (TREE_TYPE (fn)));
224*38fd1498Szrj   gimple_call_reset_alias_info (s);
225*38fd1498Szrj   return s;
226*38fd1498Szrj }
227*38fd1498Szrj 
228*38fd1498Szrj 
229*38fd1498Szrj /* Build a GIMPLE_CALL statement to function FN with the arguments
230*38fd1498Szrj    specified in vector ARGS.  */
231*38fd1498Szrj 
232*38fd1498Szrj gcall *
gimple_build_call_vec(tree fn,vec<tree> args)233*38fd1498Szrj gimple_build_call_vec (tree fn, vec<tree> args)
234*38fd1498Szrj {
235*38fd1498Szrj   unsigned i;
236*38fd1498Szrj   unsigned nargs = args.length ();
237*38fd1498Szrj   gcall *call = gimple_build_call_1 (fn, nargs);
238*38fd1498Szrj 
239*38fd1498Szrj   for (i = 0; i < nargs; i++)
240*38fd1498Szrj     gimple_call_set_arg (call, i, args[i]);
241*38fd1498Szrj 
242*38fd1498Szrj   return call;
243*38fd1498Szrj }
244*38fd1498Szrj 
245*38fd1498Szrj 
246*38fd1498Szrj /* Build a GIMPLE_CALL statement to function FN.  NARGS is the number of
247*38fd1498Szrj    arguments.  The ... are the arguments.  */
248*38fd1498Szrj 
249*38fd1498Szrj gcall *
gimple_build_call(tree fn,unsigned nargs,...)250*38fd1498Szrj gimple_build_call (tree fn, unsigned nargs, ...)
251*38fd1498Szrj {
252*38fd1498Szrj   va_list ap;
253*38fd1498Szrj   gcall *call;
254*38fd1498Szrj   unsigned i;
255*38fd1498Szrj 
256*38fd1498Szrj   gcc_assert (TREE_CODE (fn) == FUNCTION_DECL || is_gimple_call_addr (fn));
257*38fd1498Szrj 
258*38fd1498Szrj   call = gimple_build_call_1 (fn, nargs);
259*38fd1498Szrj 
260*38fd1498Szrj   va_start (ap, nargs);
261*38fd1498Szrj   for (i = 0; i < nargs; i++)
262*38fd1498Szrj     gimple_call_set_arg (call, i, va_arg (ap, tree));
263*38fd1498Szrj   va_end (ap);
264*38fd1498Szrj 
265*38fd1498Szrj   return call;
266*38fd1498Szrj }
267*38fd1498Szrj 
268*38fd1498Szrj 
269*38fd1498Szrj /* Build a GIMPLE_CALL statement to function FN.  NARGS is the number of
270*38fd1498Szrj    arguments.  AP contains the arguments.  */
271*38fd1498Szrj 
272*38fd1498Szrj gcall *
gimple_build_call_valist(tree fn,unsigned nargs,va_list ap)273*38fd1498Szrj gimple_build_call_valist (tree fn, unsigned nargs, va_list ap)
274*38fd1498Szrj {
275*38fd1498Szrj   gcall *call;
276*38fd1498Szrj   unsigned i;
277*38fd1498Szrj 
278*38fd1498Szrj   gcc_assert (TREE_CODE (fn) == FUNCTION_DECL || is_gimple_call_addr (fn));
279*38fd1498Szrj 
280*38fd1498Szrj   call = gimple_build_call_1 (fn, nargs);
281*38fd1498Szrj 
282*38fd1498Szrj   for (i = 0; i < nargs; i++)
283*38fd1498Szrj     gimple_call_set_arg (call, i, va_arg (ap, tree));
284*38fd1498Szrj 
285*38fd1498Szrj   return call;
286*38fd1498Szrj }
287*38fd1498Szrj 
288*38fd1498Szrj 
289*38fd1498Szrj /* Helper for gimple_build_call_internal and gimple_build_call_internal_vec.
290*38fd1498Szrj    Build the basic components of a GIMPLE_CALL statement to internal
291*38fd1498Szrj    function FN with NARGS arguments.  */
292*38fd1498Szrj 
293*38fd1498Szrj static inline gcall *
gimple_build_call_internal_1(enum internal_fn fn,unsigned nargs)294*38fd1498Szrj gimple_build_call_internal_1 (enum internal_fn fn, unsigned nargs)
295*38fd1498Szrj {
296*38fd1498Szrj   gcall *s
297*38fd1498Szrj     = as_a <gcall *> (gimple_build_with_ops (GIMPLE_CALL, ERROR_MARK,
298*38fd1498Szrj 					     nargs + 3));
299*38fd1498Szrj   s->subcode |= GF_CALL_INTERNAL;
300*38fd1498Szrj   gimple_call_set_internal_fn (s, fn);
301*38fd1498Szrj   gimple_call_reset_alias_info (s);
302*38fd1498Szrj   return s;
303*38fd1498Szrj }
304*38fd1498Szrj 
305*38fd1498Szrj 
306*38fd1498Szrj /* Build a GIMPLE_CALL statement to internal function FN.  NARGS is
307*38fd1498Szrj    the number of arguments.  The ... are the arguments.  */
308*38fd1498Szrj 
309*38fd1498Szrj gcall *
gimple_build_call_internal(enum internal_fn fn,unsigned nargs,...)310*38fd1498Szrj gimple_build_call_internal (enum internal_fn fn, unsigned nargs, ...)
311*38fd1498Szrj {
312*38fd1498Szrj   va_list ap;
313*38fd1498Szrj   gcall *call;
314*38fd1498Szrj   unsigned i;
315*38fd1498Szrj 
316*38fd1498Szrj   call = gimple_build_call_internal_1 (fn, nargs);
317*38fd1498Szrj   va_start (ap, nargs);
318*38fd1498Szrj   for (i = 0; i < nargs; i++)
319*38fd1498Szrj     gimple_call_set_arg (call, i, va_arg (ap, tree));
320*38fd1498Szrj   va_end (ap);
321*38fd1498Szrj 
322*38fd1498Szrj   return call;
323*38fd1498Szrj }
324*38fd1498Szrj 
325*38fd1498Szrj 
326*38fd1498Szrj /* Build a GIMPLE_CALL statement to internal function FN with the arguments
327*38fd1498Szrj    specified in vector ARGS.  */
328*38fd1498Szrj 
329*38fd1498Szrj gcall *
gimple_build_call_internal_vec(enum internal_fn fn,vec<tree> args)330*38fd1498Szrj gimple_build_call_internal_vec (enum internal_fn fn, vec<tree> args)
331*38fd1498Szrj {
332*38fd1498Szrj   unsigned i, nargs;
333*38fd1498Szrj   gcall *call;
334*38fd1498Szrj 
335*38fd1498Szrj   nargs = args.length ();
336*38fd1498Szrj   call = gimple_build_call_internal_1 (fn, nargs);
337*38fd1498Szrj   for (i = 0; i < nargs; i++)
338*38fd1498Szrj     gimple_call_set_arg (call, i, args[i]);
339*38fd1498Szrj 
340*38fd1498Szrj   return call;
341*38fd1498Szrj }
342*38fd1498Szrj 
343*38fd1498Szrj 
344*38fd1498Szrj /* Build a GIMPLE_CALL statement from CALL_EXPR T.  Note that T is
345*38fd1498Szrj    assumed to be in GIMPLE form already.  Minimal checking is done of
346*38fd1498Szrj    this fact.  */
347*38fd1498Szrj 
348*38fd1498Szrj gcall *
gimple_build_call_from_tree(tree t,tree fnptrtype)349*38fd1498Szrj gimple_build_call_from_tree (tree t, tree fnptrtype)
350*38fd1498Szrj {
351*38fd1498Szrj   unsigned i, nargs;
352*38fd1498Szrj   gcall *call;
353*38fd1498Szrj   tree fndecl = get_callee_fndecl (t);
354*38fd1498Szrj 
355*38fd1498Szrj   gcc_assert (TREE_CODE (t) == CALL_EXPR);
356*38fd1498Szrj 
357*38fd1498Szrj   nargs = call_expr_nargs (t);
358*38fd1498Szrj   call = gimple_build_call_1 (fndecl ? fndecl : CALL_EXPR_FN (t), nargs);
359*38fd1498Szrj 
360*38fd1498Szrj   for (i = 0; i < nargs; i++)
361*38fd1498Szrj     gimple_call_set_arg (call, i, CALL_EXPR_ARG (t, i));
362*38fd1498Szrj 
363*38fd1498Szrj   gimple_set_block (call, TREE_BLOCK (t));
364*38fd1498Szrj   gimple_set_location (call, EXPR_LOCATION (t));
365*38fd1498Szrj 
366*38fd1498Szrj   /* Carry all the CALL_EXPR flags to the new GIMPLE_CALL.  */
367*38fd1498Szrj   gimple_call_set_chain (call, CALL_EXPR_STATIC_CHAIN (t));
368*38fd1498Szrj   gimple_call_set_tail (call, CALL_EXPR_TAILCALL (t));
369*38fd1498Szrj   gimple_call_set_must_tail (call, CALL_EXPR_MUST_TAIL_CALL (t));
370*38fd1498Szrj   gimple_call_set_return_slot_opt (call, CALL_EXPR_RETURN_SLOT_OPT (t));
371*38fd1498Szrj   if (fndecl
372*38fd1498Szrj       && DECL_BUILT_IN_CLASS (fndecl) == BUILT_IN_NORMAL
373*38fd1498Szrj       && ALLOCA_FUNCTION_CODE_P (DECL_FUNCTION_CODE (fndecl)))
374*38fd1498Szrj     gimple_call_set_alloca_for_var (call, CALL_ALLOCA_FOR_VAR_P (t));
375*38fd1498Szrj   else
376*38fd1498Szrj     gimple_call_set_from_thunk (call, CALL_FROM_THUNK_P (t));
377*38fd1498Szrj   gimple_call_set_va_arg_pack (call, CALL_EXPR_VA_ARG_PACK (t));
378*38fd1498Szrj   gimple_call_set_nothrow (call, TREE_NOTHROW (t));
379*38fd1498Szrj   gimple_call_set_by_descriptor (call, CALL_EXPR_BY_DESCRIPTOR (t));
380*38fd1498Szrj   gimple_set_no_warning (call, TREE_NO_WARNING (t));
381*38fd1498Szrj   gimple_call_set_with_bounds (call, CALL_WITH_BOUNDS_P (t));
382*38fd1498Szrj 
383*38fd1498Szrj   if (fnptrtype)
384*38fd1498Szrj     {
385*38fd1498Szrj       gimple_call_set_fntype (call, TREE_TYPE (fnptrtype));
386*38fd1498Szrj 
387*38fd1498Szrj       /* Check if it's an indirect CALL and the type has the
388*38fd1498Szrj  	 nocf_check attribute. In that case propagate the information
389*38fd1498Szrj 	 to the gimple CALL insn.  */
390*38fd1498Szrj       if (!fndecl)
391*38fd1498Szrj 	{
392*38fd1498Szrj 	  gcc_assert (POINTER_TYPE_P (fnptrtype));
393*38fd1498Szrj 	  tree fntype = TREE_TYPE (fnptrtype);
394*38fd1498Szrj 
395*38fd1498Szrj 	  if (lookup_attribute ("nocf_check", TYPE_ATTRIBUTES (fntype)))
396*38fd1498Szrj 	    gimple_call_set_nocf_check (call, TRUE);
397*38fd1498Szrj 	}
398*38fd1498Szrj     }
399*38fd1498Szrj 
400*38fd1498Szrj   return call;
401*38fd1498Szrj }
402*38fd1498Szrj 
403*38fd1498Szrj 
404*38fd1498Szrj /* Build a GIMPLE_ASSIGN statement.
405*38fd1498Szrj 
406*38fd1498Szrj    LHS of the assignment.
407*38fd1498Szrj    RHS of the assignment which can be unary or binary.  */
408*38fd1498Szrj 
409*38fd1498Szrj gassign *
gimple_build_assign(tree lhs,tree rhs MEM_STAT_DECL)410*38fd1498Szrj gimple_build_assign (tree lhs, tree rhs MEM_STAT_DECL)
411*38fd1498Szrj {
412*38fd1498Szrj   enum tree_code subcode;
413*38fd1498Szrj   tree op1, op2, op3;
414*38fd1498Szrj 
415*38fd1498Szrj   extract_ops_from_tree (rhs, &subcode, &op1, &op2, &op3);
416*38fd1498Szrj   return gimple_build_assign (lhs, subcode, op1, op2, op3 PASS_MEM_STAT);
417*38fd1498Szrj }
418*38fd1498Szrj 
419*38fd1498Szrj 
420*38fd1498Szrj /* Build a GIMPLE_ASSIGN statement with subcode SUBCODE and operands
421*38fd1498Szrj    OP1, OP2 and OP3.  */
422*38fd1498Szrj 
423*38fd1498Szrj static inline gassign *
gimple_build_assign_1(tree lhs,enum tree_code subcode,tree op1,tree op2,tree op3 MEM_STAT_DECL)424*38fd1498Szrj gimple_build_assign_1 (tree lhs, enum tree_code subcode, tree op1,
425*38fd1498Szrj 		       tree op2, tree op3 MEM_STAT_DECL)
426*38fd1498Szrj {
427*38fd1498Szrj   unsigned num_ops;
428*38fd1498Szrj   gassign *p;
429*38fd1498Szrj 
430*38fd1498Szrj   /* Need 1 operand for LHS and 1 or 2 for the RHS (depending on the
431*38fd1498Szrj      code).  */
432*38fd1498Szrj   num_ops = get_gimple_rhs_num_ops (subcode) + 1;
433*38fd1498Szrj 
434*38fd1498Szrj   p = as_a <gassign *> (
435*38fd1498Szrj         gimple_build_with_ops_stat (GIMPLE_ASSIGN, (unsigned)subcode, num_ops
436*38fd1498Szrj 				    PASS_MEM_STAT));
437*38fd1498Szrj   gimple_assign_set_lhs (p, lhs);
438*38fd1498Szrj   gimple_assign_set_rhs1 (p, op1);
439*38fd1498Szrj   if (op2)
440*38fd1498Szrj     {
441*38fd1498Szrj       gcc_assert (num_ops > 2);
442*38fd1498Szrj       gimple_assign_set_rhs2 (p, op2);
443*38fd1498Szrj     }
444*38fd1498Szrj 
445*38fd1498Szrj   if (op3)
446*38fd1498Szrj     {
447*38fd1498Szrj       gcc_assert (num_ops > 3);
448*38fd1498Szrj       gimple_assign_set_rhs3 (p, op3);
449*38fd1498Szrj     }
450*38fd1498Szrj 
451*38fd1498Szrj   return p;
452*38fd1498Szrj }
453*38fd1498Szrj 
454*38fd1498Szrj /* Build a GIMPLE_ASSIGN statement with subcode SUBCODE and operands
455*38fd1498Szrj    OP1, OP2 and OP3.  */
456*38fd1498Szrj 
457*38fd1498Szrj gassign *
gimple_build_assign(tree lhs,enum tree_code subcode,tree op1,tree op2,tree op3 MEM_STAT_DECL)458*38fd1498Szrj gimple_build_assign (tree lhs, enum tree_code subcode, tree op1,
459*38fd1498Szrj 		     tree op2, tree op3 MEM_STAT_DECL)
460*38fd1498Szrj {
461*38fd1498Szrj   return gimple_build_assign_1 (lhs, subcode, op1, op2, op3 PASS_MEM_STAT);
462*38fd1498Szrj }
463*38fd1498Szrj 
464*38fd1498Szrj /* Build a GIMPLE_ASSIGN statement with subcode SUBCODE and operands
465*38fd1498Szrj    OP1 and OP2.  */
466*38fd1498Szrj 
467*38fd1498Szrj gassign *
gimple_build_assign(tree lhs,enum tree_code subcode,tree op1,tree op2 MEM_STAT_DECL)468*38fd1498Szrj gimple_build_assign (tree lhs, enum tree_code subcode, tree op1,
469*38fd1498Szrj 		     tree op2 MEM_STAT_DECL)
470*38fd1498Szrj {
471*38fd1498Szrj   return gimple_build_assign_1 (lhs, subcode, op1, op2, NULL_TREE
472*38fd1498Szrj 				PASS_MEM_STAT);
473*38fd1498Szrj }
474*38fd1498Szrj 
475*38fd1498Szrj /* Build a GIMPLE_ASSIGN statement with subcode SUBCODE and operand OP1.  */
476*38fd1498Szrj 
477*38fd1498Szrj gassign *
gimple_build_assign(tree lhs,enum tree_code subcode,tree op1 MEM_STAT_DECL)478*38fd1498Szrj gimple_build_assign (tree lhs, enum tree_code subcode, tree op1 MEM_STAT_DECL)
479*38fd1498Szrj {
480*38fd1498Szrj   return gimple_build_assign_1 (lhs, subcode, op1, NULL_TREE, NULL_TREE
481*38fd1498Szrj 				PASS_MEM_STAT);
482*38fd1498Szrj }
483*38fd1498Szrj 
484*38fd1498Szrj 
485*38fd1498Szrj /* Build a GIMPLE_COND statement.
486*38fd1498Szrj 
487*38fd1498Szrj    PRED is the condition used to compare LHS and the RHS.
488*38fd1498Szrj    T_LABEL is the label to jump to if the condition is true.
489*38fd1498Szrj    F_LABEL is the label to jump to otherwise.  */
490*38fd1498Szrj 
491*38fd1498Szrj gcond *
gimple_build_cond(enum tree_code pred_code,tree lhs,tree rhs,tree t_label,tree f_label)492*38fd1498Szrj gimple_build_cond (enum tree_code pred_code, tree lhs, tree rhs,
493*38fd1498Szrj 		   tree t_label, tree f_label)
494*38fd1498Szrj {
495*38fd1498Szrj   gcond *p;
496*38fd1498Szrj 
497*38fd1498Szrj   gcc_assert (TREE_CODE_CLASS (pred_code) == tcc_comparison);
498*38fd1498Szrj   p = as_a <gcond *> (gimple_build_with_ops (GIMPLE_COND, pred_code, 4));
499*38fd1498Szrj   gimple_cond_set_lhs (p, lhs);
500*38fd1498Szrj   gimple_cond_set_rhs (p, rhs);
501*38fd1498Szrj   gimple_cond_set_true_label (p, t_label);
502*38fd1498Szrj   gimple_cond_set_false_label (p, f_label);
503*38fd1498Szrj   return p;
504*38fd1498Szrj }
505*38fd1498Szrj 
506*38fd1498Szrj /* Build a GIMPLE_COND statement from the conditional expression tree
507*38fd1498Szrj    COND.  T_LABEL and F_LABEL are as in gimple_build_cond.  */
508*38fd1498Szrj 
509*38fd1498Szrj gcond *
gimple_build_cond_from_tree(tree cond,tree t_label,tree f_label)510*38fd1498Szrj gimple_build_cond_from_tree (tree cond, tree t_label, tree f_label)
511*38fd1498Szrj {
512*38fd1498Szrj   enum tree_code code;
513*38fd1498Szrj   tree lhs, rhs;
514*38fd1498Szrj 
515*38fd1498Szrj   gimple_cond_get_ops_from_tree (cond, &code, &lhs, &rhs);
516*38fd1498Szrj   return gimple_build_cond (code, lhs, rhs, t_label, f_label);
517*38fd1498Szrj }
518*38fd1498Szrj 
519*38fd1498Szrj /* Set code, lhs, and rhs of a GIMPLE_COND from a suitable
520*38fd1498Szrj    boolean expression tree COND.  */
521*38fd1498Szrj 
522*38fd1498Szrj void
gimple_cond_set_condition_from_tree(gcond * stmt,tree cond)523*38fd1498Szrj gimple_cond_set_condition_from_tree (gcond *stmt, tree cond)
524*38fd1498Szrj {
525*38fd1498Szrj   enum tree_code code;
526*38fd1498Szrj   tree lhs, rhs;
527*38fd1498Szrj 
528*38fd1498Szrj   gimple_cond_get_ops_from_tree (cond, &code, &lhs, &rhs);
529*38fd1498Szrj   gimple_cond_set_condition (stmt, code, lhs, rhs);
530*38fd1498Szrj }
531*38fd1498Szrj 
532*38fd1498Szrj /* Build a GIMPLE_LABEL statement for LABEL.  */
533*38fd1498Szrj 
534*38fd1498Szrj glabel *
gimple_build_label(tree label)535*38fd1498Szrj gimple_build_label (tree label)
536*38fd1498Szrj {
537*38fd1498Szrj   glabel *p
538*38fd1498Szrj     = as_a <glabel *> (gimple_build_with_ops (GIMPLE_LABEL, ERROR_MARK, 1));
539*38fd1498Szrj   gimple_label_set_label (p, label);
540*38fd1498Szrj   return p;
541*38fd1498Szrj }
542*38fd1498Szrj 
543*38fd1498Szrj /* Build a GIMPLE_GOTO statement to label DEST.  */
544*38fd1498Szrj 
545*38fd1498Szrj ggoto *
gimple_build_goto(tree dest)546*38fd1498Szrj gimple_build_goto (tree dest)
547*38fd1498Szrj {
548*38fd1498Szrj   ggoto *p
549*38fd1498Szrj     = as_a <ggoto *> (gimple_build_with_ops (GIMPLE_GOTO, ERROR_MARK, 1));
550*38fd1498Szrj   gimple_goto_set_dest (p, dest);
551*38fd1498Szrj   return p;
552*38fd1498Szrj }
553*38fd1498Szrj 
554*38fd1498Szrj 
555*38fd1498Szrj /* Build a GIMPLE_NOP statement.  */
556*38fd1498Szrj 
557*38fd1498Szrj gimple *
gimple_build_nop(void)558*38fd1498Szrj gimple_build_nop (void)
559*38fd1498Szrj {
560*38fd1498Szrj   return gimple_alloc (GIMPLE_NOP, 0);
561*38fd1498Szrj }
562*38fd1498Szrj 
563*38fd1498Szrj 
564*38fd1498Szrj /* Build a GIMPLE_BIND statement.
565*38fd1498Szrj    VARS are the variables in BODY.
566*38fd1498Szrj    BLOCK is the containing block.  */
567*38fd1498Szrj 
568*38fd1498Szrj gbind *
gimple_build_bind(tree vars,gimple_seq body,tree block)569*38fd1498Szrj gimple_build_bind (tree vars, gimple_seq body, tree block)
570*38fd1498Szrj {
571*38fd1498Szrj   gbind *p = as_a <gbind *> (gimple_alloc (GIMPLE_BIND, 0));
572*38fd1498Szrj   gimple_bind_set_vars (p, vars);
573*38fd1498Szrj   if (body)
574*38fd1498Szrj     gimple_bind_set_body (p, body);
575*38fd1498Szrj   if (block)
576*38fd1498Szrj     gimple_bind_set_block (p, block);
577*38fd1498Szrj   return p;
578*38fd1498Szrj }
579*38fd1498Szrj 
580*38fd1498Szrj /* Helper function to set the simple fields of a asm stmt.
581*38fd1498Szrj 
582*38fd1498Szrj    STRING is a pointer to a string that is the asm blocks assembly code.
583*38fd1498Szrj    NINPUT is the number of register inputs.
584*38fd1498Szrj    NOUTPUT is the number of register outputs.
585*38fd1498Szrj    NCLOBBERS is the number of clobbered registers.
586*38fd1498Szrj    */
587*38fd1498Szrj 
588*38fd1498Szrj static inline gasm *
gimple_build_asm_1(const char * string,unsigned ninputs,unsigned noutputs,unsigned nclobbers,unsigned nlabels)589*38fd1498Szrj gimple_build_asm_1 (const char *string, unsigned ninputs, unsigned noutputs,
590*38fd1498Szrj                     unsigned nclobbers, unsigned nlabels)
591*38fd1498Szrj {
592*38fd1498Szrj   gasm *p;
593*38fd1498Szrj   int size = strlen (string);
594*38fd1498Szrj 
595*38fd1498Szrj   /* ASMs with labels cannot have outputs.  This should have been
596*38fd1498Szrj      enforced by the front end.  */
597*38fd1498Szrj   gcc_assert (nlabels == 0 || noutputs == 0);
598*38fd1498Szrj 
599*38fd1498Szrj   p = as_a <gasm *> (
600*38fd1498Szrj         gimple_build_with_ops (GIMPLE_ASM, ERROR_MARK,
601*38fd1498Szrj 			       ninputs + noutputs + nclobbers + nlabels));
602*38fd1498Szrj 
603*38fd1498Szrj   p->ni = ninputs;
604*38fd1498Szrj   p->no = noutputs;
605*38fd1498Szrj   p->nc = nclobbers;
606*38fd1498Szrj   p->nl = nlabels;
607*38fd1498Szrj   p->string = ggc_alloc_string (string, size);
608*38fd1498Szrj 
609*38fd1498Szrj   if (GATHER_STATISTICS)
610*38fd1498Szrj     gimple_alloc_sizes[(int) gimple_alloc_kind (GIMPLE_ASM)] += size;
611*38fd1498Szrj 
612*38fd1498Szrj   return p;
613*38fd1498Szrj }
614*38fd1498Szrj 
615*38fd1498Szrj /* Build a GIMPLE_ASM statement.
616*38fd1498Szrj 
617*38fd1498Szrj    STRING is the assembly code.
618*38fd1498Szrj    NINPUT is the number of register inputs.
619*38fd1498Szrj    NOUTPUT is the number of register outputs.
620*38fd1498Szrj    NCLOBBERS is the number of clobbered registers.
621*38fd1498Szrj    INPUTS is a vector of the input register parameters.
622*38fd1498Szrj    OUTPUTS is a vector of the output register parameters.
623*38fd1498Szrj    CLOBBERS is a vector of the clobbered register parameters.
624*38fd1498Szrj    LABELS is a vector of destination labels.  */
625*38fd1498Szrj 
626*38fd1498Szrj gasm *
gimple_build_asm_vec(const char * string,vec<tree,va_gc> * inputs,vec<tree,va_gc> * outputs,vec<tree,va_gc> * clobbers,vec<tree,va_gc> * labels)627*38fd1498Szrj gimple_build_asm_vec (const char *string, vec<tree, va_gc> *inputs,
628*38fd1498Szrj                       vec<tree, va_gc> *outputs, vec<tree, va_gc> *clobbers,
629*38fd1498Szrj 		      vec<tree, va_gc> *labels)
630*38fd1498Szrj {
631*38fd1498Szrj   gasm *p;
632*38fd1498Szrj   unsigned i;
633*38fd1498Szrj 
634*38fd1498Szrj   p = gimple_build_asm_1 (string,
635*38fd1498Szrj                           vec_safe_length (inputs),
636*38fd1498Szrj                           vec_safe_length (outputs),
637*38fd1498Szrj                           vec_safe_length (clobbers),
638*38fd1498Szrj 			  vec_safe_length (labels));
639*38fd1498Szrj 
640*38fd1498Szrj   for (i = 0; i < vec_safe_length (inputs); i++)
641*38fd1498Szrj     gimple_asm_set_input_op (p, i, (*inputs)[i]);
642*38fd1498Szrj 
643*38fd1498Szrj   for (i = 0; i < vec_safe_length (outputs); i++)
644*38fd1498Szrj     gimple_asm_set_output_op (p, i, (*outputs)[i]);
645*38fd1498Szrj 
646*38fd1498Szrj   for (i = 0; i < vec_safe_length (clobbers); i++)
647*38fd1498Szrj     gimple_asm_set_clobber_op (p, i, (*clobbers)[i]);
648*38fd1498Szrj 
649*38fd1498Szrj   for (i = 0; i < vec_safe_length (labels); i++)
650*38fd1498Szrj     gimple_asm_set_label_op (p, i, (*labels)[i]);
651*38fd1498Szrj 
652*38fd1498Szrj   return p;
653*38fd1498Szrj }
654*38fd1498Szrj 
655*38fd1498Szrj /* Build a GIMPLE_CATCH statement.
656*38fd1498Szrj 
657*38fd1498Szrj   TYPES are the catch types.
658*38fd1498Szrj   HANDLER is the exception handler.  */
659*38fd1498Szrj 
660*38fd1498Szrj gcatch *
gimple_build_catch(tree types,gimple_seq handler)661*38fd1498Szrj gimple_build_catch (tree types, gimple_seq handler)
662*38fd1498Szrj {
663*38fd1498Szrj   gcatch *p = as_a <gcatch *> (gimple_alloc (GIMPLE_CATCH, 0));
664*38fd1498Szrj   gimple_catch_set_types (p, types);
665*38fd1498Szrj   if (handler)
666*38fd1498Szrj     gimple_catch_set_handler (p, handler);
667*38fd1498Szrj 
668*38fd1498Szrj   return p;
669*38fd1498Szrj }
670*38fd1498Szrj 
671*38fd1498Szrj /* Build a GIMPLE_EH_FILTER statement.
672*38fd1498Szrj 
673*38fd1498Szrj    TYPES are the filter's types.
674*38fd1498Szrj    FAILURE is the filter's failure action.  */
675*38fd1498Szrj 
676*38fd1498Szrj geh_filter *
gimple_build_eh_filter(tree types,gimple_seq failure)677*38fd1498Szrj gimple_build_eh_filter (tree types, gimple_seq failure)
678*38fd1498Szrj {
679*38fd1498Szrj   geh_filter *p = as_a <geh_filter *> (gimple_alloc (GIMPLE_EH_FILTER, 0));
680*38fd1498Szrj   gimple_eh_filter_set_types (p, types);
681*38fd1498Szrj   if (failure)
682*38fd1498Szrj     gimple_eh_filter_set_failure (p, failure);
683*38fd1498Szrj 
684*38fd1498Szrj   return p;
685*38fd1498Szrj }
686*38fd1498Szrj 
687*38fd1498Szrj /* Build a GIMPLE_EH_MUST_NOT_THROW statement.  */
688*38fd1498Szrj 
689*38fd1498Szrj geh_mnt *
gimple_build_eh_must_not_throw(tree decl)690*38fd1498Szrj gimple_build_eh_must_not_throw (tree decl)
691*38fd1498Szrj {
692*38fd1498Szrj   geh_mnt *p = as_a <geh_mnt *> (gimple_alloc (GIMPLE_EH_MUST_NOT_THROW, 0));
693*38fd1498Szrj 
694*38fd1498Szrj   gcc_assert (TREE_CODE (decl) == FUNCTION_DECL);
695*38fd1498Szrj   gcc_assert (flags_from_decl_or_type (decl) & ECF_NORETURN);
696*38fd1498Szrj   gimple_eh_must_not_throw_set_fndecl (p, decl);
697*38fd1498Szrj 
698*38fd1498Szrj   return p;
699*38fd1498Szrj }
700*38fd1498Szrj 
701*38fd1498Szrj /* Build a GIMPLE_EH_ELSE statement.  */
702*38fd1498Szrj 
703*38fd1498Szrj geh_else *
gimple_build_eh_else(gimple_seq n_body,gimple_seq e_body)704*38fd1498Szrj gimple_build_eh_else (gimple_seq n_body, gimple_seq e_body)
705*38fd1498Szrj {
706*38fd1498Szrj   geh_else *p = as_a <geh_else *> (gimple_alloc (GIMPLE_EH_ELSE, 0));
707*38fd1498Szrj   gimple_eh_else_set_n_body (p, n_body);
708*38fd1498Szrj   gimple_eh_else_set_e_body (p, e_body);
709*38fd1498Szrj   return p;
710*38fd1498Szrj }
711*38fd1498Szrj 
712*38fd1498Szrj /* Build a GIMPLE_TRY statement.
713*38fd1498Szrj 
714*38fd1498Szrj    EVAL is the expression to evaluate.
715*38fd1498Szrj    CLEANUP is the cleanup expression.
716*38fd1498Szrj    KIND is either GIMPLE_TRY_CATCH or GIMPLE_TRY_FINALLY depending on
717*38fd1498Szrj    whether this is a try/catch or a try/finally respectively.  */
718*38fd1498Szrj 
719*38fd1498Szrj gtry *
gimple_build_try(gimple_seq eval,gimple_seq cleanup,enum gimple_try_flags kind)720*38fd1498Szrj gimple_build_try (gimple_seq eval, gimple_seq cleanup,
721*38fd1498Szrj     		  enum gimple_try_flags kind)
722*38fd1498Szrj {
723*38fd1498Szrj   gtry *p;
724*38fd1498Szrj 
725*38fd1498Szrj   gcc_assert (kind == GIMPLE_TRY_CATCH || kind == GIMPLE_TRY_FINALLY);
726*38fd1498Szrj   p = as_a <gtry *> (gimple_alloc (GIMPLE_TRY, 0));
727*38fd1498Szrj   gimple_set_subcode (p, kind);
728*38fd1498Szrj   if (eval)
729*38fd1498Szrj     gimple_try_set_eval (p, eval);
730*38fd1498Szrj   if (cleanup)
731*38fd1498Szrj     gimple_try_set_cleanup (p, cleanup);
732*38fd1498Szrj 
733*38fd1498Szrj   return p;
734*38fd1498Szrj }
735*38fd1498Szrj 
736*38fd1498Szrj /* Construct a GIMPLE_WITH_CLEANUP_EXPR statement.
737*38fd1498Szrj 
738*38fd1498Szrj    CLEANUP is the cleanup expression.  */
739*38fd1498Szrj 
740*38fd1498Szrj gimple *
gimple_build_wce(gimple_seq cleanup)741*38fd1498Szrj gimple_build_wce (gimple_seq cleanup)
742*38fd1498Szrj {
743*38fd1498Szrj   gimple *p = gimple_alloc (GIMPLE_WITH_CLEANUP_EXPR, 0);
744*38fd1498Szrj   if (cleanup)
745*38fd1498Szrj     gimple_wce_set_cleanup (p, cleanup);
746*38fd1498Szrj 
747*38fd1498Szrj   return p;
748*38fd1498Szrj }
749*38fd1498Szrj 
750*38fd1498Szrj 
751*38fd1498Szrj /* Build a GIMPLE_RESX statement.  */
752*38fd1498Szrj 
753*38fd1498Szrj gresx *
gimple_build_resx(int region)754*38fd1498Szrj gimple_build_resx (int region)
755*38fd1498Szrj {
756*38fd1498Szrj   gresx *p
757*38fd1498Szrj     = as_a <gresx *> (gimple_build_with_ops (GIMPLE_RESX, ERROR_MARK, 0));
758*38fd1498Szrj   p->region = region;
759*38fd1498Szrj   return p;
760*38fd1498Szrj }
761*38fd1498Szrj 
762*38fd1498Szrj 
763*38fd1498Szrj /* The helper for constructing a gimple switch statement.
764*38fd1498Szrj    INDEX is the switch's index.
765*38fd1498Szrj    NLABELS is the number of labels in the switch excluding the default.
766*38fd1498Szrj    DEFAULT_LABEL is the default label for the switch statement.  */
767*38fd1498Szrj 
768*38fd1498Szrj gswitch *
gimple_build_switch_nlabels(unsigned nlabels,tree index,tree default_label)769*38fd1498Szrj gimple_build_switch_nlabels (unsigned nlabels, tree index, tree default_label)
770*38fd1498Szrj {
771*38fd1498Szrj   /* nlabels + 1 default label + 1 index.  */
772*38fd1498Szrj   gcc_checking_assert (default_label);
773*38fd1498Szrj   gswitch *p = as_a <gswitch *> (gimple_build_with_ops (GIMPLE_SWITCH,
774*38fd1498Szrj 							ERROR_MARK,
775*38fd1498Szrj 							1 + 1 + nlabels));
776*38fd1498Szrj   gimple_switch_set_index (p, index);
777*38fd1498Szrj   gimple_switch_set_default_label (p, default_label);
778*38fd1498Szrj   return p;
779*38fd1498Szrj }
780*38fd1498Szrj 
781*38fd1498Szrj /* Build a GIMPLE_SWITCH statement.
782*38fd1498Szrj 
783*38fd1498Szrj    INDEX is the switch's index.
784*38fd1498Szrj    DEFAULT_LABEL is the default label
785*38fd1498Szrj    ARGS is a vector of labels excluding the default.  */
786*38fd1498Szrj 
787*38fd1498Szrj gswitch *
gimple_build_switch(tree index,tree default_label,vec<tree> args)788*38fd1498Szrj gimple_build_switch (tree index, tree default_label, vec<tree> args)
789*38fd1498Szrj {
790*38fd1498Szrj   unsigned i, nlabels = args.length ();
791*38fd1498Szrj 
792*38fd1498Szrj   gswitch *p = gimple_build_switch_nlabels (nlabels, index, default_label);
793*38fd1498Szrj 
794*38fd1498Szrj   /* Copy the labels from the vector to the switch statement.  */
795*38fd1498Szrj   for (i = 0; i < nlabels; i++)
796*38fd1498Szrj     gimple_switch_set_label (p, i + 1, args[i]);
797*38fd1498Szrj 
798*38fd1498Szrj   return p;
799*38fd1498Szrj }
800*38fd1498Szrj 
801*38fd1498Szrj /* Build a GIMPLE_EH_DISPATCH statement.  */
802*38fd1498Szrj 
803*38fd1498Szrj geh_dispatch *
gimple_build_eh_dispatch(int region)804*38fd1498Szrj gimple_build_eh_dispatch (int region)
805*38fd1498Szrj {
806*38fd1498Szrj   geh_dispatch *p
807*38fd1498Szrj     = as_a <geh_dispatch *> (
808*38fd1498Szrj 	gimple_build_with_ops (GIMPLE_EH_DISPATCH, ERROR_MARK, 0));
809*38fd1498Szrj   p->region = region;
810*38fd1498Szrj   return p;
811*38fd1498Szrj }
812*38fd1498Szrj 
813*38fd1498Szrj /* Build a new GIMPLE_DEBUG_BIND statement.
814*38fd1498Szrj 
815*38fd1498Szrj    VAR is bound to VALUE; block and location are taken from STMT.  */
816*38fd1498Szrj 
817*38fd1498Szrj gdebug *
gimple_build_debug_bind(tree var,tree value,gimple * stmt MEM_STAT_DECL)818*38fd1498Szrj gimple_build_debug_bind (tree var, tree value, gimple *stmt MEM_STAT_DECL)
819*38fd1498Szrj {
820*38fd1498Szrj   gdebug *p
821*38fd1498Szrj     = as_a <gdebug *> (gimple_build_with_ops_stat (GIMPLE_DEBUG,
822*38fd1498Szrj 						   (unsigned)GIMPLE_DEBUG_BIND, 2
823*38fd1498Szrj 						   PASS_MEM_STAT));
824*38fd1498Szrj   gimple_debug_bind_set_var (p, var);
825*38fd1498Szrj   gimple_debug_bind_set_value (p, value);
826*38fd1498Szrj   if (stmt)
827*38fd1498Szrj     gimple_set_location (p, gimple_location (stmt));
828*38fd1498Szrj 
829*38fd1498Szrj   return p;
830*38fd1498Szrj }
831*38fd1498Szrj 
832*38fd1498Szrj 
833*38fd1498Szrj /* Build a new GIMPLE_DEBUG_SOURCE_BIND statement.
834*38fd1498Szrj 
835*38fd1498Szrj    VAR is bound to VALUE; block and location are taken from STMT.  */
836*38fd1498Szrj 
837*38fd1498Szrj gdebug *
gimple_build_debug_source_bind(tree var,tree value,gimple * stmt MEM_STAT_DECL)838*38fd1498Szrj gimple_build_debug_source_bind (tree var, tree value,
839*38fd1498Szrj 				     gimple *stmt MEM_STAT_DECL)
840*38fd1498Szrj {
841*38fd1498Szrj   gdebug *p
842*38fd1498Szrj     = as_a <gdebug *> (
843*38fd1498Szrj         gimple_build_with_ops_stat (GIMPLE_DEBUG,
844*38fd1498Szrj 				    (unsigned)GIMPLE_DEBUG_SOURCE_BIND, 2
845*38fd1498Szrj 				    PASS_MEM_STAT));
846*38fd1498Szrj 
847*38fd1498Szrj   gimple_debug_source_bind_set_var (p, var);
848*38fd1498Szrj   gimple_debug_source_bind_set_value (p, value);
849*38fd1498Szrj   if (stmt)
850*38fd1498Szrj     gimple_set_location (p, gimple_location (stmt));
851*38fd1498Szrj 
852*38fd1498Szrj   return p;
853*38fd1498Szrj }
854*38fd1498Szrj 
855*38fd1498Szrj 
856*38fd1498Szrj /* Build a new GIMPLE_DEBUG_BEGIN_STMT statement in BLOCK at
857*38fd1498Szrj    LOCATION.  */
858*38fd1498Szrj 
859*38fd1498Szrj gdebug *
gimple_build_debug_begin_stmt(tree block,location_t location MEM_STAT_DECL)860*38fd1498Szrj gimple_build_debug_begin_stmt (tree block, location_t location
861*38fd1498Szrj 				    MEM_STAT_DECL)
862*38fd1498Szrj {
863*38fd1498Szrj   gdebug *p
864*38fd1498Szrj     = as_a <gdebug *> (
865*38fd1498Szrj         gimple_build_with_ops_stat (GIMPLE_DEBUG,
866*38fd1498Szrj 				    (unsigned)GIMPLE_DEBUG_BEGIN_STMT, 0
867*38fd1498Szrj 				    PASS_MEM_STAT));
868*38fd1498Szrj 
869*38fd1498Szrj   gimple_set_location (p, location);
870*38fd1498Szrj   gimple_set_block (p, block);
871*38fd1498Szrj   cfun->debug_marker_count++;
872*38fd1498Szrj 
873*38fd1498Szrj   return p;
874*38fd1498Szrj }
875*38fd1498Szrj 
876*38fd1498Szrj 
877*38fd1498Szrj /* Build a new GIMPLE_DEBUG_INLINE_ENTRY statement in BLOCK at
878*38fd1498Szrj    LOCATION.  The BLOCK links to the inlined function.  */
879*38fd1498Szrj 
880*38fd1498Szrj gdebug *
gimple_build_debug_inline_entry(tree block,location_t location MEM_STAT_DECL)881*38fd1498Szrj gimple_build_debug_inline_entry (tree block, location_t location
882*38fd1498Szrj 				      MEM_STAT_DECL)
883*38fd1498Szrj {
884*38fd1498Szrj   gdebug *p
885*38fd1498Szrj     = as_a <gdebug *> (
886*38fd1498Szrj         gimple_build_with_ops_stat (GIMPLE_DEBUG,
887*38fd1498Szrj 				    (unsigned)GIMPLE_DEBUG_INLINE_ENTRY, 0
888*38fd1498Szrj 				    PASS_MEM_STAT));
889*38fd1498Szrj 
890*38fd1498Szrj   gimple_set_location (p, location);
891*38fd1498Szrj   gimple_set_block (p, block);
892*38fd1498Szrj   cfun->debug_marker_count++;
893*38fd1498Szrj 
894*38fd1498Szrj   return p;
895*38fd1498Szrj }
896*38fd1498Szrj 
897*38fd1498Szrj 
898*38fd1498Szrj /* Build a GIMPLE_OMP_CRITICAL statement.
899*38fd1498Szrj 
900*38fd1498Szrj    BODY is the sequence of statements for which only one thread can execute.
901*38fd1498Szrj    NAME is optional identifier for this critical block.
902*38fd1498Szrj    CLAUSES are clauses for this critical block.  */
903*38fd1498Szrj 
904*38fd1498Szrj gomp_critical *
gimple_build_omp_critical(gimple_seq body,tree name,tree clauses)905*38fd1498Szrj gimple_build_omp_critical (gimple_seq body, tree name, tree clauses)
906*38fd1498Szrj {
907*38fd1498Szrj   gomp_critical *p
908*38fd1498Szrj     = as_a <gomp_critical *> (gimple_alloc (GIMPLE_OMP_CRITICAL, 0));
909*38fd1498Szrj   gimple_omp_critical_set_name (p, name);
910*38fd1498Szrj   gimple_omp_critical_set_clauses (p, clauses);
911*38fd1498Szrj   if (body)
912*38fd1498Szrj     gimple_omp_set_body (p, body);
913*38fd1498Szrj 
914*38fd1498Szrj   return p;
915*38fd1498Szrj }
916*38fd1498Szrj 
917*38fd1498Szrj /* Build a GIMPLE_OMP_FOR statement.
918*38fd1498Szrj 
919*38fd1498Szrj    BODY is sequence of statements inside the for loop.
920*38fd1498Szrj    KIND is the `for' variant.
921*38fd1498Szrj    CLAUSES, are any of the construct's clauses.
922*38fd1498Szrj    COLLAPSE is the collapse count.
923*38fd1498Szrj    PRE_BODY is the sequence of statements that are loop invariant.  */
924*38fd1498Szrj 
925*38fd1498Szrj gomp_for *
gimple_build_omp_for(gimple_seq body,int kind,tree clauses,size_t collapse,gimple_seq pre_body)926*38fd1498Szrj gimple_build_omp_for (gimple_seq body, int kind, tree clauses, size_t collapse,
927*38fd1498Szrj 		      gimple_seq pre_body)
928*38fd1498Szrj {
929*38fd1498Szrj   gomp_for *p = as_a <gomp_for *> (gimple_alloc (GIMPLE_OMP_FOR, 0));
930*38fd1498Szrj   if (body)
931*38fd1498Szrj     gimple_omp_set_body (p, body);
932*38fd1498Szrj   gimple_omp_for_set_clauses (p, clauses);
933*38fd1498Szrj   gimple_omp_for_set_kind (p, kind);
934*38fd1498Szrj   p->collapse = collapse;
935*38fd1498Szrj   p->iter =  ggc_cleared_vec_alloc<gimple_omp_for_iter> (collapse);
936*38fd1498Szrj 
937*38fd1498Szrj   if (pre_body)
938*38fd1498Szrj     gimple_omp_for_set_pre_body (p, pre_body);
939*38fd1498Szrj 
940*38fd1498Szrj   return p;
941*38fd1498Szrj }
942*38fd1498Szrj 
943*38fd1498Szrj 
944*38fd1498Szrj /* Build a GIMPLE_OMP_PARALLEL statement.
945*38fd1498Szrj 
946*38fd1498Szrj    BODY is sequence of statements which are executed in parallel.
947*38fd1498Szrj    CLAUSES, are the OMP parallel construct's clauses.
948*38fd1498Szrj    CHILD_FN is the function created for the parallel threads to execute.
949*38fd1498Szrj    DATA_ARG are the shared data argument(s).  */
950*38fd1498Szrj 
951*38fd1498Szrj gomp_parallel *
gimple_build_omp_parallel(gimple_seq body,tree clauses,tree child_fn,tree data_arg)952*38fd1498Szrj gimple_build_omp_parallel (gimple_seq body, tree clauses, tree child_fn,
953*38fd1498Szrj 			   tree data_arg)
954*38fd1498Szrj {
955*38fd1498Szrj   gomp_parallel *p
956*38fd1498Szrj     = as_a <gomp_parallel *> (gimple_alloc (GIMPLE_OMP_PARALLEL, 0));
957*38fd1498Szrj   if (body)
958*38fd1498Szrj     gimple_omp_set_body (p, body);
959*38fd1498Szrj   gimple_omp_parallel_set_clauses (p, clauses);
960*38fd1498Szrj   gimple_omp_parallel_set_child_fn (p, child_fn);
961*38fd1498Szrj   gimple_omp_parallel_set_data_arg (p, data_arg);
962*38fd1498Szrj 
963*38fd1498Szrj   return p;
964*38fd1498Szrj }
965*38fd1498Szrj 
966*38fd1498Szrj 
967*38fd1498Szrj /* Build a GIMPLE_OMP_TASK statement.
968*38fd1498Szrj 
969*38fd1498Szrj    BODY is sequence of statements which are executed by the explicit task.
970*38fd1498Szrj    CLAUSES, are the OMP parallel construct's clauses.
971*38fd1498Szrj    CHILD_FN is the function created for the parallel threads to execute.
972*38fd1498Szrj    DATA_ARG are the shared data argument(s).
973*38fd1498Szrj    COPY_FN is the optional function for firstprivate initialization.
974*38fd1498Szrj    ARG_SIZE and ARG_ALIGN are size and alignment of the data block.  */
975*38fd1498Szrj 
976*38fd1498Szrj gomp_task *
gimple_build_omp_task(gimple_seq body,tree clauses,tree child_fn,tree data_arg,tree copy_fn,tree arg_size,tree arg_align)977*38fd1498Szrj gimple_build_omp_task (gimple_seq body, tree clauses, tree child_fn,
978*38fd1498Szrj 		       tree data_arg, tree copy_fn, tree arg_size,
979*38fd1498Szrj 		       tree arg_align)
980*38fd1498Szrj {
981*38fd1498Szrj   gomp_task *p = as_a <gomp_task *> (gimple_alloc (GIMPLE_OMP_TASK, 0));
982*38fd1498Szrj   if (body)
983*38fd1498Szrj     gimple_omp_set_body (p, body);
984*38fd1498Szrj   gimple_omp_task_set_clauses (p, clauses);
985*38fd1498Szrj   gimple_omp_task_set_child_fn (p, child_fn);
986*38fd1498Szrj   gimple_omp_task_set_data_arg (p, data_arg);
987*38fd1498Szrj   gimple_omp_task_set_copy_fn (p, copy_fn);
988*38fd1498Szrj   gimple_omp_task_set_arg_size (p, arg_size);
989*38fd1498Szrj   gimple_omp_task_set_arg_align (p, arg_align);
990*38fd1498Szrj 
991*38fd1498Szrj   return p;
992*38fd1498Szrj }
993*38fd1498Szrj 
994*38fd1498Szrj 
995*38fd1498Szrj /* Build a GIMPLE_OMP_SECTION statement for a sections statement.
996*38fd1498Szrj 
997*38fd1498Szrj    BODY is the sequence of statements in the section.  */
998*38fd1498Szrj 
999*38fd1498Szrj gimple *
gimple_build_omp_section(gimple_seq body)1000*38fd1498Szrj gimple_build_omp_section (gimple_seq body)
1001*38fd1498Szrj {
1002*38fd1498Szrj   gimple *p = gimple_alloc (GIMPLE_OMP_SECTION, 0);
1003*38fd1498Szrj   if (body)
1004*38fd1498Szrj     gimple_omp_set_body (p, body);
1005*38fd1498Szrj 
1006*38fd1498Szrj   return p;
1007*38fd1498Szrj }
1008*38fd1498Szrj 
1009*38fd1498Szrj 
1010*38fd1498Szrj /* Build a GIMPLE_OMP_MASTER statement.
1011*38fd1498Szrj 
1012*38fd1498Szrj    BODY is the sequence of statements to be executed by just the master.  */
1013*38fd1498Szrj 
1014*38fd1498Szrj gimple *
gimple_build_omp_master(gimple_seq body)1015*38fd1498Szrj gimple_build_omp_master (gimple_seq body)
1016*38fd1498Szrj {
1017*38fd1498Szrj   gimple *p = gimple_alloc (GIMPLE_OMP_MASTER, 0);
1018*38fd1498Szrj   if (body)
1019*38fd1498Szrj     gimple_omp_set_body (p, body);
1020*38fd1498Szrj 
1021*38fd1498Szrj   return p;
1022*38fd1498Szrj }
1023*38fd1498Szrj 
1024*38fd1498Szrj /* Build a GIMPLE_OMP_GRID_BODY statement.
1025*38fd1498Szrj 
1026*38fd1498Szrj    BODY is the sequence of statements to be executed by the kernel.  */
1027*38fd1498Szrj 
1028*38fd1498Szrj gimple *
gimple_build_omp_grid_body(gimple_seq body)1029*38fd1498Szrj gimple_build_omp_grid_body (gimple_seq body)
1030*38fd1498Szrj {
1031*38fd1498Szrj   gimple *p = gimple_alloc (GIMPLE_OMP_GRID_BODY, 0);
1032*38fd1498Szrj   if (body)
1033*38fd1498Szrj     gimple_omp_set_body (p, body);
1034*38fd1498Szrj 
1035*38fd1498Szrj   return p;
1036*38fd1498Szrj }
1037*38fd1498Szrj 
1038*38fd1498Szrj /* Build a GIMPLE_OMP_TASKGROUP statement.
1039*38fd1498Szrj 
1040*38fd1498Szrj    BODY is the sequence of statements to be executed by the taskgroup
1041*38fd1498Szrj    construct.  */
1042*38fd1498Szrj 
1043*38fd1498Szrj gimple *
gimple_build_omp_taskgroup(gimple_seq body)1044*38fd1498Szrj gimple_build_omp_taskgroup (gimple_seq body)
1045*38fd1498Szrj {
1046*38fd1498Szrj   gimple *p = gimple_alloc (GIMPLE_OMP_TASKGROUP, 0);
1047*38fd1498Szrj   if (body)
1048*38fd1498Szrj     gimple_omp_set_body (p, body);
1049*38fd1498Szrj 
1050*38fd1498Szrj   return p;
1051*38fd1498Szrj }
1052*38fd1498Szrj 
1053*38fd1498Szrj 
1054*38fd1498Szrj /* Build a GIMPLE_OMP_CONTINUE statement.
1055*38fd1498Szrj 
1056*38fd1498Szrj    CONTROL_DEF is the definition of the control variable.
1057*38fd1498Szrj    CONTROL_USE is the use of the control variable.  */
1058*38fd1498Szrj 
1059*38fd1498Szrj gomp_continue *
gimple_build_omp_continue(tree control_def,tree control_use)1060*38fd1498Szrj gimple_build_omp_continue (tree control_def, tree control_use)
1061*38fd1498Szrj {
1062*38fd1498Szrj   gomp_continue *p
1063*38fd1498Szrj     = as_a <gomp_continue *> (gimple_alloc (GIMPLE_OMP_CONTINUE, 0));
1064*38fd1498Szrj   gimple_omp_continue_set_control_def (p, control_def);
1065*38fd1498Szrj   gimple_omp_continue_set_control_use (p, control_use);
1066*38fd1498Szrj   return p;
1067*38fd1498Szrj }
1068*38fd1498Szrj 
1069*38fd1498Szrj /* Build a GIMPLE_OMP_ORDERED statement.
1070*38fd1498Szrj 
1071*38fd1498Szrj    BODY is the sequence of statements inside a loop that will executed in
1072*38fd1498Szrj    sequence.
1073*38fd1498Szrj    CLAUSES are clauses for this statement.  */
1074*38fd1498Szrj 
1075*38fd1498Szrj gomp_ordered *
gimple_build_omp_ordered(gimple_seq body,tree clauses)1076*38fd1498Szrj gimple_build_omp_ordered (gimple_seq body, tree clauses)
1077*38fd1498Szrj {
1078*38fd1498Szrj   gomp_ordered *p
1079*38fd1498Szrj     = as_a <gomp_ordered *> (gimple_alloc (GIMPLE_OMP_ORDERED, 0));
1080*38fd1498Szrj   gimple_omp_ordered_set_clauses (p, clauses);
1081*38fd1498Szrj   if (body)
1082*38fd1498Szrj     gimple_omp_set_body (p, body);
1083*38fd1498Szrj 
1084*38fd1498Szrj   return p;
1085*38fd1498Szrj }
1086*38fd1498Szrj 
1087*38fd1498Szrj 
1088*38fd1498Szrj /* Build a GIMPLE_OMP_RETURN statement.
1089*38fd1498Szrj    WAIT_P is true if this is a non-waiting return.  */
1090*38fd1498Szrj 
1091*38fd1498Szrj gimple *
gimple_build_omp_return(bool wait_p)1092*38fd1498Szrj gimple_build_omp_return (bool wait_p)
1093*38fd1498Szrj {
1094*38fd1498Szrj   gimple *p = gimple_alloc (GIMPLE_OMP_RETURN, 0);
1095*38fd1498Szrj   if (wait_p)
1096*38fd1498Szrj     gimple_omp_return_set_nowait (p);
1097*38fd1498Szrj 
1098*38fd1498Szrj   return p;
1099*38fd1498Szrj }
1100*38fd1498Szrj 
1101*38fd1498Szrj 
1102*38fd1498Szrj /* Build a GIMPLE_OMP_SECTIONS statement.
1103*38fd1498Szrj 
1104*38fd1498Szrj    BODY is a sequence of section statements.
1105*38fd1498Szrj    CLAUSES are any of the OMP sections contsruct's clauses: private,
1106*38fd1498Szrj    firstprivate, lastprivate, reduction, and nowait.  */
1107*38fd1498Szrj 
1108*38fd1498Szrj gomp_sections *
gimple_build_omp_sections(gimple_seq body,tree clauses)1109*38fd1498Szrj gimple_build_omp_sections (gimple_seq body, tree clauses)
1110*38fd1498Szrj {
1111*38fd1498Szrj   gomp_sections *p
1112*38fd1498Szrj     = as_a <gomp_sections *> (gimple_alloc (GIMPLE_OMP_SECTIONS, 0));
1113*38fd1498Szrj   if (body)
1114*38fd1498Szrj     gimple_omp_set_body (p, body);
1115*38fd1498Szrj   gimple_omp_sections_set_clauses (p, clauses);
1116*38fd1498Szrj 
1117*38fd1498Szrj   return p;
1118*38fd1498Szrj }
1119*38fd1498Szrj 
1120*38fd1498Szrj 
1121*38fd1498Szrj /* Build a GIMPLE_OMP_SECTIONS_SWITCH.  */
1122*38fd1498Szrj 
1123*38fd1498Szrj gimple *
gimple_build_omp_sections_switch(void)1124*38fd1498Szrj gimple_build_omp_sections_switch (void)
1125*38fd1498Szrj {
1126*38fd1498Szrj   return gimple_alloc (GIMPLE_OMP_SECTIONS_SWITCH, 0);
1127*38fd1498Szrj }
1128*38fd1498Szrj 
1129*38fd1498Szrj 
1130*38fd1498Szrj /* Build a GIMPLE_OMP_SINGLE statement.
1131*38fd1498Szrj 
1132*38fd1498Szrj    BODY is the sequence of statements that will be executed once.
1133*38fd1498Szrj    CLAUSES are any of the OMP single construct's clauses: private, firstprivate,
1134*38fd1498Szrj    copyprivate, nowait.  */
1135*38fd1498Szrj 
1136*38fd1498Szrj gomp_single *
gimple_build_omp_single(gimple_seq body,tree clauses)1137*38fd1498Szrj gimple_build_omp_single (gimple_seq body, tree clauses)
1138*38fd1498Szrj {
1139*38fd1498Szrj   gomp_single *p
1140*38fd1498Szrj     = as_a <gomp_single *> (gimple_alloc (GIMPLE_OMP_SINGLE, 0));
1141*38fd1498Szrj   if (body)
1142*38fd1498Szrj     gimple_omp_set_body (p, body);
1143*38fd1498Szrj   gimple_omp_single_set_clauses (p, clauses);
1144*38fd1498Szrj 
1145*38fd1498Szrj   return p;
1146*38fd1498Szrj }
1147*38fd1498Szrj 
1148*38fd1498Szrj 
1149*38fd1498Szrj /* Build a GIMPLE_OMP_TARGET statement.
1150*38fd1498Szrj 
1151*38fd1498Szrj    BODY is the sequence of statements that will be executed.
1152*38fd1498Szrj    KIND is the kind of the region.
1153*38fd1498Szrj    CLAUSES are any of the construct's clauses.  */
1154*38fd1498Szrj 
1155*38fd1498Szrj gomp_target *
gimple_build_omp_target(gimple_seq body,int kind,tree clauses)1156*38fd1498Szrj gimple_build_omp_target (gimple_seq body, int kind, tree clauses)
1157*38fd1498Szrj {
1158*38fd1498Szrj   gomp_target *p
1159*38fd1498Szrj     = as_a <gomp_target *> (gimple_alloc (GIMPLE_OMP_TARGET, 0));
1160*38fd1498Szrj   if (body)
1161*38fd1498Szrj     gimple_omp_set_body (p, body);
1162*38fd1498Szrj   gimple_omp_target_set_clauses (p, clauses);
1163*38fd1498Szrj   gimple_omp_target_set_kind (p, kind);
1164*38fd1498Szrj 
1165*38fd1498Szrj   return p;
1166*38fd1498Szrj }
1167*38fd1498Szrj 
1168*38fd1498Szrj 
1169*38fd1498Szrj /* Build a GIMPLE_OMP_TEAMS statement.
1170*38fd1498Szrj 
1171*38fd1498Szrj    BODY is the sequence of statements that will be executed.
1172*38fd1498Szrj    CLAUSES are any of the OMP teams construct's clauses.  */
1173*38fd1498Szrj 
1174*38fd1498Szrj gomp_teams *
gimple_build_omp_teams(gimple_seq body,tree clauses)1175*38fd1498Szrj gimple_build_omp_teams (gimple_seq body, tree clauses)
1176*38fd1498Szrj {
1177*38fd1498Szrj   gomp_teams *p = as_a <gomp_teams *> (gimple_alloc (GIMPLE_OMP_TEAMS, 0));
1178*38fd1498Szrj   if (body)
1179*38fd1498Szrj     gimple_omp_set_body (p, body);
1180*38fd1498Szrj   gimple_omp_teams_set_clauses (p, clauses);
1181*38fd1498Szrj 
1182*38fd1498Szrj   return p;
1183*38fd1498Szrj }
1184*38fd1498Szrj 
1185*38fd1498Szrj 
1186*38fd1498Szrj /* Build a GIMPLE_OMP_ATOMIC_LOAD statement.  */
1187*38fd1498Szrj 
1188*38fd1498Szrj gomp_atomic_load *
gimple_build_omp_atomic_load(tree lhs,tree rhs)1189*38fd1498Szrj gimple_build_omp_atomic_load (tree lhs, tree rhs)
1190*38fd1498Szrj {
1191*38fd1498Szrj   gomp_atomic_load *p
1192*38fd1498Szrj     = as_a <gomp_atomic_load *> (gimple_alloc (GIMPLE_OMP_ATOMIC_LOAD, 0));
1193*38fd1498Szrj   gimple_omp_atomic_load_set_lhs (p, lhs);
1194*38fd1498Szrj   gimple_omp_atomic_load_set_rhs (p, rhs);
1195*38fd1498Szrj   return p;
1196*38fd1498Szrj }
1197*38fd1498Szrj 
1198*38fd1498Szrj /* Build a GIMPLE_OMP_ATOMIC_STORE statement.
1199*38fd1498Szrj 
1200*38fd1498Szrj    VAL is the value we are storing.  */
1201*38fd1498Szrj 
1202*38fd1498Szrj gomp_atomic_store *
gimple_build_omp_atomic_store(tree val)1203*38fd1498Szrj gimple_build_omp_atomic_store (tree val)
1204*38fd1498Szrj {
1205*38fd1498Szrj   gomp_atomic_store *p
1206*38fd1498Szrj     = as_a <gomp_atomic_store *> (gimple_alloc (GIMPLE_OMP_ATOMIC_STORE, 0));
1207*38fd1498Szrj   gimple_omp_atomic_store_set_val (p, val);
1208*38fd1498Szrj   return p;
1209*38fd1498Szrj }
1210*38fd1498Szrj 
1211*38fd1498Szrj /* Build a GIMPLE_TRANSACTION statement.  */
1212*38fd1498Szrj 
1213*38fd1498Szrj gtransaction *
gimple_build_transaction(gimple_seq body)1214*38fd1498Szrj gimple_build_transaction (gimple_seq body)
1215*38fd1498Szrj {
1216*38fd1498Szrj   gtransaction *p
1217*38fd1498Szrj     = as_a <gtransaction *> (gimple_alloc (GIMPLE_TRANSACTION, 0));
1218*38fd1498Szrj   gimple_transaction_set_body (p, body);
1219*38fd1498Szrj   gimple_transaction_set_label_norm (p, 0);
1220*38fd1498Szrj   gimple_transaction_set_label_uninst (p, 0);
1221*38fd1498Szrj   gimple_transaction_set_label_over (p, 0);
1222*38fd1498Szrj   return p;
1223*38fd1498Szrj }
1224*38fd1498Szrj 
1225*38fd1498Szrj #if defined ENABLE_GIMPLE_CHECKING
1226*38fd1498Szrj /* Complain of a gimple type mismatch and die.  */
1227*38fd1498Szrj 
1228*38fd1498Szrj void
gimple_check_failed(const gimple * gs,const char * file,int line,const char * function,enum gimple_code code,enum tree_code subcode)1229*38fd1498Szrj gimple_check_failed (const gimple *gs, const char *file, int line,
1230*38fd1498Szrj 		     const char *function, enum gimple_code code,
1231*38fd1498Szrj 		     enum tree_code subcode)
1232*38fd1498Szrj {
1233*38fd1498Szrj   internal_error ("gimple check: expected %s(%s), have %s(%s) in %s, at %s:%d",
1234*38fd1498Szrj       		  gimple_code_name[code],
1235*38fd1498Szrj 		  get_tree_code_name (subcode),
1236*38fd1498Szrj 		  gimple_code_name[gimple_code (gs)],
1237*38fd1498Szrj 		  gs->subcode > 0
1238*38fd1498Szrj 		    ? get_tree_code_name ((enum tree_code) gs->subcode)
1239*38fd1498Szrj 		    : "",
1240*38fd1498Szrj 		  function, trim_filename (file), line);
1241*38fd1498Szrj }
1242*38fd1498Szrj #endif /* ENABLE_GIMPLE_CHECKING */
1243*38fd1498Szrj 
1244*38fd1498Szrj 
1245*38fd1498Szrj /* Link gimple statement GS to the end of the sequence *SEQ_P.  If
1246*38fd1498Szrj    *SEQ_P is NULL, a new sequence is allocated.  */
1247*38fd1498Szrj 
1248*38fd1498Szrj void
gimple_seq_add_stmt(gimple_seq * seq_p,gimple * gs)1249*38fd1498Szrj gimple_seq_add_stmt (gimple_seq *seq_p, gimple *gs)
1250*38fd1498Szrj {
1251*38fd1498Szrj   gimple_stmt_iterator si;
1252*38fd1498Szrj   if (gs == NULL)
1253*38fd1498Szrj     return;
1254*38fd1498Szrj 
1255*38fd1498Szrj   si = gsi_last (*seq_p);
1256*38fd1498Szrj   gsi_insert_after (&si, gs, GSI_NEW_STMT);
1257*38fd1498Szrj }
1258*38fd1498Szrj 
1259*38fd1498Szrj /* Link gimple statement GS to the end of the sequence *SEQ_P.  If
1260*38fd1498Szrj    *SEQ_P is NULL, a new sequence is allocated.  This function is
1261*38fd1498Szrj    similar to gimple_seq_add_stmt, but does not scan the operands.
1262*38fd1498Szrj    During gimplification, we need to manipulate statement sequences
1263*38fd1498Szrj    before the def/use vectors have been constructed.  */
1264*38fd1498Szrj 
1265*38fd1498Szrj void
gimple_seq_add_stmt_without_update(gimple_seq * seq_p,gimple * gs)1266*38fd1498Szrj gimple_seq_add_stmt_without_update (gimple_seq *seq_p, gimple *gs)
1267*38fd1498Szrj {
1268*38fd1498Szrj   gimple_stmt_iterator si;
1269*38fd1498Szrj 
1270*38fd1498Szrj   if (gs == NULL)
1271*38fd1498Szrj     return;
1272*38fd1498Szrj 
1273*38fd1498Szrj   si = gsi_last (*seq_p);
1274*38fd1498Szrj   gsi_insert_after_without_update (&si, gs, GSI_NEW_STMT);
1275*38fd1498Szrj }
1276*38fd1498Szrj 
1277*38fd1498Szrj /* Append sequence SRC to the end of sequence *DST_P.  If *DST_P is
1278*38fd1498Szrj    NULL, a new sequence is allocated.  */
1279*38fd1498Szrj 
1280*38fd1498Szrj void
gimple_seq_add_seq(gimple_seq * dst_p,gimple_seq src)1281*38fd1498Szrj gimple_seq_add_seq (gimple_seq *dst_p, gimple_seq src)
1282*38fd1498Szrj {
1283*38fd1498Szrj   gimple_stmt_iterator si;
1284*38fd1498Szrj   if (src == NULL)
1285*38fd1498Szrj     return;
1286*38fd1498Szrj 
1287*38fd1498Szrj   si = gsi_last (*dst_p);
1288*38fd1498Szrj   gsi_insert_seq_after (&si, src, GSI_NEW_STMT);
1289*38fd1498Szrj }
1290*38fd1498Szrj 
1291*38fd1498Szrj /* Append sequence SRC to the end of sequence *DST_P.  If *DST_P is
1292*38fd1498Szrj    NULL, a new sequence is allocated.  This function is
1293*38fd1498Szrj    similar to gimple_seq_add_seq, but does not scan the operands.  */
1294*38fd1498Szrj 
1295*38fd1498Szrj void
gimple_seq_add_seq_without_update(gimple_seq * dst_p,gimple_seq src)1296*38fd1498Szrj gimple_seq_add_seq_without_update (gimple_seq *dst_p, gimple_seq src)
1297*38fd1498Szrj {
1298*38fd1498Szrj   gimple_stmt_iterator si;
1299*38fd1498Szrj   if (src == NULL)
1300*38fd1498Szrj     return;
1301*38fd1498Szrj 
1302*38fd1498Szrj   si = gsi_last (*dst_p);
1303*38fd1498Szrj   gsi_insert_seq_after_without_update (&si, src, GSI_NEW_STMT);
1304*38fd1498Szrj }
1305*38fd1498Szrj 
1306*38fd1498Szrj /* Determine whether to assign a location to the statement GS.  */
1307*38fd1498Szrj 
1308*38fd1498Szrj static bool
should_carry_location_p(gimple * gs)1309*38fd1498Szrj should_carry_location_p (gimple *gs)
1310*38fd1498Szrj {
1311*38fd1498Szrj   /* Don't emit a line note for a label.  We particularly don't want to
1312*38fd1498Szrj      emit one for the break label, since it doesn't actually correspond
1313*38fd1498Szrj      to the beginning of the loop/switch.  */
1314*38fd1498Szrj   if (gimple_code (gs) == GIMPLE_LABEL)
1315*38fd1498Szrj     return false;
1316*38fd1498Szrj 
1317*38fd1498Szrj   return true;
1318*38fd1498Szrj }
1319*38fd1498Szrj 
1320*38fd1498Szrj /* Set the location for gimple statement GS to LOCATION.  */
1321*38fd1498Szrj 
1322*38fd1498Szrj static void
annotate_one_with_location(gimple * gs,location_t location)1323*38fd1498Szrj annotate_one_with_location (gimple *gs, location_t location)
1324*38fd1498Szrj {
1325*38fd1498Szrj   if (!gimple_has_location (gs)
1326*38fd1498Szrj       && !gimple_do_not_emit_location_p (gs)
1327*38fd1498Szrj       && should_carry_location_p (gs))
1328*38fd1498Szrj     gimple_set_location (gs, location);
1329*38fd1498Szrj }
1330*38fd1498Szrj 
1331*38fd1498Szrj /* Set LOCATION for all the statements after iterator GSI in sequence
1332*38fd1498Szrj    SEQ.  If GSI is pointing to the end of the sequence, start with the
1333*38fd1498Szrj    first statement in SEQ.  */
1334*38fd1498Szrj 
1335*38fd1498Szrj void
annotate_all_with_location_after(gimple_seq seq,gimple_stmt_iterator gsi,location_t location)1336*38fd1498Szrj annotate_all_with_location_after (gimple_seq seq, gimple_stmt_iterator gsi,
1337*38fd1498Szrj 				  location_t location)
1338*38fd1498Szrj {
1339*38fd1498Szrj   if (gsi_end_p (gsi))
1340*38fd1498Szrj     gsi = gsi_start (seq);
1341*38fd1498Szrj   else
1342*38fd1498Szrj     gsi_next (&gsi);
1343*38fd1498Szrj 
1344*38fd1498Szrj   for (; !gsi_end_p (gsi); gsi_next (&gsi))
1345*38fd1498Szrj     annotate_one_with_location (gsi_stmt (gsi), location);
1346*38fd1498Szrj }
1347*38fd1498Szrj 
1348*38fd1498Szrj /* Set the location for all the statements in a sequence STMT_P to LOCATION.  */
1349*38fd1498Szrj 
1350*38fd1498Szrj void
annotate_all_with_location(gimple_seq stmt_p,location_t location)1351*38fd1498Szrj annotate_all_with_location (gimple_seq stmt_p, location_t location)
1352*38fd1498Szrj {
1353*38fd1498Szrj   gimple_stmt_iterator i;
1354*38fd1498Szrj 
1355*38fd1498Szrj   if (gimple_seq_empty_p (stmt_p))
1356*38fd1498Szrj     return;
1357*38fd1498Szrj 
1358*38fd1498Szrj   for (i = gsi_start (stmt_p); !gsi_end_p (i); gsi_next (&i))
1359*38fd1498Szrj     {
1360*38fd1498Szrj       gimple *gs = gsi_stmt (i);
1361*38fd1498Szrj       annotate_one_with_location (gs, location);
1362*38fd1498Szrj     }
1363*38fd1498Szrj }
1364*38fd1498Szrj 
1365*38fd1498Szrj /* Helper function of empty_body_p.  Return true if STMT is an empty
1366*38fd1498Szrj    statement.  */
1367*38fd1498Szrj 
1368*38fd1498Szrj static bool
empty_stmt_p(gimple * stmt)1369*38fd1498Szrj empty_stmt_p (gimple *stmt)
1370*38fd1498Szrj {
1371*38fd1498Szrj   if (gimple_code (stmt) == GIMPLE_NOP)
1372*38fd1498Szrj     return true;
1373*38fd1498Szrj   if (gbind *bind_stmt = dyn_cast <gbind *> (stmt))
1374*38fd1498Szrj     return empty_body_p (gimple_bind_body (bind_stmt));
1375*38fd1498Szrj   return false;
1376*38fd1498Szrj }
1377*38fd1498Szrj 
1378*38fd1498Szrj 
1379*38fd1498Szrj /* Return true if BODY contains nothing but empty statements.  */
1380*38fd1498Szrj 
1381*38fd1498Szrj bool
empty_body_p(gimple_seq body)1382*38fd1498Szrj empty_body_p (gimple_seq body)
1383*38fd1498Szrj {
1384*38fd1498Szrj   gimple_stmt_iterator i;
1385*38fd1498Szrj 
1386*38fd1498Szrj   if (gimple_seq_empty_p (body))
1387*38fd1498Szrj     return true;
1388*38fd1498Szrj   for (i = gsi_start (body); !gsi_end_p (i); gsi_next (&i))
1389*38fd1498Szrj     if (!empty_stmt_p (gsi_stmt (i))
1390*38fd1498Szrj 	&& !is_gimple_debug (gsi_stmt (i)))
1391*38fd1498Szrj       return false;
1392*38fd1498Szrj 
1393*38fd1498Szrj   return true;
1394*38fd1498Szrj }
1395*38fd1498Szrj 
1396*38fd1498Szrj 
1397*38fd1498Szrj /* Perform a deep copy of sequence SRC and return the result.  */
1398*38fd1498Szrj 
1399*38fd1498Szrj gimple_seq
gimple_seq_copy(gimple_seq src)1400*38fd1498Szrj gimple_seq_copy (gimple_seq src)
1401*38fd1498Szrj {
1402*38fd1498Szrj   gimple_stmt_iterator gsi;
1403*38fd1498Szrj   gimple_seq new_seq = NULL;
1404*38fd1498Szrj   gimple *stmt;
1405*38fd1498Szrj 
1406*38fd1498Szrj   for (gsi = gsi_start (src); !gsi_end_p (gsi); gsi_next (&gsi))
1407*38fd1498Szrj     {
1408*38fd1498Szrj       stmt = gimple_copy (gsi_stmt (gsi));
1409*38fd1498Szrj       gimple_seq_add_stmt (&new_seq, stmt);
1410*38fd1498Szrj     }
1411*38fd1498Szrj 
1412*38fd1498Szrj   return new_seq;
1413*38fd1498Szrj }
1414*38fd1498Szrj 
1415*38fd1498Szrj 
1416*38fd1498Szrj 
1417*38fd1498Szrj /* Return true if calls C1 and C2 are known to go to the same function.  */
1418*38fd1498Szrj 
1419*38fd1498Szrj bool
gimple_call_same_target_p(const gimple * c1,const gimple * c2)1420*38fd1498Szrj gimple_call_same_target_p (const gimple *c1, const gimple *c2)
1421*38fd1498Szrj {
1422*38fd1498Szrj   if (gimple_call_internal_p (c1))
1423*38fd1498Szrj     return (gimple_call_internal_p (c2)
1424*38fd1498Szrj 	    && gimple_call_internal_fn (c1) == gimple_call_internal_fn (c2)
1425*38fd1498Szrj 	    && (!gimple_call_internal_unique_p (as_a <const gcall *> (c1))
1426*38fd1498Szrj 		|| c1 == c2));
1427*38fd1498Szrj   else
1428*38fd1498Szrj     return (gimple_call_fn (c1) == gimple_call_fn (c2)
1429*38fd1498Szrj 	    || (gimple_call_fndecl (c1)
1430*38fd1498Szrj 		&& gimple_call_fndecl (c1) == gimple_call_fndecl (c2)));
1431*38fd1498Szrj }
1432*38fd1498Szrj 
1433*38fd1498Szrj /* Detect flags from a GIMPLE_CALL.  This is just like
1434*38fd1498Szrj    call_expr_flags, but for gimple tuples.  */
1435*38fd1498Szrj 
1436*38fd1498Szrj int
gimple_call_flags(const gimple * stmt)1437*38fd1498Szrj gimple_call_flags (const gimple *stmt)
1438*38fd1498Szrj {
1439*38fd1498Szrj   int flags;
1440*38fd1498Szrj   tree decl = gimple_call_fndecl (stmt);
1441*38fd1498Szrj 
1442*38fd1498Szrj   if (decl)
1443*38fd1498Szrj     flags = flags_from_decl_or_type (decl);
1444*38fd1498Szrj   else if (gimple_call_internal_p (stmt))
1445*38fd1498Szrj     flags = internal_fn_flags (gimple_call_internal_fn (stmt));
1446*38fd1498Szrj   else
1447*38fd1498Szrj     flags = flags_from_decl_or_type (gimple_call_fntype (stmt));
1448*38fd1498Szrj 
1449*38fd1498Szrj   if (stmt->subcode & GF_CALL_NOTHROW)
1450*38fd1498Szrj     flags |= ECF_NOTHROW;
1451*38fd1498Szrj 
1452*38fd1498Szrj   if (stmt->subcode & GF_CALL_BY_DESCRIPTOR)
1453*38fd1498Szrj     flags |= ECF_BY_DESCRIPTOR;
1454*38fd1498Szrj 
1455*38fd1498Szrj   return flags;
1456*38fd1498Szrj }
1457*38fd1498Szrj 
1458*38fd1498Szrj /* Return the "fn spec" string for call STMT.  */
1459*38fd1498Szrj 
1460*38fd1498Szrj static const_tree
gimple_call_fnspec(const gcall * stmt)1461*38fd1498Szrj gimple_call_fnspec (const gcall *stmt)
1462*38fd1498Szrj {
1463*38fd1498Szrj   tree type, attr;
1464*38fd1498Szrj 
1465*38fd1498Szrj   if (gimple_call_internal_p (stmt))
1466*38fd1498Szrj     return internal_fn_fnspec (gimple_call_internal_fn (stmt));
1467*38fd1498Szrj 
1468*38fd1498Szrj   type = gimple_call_fntype (stmt);
1469*38fd1498Szrj   if (!type)
1470*38fd1498Szrj     return NULL_TREE;
1471*38fd1498Szrj 
1472*38fd1498Szrj   attr = lookup_attribute ("fn spec", TYPE_ATTRIBUTES (type));
1473*38fd1498Szrj   if (!attr)
1474*38fd1498Szrj     return NULL_TREE;
1475*38fd1498Szrj 
1476*38fd1498Szrj   return TREE_VALUE (TREE_VALUE (attr));
1477*38fd1498Szrj }
1478*38fd1498Szrj 
1479*38fd1498Szrj /* Detects argument flags for argument number ARG on call STMT.  */
1480*38fd1498Szrj 
1481*38fd1498Szrj int
gimple_call_arg_flags(const gcall * stmt,unsigned arg)1482*38fd1498Szrj gimple_call_arg_flags (const gcall *stmt, unsigned arg)
1483*38fd1498Szrj {
1484*38fd1498Szrj   const_tree attr = gimple_call_fnspec (stmt);
1485*38fd1498Szrj 
1486*38fd1498Szrj   if (!attr || 1 + arg >= (unsigned) TREE_STRING_LENGTH (attr))
1487*38fd1498Szrj     return 0;
1488*38fd1498Szrj 
1489*38fd1498Szrj   switch (TREE_STRING_POINTER (attr)[1 + arg])
1490*38fd1498Szrj     {
1491*38fd1498Szrj     case 'x':
1492*38fd1498Szrj     case 'X':
1493*38fd1498Szrj       return EAF_UNUSED;
1494*38fd1498Szrj 
1495*38fd1498Szrj     case 'R':
1496*38fd1498Szrj       return EAF_DIRECT | EAF_NOCLOBBER | EAF_NOESCAPE;
1497*38fd1498Szrj 
1498*38fd1498Szrj     case 'r':
1499*38fd1498Szrj       return EAF_NOCLOBBER | EAF_NOESCAPE;
1500*38fd1498Szrj 
1501*38fd1498Szrj     case 'W':
1502*38fd1498Szrj       return EAF_DIRECT | EAF_NOESCAPE;
1503*38fd1498Szrj 
1504*38fd1498Szrj     case 'w':
1505*38fd1498Szrj       return EAF_NOESCAPE;
1506*38fd1498Szrj 
1507*38fd1498Szrj     case '.':
1508*38fd1498Szrj     default:
1509*38fd1498Szrj       return 0;
1510*38fd1498Szrj     }
1511*38fd1498Szrj }
1512*38fd1498Szrj 
1513*38fd1498Szrj /* Detects return flags for the call STMT.  */
1514*38fd1498Szrj 
1515*38fd1498Szrj int
gimple_call_return_flags(const gcall * stmt)1516*38fd1498Szrj gimple_call_return_flags (const gcall *stmt)
1517*38fd1498Szrj {
1518*38fd1498Szrj   const_tree attr;
1519*38fd1498Szrj 
1520*38fd1498Szrj   if (gimple_call_flags (stmt) & ECF_MALLOC)
1521*38fd1498Szrj     return ERF_NOALIAS;
1522*38fd1498Szrj 
1523*38fd1498Szrj   attr = gimple_call_fnspec (stmt);
1524*38fd1498Szrj   if (!attr || TREE_STRING_LENGTH (attr) < 1)
1525*38fd1498Szrj     return 0;
1526*38fd1498Szrj 
1527*38fd1498Szrj   switch (TREE_STRING_POINTER (attr)[0])
1528*38fd1498Szrj     {
1529*38fd1498Szrj     case '1':
1530*38fd1498Szrj     case '2':
1531*38fd1498Szrj     case '3':
1532*38fd1498Szrj     case '4':
1533*38fd1498Szrj       return ERF_RETURNS_ARG | (TREE_STRING_POINTER (attr)[0] - '1');
1534*38fd1498Szrj 
1535*38fd1498Szrj     case 'm':
1536*38fd1498Szrj       return ERF_NOALIAS;
1537*38fd1498Szrj 
1538*38fd1498Szrj     case '.':
1539*38fd1498Szrj     default:
1540*38fd1498Szrj       return 0;
1541*38fd1498Szrj     }
1542*38fd1498Szrj }
1543*38fd1498Szrj 
1544*38fd1498Szrj 
1545*38fd1498Szrj /* Return true if GS is a copy assignment.  */
1546*38fd1498Szrj 
1547*38fd1498Szrj bool
gimple_assign_copy_p(gimple * gs)1548*38fd1498Szrj gimple_assign_copy_p (gimple *gs)
1549*38fd1498Szrj {
1550*38fd1498Szrj   return (gimple_assign_single_p (gs)
1551*38fd1498Szrj 	  && is_gimple_val (gimple_op (gs, 1)));
1552*38fd1498Szrj }
1553*38fd1498Szrj 
1554*38fd1498Szrj 
1555*38fd1498Szrj /* Return true if GS is a SSA_NAME copy assignment.  */
1556*38fd1498Szrj 
1557*38fd1498Szrj bool
gimple_assign_ssa_name_copy_p(gimple * gs)1558*38fd1498Szrj gimple_assign_ssa_name_copy_p (gimple *gs)
1559*38fd1498Szrj {
1560*38fd1498Szrj   return (gimple_assign_single_p (gs)
1561*38fd1498Szrj 	  && TREE_CODE (gimple_assign_lhs (gs)) == SSA_NAME
1562*38fd1498Szrj 	  && TREE_CODE (gimple_assign_rhs1 (gs)) == SSA_NAME);
1563*38fd1498Szrj }
1564*38fd1498Szrj 
1565*38fd1498Szrj 
1566*38fd1498Szrj /* Return true if GS is an assignment with a unary RHS, but the
1567*38fd1498Szrj    operator has no effect on the assigned value.  The logic is adapted
1568*38fd1498Szrj    from STRIP_NOPS.  This predicate is intended to be used in tuplifying
1569*38fd1498Szrj    instances in which STRIP_NOPS was previously applied to the RHS of
1570*38fd1498Szrj    an assignment.
1571*38fd1498Szrj 
1572*38fd1498Szrj    NOTE: In the use cases that led to the creation of this function
1573*38fd1498Szrj    and of gimple_assign_single_p, it is typical to test for either
1574*38fd1498Szrj    condition and to proceed in the same manner.  In each case, the
1575*38fd1498Szrj    assigned value is represented by the single RHS operand of the
1576*38fd1498Szrj    assignment.  I suspect there may be cases where gimple_assign_copy_p,
1577*38fd1498Szrj    gimple_assign_single_p, or equivalent logic is used where a similar
1578*38fd1498Szrj    treatment of unary NOPs is appropriate.  */
1579*38fd1498Szrj 
1580*38fd1498Szrj bool
gimple_assign_unary_nop_p(gimple * gs)1581*38fd1498Szrj gimple_assign_unary_nop_p (gimple *gs)
1582*38fd1498Szrj {
1583*38fd1498Szrj   return (is_gimple_assign (gs)
1584*38fd1498Szrj           && (CONVERT_EXPR_CODE_P (gimple_assign_rhs_code (gs))
1585*38fd1498Szrj               || gimple_assign_rhs_code (gs) == NON_LVALUE_EXPR)
1586*38fd1498Szrj           && gimple_assign_rhs1 (gs) != error_mark_node
1587*38fd1498Szrj           && (TYPE_MODE (TREE_TYPE (gimple_assign_lhs (gs)))
1588*38fd1498Szrj               == TYPE_MODE (TREE_TYPE (gimple_assign_rhs1 (gs)))));
1589*38fd1498Szrj }
1590*38fd1498Szrj 
1591*38fd1498Szrj /* Set BB to be the basic block holding G.  */
1592*38fd1498Szrj 
1593*38fd1498Szrj void
gimple_set_bb(gimple * stmt,basic_block bb)1594*38fd1498Szrj gimple_set_bb (gimple *stmt, basic_block bb)
1595*38fd1498Szrj {
1596*38fd1498Szrj   stmt->bb = bb;
1597*38fd1498Szrj 
1598*38fd1498Szrj   if (gimple_code (stmt) != GIMPLE_LABEL)
1599*38fd1498Szrj     return;
1600*38fd1498Szrj 
1601*38fd1498Szrj   /* If the statement is a label, add the label to block-to-labels map
1602*38fd1498Szrj      so that we can speed up edge creation for GIMPLE_GOTOs.  */
1603*38fd1498Szrj   if (cfun->cfg)
1604*38fd1498Szrj     {
1605*38fd1498Szrj       tree t;
1606*38fd1498Szrj       int uid;
1607*38fd1498Szrj 
1608*38fd1498Szrj       t = gimple_label_label (as_a <glabel *> (stmt));
1609*38fd1498Szrj       uid = LABEL_DECL_UID (t);
1610*38fd1498Szrj       if (uid == -1)
1611*38fd1498Szrj 	{
1612*38fd1498Szrj 	  unsigned old_len =
1613*38fd1498Szrj 	    vec_safe_length (label_to_block_map_for_fn (cfun));
1614*38fd1498Szrj 	  LABEL_DECL_UID (t) = uid = cfun->cfg->last_label_uid++;
1615*38fd1498Szrj 	  if (old_len <= (unsigned) uid)
1616*38fd1498Szrj 	    {
1617*38fd1498Szrj 	      unsigned new_len = 3 * uid / 2 + 1;
1618*38fd1498Szrj 
1619*38fd1498Szrj 	      vec_safe_grow_cleared (label_to_block_map_for_fn (cfun),
1620*38fd1498Szrj 				     new_len);
1621*38fd1498Szrj 	    }
1622*38fd1498Szrj 	}
1623*38fd1498Szrj 
1624*38fd1498Szrj       (*label_to_block_map_for_fn (cfun))[uid] = bb;
1625*38fd1498Szrj     }
1626*38fd1498Szrj }
1627*38fd1498Szrj 
1628*38fd1498Szrj 
1629*38fd1498Szrj /* Modify the RHS of the assignment pointed-to by GSI using the
1630*38fd1498Szrj    operands in the expression tree EXPR.
1631*38fd1498Szrj 
1632*38fd1498Szrj    NOTE: The statement pointed-to by GSI may be reallocated if it
1633*38fd1498Szrj    did not have enough operand slots.
1634*38fd1498Szrj 
1635*38fd1498Szrj    This function is useful to convert an existing tree expression into
1636*38fd1498Szrj    the flat representation used for the RHS of a GIMPLE assignment.
1637*38fd1498Szrj    It will reallocate memory as needed to expand or shrink the number
1638*38fd1498Szrj    of operand slots needed to represent EXPR.
1639*38fd1498Szrj 
1640*38fd1498Szrj    NOTE: If you find yourself building a tree and then calling this
1641*38fd1498Szrj    function, you are most certainly doing it the slow way.  It is much
1642*38fd1498Szrj    better to build a new assignment or to use the function
1643*38fd1498Szrj    gimple_assign_set_rhs_with_ops, which does not require an
1644*38fd1498Szrj    expression tree to be built.  */
1645*38fd1498Szrj 
1646*38fd1498Szrj void
gimple_assign_set_rhs_from_tree(gimple_stmt_iterator * gsi,tree expr)1647*38fd1498Szrj gimple_assign_set_rhs_from_tree (gimple_stmt_iterator *gsi, tree expr)
1648*38fd1498Szrj {
1649*38fd1498Szrj   enum tree_code subcode;
1650*38fd1498Szrj   tree op1, op2, op3;
1651*38fd1498Szrj 
1652*38fd1498Szrj   extract_ops_from_tree (expr, &subcode, &op1, &op2, &op3);
1653*38fd1498Szrj   gimple_assign_set_rhs_with_ops (gsi, subcode, op1, op2, op3);
1654*38fd1498Szrj }
1655*38fd1498Szrj 
1656*38fd1498Szrj 
1657*38fd1498Szrj /* Set the RHS of assignment statement pointed-to by GSI to CODE with
1658*38fd1498Szrj    operands OP1, OP2 and OP3.
1659*38fd1498Szrj 
1660*38fd1498Szrj    NOTE: The statement pointed-to by GSI may be reallocated if it
1661*38fd1498Szrj    did not have enough operand slots.  */
1662*38fd1498Szrj 
1663*38fd1498Szrj void
gimple_assign_set_rhs_with_ops(gimple_stmt_iterator * gsi,enum tree_code code,tree op1,tree op2,tree op3)1664*38fd1498Szrj gimple_assign_set_rhs_with_ops (gimple_stmt_iterator *gsi, enum tree_code code,
1665*38fd1498Szrj 				tree op1, tree op2, tree op3)
1666*38fd1498Szrj {
1667*38fd1498Szrj   unsigned new_rhs_ops = get_gimple_rhs_num_ops (code);
1668*38fd1498Szrj   gimple *stmt = gsi_stmt (*gsi);
1669*38fd1498Szrj 
1670*38fd1498Szrj   /* If the new CODE needs more operands, allocate a new statement.  */
1671*38fd1498Szrj   if (gimple_num_ops (stmt) < new_rhs_ops + 1)
1672*38fd1498Szrj     {
1673*38fd1498Szrj       tree lhs = gimple_assign_lhs (stmt);
1674*38fd1498Szrj       gimple *new_stmt = gimple_alloc (gimple_code (stmt), new_rhs_ops + 1);
1675*38fd1498Szrj       memcpy (new_stmt, stmt, gimple_size (gimple_code (stmt)));
1676*38fd1498Szrj       gimple_init_singleton (new_stmt);
1677*38fd1498Szrj       gsi_replace (gsi, new_stmt, false);
1678*38fd1498Szrj       stmt = new_stmt;
1679*38fd1498Szrj 
1680*38fd1498Szrj       /* The LHS needs to be reset as this also changes the SSA name
1681*38fd1498Szrj 	 on the LHS.  */
1682*38fd1498Szrj       gimple_assign_set_lhs (stmt, lhs);
1683*38fd1498Szrj     }
1684*38fd1498Szrj 
1685*38fd1498Szrj   gimple_set_num_ops (stmt, new_rhs_ops + 1);
1686*38fd1498Szrj   gimple_set_subcode (stmt, code);
1687*38fd1498Szrj   gimple_assign_set_rhs1 (stmt, op1);
1688*38fd1498Szrj   if (new_rhs_ops > 1)
1689*38fd1498Szrj     gimple_assign_set_rhs2 (stmt, op2);
1690*38fd1498Szrj   if (new_rhs_ops > 2)
1691*38fd1498Szrj     gimple_assign_set_rhs3 (stmt, op3);
1692*38fd1498Szrj }
1693*38fd1498Szrj 
1694*38fd1498Szrj 
1695*38fd1498Szrj /* Return the LHS of a statement that performs an assignment,
1696*38fd1498Szrj    either a GIMPLE_ASSIGN or a GIMPLE_CALL.  Returns NULL_TREE
1697*38fd1498Szrj    for a call to a function that returns no value, or for a
1698*38fd1498Szrj    statement other than an assignment or a call.  */
1699*38fd1498Szrj 
1700*38fd1498Szrj tree
gimple_get_lhs(const gimple * stmt)1701*38fd1498Szrj gimple_get_lhs (const gimple *stmt)
1702*38fd1498Szrj {
1703*38fd1498Szrj   enum gimple_code code = gimple_code (stmt);
1704*38fd1498Szrj 
1705*38fd1498Szrj   if (code == GIMPLE_ASSIGN)
1706*38fd1498Szrj     return gimple_assign_lhs (stmt);
1707*38fd1498Szrj   else if (code == GIMPLE_CALL)
1708*38fd1498Szrj     return gimple_call_lhs (stmt);
1709*38fd1498Szrj   else
1710*38fd1498Szrj     return NULL_TREE;
1711*38fd1498Szrj }
1712*38fd1498Szrj 
1713*38fd1498Szrj 
1714*38fd1498Szrj /* Set the LHS of a statement that performs an assignment,
1715*38fd1498Szrj    either a GIMPLE_ASSIGN or a GIMPLE_CALL.  */
1716*38fd1498Szrj 
1717*38fd1498Szrj void
gimple_set_lhs(gimple * stmt,tree lhs)1718*38fd1498Szrj gimple_set_lhs (gimple *stmt, tree lhs)
1719*38fd1498Szrj {
1720*38fd1498Szrj   enum gimple_code code = gimple_code (stmt);
1721*38fd1498Szrj 
1722*38fd1498Szrj   if (code == GIMPLE_ASSIGN)
1723*38fd1498Szrj     gimple_assign_set_lhs (stmt, lhs);
1724*38fd1498Szrj   else if (code == GIMPLE_CALL)
1725*38fd1498Szrj     gimple_call_set_lhs (stmt, lhs);
1726*38fd1498Szrj   else
1727*38fd1498Szrj     gcc_unreachable ();
1728*38fd1498Szrj }
1729*38fd1498Szrj 
1730*38fd1498Szrj 
1731*38fd1498Szrj /* Return a deep copy of statement STMT.  All the operands from STMT
1732*38fd1498Szrj    are reallocated and copied using unshare_expr.  The DEF, USE, VDEF
1733*38fd1498Szrj    and VUSE operand arrays are set to empty in the new copy.  The new
1734*38fd1498Szrj    copy isn't part of any sequence.  */
1735*38fd1498Szrj 
1736*38fd1498Szrj gimple *
gimple_copy(gimple * stmt)1737*38fd1498Szrj gimple_copy (gimple *stmt)
1738*38fd1498Szrj {
1739*38fd1498Szrj   enum gimple_code code = gimple_code (stmt);
1740*38fd1498Szrj   unsigned num_ops = gimple_num_ops (stmt);
1741*38fd1498Szrj   gimple *copy = gimple_alloc (code, num_ops);
1742*38fd1498Szrj   unsigned i;
1743*38fd1498Szrj 
1744*38fd1498Szrj   /* Shallow copy all the fields from STMT.  */
1745*38fd1498Szrj   memcpy (copy, stmt, gimple_size (code));
1746*38fd1498Szrj   gimple_init_singleton (copy);
1747*38fd1498Szrj 
1748*38fd1498Szrj   /* If STMT has sub-statements, deep-copy them as well.  */
1749*38fd1498Szrj   if (gimple_has_substatements (stmt))
1750*38fd1498Szrj     {
1751*38fd1498Szrj       gimple_seq new_seq;
1752*38fd1498Szrj       tree t;
1753*38fd1498Szrj 
1754*38fd1498Szrj       switch (gimple_code (stmt))
1755*38fd1498Szrj 	{
1756*38fd1498Szrj 	case GIMPLE_BIND:
1757*38fd1498Szrj 	  {
1758*38fd1498Szrj 	    gbind *bind_stmt = as_a <gbind *> (stmt);
1759*38fd1498Szrj 	    gbind *bind_copy = as_a <gbind *> (copy);
1760*38fd1498Szrj 	    new_seq = gimple_seq_copy (gimple_bind_body (bind_stmt));
1761*38fd1498Szrj 	    gimple_bind_set_body (bind_copy, new_seq);
1762*38fd1498Szrj 	    gimple_bind_set_vars (bind_copy,
1763*38fd1498Szrj 				  unshare_expr (gimple_bind_vars (bind_stmt)));
1764*38fd1498Szrj 	    gimple_bind_set_block (bind_copy, gimple_bind_block (bind_stmt));
1765*38fd1498Szrj 	  }
1766*38fd1498Szrj 	  break;
1767*38fd1498Szrj 
1768*38fd1498Szrj 	case GIMPLE_CATCH:
1769*38fd1498Szrj 	  {
1770*38fd1498Szrj 	    gcatch *catch_stmt = as_a <gcatch *> (stmt);
1771*38fd1498Szrj 	    gcatch *catch_copy = as_a <gcatch *> (copy);
1772*38fd1498Szrj 	    new_seq = gimple_seq_copy (gimple_catch_handler (catch_stmt));
1773*38fd1498Szrj 	    gimple_catch_set_handler (catch_copy, new_seq);
1774*38fd1498Szrj 	    t = unshare_expr (gimple_catch_types (catch_stmt));
1775*38fd1498Szrj 	    gimple_catch_set_types (catch_copy, t);
1776*38fd1498Szrj 	  }
1777*38fd1498Szrj 	  break;
1778*38fd1498Szrj 
1779*38fd1498Szrj 	case GIMPLE_EH_FILTER:
1780*38fd1498Szrj 	  {
1781*38fd1498Szrj 	    geh_filter *eh_filter_stmt = as_a <geh_filter *> (stmt);
1782*38fd1498Szrj 	    geh_filter *eh_filter_copy = as_a <geh_filter *> (copy);
1783*38fd1498Szrj 	    new_seq
1784*38fd1498Szrj 	      = gimple_seq_copy (gimple_eh_filter_failure (eh_filter_stmt));
1785*38fd1498Szrj 	    gimple_eh_filter_set_failure (eh_filter_copy, new_seq);
1786*38fd1498Szrj 	    t = unshare_expr (gimple_eh_filter_types (eh_filter_stmt));
1787*38fd1498Szrj 	    gimple_eh_filter_set_types (eh_filter_copy, t);
1788*38fd1498Szrj 	  }
1789*38fd1498Szrj 	  break;
1790*38fd1498Szrj 
1791*38fd1498Szrj 	case GIMPLE_EH_ELSE:
1792*38fd1498Szrj 	  {
1793*38fd1498Szrj 	    geh_else *eh_else_stmt = as_a <geh_else *> (stmt);
1794*38fd1498Szrj 	    geh_else *eh_else_copy = as_a <geh_else *> (copy);
1795*38fd1498Szrj 	    new_seq = gimple_seq_copy (gimple_eh_else_n_body (eh_else_stmt));
1796*38fd1498Szrj 	    gimple_eh_else_set_n_body (eh_else_copy, new_seq);
1797*38fd1498Szrj 	    new_seq = gimple_seq_copy (gimple_eh_else_e_body (eh_else_stmt));
1798*38fd1498Szrj 	    gimple_eh_else_set_e_body (eh_else_copy, new_seq);
1799*38fd1498Szrj 	  }
1800*38fd1498Szrj 	  break;
1801*38fd1498Szrj 
1802*38fd1498Szrj 	case GIMPLE_TRY:
1803*38fd1498Szrj 	  {
1804*38fd1498Szrj 	    gtry *try_stmt = as_a <gtry *> (stmt);
1805*38fd1498Szrj 	    gtry *try_copy = as_a <gtry *> (copy);
1806*38fd1498Szrj 	    new_seq = gimple_seq_copy (gimple_try_eval (try_stmt));
1807*38fd1498Szrj 	    gimple_try_set_eval (try_copy, new_seq);
1808*38fd1498Szrj 	    new_seq = gimple_seq_copy (gimple_try_cleanup (try_stmt));
1809*38fd1498Szrj 	    gimple_try_set_cleanup (try_copy, new_seq);
1810*38fd1498Szrj 	  }
1811*38fd1498Szrj 	  break;
1812*38fd1498Szrj 
1813*38fd1498Szrj 	case GIMPLE_OMP_FOR:
1814*38fd1498Szrj 	  new_seq = gimple_seq_copy (gimple_omp_for_pre_body (stmt));
1815*38fd1498Szrj 	  gimple_omp_for_set_pre_body (copy, new_seq);
1816*38fd1498Szrj 	  t = unshare_expr (gimple_omp_for_clauses (stmt));
1817*38fd1498Szrj 	  gimple_omp_for_set_clauses (copy, t);
1818*38fd1498Szrj 	  {
1819*38fd1498Szrj 	    gomp_for *omp_for_copy = as_a <gomp_for *> (copy);
1820*38fd1498Szrj 	    omp_for_copy->iter = ggc_vec_alloc<gimple_omp_for_iter>
1821*38fd1498Szrj 	      ( gimple_omp_for_collapse (stmt));
1822*38fd1498Szrj           }
1823*38fd1498Szrj 	  for (i = 0; i < gimple_omp_for_collapse (stmt); i++)
1824*38fd1498Szrj 	    {
1825*38fd1498Szrj 	      gimple_omp_for_set_cond (copy, i,
1826*38fd1498Szrj 				       gimple_omp_for_cond (stmt, i));
1827*38fd1498Szrj 	      gimple_omp_for_set_index (copy, i,
1828*38fd1498Szrj 					gimple_omp_for_index (stmt, i));
1829*38fd1498Szrj 	      t = unshare_expr (gimple_omp_for_initial (stmt, i));
1830*38fd1498Szrj 	      gimple_omp_for_set_initial (copy, i, t);
1831*38fd1498Szrj 	      t = unshare_expr (gimple_omp_for_final (stmt, i));
1832*38fd1498Szrj 	      gimple_omp_for_set_final (copy, i, t);
1833*38fd1498Szrj 	      t = unshare_expr (gimple_omp_for_incr (stmt, i));
1834*38fd1498Szrj 	      gimple_omp_for_set_incr (copy, i, t);
1835*38fd1498Szrj 	    }
1836*38fd1498Szrj 	  goto copy_omp_body;
1837*38fd1498Szrj 
1838*38fd1498Szrj 	case GIMPLE_OMP_PARALLEL:
1839*38fd1498Szrj 	  {
1840*38fd1498Szrj 	    gomp_parallel *omp_par_stmt = as_a <gomp_parallel *> (stmt);
1841*38fd1498Szrj 	    gomp_parallel *omp_par_copy = as_a <gomp_parallel *> (copy);
1842*38fd1498Szrj 	    t = unshare_expr (gimple_omp_parallel_clauses (omp_par_stmt));
1843*38fd1498Szrj 	    gimple_omp_parallel_set_clauses (omp_par_copy, t);
1844*38fd1498Szrj 	    t = unshare_expr (gimple_omp_parallel_child_fn (omp_par_stmt));
1845*38fd1498Szrj 	    gimple_omp_parallel_set_child_fn (omp_par_copy, t);
1846*38fd1498Szrj 	    t = unshare_expr (gimple_omp_parallel_data_arg (omp_par_stmt));
1847*38fd1498Szrj 	    gimple_omp_parallel_set_data_arg (omp_par_copy, t);
1848*38fd1498Szrj 	  }
1849*38fd1498Szrj 	  goto copy_omp_body;
1850*38fd1498Szrj 
1851*38fd1498Szrj 	case GIMPLE_OMP_TASK:
1852*38fd1498Szrj 	  t = unshare_expr (gimple_omp_task_clauses (stmt));
1853*38fd1498Szrj 	  gimple_omp_task_set_clauses (copy, t);
1854*38fd1498Szrj 	  t = unshare_expr (gimple_omp_task_child_fn (stmt));
1855*38fd1498Szrj 	  gimple_omp_task_set_child_fn (copy, t);
1856*38fd1498Szrj 	  t = unshare_expr (gimple_omp_task_data_arg (stmt));
1857*38fd1498Szrj 	  gimple_omp_task_set_data_arg (copy, t);
1858*38fd1498Szrj 	  t = unshare_expr (gimple_omp_task_copy_fn (stmt));
1859*38fd1498Szrj 	  gimple_omp_task_set_copy_fn (copy, t);
1860*38fd1498Szrj 	  t = unshare_expr (gimple_omp_task_arg_size (stmt));
1861*38fd1498Szrj 	  gimple_omp_task_set_arg_size (copy, t);
1862*38fd1498Szrj 	  t = unshare_expr (gimple_omp_task_arg_align (stmt));
1863*38fd1498Szrj 	  gimple_omp_task_set_arg_align (copy, t);
1864*38fd1498Szrj 	  goto copy_omp_body;
1865*38fd1498Szrj 
1866*38fd1498Szrj 	case GIMPLE_OMP_CRITICAL:
1867*38fd1498Szrj 	  t = unshare_expr (gimple_omp_critical_name
1868*38fd1498Szrj 				(as_a <gomp_critical *> (stmt)));
1869*38fd1498Szrj 	  gimple_omp_critical_set_name (as_a <gomp_critical *> (copy), t);
1870*38fd1498Szrj 	  t = unshare_expr (gimple_omp_critical_clauses
1871*38fd1498Szrj 				(as_a <gomp_critical *> (stmt)));
1872*38fd1498Szrj 	  gimple_omp_critical_set_clauses (as_a <gomp_critical *> (copy), t);
1873*38fd1498Szrj 	  goto copy_omp_body;
1874*38fd1498Szrj 
1875*38fd1498Szrj 	case GIMPLE_OMP_ORDERED:
1876*38fd1498Szrj 	  t = unshare_expr (gimple_omp_ordered_clauses
1877*38fd1498Szrj 				(as_a <gomp_ordered *> (stmt)));
1878*38fd1498Szrj 	  gimple_omp_ordered_set_clauses (as_a <gomp_ordered *> (copy), t);
1879*38fd1498Szrj 	  goto copy_omp_body;
1880*38fd1498Szrj 
1881*38fd1498Szrj 	case GIMPLE_OMP_SECTIONS:
1882*38fd1498Szrj 	  t = unshare_expr (gimple_omp_sections_clauses (stmt));
1883*38fd1498Szrj 	  gimple_omp_sections_set_clauses (copy, t);
1884*38fd1498Szrj 	  t = unshare_expr (gimple_omp_sections_control (stmt));
1885*38fd1498Szrj 	  gimple_omp_sections_set_control (copy, t);
1886*38fd1498Szrj 	  goto copy_omp_body;
1887*38fd1498Szrj 
1888*38fd1498Szrj 	case GIMPLE_OMP_SINGLE:
1889*38fd1498Szrj 	  {
1890*38fd1498Szrj 	    gomp_single *omp_single_copy = as_a <gomp_single *> (copy);
1891*38fd1498Szrj 	    t = unshare_expr (gimple_omp_single_clauses (stmt));
1892*38fd1498Szrj 	    gimple_omp_single_set_clauses (omp_single_copy, t);
1893*38fd1498Szrj 	  }
1894*38fd1498Szrj 	  goto copy_omp_body;
1895*38fd1498Szrj 
1896*38fd1498Szrj 	case GIMPLE_OMP_TARGET:
1897*38fd1498Szrj 	  {
1898*38fd1498Szrj 	    gomp_target *omp_target_stmt = as_a <gomp_target *> (stmt);
1899*38fd1498Szrj 	    gomp_target *omp_target_copy = as_a <gomp_target *> (copy);
1900*38fd1498Szrj 	    t = unshare_expr (gimple_omp_target_clauses (omp_target_stmt));
1901*38fd1498Szrj 	    gimple_omp_target_set_clauses (omp_target_copy, t);
1902*38fd1498Szrj 	    t = unshare_expr (gimple_omp_target_data_arg (omp_target_stmt));
1903*38fd1498Szrj 	    gimple_omp_target_set_data_arg (omp_target_copy, t);
1904*38fd1498Szrj 	  }
1905*38fd1498Szrj 	  goto copy_omp_body;
1906*38fd1498Szrj 
1907*38fd1498Szrj 	case GIMPLE_OMP_TEAMS:
1908*38fd1498Szrj 	  {
1909*38fd1498Szrj 	    gomp_teams *omp_teams_copy = as_a <gomp_teams *> (copy);
1910*38fd1498Szrj 	    t = unshare_expr (gimple_omp_teams_clauses (stmt));
1911*38fd1498Szrj 	    gimple_omp_teams_set_clauses (omp_teams_copy, t);
1912*38fd1498Szrj 	  }
1913*38fd1498Szrj 	  /* FALLTHRU  */
1914*38fd1498Szrj 
1915*38fd1498Szrj 	case GIMPLE_OMP_SECTION:
1916*38fd1498Szrj 	case GIMPLE_OMP_MASTER:
1917*38fd1498Szrj 	case GIMPLE_OMP_TASKGROUP:
1918*38fd1498Szrj 	case GIMPLE_OMP_GRID_BODY:
1919*38fd1498Szrj 	copy_omp_body:
1920*38fd1498Szrj 	  new_seq = gimple_seq_copy (gimple_omp_body (stmt));
1921*38fd1498Szrj 	  gimple_omp_set_body (copy, new_seq);
1922*38fd1498Szrj 	  break;
1923*38fd1498Szrj 
1924*38fd1498Szrj 	case GIMPLE_TRANSACTION:
1925*38fd1498Szrj 	  new_seq = gimple_seq_copy (gimple_transaction_body (
1926*38fd1498Szrj 				       as_a <gtransaction *> (stmt)));
1927*38fd1498Szrj 	  gimple_transaction_set_body (as_a <gtransaction *> (copy),
1928*38fd1498Szrj 				       new_seq);
1929*38fd1498Szrj 	  break;
1930*38fd1498Szrj 
1931*38fd1498Szrj 	case GIMPLE_WITH_CLEANUP_EXPR:
1932*38fd1498Szrj 	  new_seq = gimple_seq_copy (gimple_wce_cleanup (stmt));
1933*38fd1498Szrj 	  gimple_wce_set_cleanup (copy, new_seq);
1934*38fd1498Szrj 	  break;
1935*38fd1498Szrj 
1936*38fd1498Szrj 	default:
1937*38fd1498Szrj 	  gcc_unreachable ();
1938*38fd1498Szrj 	}
1939*38fd1498Szrj     }
1940*38fd1498Szrj 
1941*38fd1498Szrj   /* Make copy of operands.  */
1942*38fd1498Szrj   for (i = 0; i < num_ops; i++)
1943*38fd1498Szrj     gimple_set_op (copy, i, unshare_expr (gimple_op (stmt, i)));
1944*38fd1498Szrj 
1945*38fd1498Szrj   if (gimple_has_mem_ops (stmt))
1946*38fd1498Szrj     {
1947*38fd1498Szrj       gimple_set_vdef (copy, gimple_vdef (stmt));
1948*38fd1498Szrj       gimple_set_vuse (copy, gimple_vuse (stmt));
1949*38fd1498Szrj     }
1950*38fd1498Szrj 
1951*38fd1498Szrj   /* Clear out SSA operand vectors on COPY.  */
1952*38fd1498Szrj   if (gimple_has_ops (stmt))
1953*38fd1498Szrj     {
1954*38fd1498Szrj       gimple_set_use_ops (copy, NULL);
1955*38fd1498Szrj 
1956*38fd1498Szrj       /* SSA operands need to be updated.  */
1957*38fd1498Szrj       gimple_set_modified (copy, true);
1958*38fd1498Szrj     }
1959*38fd1498Szrj 
1960*38fd1498Szrj   if (gimple_debug_nonbind_marker_p (stmt))
1961*38fd1498Szrj     cfun->debug_marker_count++;
1962*38fd1498Szrj 
1963*38fd1498Szrj   return copy;
1964*38fd1498Szrj }
1965*38fd1498Szrj 
1966*38fd1498Szrj 
1967*38fd1498Szrj /* Return true if statement S has side-effects.  We consider a
1968*38fd1498Szrj    statement to have side effects if:
1969*38fd1498Szrj 
1970*38fd1498Szrj    - It is a GIMPLE_CALL not marked with ECF_PURE or ECF_CONST.
1971*38fd1498Szrj    - Any of its operands are marked TREE_THIS_VOLATILE or TREE_SIDE_EFFECTS.  */
1972*38fd1498Szrj 
1973*38fd1498Szrj bool
gimple_has_side_effects(const gimple * s)1974*38fd1498Szrj gimple_has_side_effects (const gimple *s)
1975*38fd1498Szrj {
1976*38fd1498Szrj   if (is_gimple_debug (s))
1977*38fd1498Szrj     return false;
1978*38fd1498Szrj 
1979*38fd1498Szrj   /* We don't have to scan the arguments to check for
1980*38fd1498Szrj      volatile arguments, though, at present, we still
1981*38fd1498Szrj      do a scan to check for TREE_SIDE_EFFECTS.  */
1982*38fd1498Szrj   if (gimple_has_volatile_ops (s))
1983*38fd1498Szrj     return true;
1984*38fd1498Szrj 
1985*38fd1498Szrj   if (gimple_code (s) == GIMPLE_ASM
1986*38fd1498Szrj       && gimple_asm_volatile_p (as_a <const gasm *> (s)))
1987*38fd1498Szrj     return true;
1988*38fd1498Szrj 
1989*38fd1498Szrj   if (is_gimple_call (s))
1990*38fd1498Szrj     {
1991*38fd1498Szrj       int flags = gimple_call_flags (s);
1992*38fd1498Szrj 
1993*38fd1498Szrj       /* An infinite loop is considered a side effect.  */
1994*38fd1498Szrj       if (!(flags & (ECF_CONST | ECF_PURE))
1995*38fd1498Szrj 	  || (flags & ECF_LOOPING_CONST_OR_PURE))
1996*38fd1498Szrj 	return true;
1997*38fd1498Szrj 
1998*38fd1498Szrj       return false;
1999*38fd1498Szrj     }
2000*38fd1498Szrj 
2001*38fd1498Szrj   return false;
2002*38fd1498Szrj }
2003*38fd1498Szrj 
2004*38fd1498Szrj /* Helper for gimple_could_trap_p and gimple_assign_rhs_could_trap_p.
2005*38fd1498Szrj    Return true if S can trap.  When INCLUDE_MEM is true, check whether
2006*38fd1498Szrj    the memory operations could trap.  When INCLUDE_STORES is true and
2007*38fd1498Szrj    S is a GIMPLE_ASSIGN, the LHS of the assignment is also checked.  */
2008*38fd1498Szrj 
2009*38fd1498Szrj bool
gimple_could_trap_p_1(gimple * s,bool include_mem,bool include_stores)2010*38fd1498Szrj gimple_could_trap_p_1 (gimple *s, bool include_mem, bool include_stores)
2011*38fd1498Szrj {
2012*38fd1498Szrj   tree t, div = NULL_TREE;
2013*38fd1498Szrj   enum tree_code op;
2014*38fd1498Szrj 
2015*38fd1498Szrj   if (include_mem)
2016*38fd1498Szrj     {
2017*38fd1498Szrj       unsigned i, start = (is_gimple_assign (s) && !include_stores) ? 1 : 0;
2018*38fd1498Szrj 
2019*38fd1498Szrj       for (i = start; i < gimple_num_ops (s); i++)
2020*38fd1498Szrj 	if (tree_could_trap_p (gimple_op (s, i)))
2021*38fd1498Szrj 	  return true;
2022*38fd1498Szrj     }
2023*38fd1498Szrj 
2024*38fd1498Szrj   switch (gimple_code (s))
2025*38fd1498Szrj     {
2026*38fd1498Szrj     case GIMPLE_ASM:
2027*38fd1498Szrj       return gimple_asm_volatile_p (as_a <gasm *> (s));
2028*38fd1498Szrj 
2029*38fd1498Szrj     case GIMPLE_CALL:
2030*38fd1498Szrj       t = gimple_call_fndecl (s);
2031*38fd1498Szrj       /* Assume that calls to weak functions may trap.  */
2032*38fd1498Szrj       if (!t || !DECL_P (t) || DECL_WEAK (t))
2033*38fd1498Szrj 	return true;
2034*38fd1498Szrj       return false;
2035*38fd1498Szrj 
2036*38fd1498Szrj     case GIMPLE_ASSIGN:
2037*38fd1498Szrj       t = gimple_expr_type (s);
2038*38fd1498Szrj       op = gimple_assign_rhs_code (s);
2039*38fd1498Szrj       if (get_gimple_rhs_class (op) == GIMPLE_BINARY_RHS)
2040*38fd1498Szrj 	div = gimple_assign_rhs2 (s);
2041*38fd1498Szrj       return (operation_could_trap_p (op, FLOAT_TYPE_P (t),
2042*38fd1498Szrj 				      (INTEGRAL_TYPE_P (t)
2043*38fd1498Szrj 				       && TYPE_OVERFLOW_TRAPS (t)),
2044*38fd1498Szrj 				      div));
2045*38fd1498Szrj 
2046*38fd1498Szrj     case GIMPLE_COND:
2047*38fd1498Szrj       t = TREE_TYPE (gimple_cond_lhs (s));
2048*38fd1498Szrj       return operation_could_trap_p (gimple_cond_code (s),
2049*38fd1498Szrj 				     FLOAT_TYPE_P (t), false, NULL_TREE);
2050*38fd1498Szrj 
2051*38fd1498Szrj     default:
2052*38fd1498Szrj       break;
2053*38fd1498Szrj     }
2054*38fd1498Szrj 
2055*38fd1498Szrj   return false;
2056*38fd1498Szrj }
2057*38fd1498Szrj 
2058*38fd1498Szrj /* Return true if statement S can trap.  */
2059*38fd1498Szrj 
2060*38fd1498Szrj bool
gimple_could_trap_p(gimple * s)2061*38fd1498Szrj gimple_could_trap_p (gimple *s)
2062*38fd1498Szrj {
2063*38fd1498Szrj   return gimple_could_trap_p_1 (s, true, true);
2064*38fd1498Szrj }
2065*38fd1498Szrj 
2066*38fd1498Szrj /* Return true if RHS of a GIMPLE_ASSIGN S can trap.  */
2067*38fd1498Szrj 
2068*38fd1498Szrj bool
gimple_assign_rhs_could_trap_p(gimple * s)2069*38fd1498Szrj gimple_assign_rhs_could_trap_p (gimple *s)
2070*38fd1498Szrj {
2071*38fd1498Szrj   gcc_assert (is_gimple_assign (s));
2072*38fd1498Szrj   return gimple_could_trap_p_1 (s, true, false);
2073*38fd1498Szrj }
2074*38fd1498Szrj 
2075*38fd1498Szrj 
2076*38fd1498Szrj /* Print debugging information for gimple stmts generated.  */
2077*38fd1498Szrj 
2078*38fd1498Szrj void
dump_gimple_statistics(void)2079*38fd1498Szrj dump_gimple_statistics (void)
2080*38fd1498Szrj {
2081*38fd1498Szrj   int i;
2082*38fd1498Szrj   uint64_t total_tuples = 0, total_bytes = 0;
2083*38fd1498Szrj 
2084*38fd1498Szrj   if (! GATHER_STATISTICS)
2085*38fd1498Szrj     {
2086*38fd1498Szrj       fprintf (stderr, "No GIMPLE statistics\n");
2087*38fd1498Szrj       return;
2088*38fd1498Szrj     }
2089*38fd1498Szrj 
2090*38fd1498Szrj   fprintf (stderr, "\nGIMPLE statements\n");
2091*38fd1498Szrj   fprintf (stderr, "Kind                   Stmts      Bytes\n");
2092*38fd1498Szrj   fprintf (stderr, "---------------------------------------\n");
2093*38fd1498Szrj   for (i = 0; i < (int) gimple_alloc_kind_all; ++i)
2094*38fd1498Szrj     {
2095*38fd1498Szrj       fprintf (stderr, "%-20s %7" PRIu64 " %10" PRIu64 "\n",
2096*38fd1498Szrj 	       gimple_alloc_kind_names[i], gimple_alloc_counts[i],
2097*38fd1498Szrj 	       gimple_alloc_sizes[i]);
2098*38fd1498Szrj       total_tuples += gimple_alloc_counts[i];
2099*38fd1498Szrj       total_bytes += gimple_alloc_sizes[i];
2100*38fd1498Szrj     }
2101*38fd1498Szrj   fprintf (stderr, "---------------------------------------\n");
2102*38fd1498Szrj   fprintf (stderr, "%-20s %7" PRIu64 " %10" PRIu64 "\n", "Total",
2103*38fd1498Szrj 	   total_tuples, total_bytes);
2104*38fd1498Szrj   fprintf (stderr, "---------------------------------------\n");
2105*38fd1498Szrj }
2106*38fd1498Szrj 
2107*38fd1498Szrj 
2108*38fd1498Szrj /* Return the number of operands needed on the RHS of a GIMPLE
2109*38fd1498Szrj    assignment for an expression with tree code CODE.  */
2110*38fd1498Szrj 
2111*38fd1498Szrj unsigned
get_gimple_rhs_num_ops(enum tree_code code)2112*38fd1498Szrj get_gimple_rhs_num_ops (enum tree_code code)
2113*38fd1498Szrj {
2114*38fd1498Szrj   enum gimple_rhs_class rhs_class = get_gimple_rhs_class (code);
2115*38fd1498Szrj 
2116*38fd1498Szrj   if (rhs_class == GIMPLE_UNARY_RHS || rhs_class == GIMPLE_SINGLE_RHS)
2117*38fd1498Szrj     return 1;
2118*38fd1498Szrj   else if (rhs_class == GIMPLE_BINARY_RHS)
2119*38fd1498Szrj     return 2;
2120*38fd1498Szrj   else if (rhs_class == GIMPLE_TERNARY_RHS)
2121*38fd1498Szrj     return 3;
2122*38fd1498Szrj   else
2123*38fd1498Szrj     gcc_unreachable ();
2124*38fd1498Szrj }
2125*38fd1498Szrj 
2126*38fd1498Szrj #define DEFTREECODE(SYM, STRING, TYPE, NARGS)   			    \
2127*38fd1498Szrj   (unsigned char)							    \
2128*38fd1498Szrj   ((TYPE) == tcc_unary ? GIMPLE_UNARY_RHS				    \
2129*38fd1498Szrj    : ((TYPE) == tcc_binary						    \
2130*38fd1498Szrj       || (TYPE) == tcc_comparison) ? GIMPLE_BINARY_RHS   		    \
2131*38fd1498Szrj    : ((TYPE) == tcc_constant						    \
2132*38fd1498Szrj       || (TYPE) == tcc_declaration					    \
2133*38fd1498Szrj       || (TYPE) == tcc_reference) ? GIMPLE_SINGLE_RHS			    \
2134*38fd1498Szrj    : ((SYM) == TRUTH_AND_EXPR						    \
2135*38fd1498Szrj       || (SYM) == TRUTH_OR_EXPR						    \
2136*38fd1498Szrj       || (SYM) == TRUTH_XOR_EXPR) ? GIMPLE_BINARY_RHS			    \
2137*38fd1498Szrj    : (SYM) == TRUTH_NOT_EXPR ? GIMPLE_UNARY_RHS				    \
2138*38fd1498Szrj    : ((SYM) == COND_EXPR						    \
2139*38fd1498Szrj       || (SYM) == WIDEN_MULT_PLUS_EXPR					    \
2140*38fd1498Szrj       || (SYM) == WIDEN_MULT_MINUS_EXPR					    \
2141*38fd1498Szrj       || (SYM) == DOT_PROD_EXPR						    \
2142*38fd1498Szrj       || (SYM) == SAD_EXPR						    \
2143*38fd1498Szrj       || (SYM) == REALIGN_LOAD_EXPR					    \
2144*38fd1498Szrj       || (SYM) == VEC_COND_EXPR						    \
2145*38fd1498Szrj       || (SYM) == VEC_PERM_EXPR                                             \
2146*38fd1498Szrj       || (SYM) == BIT_INSERT_EXPR					    \
2147*38fd1498Szrj       || (SYM) == FMA_EXPR) ? GIMPLE_TERNARY_RHS			    \
2148*38fd1498Szrj    : ((SYM) == CONSTRUCTOR						    \
2149*38fd1498Szrj       || (SYM) == OBJ_TYPE_REF						    \
2150*38fd1498Szrj       || (SYM) == ASSERT_EXPR						    \
2151*38fd1498Szrj       || (SYM) == ADDR_EXPR						    \
2152*38fd1498Szrj       || (SYM) == WITH_SIZE_EXPR					    \
2153*38fd1498Szrj       || (SYM) == SSA_NAME) ? GIMPLE_SINGLE_RHS				    \
2154*38fd1498Szrj    : GIMPLE_INVALID_RHS),
2155*38fd1498Szrj #define END_OF_BASE_TREE_CODES (unsigned char) GIMPLE_INVALID_RHS,
2156*38fd1498Szrj 
2157*38fd1498Szrj const unsigned char gimple_rhs_class_table[] = {
2158*38fd1498Szrj #include "all-tree.def"
2159*38fd1498Szrj };
2160*38fd1498Szrj 
2161*38fd1498Szrj #undef DEFTREECODE
2162*38fd1498Szrj #undef END_OF_BASE_TREE_CODES
2163*38fd1498Szrj 
2164*38fd1498Szrj /* Canonicalize a tree T for use in a COND_EXPR as conditional.  Returns
2165*38fd1498Szrj    a canonicalized tree that is valid for a COND_EXPR or NULL_TREE, if
2166*38fd1498Szrj    we failed to create one.  */
2167*38fd1498Szrj 
2168*38fd1498Szrj tree
canonicalize_cond_expr_cond(tree t)2169*38fd1498Szrj canonicalize_cond_expr_cond (tree t)
2170*38fd1498Szrj {
2171*38fd1498Szrj   /* Strip conversions around boolean operations.  */
2172*38fd1498Szrj   if (CONVERT_EXPR_P (t)
2173*38fd1498Szrj       && (truth_value_p (TREE_CODE (TREE_OPERAND (t, 0)))
2174*38fd1498Szrj           || TREE_CODE (TREE_TYPE (TREE_OPERAND (t, 0)))
2175*38fd1498Szrj 	     == BOOLEAN_TYPE))
2176*38fd1498Szrj     t = TREE_OPERAND (t, 0);
2177*38fd1498Szrj 
2178*38fd1498Szrj   /* For !x use x == 0.  */
2179*38fd1498Szrj   if (TREE_CODE (t) == TRUTH_NOT_EXPR)
2180*38fd1498Szrj     {
2181*38fd1498Szrj       tree top0 = TREE_OPERAND (t, 0);
2182*38fd1498Szrj       t = build2 (EQ_EXPR, TREE_TYPE (t),
2183*38fd1498Szrj 		  top0, build_int_cst (TREE_TYPE (top0), 0));
2184*38fd1498Szrj     }
2185*38fd1498Szrj   /* For cmp ? 1 : 0 use cmp.  */
2186*38fd1498Szrj   else if (TREE_CODE (t) == COND_EXPR
2187*38fd1498Szrj 	   && COMPARISON_CLASS_P (TREE_OPERAND (t, 0))
2188*38fd1498Szrj 	   && integer_onep (TREE_OPERAND (t, 1))
2189*38fd1498Szrj 	   && integer_zerop (TREE_OPERAND (t, 2)))
2190*38fd1498Szrj     {
2191*38fd1498Szrj       tree top0 = TREE_OPERAND (t, 0);
2192*38fd1498Szrj       t = build2 (TREE_CODE (top0), TREE_TYPE (t),
2193*38fd1498Szrj 		  TREE_OPERAND (top0, 0), TREE_OPERAND (top0, 1));
2194*38fd1498Szrj     }
2195*38fd1498Szrj   /* For x ^ y use x != y.  */
2196*38fd1498Szrj   else if (TREE_CODE (t) == BIT_XOR_EXPR)
2197*38fd1498Szrj     t = build2 (NE_EXPR, TREE_TYPE (t),
2198*38fd1498Szrj 		TREE_OPERAND (t, 0), TREE_OPERAND (t, 1));
2199*38fd1498Szrj 
2200*38fd1498Szrj   if (is_gimple_condexpr (t))
2201*38fd1498Szrj     return t;
2202*38fd1498Szrj 
2203*38fd1498Szrj   return NULL_TREE;
2204*38fd1498Szrj }
2205*38fd1498Szrj 
2206*38fd1498Szrj /* Build a GIMPLE_CALL identical to STMT but skipping the arguments in
2207*38fd1498Szrj    the positions marked by the set ARGS_TO_SKIP.  */
2208*38fd1498Szrj 
2209*38fd1498Szrj gcall *
gimple_call_copy_skip_args(gcall * stmt,bitmap args_to_skip)2210*38fd1498Szrj gimple_call_copy_skip_args (gcall *stmt, bitmap args_to_skip)
2211*38fd1498Szrj {
2212*38fd1498Szrj   int i;
2213*38fd1498Szrj   int nargs = gimple_call_num_args (stmt);
2214*38fd1498Szrj   auto_vec<tree> vargs (nargs);
2215*38fd1498Szrj   gcall *new_stmt;
2216*38fd1498Szrj 
2217*38fd1498Szrj   for (i = 0; i < nargs; i++)
2218*38fd1498Szrj     if (!bitmap_bit_p (args_to_skip, i))
2219*38fd1498Szrj       vargs.quick_push (gimple_call_arg (stmt, i));
2220*38fd1498Szrj 
2221*38fd1498Szrj   if (gimple_call_internal_p (stmt))
2222*38fd1498Szrj     new_stmt = gimple_build_call_internal_vec (gimple_call_internal_fn (stmt),
2223*38fd1498Szrj 					       vargs);
2224*38fd1498Szrj   else
2225*38fd1498Szrj     new_stmt = gimple_build_call_vec (gimple_call_fn (stmt), vargs);
2226*38fd1498Szrj 
2227*38fd1498Szrj   if (gimple_call_lhs (stmt))
2228*38fd1498Szrj     gimple_call_set_lhs (new_stmt, gimple_call_lhs (stmt));
2229*38fd1498Szrj 
2230*38fd1498Szrj   gimple_set_vuse (new_stmt, gimple_vuse (stmt));
2231*38fd1498Szrj   gimple_set_vdef (new_stmt, gimple_vdef (stmt));
2232*38fd1498Szrj 
2233*38fd1498Szrj   if (gimple_has_location (stmt))
2234*38fd1498Szrj     gimple_set_location (new_stmt, gimple_location (stmt));
2235*38fd1498Szrj   gimple_call_copy_flags (new_stmt, stmt);
2236*38fd1498Szrj   gimple_call_set_chain (new_stmt, gimple_call_chain (stmt));
2237*38fd1498Szrj 
2238*38fd1498Szrj   gimple_set_modified (new_stmt, true);
2239*38fd1498Szrj 
2240*38fd1498Szrj   return new_stmt;
2241*38fd1498Szrj }
2242*38fd1498Szrj 
2243*38fd1498Szrj 
2244*38fd1498Szrj 
2245*38fd1498Szrj /* Return true if the field decls F1 and F2 are at the same offset.
2246*38fd1498Szrj 
2247*38fd1498Szrj    This is intended to be used on GIMPLE types only.  */
2248*38fd1498Szrj 
2249*38fd1498Szrj bool
gimple_compare_field_offset(tree f1,tree f2)2250*38fd1498Szrj gimple_compare_field_offset (tree f1, tree f2)
2251*38fd1498Szrj {
2252*38fd1498Szrj   if (DECL_OFFSET_ALIGN (f1) == DECL_OFFSET_ALIGN (f2))
2253*38fd1498Szrj     {
2254*38fd1498Szrj       tree offset1 = DECL_FIELD_OFFSET (f1);
2255*38fd1498Szrj       tree offset2 = DECL_FIELD_OFFSET (f2);
2256*38fd1498Szrj       return ((offset1 == offset2
2257*38fd1498Szrj 	       /* Once gimplification is done, self-referential offsets are
2258*38fd1498Szrj 		  instantiated as operand #2 of the COMPONENT_REF built for
2259*38fd1498Szrj 		  each access and reset.  Therefore, they are not relevant
2260*38fd1498Szrj 		  anymore and fields are interchangeable provided that they
2261*38fd1498Szrj 		  represent the same access.  */
2262*38fd1498Szrj 	       || (TREE_CODE (offset1) == PLACEHOLDER_EXPR
2263*38fd1498Szrj 		   && TREE_CODE (offset2) == PLACEHOLDER_EXPR
2264*38fd1498Szrj 		   && (DECL_SIZE (f1) == DECL_SIZE (f2)
2265*38fd1498Szrj 		       || (TREE_CODE (DECL_SIZE (f1)) == PLACEHOLDER_EXPR
2266*38fd1498Szrj 			   && TREE_CODE (DECL_SIZE (f2)) == PLACEHOLDER_EXPR)
2267*38fd1498Szrj 		       || operand_equal_p (DECL_SIZE (f1), DECL_SIZE (f2), 0))
2268*38fd1498Szrj 		   && DECL_ALIGN (f1) == DECL_ALIGN (f2))
2269*38fd1498Szrj 	       || operand_equal_p (offset1, offset2, 0))
2270*38fd1498Szrj 	      && tree_int_cst_equal (DECL_FIELD_BIT_OFFSET (f1),
2271*38fd1498Szrj 				     DECL_FIELD_BIT_OFFSET (f2)));
2272*38fd1498Szrj     }
2273*38fd1498Szrj 
2274*38fd1498Szrj   /* Fortran and C do not always agree on what DECL_OFFSET_ALIGN
2275*38fd1498Szrj      should be, so handle differing ones specially by decomposing
2276*38fd1498Szrj      the offset into a byte and bit offset manually.  */
2277*38fd1498Szrj   if (tree_fits_shwi_p (DECL_FIELD_OFFSET (f1))
2278*38fd1498Szrj       && tree_fits_shwi_p (DECL_FIELD_OFFSET (f2)))
2279*38fd1498Szrj     {
2280*38fd1498Szrj       unsigned HOST_WIDE_INT byte_offset1, byte_offset2;
2281*38fd1498Szrj       unsigned HOST_WIDE_INT bit_offset1, bit_offset2;
2282*38fd1498Szrj       bit_offset1 = TREE_INT_CST_LOW (DECL_FIELD_BIT_OFFSET (f1));
2283*38fd1498Szrj       byte_offset1 = (TREE_INT_CST_LOW (DECL_FIELD_OFFSET (f1))
2284*38fd1498Szrj 		      + bit_offset1 / BITS_PER_UNIT);
2285*38fd1498Szrj       bit_offset2 = TREE_INT_CST_LOW (DECL_FIELD_BIT_OFFSET (f2));
2286*38fd1498Szrj       byte_offset2 = (TREE_INT_CST_LOW (DECL_FIELD_OFFSET (f2))
2287*38fd1498Szrj 		      + bit_offset2 / BITS_PER_UNIT);
2288*38fd1498Szrj       if (byte_offset1 != byte_offset2)
2289*38fd1498Szrj 	return false;
2290*38fd1498Szrj       return bit_offset1 % BITS_PER_UNIT == bit_offset2 % BITS_PER_UNIT;
2291*38fd1498Szrj     }
2292*38fd1498Szrj 
2293*38fd1498Szrj   return false;
2294*38fd1498Szrj }
2295*38fd1498Szrj 
2296*38fd1498Szrj 
2297*38fd1498Szrj /* Return a type the same as TYPE except unsigned or
2298*38fd1498Szrj    signed according to UNSIGNEDP.  */
2299*38fd1498Szrj 
2300*38fd1498Szrj static tree
gimple_signed_or_unsigned_type(bool unsignedp,tree type)2301*38fd1498Szrj gimple_signed_or_unsigned_type (bool unsignedp, tree type)
2302*38fd1498Szrj {
2303*38fd1498Szrj   tree type1;
2304*38fd1498Szrj   int i;
2305*38fd1498Szrj 
2306*38fd1498Szrj   type1 = TYPE_MAIN_VARIANT (type);
2307*38fd1498Szrj   if (type1 == signed_char_type_node
2308*38fd1498Szrj       || type1 == char_type_node
2309*38fd1498Szrj       || type1 == unsigned_char_type_node)
2310*38fd1498Szrj     return unsignedp ? unsigned_char_type_node : signed_char_type_node;
2311*38fd1498Szrj   if (type1 == integer_type_node || type1 == unsigned_type_node)
2312*38fd1498Szrj     return unsignedp ? unsigned_type_node : integer_type_node;
2313*38fd1498Szrj   if (type1 == short_integer_type_node || type1 == short_unsigned_type_node)
2314*38fd1498Szrj     return unsignedp ? short_unsigned_type_node : short_integer_type_node;
2315*38fd1498Szrj   if (type1 == long_integer_type_node || type1 == long_unsigned_type_node)
2316*38fd1498Szrj     return unsignedp ? long_unsigned_type_node : long_integer_type_node;
2317*38fd1498Szrj   if (type1 == long_long_integer_type_node
2318*38fd1498Szrj       || type1 == long_long_unsigned_type_node)
2319*38fd1498Szrj     return unsignedp
2320*38fd1498Szrj            ? long_long_unsigned_type_node
2321*38fd1498Szrj 	   : long_long_integer_type_node;
2322*38fd1498Szrj 
2323*38fd1498Szrj   for (i = 0; i < NUM_INT_N_ENTS; i ++)
2324*38fd1498Szrj     if (int_n_enabled_p[i]
2325*38fd1498Szrj 	&& (type1 == int_n_trees[i].unsigned_type
2326*38fd1498Szrj 	    || type1 == int_n_trees[i].signed_type))
2327*38fd1498Szrj 	return unsignedp
2328*38fd1498Szrj 	  ? int_n_trees[i].unsigned_type
2329*38fd1498Szrj 	  : int_n_trees[i].signed_type;
2330*38fd1498Szrj 
2331*38fd1498Szrj #if HOST_BITS_PER_WIDE_INT >= 64
2332*38fd1498Szrj   if (type1 == intTI_type_node || type1 == unsigned_intTI_type_node)
2333*38fd1498Szrj     return unsignedp ? unsigned_intTI_type_node : intTI_type_node;
2334*38fd1498Szrj #endif
2335*38fd1498Szrj   if (type1 == intDI_type_node || type1 == unsigned_intDI_type_node)
2336*38fd1498Szrj     return unsignedp ? unsigned_intDI_type_node : intDI_type_node;
2337*38fd1498Szrj   if (type1 == intSI_type_node || type1 == unsigned_intSI_type_node)
2338*38fd1498Szrj     return unsignedp ? unsigned_intSI_type_node : intSI_type_node;
2339*38fd1498Szrj   if (type1 == intHI_type_node || type1 == unsigned_intHI_type_node)
2340*38fd1498Szrj     return unsignedp ? unsigned_intHI_type_node : intHI_type_node;
2341*38fd1498Szrj   if (type1 == intQI_type_node || type1 == unsigned_intQI_type_node)
2342*38fd1498Szrj     return unsignedp ? unsigned_intQI_type_node : intQI_type_node;
2343*38fd1498Szrj 
2344*38fd1498Szrj #define GIMPLE_FIXED_TYPES(NAME)	    \
2345*38fd1498Szrj   if (type1 == short_ ## NAME ## _type_node \
2346*38fd1498Szrj       || type1 == unsigned_short_ ## NAME ## _type_node) \
2347*38fd1498Szrj     return unsignedp ? unsigned_short_ ## NAME ## _type_node \
2348*38fd1498Szrj 		     : short_ ## NAME ## _type_node; \
2349*38fd1498Szrj   if (type1 == NAME ## _type_node \
2350*38fd1498Szrj       || type1 == unsigned_ ## NAME ## _type_node) \
2351*38fd1498Szrj     return unsignedp ? unsigned_ ## NAME ## _type_node \
2352*38fd1498Szrj 		     : NAME ## _type_node; \
2353*38fd1498Szrj   if (type1 == long_ ## NAME ## _type_node \
2354*38fd1498Szrj       || type1 == unsigned_long_ ## NAME ## _type_node) \
2355*38fd1498Szrj     return unsignedp ? unsigned_long_ ## NAME ## _type_node \
2356*38fd1498Szrj 		     : long_ ## NAME ## _type_node; \
2357*38fd1498Szrj   if (type1 == long_long_ ## NAME ## _type_node \
2358*38fd1498Szrj       || type1 == unsigned_long_long_ ## NAME ## _type_node) \
2359*38fd1498Szrj     return unsignedp ? unsigned_long_long_ ## NAME ## _type_node \
2360*38fd1498Szrj 		     : long_long_ ## NAME ## _type_node;
2361*38fd1498Szrj 
2362*38fd1498Szrj #define GIMPLE_FIXED_MODE_TYPES(NAME) \
2363*38fd1498Szrj   if (type1 == NAME ## _type_node \
2364*38fd1498Szrj       || type1 == u ## NAME ## _type_node) \
2365*38fd1498Szrj     return unsignedp ? u ## NAME ## _type_node \
2366*38fd1498Szrj 		     : NAME ## _type_node;
2367*38fd1498Szrj 
2368*38fd1498Szrj #define GIMPLE_FIXED_TYPES_SAT(NAME) \
2369*38fd1498Szrj   if (type1 == sat_ ## short_ ## NAME ## _type_node \
2370*38fd1498Szrj       || type1 == sat_ ## unsigned_short_ ## NAME ## _type_node) \
2371*38fd1498Szrj     return unsignedp ? sat_ ## unsigned_short_ ## NAME ## _type_node \
2372*38fd1498Szrj 		     : sat_ ## short_ ## NAME ## _type_node; \
2373*38fd1498Szrj   if (type1 == sat_ ## NAME ## _type_node \
2374*38fd1498Szrj       || type1 == sat_ ## unsigned_ ## NAME ## _type_node) \
2375*38fd1498Szrj     return unsignedp ? sat_ ## unsigned_ ## NAME ## _type_node \
2376*38fd1498Szrj 		     : sat_ ## NAME ## _type_node; \
2377*38fd1498Szrj   if (type1 == sat_ ## long_ ## NAME ## _type_node \
2378*38fd1498Szrj       || type1 == sat_ ## unsigned_long_ ## NAME ## _type_node) \
2379*38fd1498Szrj     return unsignedp ? sat_ ## unsigned_long_ ## NAME ## _type_node \
2380*38fd1498Szrj 		     : sat_ ## long_ ## NAME ## _type_node; \
2381*38fd1498Szrj   if (type1 == sat_ ## long_long_ ## NAME ## _type_node \
2382*38fd1498Szrj       || type1 == sat_ ## unsigned_long_long_ ## NAME ## _type_node) \
2383*38fd1498Szrj     return unsignedp ? sat_ ## unsigned_long_long_ ## NAME ## _type_node \
2384*38fd1498Szrj 		     : sat_ ## long_long_ ## NAME ## _type_node;
2385*38fd1498Szrj 
2386*38fd1498Szrj #define GIMPLE_FIXED_MODE_TYPES_SAT(NAME)	\
2387*38fd1498Szrj   if (type1 == sat_ ## NAME ## _type_node \
2388*38fd1498Szrj       || type1 == sat_ ## u ## NAME ## _type_node) \
2389*38fd1498Szrj     return unsignedp ? sat_ ## u ## NAME ## _type_node \
2390*38fd1498Szrj 		     : sat_ ## NAME ## _type_node;
2391*38fd1498Szrj 
2392*38fd1498Szrj   GIMPLE_FIXED_TYPES (fract);
2393*38fd1498Szrj   GIMPLE_FIXED_TYPES_SAT (fract);
2394*38fd1498Szrj   GIMPLE_FIXED_TYPES (accum);
2395*38fd1498Szrj   GIMPLE_FIXED_TYPES_SAT (accum);
2396*38fd1498Szrj 
2397*38fd1498Szrj   GIMPLE_FIXED_MODE_TYPES (qq);
2398*38fd1498Szrj   GIMPLE_FIXED_MODE_TYPES (hq);
2399*38fd1498Szrj   GIMPLE_FIXED_MODE_TYPES (sq);
2400*38fd1498Szrj   GIMPLE_FIXED_MODE_TYPES (dq);
2401*38fd1498Szrj   GIMPLE_FIXED_MODE_TYPES (tq);
2402*38fd1498Szrj   GIMPLE_FIXED_MODE_TYPES_SAT (qq);
2403*38fd1498Szrj   GIMPLE_FIXED_MODE_TYPES_SAT (hq);
2404*38fd1498Szrj   GIMPLE_FIXED_MODE_TYPES_SAT (sq);
2405*38fd1498Szrj   GIMPLE_FIXED_MODE_TYPES_SAT (dq);
2406*38fd1498Szrj   GIMPLE_FIXED_MODE_TYPES_SAT (tq);
2407*38fd1498Szrj   GIMPLE_FIXED_MODE_TYPES (ha);
2408*38fd1498Szrj   GIMPLE_FIXED_MODE_TYPES (sa);
2409*38fd1498Szrj   GIMPLE_FIXED_MODE_TYPES (da);
2410*38fd1498Szrj   GIMPLE_FIXED_MODE_TYPES (ta);
2411*38fd1498Szrj   GIMPLE_FIXED_MODE_TYPES_SAT (ha);
2412*38fd1498Szrj   GIMPLE_FIXED_MODE_TYPES_SAT (sa);
2413*38fd1498Szrj   GIMPLE_FIXED_MODE_TYPES_SAT (da);
2414*38fd1498Szrj   GIMPLE_FIXED_MODE_TYPES_SAT (ta);
2415*38fd1498Szrj 
2416*38fd1498Szrj   /* For ENUMERAL_TYPEs in C++, must check the mode of the types, not
2417*38fd1498Szrj      the precision; they have precision set to match their range, but
2418*38fd1498Szrj      may use a wider mode to match an ABI.  If we change modes, we may
2419*38fd1498Szrj      wind up with bad conversions.  For INTEGER_TYPEs in C, must check
2420*38fd1498Szrj      the precision as well, so as to yield correct results for
2421*38fd1498Szrj      bit-field types.  C++ does not have these separate bit-field
2422*38fd1498Szrj      types, and producing a signed or unsigned variant of an
2423*38fd1498Szrj      ENUMERAL_TYPE may cause other problems as well.  */
2424*38fd1498Szrj   if (!INTEGRAL_TYPE_P (type)
2425*38fd1498Szrj       || TYPE_UNSIGNED (type) == unsignedp)
2426*38fd1498Szrj     return type;
2427*38fd1498Szrj 
2428*38fd1498Szrj #define TYPE_OK(node)							    \
2429*38fd1498Szrj   (TYPE_MODE (type) == TYPE_MODE (node)					    \
2430*38fd1498Szrj    && TYPE_PRECISION (type) == TYPE_PRECISION (node))
2431*38fd1498Szrj   if (TYPE_OK (signed_char_type_node))
2432*38fd1498Szrj     return unsignedp ? unsigned_char_type_node : signed_char_type_node;
2433*38fd1498Szrj   if (TYPE_OK (integer_type_node))
2434*38fd1498Szrj     return unsignedp ? unsigned_type_node : integer_type_node;
2435*38fd1498Szrj   if (TYPE_OK (short_integer_type_node))
2436*38fd1498Szrj     return unsignedp ? short_unsigned_type_node : short_integer_type_node;
2437*38fd1498Szrj   if (TYPE_OK (long_integer_type_node))
2438*38fd1498Szrj     return unsignedp ? long_unsigned_type_node : long_integer_type_node;
2439*38fd1498Szrj   if (TYPE_OK (long_long_integer_type_node))
2440*38fd1498Szrj     return (unsignedp
2441*38fd1498Szrj 	    ? long_long_unsigned_type_node
2442*38fd1498Szrj 	    : long_long_integer_type_node);
2443*38fd1498Szrj 
2444*38fd1498Szrj   for (i = 0; i < NUM_INT_N_ENTS; i ++)
2445*38fd1498Szrj     if (int_n_enabled_p[i]
2446*38fd1498Szrj 	&& TYPE_MODE (type) == int_n_data[i].m
2447*38fd1498Szrj 	&& TYPE_PRECISION (type) == int_n_data[i].bitsize)
2448*38fd1498Szrj 	return unsignedp
2449*38fd1498Szrj 	  ? int_n_trees[i].unsigned_type
2450*38fd1498Szrj 	  : int_n_trees[i].signed_type;
2451*38fd1498Szrj 
2452*38fd1498Szrj #if HOST_BITS_PER_WIDE_INT >= 64
2453*38fd1498Szrj   if (TYPE_OK (intTI_type_node))
2454*38fd1498Szrj     return unsignedp ? unsigned_intTI_type_node : intTI_type_node;
2455*38fd1498Szrj #endif
2456*38fd1498Szrj   if (TYPE_OK (intDI_type_node))
2457*38fd1498Szrj     return unsignedp ? unsigned_intDI_type_node : intDI_type_node;
2458*38fd1498Szrj   if (TYPE_OK (intSI_type_node))
2459*38fd1498Szrj     return unsignedp ? unsigned_intSI_type_node : intSI_type_node;
2460*38fd1498Szrj   if (TYPE_OK (intHI_type_node))
2461*38fd1498Szrj     return unsignedp ? unsigned_intHI_type_node : intHI_type_node;
2462*38fd1498Szrj   if (TYPE_OK (intQI_type_node))
2463*38fd1498Szrj     return unsignedp ? unsigned_intQI_type_node : intQI_type_node;
2464*38fd1498Szrj 
2465*38fd1498Szrj #undef GIMPLE_FIXED_TYPES
2466*38fd1498Szrj #undef GIMPLE_FIXED_MODE_TYPES
2467*38fd1498Szrj #undef GIMPLE_FIXED_TYPES_SAT
2468*38fd1498Szrj #undef GIMPLE_FIXED_MODE_TYPES_SAT
2469*38fd1498Szrj #undef TYPE_OK
2470*38fd1498Szrj 
2471*38fd1498Szrj   return build_nonstandard_integer_type (TYPE_PRECISION (type), unsignedp);
2472*38fd1498Szrj }
2473*38fd1498Szrj 
2474*38fd1498Szrj 
2475*38fd1498Szrj /* Return an unsigned type the same as TYPE in other respects.  */
2476*38fd1498Szrj 
2477*38fd1498Szrj tree
gimple_unsigned_type(tree type)2478*38fd1498Szrj gimple_unsigned_type (tree type)
2479*38fd1498Szrj {
2480*38fd1498Szrj   return gimple_signed_or_unsigned_type (true, type);
2481*38fd1498Szrj }
2482*38fd1498Szrj 
2483*38fd1498Szrj 
2484*38fd1498Szrj /* Return a signed type the same as TYPE in other respects.  */
2485*38fd1498Szrj 
2486*38fd1498Szrj tree
gimple_signed_type(tree type)2487*38fd1498Szrj gimple_signed_type (tree type)
2488*38fd1498Szrj {
2489*38fd1498Szrj   return gimple_signed_or_unsigned_type (false, type);
2490*38fd1498Szrj }
2491*38fd1498Szrj 
2492*38fd1498Szrj 
2493*38fd1498Szrj /* Return the typed-based alias set for T, which may be an expression
2494*38fd1498Szrj    or a type.  Return -1 if we don't do anything special.  */
2495*38fd1498Szrj 
2496*38fd1498Szrj alias_set_type
gimple_get_alias_set(tree t)2497*38fd1498Szrj gimple_get_alias_set (tree t)
2498*38fd1498Szrj {
2499*38fd1498Szrj   /* That's all the expressions we handle specially.  */
2500*38fd1498Szrj   if (!TYPE_P (t))
2501*38fd1498Szrj     return -1;
2502*38fd1498Szrj 
2503*38fd1498Szrj   /* For convenience, follow the C standard when dealing with
2504*38fd1498Szrj      character types.  Any object may be accessed via an lvalue that
2505*38fd1498Szrj      has character type.  */
2506*38fd1498Szrj   if (t == char_type_node
2507*38fd1498Szrj       || t == signed_char_type_node
2508*38fd1498Szrj       || t == unsigned_char_type_node)
2509*38fd1498Szrj     return 0;
2510*38fd1498Szrj 
2511*38fd1498Szrj   /* Allow aliasing between signed and unsigned variants of the same
2512*38fd1498Szrj      type.  We treat the signed variant as canonical.  */
2513*38fd1498Szrj   if (TREE_CODE (t) == INTEGER_TYPE && TYPE_UNSIGNED (t))
2514*38fd1498Szrj     {
2515*38fd1498Szrj       tree t1 = gimple_signed_type (t);
2516*38fd1498Szrj 
2517*38fd1498Szrj       /* t1 == t can happen for boolean nodes which are always unsigned.  */
2518*38fd1498Szrj       if (t1 != t)
2519*38fd1498Szrj 	return get_alias_set (t1);
2520*38fd1498Szrj     }
2521*38fd1498Szrj 
2522*38fd1498Szrj   return -1;
2523*38fd1498Szrj }
2524*38fd1498Szrj 
2525*38fd1498Szrj 
2526*38fd1498Szrj /* Helper for gimple_ior_addresses_taken_1.  */
2527*38fd1498Szrj 
2528*38fd1498Szrj static bool
gimple_ior_addresses_taken_1(gimple *,tree addr,tree,void * data)2529*38fd1498Szrj gimple_ior_addresses_taken_1 (gimple *, tree addr, tree, void *data)
2530*38fd1498Szrj {
2531*38fd1498Szrj   bitmap addresses_taken = (bitmap)data;
2532*38fd1498Szrj   addr = get_base_address (addr);
2533*38fd1498Szrj   if (addr
2534*38fd1498Szrj       && DECL_P (addr))
2535*38fd1498Szrj     {
2536*38fd1498Szrj       bitmap_set_bit (addresses_taken, DECL_UID (addr));
2537*38fd1498Szrj       return true;
2538*38fd1498Szrj     }
2539*38fd1498Szrj   return false;
2540*38fd1498Szrj }
2541*38fd1498Szrj 
2542*38fd1498Szrj /* Set the bit for the uid of all decls that have their address taken
2543*38fd1498Szrj    in STMT in the ADDRESSES_TAKEN bitmap.  Returns true if there
2544*38fd1498Szrj    were any in this stmt.  */
2545*38fd1498Szrj 
2546*38fd1498Szrj bool
gimple_ior_addresses_taken(bitmap addresses_taken,gimple * stmt)2547*38fd1498Szrj gimple_ior_addresses_taken (bitmap addresses_taken, gimple *stmt)
2548*38fd1498Szrj {
2549*38fd1498Szrj   return walk_stmt_load_store_addr_ops (stmt, addresses_taken, NULL, NULL,
2550*38fd1498Szrj 					gimple_ior_addresses_taken_1);
2551*38fd1498Szrj }
2552*38fd1498Szrj 
2553*38fd1498Szrj 
2554*38fd1498Szrj /* Return true when STMTs arguments and return value match those of FNDECL,
2555*38fd1498Szrj    a decl of a builtin function.  */
2556*38fd1498Szrj 
2557*38fd1498Szrj bool
gimple_builtin_call_types_compatible_p(const gimple * stmt,tree fndecl)2558*38fd1498Szrj gimple_builtin_call_types_compatible_p (const gimple *stmt, tree fndecl)
2559*38fd1498Szrj {
2560*38fd1498Szrj   gcc_checking_assert (DECL_BUILT_IN_CLASS (fndecl) != NOT_BUILT_IN);
2561*38fd1498Szrj 
2562*38fd1498Szrj   tree ret = gimple_call_lhs (stmt);
2563*38fd1498Szrj   if (ret
2564*38fd1498Szrj       && !useless_type_conversion_p (TREE_TYPE (ret),
2565*38fd1498Szrj 				     TREE_TYPE (TREE_TYPE (fndecl))))
2566*38fd1498Szrj     return false;
2567*38fd1498Szrj 
2568*38fd1498Szrj   tree targs = TYPE_ARG_TYPES (TREE_TYPE (fndecl));
2569*38fd1498Szrj   unsigned nargs = gimple_call_num_args (stmt);
2570*38fd1498Szrj   for (unsigned i = 0; i < nargs; ++i)
2571*38fd1498Szrj     {
2572*38fd1498Szrj       /* Variadic args follow.  */
2573*38fd1498Szrj       if (!targs)
2574*38fd1498Szrj 	return true;
2575*38fd1498Szrj       tree arg = gimple_call_arg (stmt, i);
2576*38fd1498Szrj       tree type = TREE_VALUE (targs);
2577*38fd1498Szrj       if (!useless_type_conversion_p (type, TREE_TYPE (arg))
2578*38fd1498Szrj 	  /* char/short integral arguments are promoted to int
2579*38fd1498Szrj 	     by several frontends if targetm.calls.promote_prototypes
2580*38fd1498Szrj 	     is true.  Allow such promotion too.  */
2581*38fd1498Szrj 	  && !(INTEGRAL_TYPE_P (type)
2582*38fd1498Szrj 	       && TYPE_PRECISION (type) < TYPE_PRECISION (integer_type_node)
2583*38fd1498Szrj 	       && targetm.calls.promote_prototypes (TREE_TYPE (fndecl))
2584*38fd1498Szrj 	       && useless_type_conversion_p (integer_type_node,
2585*38fd1498Szrj 					     TREE_TYPE (arg))))
2586*38fd1498Szrj 	return false;
2587*38fd1498Szrj       targs = TREE_CHAIN (targs);
2588*38fd1498Szrj     }
2589*38fd1498Szrj   if (targs && !VOID_TYPE_P (TREE_VALUE (targs)))
2590*38fd1498Szrj     return false;
2591*38fd1498Szrj   return true;
2592*38fd1498Szrj }
2593*38fd1498Szrj 
2594*38fd1498Szrj /* Return true when STMT is builtins call.  */
2595*38fd1498Szrj 
2596*38fd1498Szrj bool
gimple_call_builtin_p(const gimple * stmt)2597*38fd1498Szrj gimple_call_builtin_p (const gimple *stmt)
2598*38fd1498Szrj {
2599*38fd1498Szrj   tree fndecl;
2600*38fd1498Szrj   if (is_gimple_call (stmt)
2601*38fd1498Szrj       && (fndecl = gimple_call_fndecl (stmt)) != NULL_TREE
2602*38fd1498Szrj       && DECL_BUILT_IN_CLASS (fndecl) != NOT_BUILT_IN)
2603*38fd1498Szrj     return gimple_builtin_call_types_compatible_p (stmt, fndecl);
2604*38fd1498Szrj   return false;
2605*38fd1498Szrj }
2606*38fd1498Szrj 
2607*38fd1498Szrj /* Return true when STMT is builtins call to CLASS.  */
2608*38fd1498Szrj 
2609*38fd1498Szrj bool
gimple_call_builtin_p(const gimple * stmt,enum built_in_class klass)2610*38fd1498Szrj gimple_call_builtin_p (const gimple *stmt, enum built_in_class klass)
2611*38fd1498Szrj {
2612*38fd1498Szrj   tree fndecl;
2613*38fd1498Szrj   if (is_gimple_call (stmt)
2614*38fd1498Szrj       && (fndecl = gimple_call_fndecl (stmt)) != NULL_TREE
2615*38fd1498Szrj       && DECL_BUILT_IN_CLASS (fndecl) == klass)
2616*38fd1498Szrj     return gimple_builtin_call_types_compatible_p (stmt, fndecl);
2617*38fd1498Szrj   return false;
2618*38fd1498Szrj }
2619*38fd1498Szrj 
2620*38fd1498Szrj /* Return true when STMT is builtins call to CODE of CLASS.  */
2621*38fd1498Szrj 
2622*38fd1498Szrj bool
gimple_call_builtin_p(const gimple * stmt,enum built_in_function code)2623*38fd1498Szrj gimple_call_builtin_p (const gimple *stmt, enum built_in_function code)
2624*38fd1498Szrj {
2625*38fd1498Szrj   tree fndecl;
2626*38fd1498Szrj   if (is_gimple_call (stmt)
2627*38fd1498Szrj       && (fndecl = gimple_call_fndecl (stmt)) != NULL_TREE
2628*38fd1498Szrj       && DECL_BUILT_IN_CLASS (fndecl) == BUILT_IN_NORMAL
2629*38fd1498Szrj       && DECL_FUNCTION_CODE (fndecl) == code)
2630*38fd1498Szrj     return gimple_builtin_call_types_compatible_p (stmt, fndecl);
2631*38fd1498Szrj   return false;
2632*38fd1498Szrj }
2633*38fd1498Szrj 
2634*38fd1498Szrj /* If CALL is a call to a combined_fn (i.e. an internal function or
2635*38fd1498Szrj    a normal built-in function), return its code, otherwise return
2636*38fd1498Szrj    CFN_LAST.  */
2637*38fd1498Szrj 
2638*38fd1498Szrj combined_fn
gimple_call_combined_fn(const gimple * stmt)2639*38fd1498Szrj gimple_call_combined_fn (const gimple *stmt)
2640*38fd1498Szrj {
2641*38fd1498Szrj   if (const gcall *call = dyn_cast <const gcall *> (stmt))
2642*38fd1498Szrj     {
2643*38fd1498Szrj       if (gimple_call_internal_p (call))
2644*38fd1498Szrj 	return as_combined_fn (gimple_call_internal_fn (call));
2645*38fd1498Szrj 
2646*38fd1498Szrj       tree fndecl = gimple_call_fndecl (stmt);
2647*38fd1498Szrj       if (fndecl
2648*38fd1498Szrj 	  && DECL_BUILT_IN_CLASS (fndecl) == BUILT_IN_NORMAL
2649*38fd1498Szrj 	  && gimple_builtin_call_types_compatible_p (stmt, fndecl))
2650*38fd1498Szrj 	return as_combined_fn (DECL_FUNCTION_CODE (fndecl));
2651*38fd1498Szrj     }
2652*38fd1498Szrj   return CFN_LAST;
2653*38fd1498Szrj }
2654*38fd1498Szrj 
2655*38fd1498Szrj /* Return true if STMT clobbers memory.  STMT is required to be a
2656*38fd1498Szrj    GIMPLE_ASM.  */
2657*38fd1498Szrj 
2658*38fd1498Szrj bool
gimple_asm_clobbers_memory_p(const gasm * stmt)2659*38fd1498Szrj gimple_asm_clobbers_memory_p (const gasm *stmt)
2660*38fd1498Szrj {
2661*38fd1498Szrj   unsigned i;
2662*38fd1498Szrj 
2663*38fd1498Szrj   for (i = 0; i < gimple_asm_nclobbers (stmt); i++)
2664*38fd1498Szrj     {
2665*38fd1498Szrj       tree op = gimple_asm_clobber_op (stmt, i);
2666*38fd1498Szrj       if (strcmp (TREE_STRING_POINTER (TREE_VALUE (op)), "memory") == 0)
2667*38fd1498Szrj 	return true;
2668*38fd1498Szrj     }
2669*38fd1498Szrj 
2670*38fd1498Szrj   /* Non-empty basic ASM implicitly clobbers memory.  */
2671*38fd1498Szrj   if (gimple_asm_input_p (stmt) && strlen (gimple_asm_string (stmt)) != 0)
2672*38fd1498Szrj     return true;
2673*38fd1498Szrj 
2674*38fd1498Szrj   return false;
2675*38fd1498Szrj }
2676*38fd1498Szrj 
2677*38fd1498Szrj /* Dump bitmap SET (assumed to contain VAR_DECLs) to FILE.  */
2678*38fd1498Szrj 
2679*38fd1498Szrj void
dump_decl_set(FILE * file,bitmap set)2680*38fd1498Szrj dump_decl_set (FILE *file, bitmap set)
2681*38fd1498Szrj {
2682*38fd1498Szrj   if (set)
2683*38fd1498Szrj     {
2684*38fd1498Szrj       bitmap_iterator bi;
2685*38fd1498Szrj       unsigned i;
2686*38fd1498Szrj 
2687*38fd1498Szrj       fprintf (file, "{ ");
2688*38fd1498Szrj 
2689*38fd1498Szrj       EXECUTE_IF_SET_IN_BITMAP (set, 0, i, bi)
2690*38fd1498Szrj 	{
2691*38fd1498Szrj 	  fprintf (file, "D.%u", i);
2692*38fd1498Szrj 	  fprintf (file, " ");
2693*38fd1498Szrj 	}
2694*38fd1498Szrj 
2695*38fd1498Szrj       fprintf (file, "}");
2696*38fd1498Szrj     }
2697*38fd1498Szrj   else
2698*38fd1498Szrj     fprintf (file, "NIL");
2699*38fd1498Szrj }
2700*38fd1498Szrj 
2701*38fd1498Szrj /* Return true when CALL is a call stmt that definitely doesn't
2702*38fd1498Szrj    free any memory or makes it unavailable otherwise.  */
2703*38fd1498Szrj bool
nonfreeing_call_p(gimple * call)2704*38fd1498Szrj nonfreeing_call_p (gimple *call)
2705*38fd1498Szrj {
2706*38fd1498Szrj   if (gimple_call_builtin_p (call, BUILT_IN_NORMAL)
2707*38fd1498Szrj       && gimple_call_flags (call) & ECF_LEAF)
2708*38fd1498Szrj     switch (DECL_FUNCTION_CODE (gimple_call_fndecl (call)))
2709*38fd1498Szrj       {
2710*38fd1498Szrj 	/* Just in case these become ECF_LEAF in the future.  */
2711*38fd1498Szrj 	case BUILT_IN_FREE:
2712*38fd1498Szrj 	case BUILT_IN_TM_FREE:
2713*38fd1498Szrj 	case BUILT_IN_REALLOC:
2714*38fd1498Szrj 	case BUILT_IN_STACK_RESTORE:
2715*38fd1498Szrj 	  return false;
2716*38fd1498Szrj 	default:
2717*38fd1498Szrj 	  return true;
2718*38fd1498Szrj       }
2719*38fd1498Szrj   else if (gimple_call_internal_p (call))
2720*38fd1498Szrj     switch (gimple_call_internal_fn (call))
2721*38fd1498Szrj       {
2722*38fd1498Szrj       case IFN_ABNORMAL_DISPATCHER:
2723*38fd1498Szrj         return true;
2724*38fd1498Szrj       case IFN_ASAN_MARK:
2725*38fd1498Szrj 	return tree_to_uhwi (gimple_call_arg (call, 0)) == ASAN_MARK_UNPOISON;
2726*38fd1498Szrj       default:
2727*38fd1498Szrj 	if (gimple_call_flags (call) & ECF_LEAF)
2728*38fd1498Szrj 	  return true;
2729*38fd1498Szrj 	return false;
2730*38fd1498Szrj       }
2731*38fd1498Szrj 
2732*38fd1498Szrj   tree fndecl = gimple_call_fndecl (call);
2733*38fd1498Szrj   if (!fndecl)
2734*38fd1498Szrj     return false;
2735*38fd1498Szrj   struct cgraph_node *n = cgraph_node::get (fndecl);
2736*38fd1498Szrj   if (!n)
2737*38fd1498Szrj     return false;
2738*38fd1498Szrj   enum availability availability;
2739*38fd1498Szrj   n = n->function_symbol (&availability);
2740*38fd1498Szrj   if (!n || availability <= AVAIL_INTERPOSABLE)
2741*38fd1498Szrj     return false;
2742*38fd1498Szrj   return n->nonfreeing_fn;
2743*38fd1498Szrj }
2744*38fd1498Szrj 
2745*38fd1498Szrj /* Return true when CALL is a call stmt that definitely need not
2746*38fd1498Szrj    be considered to be a memory barrier.  */
2747*38fd1498Szrj bool
nonbarrier_call_p(gimple * call)2748*38fd1498Szrj nonbarrier_call_p (gimple *call)
2749*38fd1498Szrj {
2750*38fd1498Szrj   if (gimple_call_flags (call) & (ECF_PURE | ECF_CONST))
2751*38fd1498Szrj     return true;
2752*38fd1498Szrj   /* Should extend this to have a nonbarrier_fn flag, just as above in
2753*38fd1498Szrj      the nonfreeing case.  */
2754*38fd1498Szrj   return false;
2755*38fd1498Szrj }
2756*38fd1498Szrj 
2757*38fd1498Szrj /* Callback for walk_stmt_load_store_ops.
2758*38fd1498Szrj 
2759*38fd1498Szrj    Return TRUE if OP will dereference the tree stored in DATA, FALSE
2760*38fd1498Szrj    otherwise.
2761*38fd1498Szrj 
2762*38fd1498Szrj    This routine only makes a superficial check for a dereference.  Thus
2763*38fd1498Szrj    it must only be used if it is safe to return a false negative.  */
2764*38fd1498Szrj static bool
check_loadstore(gimple *,tree op,tree,void * data)2765*38fd1498Szrj check_loadstore (gimple *, tree op, tree, void *data)
2766*38fd1498Szrj {
2767*38fd1498Szrj   if (TREE_CODE (op) == MEM_REF || TREE_CODE (op) == TARGET_MEM_REF)
2768*38fd1498Szrj     {
2769*38fd1498Szrj       /* Some address spaces may legitimately dereference zero.  */
2770*38fd1498Szrj       addr_space_t as = TYPE_ADDR_SPACE (TREE_TYPE (op));
2771*38fd1498Szrj       if (targetm.addr_space.zero_address_valid (as))
2772*38fd1498Szrj 	return false;
2773*38fd1498Szrj 
2774*38fd1498Szrj       return operand_equal_p (TREE_OPERAND (op, 0), (tree)data, 0);
2775*38fd1498Szrj     }
2776*38fd1498Szrj   return false;
2777*38fd1498Szrj }
2778*38fd1498Szrj 
2779*38fd1498Szrj 
2780*38fd1498Szrj /* Return true if OP can be inferred to be non-NULL after STMT executes,
2781*38fd1498Szrj    either by using a pointer dereference or attributes.  */
2782*38fd1498Szrj bool
infer_nonnull_range(gimple * stmt,tree op)2783*38fd1498Szrj infer_nonnull_range (gimple *stmt, tree op)
2784*38fd1498Szrj {
2785*38fd1498Szrj   return infer_nonnull_range_by_dereference (stmt, op)
2786*38fd1498Szrj     || infer_nonnull_range_by_attribute (stmt, op);
2787*38fd1498Szrj }
2788*38fd1498Szrj 
2789*38fd1498Szrj /* Return true if OP can be inferred to be non-NULL after STMT
2790*38fd1498Szrj    executes by using a pointer dereference.  */
2791*38fd1498Szrj bool
infer_nonnull_range_by_dereference(gimple * stmt,tree op)2792*38fd1498Szrj infer_nonnull_range_by_dereference (gimple *stmt, tree op)
2793*38fd1498Szrj {
2794*38fd1498Szrj   /* We can only assume that a pointer dereference will yield
2795*38fd1498Szrj      non-NULL if -fdelete-null-pointer-checks is enabled.  */
2796*38fd1498Szrj   if (!flag_delete_null_pointer_checks
2797*38fd1498Szrj       || !POINTER_TYPE_P (TREE_TYPE (op))
2798*38fd1498Szrj       || gimple_code (stmt) == GIMPLE_ASM)
2799*38fd1498Szrj     return false;
2800*38fd1498Szrj 
2801*38fd1498Szrj   if (walk_stmt_load_store_ops (stmt, (void *)op,
2802*38fd1498Szrj 				check_loadstore, check_loadstore))
2803*38fd1498Szrj     return true;
2804*38fd1498Szrj 
2805*38fd1498Szrj   return false;
2806*38fd1498Szrj }
2807*38fd1498Szrj 
2808*38fd1498Szrj /* Return true if OP can be inferred to be a non-NULL after STMT
2809*38fd1498Szrj    executes by using attributes.  */
2810*38fd1498Szrj bool
infer_nonnull_range_by_attribute(gimple * stmt,tree op)2811*38fd1498Szrj infer_nonnull_range_by_attribute (gimple *stmt, tree op)
2812*38fd1498Szrj {
2813*38fd1498Szrj   /* We can only assume that a pointer dereference will yield
2814*38fd1498Szrj      non-NULL if -fdelete-null-pointer-checks is enabled.  */
2815*38fd1498Szrj   if (!flag_delete_null_pointer_checks
2816*38fd1498Szrj       || !POINTER_TYPE_P (TREE_TYPE (op))
2817*38fd1498Szrj       || gimple_code (stmt) == GIMPLE_ASM)
2818*38fd1498Szrj     return false;
2819*38fd1498Szrj 
2820*38fd1498Szrj   if (is_gimple_call (stmt) && !gimple_call_internal_p (stmt))
2821*38fd1498Szrj     {
2822*38fd1498Szrj       tree fntype = gimple_call_fntype (stmt);
2823*38fd1498Szrj       tree attrs = TYPE_ATTRIBUTES (fntype);
2824*38fd1498Szrj       for (; attrs; attrs = TREE_CHAIN (attrs))
2825*38fd1498Szrj 	{
2826*38fd1498Szrj 	  attrs = lookup_attribute ("nonnull", attrs);
2827*38fd1498Szrj 
2828*38fd1498Szrj 	  /* If "nonnull" wasn't specified, we know nothing about
2829*38fd1498Szrj 	     the argument.  */
2830*38fd1498Szrj 	  if (attrs == NULL_TREE)
2831*38fd1498Szrj 	    return false;
2832*38fd1498Szrj 
2833*38fd1498Szrj 	  /* If "nonnull" applies to all the arguments, then ARG
2834*38fd1498Szrj 	     is non-null if it's in the argument list.  */
2835*38fd1498Szrj 	  if (TREE_VALUE (attrs) == NULL_TREE)
2836*38fd1498Szrj 	    {
2837*38fd1498Szrj 	      for (unsigned int i = 0; i < gimple_call_num_args (stmt); i++)
2838*38fd1498Szrj 		{
2839*38fd1498Szrj 		  if (POINTER_TYPE_P (TREE_TYPE (gimple_call_arg (stmt, i)))
2840*38fd1498Szrj 		      && operand_equal_p (op, gimple_call_arg (stmt, i), 0))
2841*38fd1498Szrj 		    return true;
2842*38fd1498Szrj 		}
2843*38fd1498Szrj 	      return false;
2844*38fd1498Szrj 	    }
2845*38fd1498Szrj 
2846*38fd1498Szrj 	  /* Now see if op appears in the nonnull list.  */
2847*38fd1498Szrj 	  for (tree t = TREE_VALUE (attrs); t; t = TREE_CHAIN (t))
2848*38fd1498Szrj 	    {
2849*38fd1498Szrj 	      unsigned int idx = TREE_INT_CST_LOW (TREE_VALUE (t)) - 1;
2850*38fd1498Szrj 	      if (idx < gimple_call_num_args (stmt))
2851*38fd1498Szrj 		{
2852*38fd1498Szrj 		  tree arg = gimple_call_arg (stmt, idx);
2853*38fd1498Szrj 		  if (operand_equal_p (op, arg, 0))
2854*38fd1498Szrj 		    return true;
2855*38fd1498Szrj 		}
2856*38fd1498Szrj 	    }
2857*38fd1498Szrj 	}
2858*38fd1498Szrj     }
2859*38fd1498Szrj 
2860*38fd1498Szrj   /* If this function is marked as returning non-null, then we can
2861*38fd1498Szrj      infer OP is non-null if it is used in the return statement.  */
2862*38fd1498Szrj   if (greturn *return_stmt = dyn_cast <greturn *> (stmt))
2863*38fd1498Szrj     if (gimple_return_retval (return_stmt)
2864*38fd1498Szrj 	&& operand_equal_p (gimple_return_retval (return_stmt), op, 0)
2865*38fd1498Szrj 	&& lookup_attribute ("returns_nonnull",
2866*38fd1498Szrj 			     TYPE_ATTRIBUTES (TREE_TYPE (current_function_decl))))
2867*38fd1498Szrj       return true;
2868*38fd1498Szrj 
2869*38fd1498Szrj   return false;
2870*38fd1498Szrj }
2871*38fd1498Szrj 
2872*38fd1498Szrj /* Compare two case labels.  Because the front end should already have
2873*38fd1498Szrj    made sure that case ranges do not overlap, it is enough to only compare
2874*38fd1498Szrj    the CASE_LOW values of each case label.  */
2875*38fd1498Szrj 
2876*38fd1498Szrj static int
compare_case_labels(const void * p1,const void * p2)2877*38fd1498Szrj compare_case_labels (const void *p1, const void *p2)
2878*38fd1498Szrj {
2879*38fd1498Szrj   const_tree const case1 = *(const_tree const*)p1;
2880*38fd1498Szrj   const_tree const case2 = *(const_tree const*)p2;
2881*38fd1498Szrj 
2882*38fd1498Szrj   /* The 'default' case label always goes first.  */
2883*38fd1498Szrj   if (!CASE_LOW (case1))
2884*38fd1498Szrj     return -1;
2885*38fd1498Szrj   else if (!CASE_LOW (case2))
2886*38fd1498Szrj     return 1;
2887*38fd1498Szrj   else
2888*38fd1498Szrj     return tree_int_cst_compare (CASE_LOW (case1), CASE_LOW (case2));
2889*38fd1498Szrj }
2890*38fd1498Szrj 
2891*38fd1498Szrj /* Sort the case labels in LABEL_VEC in place in ascending order.  */
2892*38fd1498Szrj 
2893*38fd1498Szrj void
sort_case_labels(vec<tree> label_vec)2894*38fd1498Szrj sort_case_labels (vec<tree> label_vec)
2895*38fd1498Szrj {
2896*38fd1498Szrj   label_vec.qsort (compare_case_labels);
2897*38fd1498Szrj }
2898*38fd1498Szrj 
2899*38fd1498Szrj /* Prepare a vector of case labels to be used in a GIMPLE_SWITCH statement.
2900*38fd1498Szrj 
2901*38fd1498Szrj    LABELS is a vector that contains all case labels to look at.
2902*38fd1498Szrj 
2903*38fd1498Szrj    INDEX_TYPE is the type of the switch index expression.  Case labels
2904*38fd1498Szrj    in LABELS are discarded if their values are not in the value range
2905*38fd1498Szrj    covered by INDEX_TYPE.  The remaining case label values are folded
2906*38fd1498Szrj    to INDEX_TYPE.
2907*38fd1498Szrj 
2908*38fd1498Szrj    If a default case exists in LABELS, it is removed from LABELS and
2909*38fd1498Szrj    returned in DEFAULT_CASEP.  If no default case exists, but the
2910*38fd1498Szrj    case labels already cover the whole range of INDEX_TYPE, a default
2911*38fd1498Szrj    case is returned pointing to one of the existing case labels.
2912*38fd1498Szrj    Otherwise DEFAULT_CASEP is set to NULL_TREE.
2913*38fd1498Szrj 
2914*38fd1498Szrj    DEFAULT_CASEP may be NULL, in which case the above comment doesn't
2915*38fd1498Szrj    apply and no action is taken regardless of whether a default case is
2916*38fd1498Szrj    found or not.  */
2917*38fd1498Szrj 
2918*38fd1498Szrj void
preprocess_case_label_vec_for_gimple(vec<tree> labels,tree index_type,tree * default_casep)2919*38fd1498Szrj preprocess_case_label_vec_for_gimple (vec<tree> labels,
2920*38fd1498Szrj 				      tree index_type,
2921*38fd1498Szrj 				      tree *default_casep)
2922*38fd1498Szrj {
2923*38fd1498Szrj   tree min_value, max_value;
2924*38fd1498Szrj   tree default_case = NULL_TREE;
2925*38fd1498Szrj   size_t i, len;
2926*38fd1498Szrj 
2927*38fd1498Szrj   i = 0;
2928*38fd1498Szrj   min_value = TYPE_MIN_VALUE (index_type);
2929*38fd1498Szrj   max_value = TYPE_MAX_VALUE (index_type);
2930*38fd1498Szrj   while (i < labels.length ())
2931*38fd1498Szrj     {
2932*38fd1498Szrj       tree elt = labels[i];
2933*38fd1498Szrj       tree low = CASE_LOW (elt);
2934*38fd1498Szrj       tree high = CASE_HIGH (elt);
2935*38fd1498Szrj       bool remove_element = FALSE;
2936*38fd1498Szrj 
2937*38fd1498Szrj       if (low)
2938*38fd1498Szrj 	{
2939*38fd1498Szrj 	  gcc_checking_assert (TREE_CODE (low) == INTEGER_CST);
2940*38fd1498Szrj 	  gcc_checking_assert (!high || TREE_CODE (high) == INTEGER_CST);
2941*38fd1498Szrj 
2942*38fd1498Szrj 	  /* This is a non-default case label, i.e. it has a value.
2943*38fd1498Szrj 
2944*38fd1498Szrj 	     See if the case label is reachable within the range of
2945*38fd1498Szrj 	     the index type.  Remove out-of-range case values.  Turn
2946*38fd1498Szrj 	     case ranges into a canonical form (high > low strictly)
2947*38fd1498Szrj 	     and convert the case label values to the index type.
2948*38fd1498Szrj 
2949*38fd1498Szrj 	     NB: The type of gimple_switch_index() may be the promoted
2950*38fd1498Szrj 	     type, but the case labels retain the original type.  */
2951*38fd1498Szrj 
2952*38fd1498Szrj 	  if (high)
2953*38fd1498Szrj 	    {
2954*38fd1498Szrj 	      /* This is a case range.  Discard empty ranges.
2955*38fd1498Szrj 		 If the bounds or the range are equal, turn this
2956*38fd1498Szrj 		 into a simple (one-value) case.  */
2957*38fd1498Szrj 	      int cmp = tree_int_cst_compare (high, low);
2958*38fd1498Szrj 	      if (cmp < 0)
2959*38fd1498Szrj 		remove_element = TRUE;
2960*38fd1498Szrj 	      else if (cmp == 0)
2961*38fd1498Szrj 		high = NULL_TREE;
2962*38fd1498Szrj 	    }
2963*38fd1498Szrj 
2964*38fd1498Szrj 	  if (! high)
2965*38fd1498Szrj 	    {
2966*38fd1498Szrj 	      /* If the simple case value is unreachable, ignore it.  */
2967*38fd1498Szrj 	      if ((TREE_CODE (min_value) == INTEGER_CST
2968*38fd1498Szrj 		   && tree_int_cst_compare (low, min_value) < 0)
2969*38fd1498Szrj 		  || (TREE_CODE (max_value) == INTEGER_CST
2970*38fd1498Szrj 		      && tree_int_cst_compare (low, max_value) > 0))
2971*38fd1498Szrj 		remove_element = TRUE;
2972*38fd1498Szrj 	      else
2973*38fd1498Szrj 		low = fold_convert (index_type, low);
2974*38fd1498Szrj 	    }
2975*38fd1498Szrj 	  else
2976*38fd1498Szrj 	    {
2977*38fd1498Szrj 	      /* If the entire case range is unreachable, ignore it.  */
2978*38fd1498Szrj 	      if ((TREE_CODE (min_value) == INTEGER_CST
2979*38fd1498Szrj 		   && tree_int_cst_compare (high, min_value) < 0)
2980*38fd1498Szrj 		  || (TREE_CODE (max_value) == INTEGER_CST
2981*38fd1498Szrj 		      && tree_int_cst_compare (low, max_value) > 0))
2982*38fd1498Szrj 		remove_element = TRUE;
2983*38fd1498Szrj 	      else
2984*38fd1498Szrj 		{
2985*38fd1498Szrj 		  /* If the lower bound is less than the index type's
2986*38fd1498Szrj 		     minimum value, truncate the range bounds.  */
2987*38fd1498Szrj 		  if (TREE_CODE (min_value) == INTEGER_CST
2988*38fd1498Szrj 		      && tree_int_cst_compare (low, min_value) < 0)
2989*38fd1498Szrj 		    low = min_value;
2990*38fd1498Szrj 		  low = fold_convert (index_type, low);
2991*38fd1498Szrj 
2992*38fd1498Szrj 		  /* If the upper bound is greater than the index type's
2993*38fd1498Szrj 		     maximum value, truncate the range bounds.  */
2994*38fd1498Szrj 		  if (TREE_CODE (max_value) == INTEGER_CST
2995*38fd1498Szrj 		      && tree_int_cst_compare (high, max_value) > 0)
2996*38fd1498Szrj 		    high = max_value;
2997*38fd1498Szrj 		  high = fold_convert (index_type, high);
2998*38fd1498Szrj 
2999*38fd1498Szrj 		  /* We may have folded a case range to a one-value case.  */
3000*38fd1498Szrj 		  if (tree_int_cst_equal (low, high))
3001*38fd1498Szrj 		    high = NULL_TREE;
3002*38fd1498Szrj 		}
3003*38fd1498Szrj 	    }
3004*38fd1498Szrj 
3005*38fd1498Szrj 	  CASE_LOW (elt) = low;
3006*38fd1498Szrj 	  CASE_HIGH (elt) = high;
3007*38fd1498Szrj 	}
3008*38fd1498Szrj       else
3009*38fd1498Szrj 	{
3010*38fd1498Szrj 	  gcc_assert (!default_case);
3011*38fd1498Szrj 	  default_case = elt;
3012*38fd1498Szrj 	  /* The default case must be passed separately to the
3013*38fd1498Szrj 	     gimple_build_switch routine.  But if DEFAULT_CASEP
3014*38fd1498Szrj 	     is NULL, we do not remove the default case (it would
3015*38fd1498Szrj 	     be completely lost).  */
3016*38fd1498Szrj 	  if (default_casep)
3017*38fd1498Szrj 	    remove_element = TRUE;
3018*38fd1498Szrj 	}
3019*38fd1498Szrj 
3020*38fd1498Szrj       if (remove_element)
3021*38fd1498Szrj 	labels.ordered_remove (i);
3022*38fd1498Szrj       else
3023*38fd1498Szrj 	i++;
3024*38fd1498Szrj     }
3025*38fd1498Szrj   len = i;
3026*38fd1498Szrj 
3027*38fd1498Szrj   if (!labels.is_empty ())
3028*38fd1498Szrj     sort_case_labels (labels);
3029*38fd1498Szrj 
3030*38fd1498Szrj   if (default_casep && !default_case)
3031*38fd1498Szrj     {
3032*38fd1498Szrj       /* If the switch has no default label, add one, so that we jump
3033*38fd1498Szrj 	 around the switch body.  If the labels already cover the whole
3034*38fd1498Szrj 	 range of the switch index_type, add the default label pointing
3035*38fd1498Szrj 	 to one of the existing labels.  */
3036*38fd1498Szrj       if (len
3037*38fd1498Szrj 	  && TYPE_MIN_VALUE (index_type)
3038*38fd1498Szrj 	  && TYPE_MAX_VALUE (index_type)
3039*38fd1498Szrj 	  && tree_int_cst_equal (CASE_LOW (labels[0]),
3040*38fd1498Szrj 				 TYPE_MIN_VALUE (index_type)))
3041*38fd1498Szrj 	{
3042*38fd1498Szrj 	  tree low, high = CASE_HIGH (labels[len - 1]);
3043*38fd1498Szrj 	  if (!high)
3044*38fd1498Szrj 	    high = CASE_LOW (labels[len - 1]);
3045*38fd1498Szrj 	  if (tree_int_cst_equal (high, TYPE_MAX_VALUE (index_type)))
3046*38fd1498Szrj 	    {
3047*38fd1498Szrj 	      tree widest_label = labels[0];
3048*38fd1498Szrj 	      for (i = 1; i < len; i++)
3049*38fd1498Szrj 		{
3050*38fd1498Szrj 		  high = CASE_LOW (labels[i]);
3051*38fd1498Szrj 		  low = CASE_HIGH (labels[i - 1]);
3052*38fd1498Szrj 		  if (!low)
3053*38fd1498Szrj 		    low = CASE_LOW (labels[i - 1]);
3054*38fd1498Szrj 
3055*38fd1498Szrj 		  if (CASE_HIGH (labels[i]) != NULL_TREE
3056*38fd1498Szrj 		      && (CASE_HIGH (widest_label) == NULL_TREE
3057*38fd1498Szrj 			  || (wi::gtu_p
3058*38fd1498Szrj 			      (wi::to_wide (CASE_HIGH (labels[i]))
3059*38fd1498Szrj 			       - wi::to_wide (CASE_LOW (labels[i])),
3060*38fd1498Szrj 			       wi::to_wide (CASE_HIGH (widest_label))
3061*38fd1498Szrj 			       - wi::to_wide (CASE_LOW (widest_label))))))
3062*38fd1498Szrj 		    widest_label = labels[i];
3063*38fd1498Szrj 
3064*38fd1498Szrj 		  if (wi::to_wide (low) + 1 != wi::to_wide (high))
3065*38fd1498Szrj 		    break;
3066*38fd1498Szrj 		}
3067*38fd1498Szrj 	      if (i == len)
3068*38fd1498Szrj 		{
3069*38fd1498Szrj 		  /* Designate the label with the widest range to be the
3070*38fd1498Szrj 		     default label.  */
3071*38fd1498Szrj 		  tree label = CASE_LABEL (widest_label);
3072*38fd1498Szrj 		  default_case = build_case_label (NULL_TREE, NULL_TREE,
3073*38fd1498Szrj 						   label);
3074*38fd1498Szrj 		}
3075*38fd1498Szrj 	    }
3076*38fd1498Szrj 	}
3077*38fd1498Szrj     }
3078*38fd1498Szrj 
3079*38fd1498Szrj   if (default_casep)
3080*38fd1498Szrj     *default_casep = default_case;
3081*38fd1498Szrj }
3082*38fd1498Szrj 
3083*38fd1498Szrj /* Set the location of all statements in SEQ to LOC.  */
3084*38fd1498Szrj 
3085*38fd1498Szrj void
gimple_seq_set_location(gimple_seq seq,location_t loc)3086*38fd1498Szrj gimple_seq_set_location (gimple_seq seq, location_t loc)
3087*38fd1498Szrj {
3088*38fd1498Szrj   for (gimple_stmt_iterator i = gsi_start (seq); !gsi_end_p (i); gsi_next (&i))
3089*38fd1498Szrj     gimple_set_location (gsi_stmt (i), loc);
3090*38fd1498Szrj }
3091*38fd1498Szrj 
3092*38fd1498Szrj /* Release SSA_NAMEs in SEQ as well as the GIMPLE statements.  */
3093*38fd1498Szrj 
3094*38fd1498Szrj void
gimple_seq_discard(gimple_seq seq)3095*38fd1498Szrj gimple_seq_discard (gimple_seq seq)
3096*38fd1498Szrj {
3097*38fd1498Szrj   gimple_stmt_iterator gsi;
3098*38fd1498Szrj 
3099*38fd1498Szrj   for (gsi = gsi_start (seq); !gsi_end_p (gsi); )
3100*38fd1498Szrj     {
3101*38fd1498Szrj       gimple *stmt = gsi_stmt (gsi);
3102*38fd1498Szrj       gsi_remove (&gsi, true);
3103*38fd1498Szrj       release_defs (stmt);
3104*38fd1498Szrj       ggc_free (stmt);
3105*38fd1498Szrj     }
3106*38fd1498Szrj }
3107*38fd1498Szrj 
3108*38fd1498Szrj /* See if STMT now calls function that takes no parameters and if so, drop
3109*38fd1498Szrj    call arguments.  This is used when devirtualization machinery redirects
3110*38fd1498Szrj    to __builtin_unreachable or __cxa_pure_virtual.  */
3111*38fd1498Szrj 
3112*38fd1498Szrj void
maybe_remove_unused_call_args(struct function * fn,gimple * stmt)3113*38fd1498Szrj maybe_remove_unused_call_args (struct function *fn, gimple *stmt)
3114*38fd1498Szrj {
3115*38fd1498Szrj   tree decl = gimple_call_fndecl (stmt);
3116*38fd1498Szrj   if (TYPE_ARG_TYPES (TREE_TYPE (decl))
3117*38fd1498Szrj       && TREE_VALUE (TYPE_ARG_TYPES (TREE_TYPE (decl))) == void_type_node
3118*38fd1498Szrj       && gimple_call_num_args (stmt))
3119*38fd1498Szrj     {
3120*38fd1498Szrj       gimple_set_num_ops (stmt, 3);
3121*38fd1498Szrj       update_stmt_fn (fn, stmt);
3122*38fd1498Szrj     }
3123*38fd1498Szrj }
3124*38fd1498Szrj 
3125*38fd1498Szrj /* Return false if STMT will likely expand to real function call.  */
3126*38fd1498Szrj 
3127*38fd1498Szrj bool
gimple_inexpensive_call_p(gcall * stmt)3128*38fd1498Szrj gimple_inexpensive_call_p (gcall *stmt)
3129*38fd1498Szrj {
3130*38fd1498Szrj   if (gimple_call_internal_p (stmt))
3131*38fd1498Szrj     return true;
3132*38fd1498Szrj   tree decl = gimple_call_fndecl (stmt);
3133*38fd1498Szrj   if (decl && is_inexpensive_builtin (decl))
3134*38fd1498Szrj     return true;
3135*38fd1498Szrj   return false;
3136*38fd1498Szrj }
3137*38fd1498Szrj 
3138*38fd1498Szrj #if CHECKING_P
3139*38fd1498Szrj 
3140*38fd1498Szrj namespace selftest {
3141*38fd1498Szrj 
3142*38fd1498Szrj /* Selftests for core gimple structures.  */
3143*38fd1498Szrj 
3144*38fd1498Szrj /* Verify that STMT is pretty-printed as EXPECTED.
3145*38fd1498Szrj    Helper function for selftests.  */
3146*38fd1498Szrj 
3147*38fd1498Szrj static void
verify_gimple_pp(const char * expected,gimple * stmt)3148*38fd1498Szrj verify_gimple_pp (const char *expected, gimple *stmt)
3149*38fd1498Szrj {
3150*38fd1498Szrj   pretty_printer pp;
3151*38fd1498Szrj   pp_gimple_stmt_1 (&pp, stmt, 0 /* spc */, 0 /* flags */);
3152*38fd1498Szrj   ASSERT_STREQ (expected, pp_formatted_text (&pp));
3153*38fd1498Szrj }
3154*38fd1498Szrj 
3155*38fd1498Szrj /* Build a GIMPLE_ASSIGN equivalent to
3156*38fd1498Szrj      tmp = 5;
3157*38fd1498Szrj    and verify various properties of it.  */
3158*38fd1498Szrj 
3159*38fd1498Szrj static void
test_assign_single()3160*38fd1498Szrj test_assign_single ()
3161*38fd1498Szrj {
3162*38fd1498Szrj   tree type = integer_type_node;
3163*38fd1498Szrj   tree lhs = build_decl (UNKNOWN_LOCATION, VAR_DECL,
3164*38fd1498Szrj 			 get_identifier ("tmp"),
3165*38fd1498Szrj 			 type);
3166*38fd1498Szrj   tree rhs = build_int_cst (type, 5);
3167*38fd1498Szrj   gassign *stmt = gimple_build_assign (lhs, rhs);
3168*38fd1498Szrj   verify_gimple_pp ("tmp = 5;", stmt);
3169*38fd1498Szrj 
3170*38fd1498Szrj   ASSERT_TRUE (is_gimple_assign (stmt));
3171*38fd1498Szrj   ASSERT_EQ (lhs, gimple_assign_lhs (stmt));
3172*38fd1498Szrj   ASSERT_EQ (lhs, gimple_get_lhs (stmt));
3173*38fd1498Szrj   ASSERT_EQ (rhs, gimple_assign_rhs1 (stmt));
3174*38fd1498Szrj   ASSERT_EQ (NULL, gimple_assign_rhs2 (stmt));
3175*38fd1498Szrj   ASSERT_EQ (NULL, gimple_assign_rhs3 (stmt));
3176*38fd1498Szrj   ASSERT_TRUE (gimple_assign_single_p (stmt));
3177*38fd1498Szrj   ASSERT_EQ (INTEGER_CST, gimple_assign_rhs_code (stmt));
3178*38fd1498Szrj }
3179*38fd1498Szrj 
3180*38fd1498Szrj /* Build a GIMPLE_ASSIGN equivalent to
3181*38fd1498Szrj      tmp = a * b;
3182*38fd1498Szrj    and verify various properties of it.  */
3183*38fd1498Szrj 
3184*38fd1498Szrj static void
test_assign_binop()3185*38fd1498Szrj test_assign_binop ()
3186*38fd1498Szrj {
3187*38fd1498Szrj   tree type = integer_type_node;
3188*38fd1498Szrj   tree lhs = build_decl (UNKNOWN_LOCATION, VAR_DECL,
3189*38fd1498Szrj 			 get_identifier ("tmp"),
3190*38fd1498Szrj 			 type);
3191*38fd1498Szrj   tree a = build_decl (UNKNOWN_LOCATION, VAR_DECL,
3192*38fd1498Szrj 		       get_identifier ("a"),
3193*38fd1498Szrj 		       type);
3194*38fd1498Szrj   tree b = build_decl (UNKNOWN_LOCATION, VAR_DECL,
3195*38fd1498Szrj 		       get_identifier ("b"),
3196*38fd1498Szrj 		       type);
3197*38fd1498Szrj   gassign *stmt = gimple_build_assign (lhs, MULT_EXPR, a, b);
3198*38fd1498Szrj   verify_gimple_pp ("tmp = a * b;", stmt);
3199*38fd1498Szrj 
3200*38fd1498Szrj   ASSERT_TRUE (is_gimple_assign (stmt));
3201*38fd1498Szrj   ASSERT_EQ (lhs, gimple_assign_lhs (stmt));
3202*38fd1498Szrj   ASSERT_EQ (lhs, gimple_get_lhs (stmt));
3203*38fd1498Szrj   ASSERT_EQ (a, gimple_assign_rhs1 (stmt));
3204*38fd1498Szrj   ASSERT_EQ (b, gimple_assign_rhs2 (stmt));
3205*38fd1498Szrj   ASSERT_EQ (NULL, gimple_assign_rhs3 (stmt));
3206*38fd1498Szrj   ASSERT_FALSE (gimple_assign_single_p (stmt));
3207*38fd1498Szrj   ASSERT_EQ (MULT_EXPR, gimple_assign_rhs_code (stmt));
3208*38fd1498Szrj }
3209*38fd1498Szrj 
3210*38fd1498Szrj /* Build a GIMPLE_NOP and verify various properties of it.  */
3211*38fd1498Szrj 
3212*38fd1498Szrj static void
test_nop_stmt()3213*38fd1498Szrj test_nop_stmt ()
3214*38fd1498Szrj {
3215*38fd1498Szrj   gimple *stmt = gimple_build_nop ();
3216*38fd1498Szrj   verify_gimple_pp ("GIMPLE_NOP", stmt);
3217*38fd1498Szrj   ASSERT_EQ (GIMPLE_NOP, gimple_code (stmt));
3218*38fd1498Szrj   ASSERT_EQ (NULL, gimple_get_lhs (stmt));
3219*38fd1498Szrj   ASSERT_FALSE (gimple_assign_single_p (stmt));
3220*38fd1498Szrj }
3221*38fd1498Szrj 
3222*38fd1498Szrj /* Build a GIMPLE_RETURN equivalent to
3223*38fd1498Szrj      return 7;
3224*38fd1498Szrj    and verify various properties of it.  */
3225*38fd1498Szrj 
3226*38fd1498Szrj static void
test_return_stmt()3227*38fd1498Szrj test_return_stmt ()
3228*38fd1498Szrj {
3229*38fd1498Szrj   tree type = integer_type_node;
3230*38fd1498Szrj   tree val = build_int_cst (type, 7);
3231*38fd1498Szrj   greturn *stmt = gimple_build_return (val);
3232*38fd1498Szrj   verify_gimple_pp ("return 7;", stmt);
3233*38fd1498Szrj 
3234*38fd1498Szrj   ASSERT_EQ (GIMPLE_RETURN, gimple_code (stmt));
3235*38fd1498Szrj   ASSERT_EQ (NULL, gimple_get_lhs (stmt));
3236*38fd1498Szrj   ASSERT_EQ (val, gimple_return_retval (stmt));
3237*38fd1498Szrj   ASSERT_FALSE (gimple_assign_single_p (stmt));
3238*38fd1498Szrj }
3239*38fd1498Szrj 
3240*38fd1498Szrj /* Build a GIMPLE_RETURN equivalent to
3241*38fd1498Szrj      return;
3242*38fd1498Szrj    and verify various properties of it.  */
3243*38fd1498Szrj 
3244*38fd1498Szrj static void
test_return_without_value()3245*38fd1498Szrj test_return_without_value ()
3246*38fd1498Szrj {
3247*38fd1498Szrj   greturn *stmt = gimple_build_return (NULL);
3248*38fd1498Szrj   verify_gimple_pp ("return;", stmt);
3249*38fd1498Szrj 
3250*38fd1498Szrj   ASSERT_EQ (GIMPLE_RETURN, gimple_code (stmt));
3251*38fd1498Szrj   ASSERT_EQ (NULL, gimple_get_lhs (stmt));
3252*38fd1498Szrj   ASSERT_EQ (NULL, gimple_return_retval (stmt));
3253*38fd1498Szrj   ASSERT_FALSE (gimple_assign_single_p (stmt));
3254*38fd1498Szrj }
3255*38fd1498Szrj 
3256*38fd1498Szrj /* Run all of the selftests within this file.  */
3257*38fd1498Szrj 
3258*38fd1498Szrj void
gimple_c_tests()3259*38fd1498Szrj gimple_c_tests ()
3260*38fd1498Szrj {
3261*38fd1498Szrj   test_assign_single ();
3262*38fd1498Szrj   test_assign_binop ();
3263*38fd1498Szrj   test_nop_stmt ();
3264*38fd1498Szrj   test_return_stmt ();
3265*38fd1498Szrj   test_return_without_value ();
3266*38fd1498Szrj }
3267*38fd1498Szrj 
3268*38fd1498Szrj } // namespace selftest
3269*38fd1498Szrj 
3270*38fd1498Szrj 
3271*38fd1498Szrj #endif /* CHECKING_P */
3272