1*e4b17023SJohn Marino /* SSA operands management for trees.
2*e4b17023SJohn Marino Copyright (C) 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010
3*e4b17023SJohn Marino Free Software Foundation, Inc.
4*e4b17023SJohn Marino
5*e4b17023SJohn Marino This file is part of GCC.
6*e4b17023SJohn Marino
7*e4b17023SJohn Marino GCC is free software; you can redistribute it and/or modify
8*e4b17023SJohn Marino it under the terms of the GNU General Public License as published by
9*e4b17023SJohn Marino the Free Software Foundation; either version 3, or (at your option)
10*e4b17023SJohn Marino any later version.
11*e4b17023SJohn Marino
12*e4b17023SJohn Marino GCC is distributed in the hope that it will be useful,
13*e4b17023SJohn Marino but WITHOUT ANY WARRANTY; without even the implied warranty of
14*e4b17023SJohn Marino MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15*e4b17023SJohn Marino GNU General Public License for more details.
16*e4b17023SJohn Marino
17*e4b17023SJohn Marino You should have received a copy of the GNU General Public License
18*e4b17023SJohn Marino along with GCC; see the file COPYING3. If not see
19*e4b17023SJohn Marino <http://www.gnu.org/licenses/>. */
20*e4b17023SJohn Marino
21*e4b17023SJohn Marino #include "config.h"
22*e4b17023SJohn Marino #include "system.h"
23*e4b17023SJohn Marino #include "coretypes.h"
24*e4b17023SJohn Marino #include "tm.h"
25*e4b17023SJohn Marino #include "tree.h"
26*e4b17023SJohn Marino #include "flags.h"
27*e4b17023SJohn Marino #include "function.h"
28*e4b17023SJohn Marino #include "tree-pretty-print.h"
29*e4b17023SJohn Marino #include "gimple-pretty-print.h"
30*e4b17023SJohn Marino #include "tree-flow.h"
31*e4b17023SJohn Marino #include "tree-inline.h"
32*e4b17023SJohn Marino #include "tree-pass.h"
33*e4b17023SJohn Marino #include "ggc.h"
34*e4b17023SJohn Marino #include "timevar.h"
35*e4b17023SJohn Marino #include "langhooks.h"
36*e4b17023SJohn Marino #include "diagnostic-core.h"
37*e4b17023SJohn Marino
38*e4b17023SJohn Marino
39*e4b17023SJohn Marino /* This file contains the code required to manage the operands cache of the
40*e4b17023SJohn Marino SSA optimizer. For every stmt, we maintain an operand cache in the stmt
41*e4b17023SJohn Marino annotation. This cache contains operands that will be of interest to
42*e4b17023SJohn Marino optimizers and other passes wishing to manipulate the IL.
43*e4b17023SJohn Marino
44*e4b17023SJohn Marino The operand type are broken up into REAL and VIRTUAL operands. The real
45*e4b17023SJohn Marino operands are represented as pointers into the stmt's operand tree. Thus
46*e4b17023SJohn Marino any manipulation of the real operands will be reflected in the actual tree.
47*e4b17023SJohn Marino Virtual operands are represented solely in the cache, although the base
48*e4b17023SJohn Marino variable for the SSA_NAME may, or may not occur in the stmt's tree.
49*e4b17023SJohn Marino Manipulation of the virtual operands will not be reflected in the stmt tree.
50*e4b17023SJohn Marino
51*e4b17023SJohn Marino The routines in this file are concerned with creating this operand cache
52*e4b17023SJohn Marino from a stmt tree.
53*e4b17023SJohn Marino
54*e4b17023SJohn Marino The operand tree is the parsed by the various get_* routines which look
55*e4b17023SJohn Marino through the stmt tree for the occurrence of operands which may be of
56*e4b17023SJohn Marino interest, and calls are made to the append_* routines whenever one is
57*e4b17023SJohn Marino found. There are 4 of these routines, each representing one of the
58*e4b17023SJohn Marino 4 types of operands. Defs, Uses, Virtual Uses, and Virtual May Defs.
59*e4b17023SJohn Marino
60*e4b17023SJohn Marino The append_* routines check for duplication, and simply keep a list of
61*e4b17023SJohn Marino unique objects for each operand type in the build_* extendable vectors.
62*e4b17023SJohn Marino
63*e4b17023SJohn Marino Once the stmt tree is completely parsed, the finalize_ssa_operands()
64*e4b17023SJohn Marino routine is called, which proceeds to perform the finalization routine
65*e4b17023SJohn Marino on each of the 4 operand vectors which have been built up.
66*e4b17023SJohn Marino
67*e4b17023SJohn Marino If the stmt had a previous operand cache, the finalization routines
68*e4b17023SJohn Marino attempt to match up the new operands with the old ones. If it's a perfect
69*e4b17023SJohn Marino match, the old vector is simply reused. If it isn't a perfect match, then
70*e4b17023SJohn Marino a new vector is created and the new operands are placed there. For
71*e4b17023SJohn Marino virtual operands, if the previous cache had SSA_NAME version of a
72*e4b17023SJohn Marino variable, and that same variable occurs in the same operands cache, then
73*e4b17023SJohn Marino the new cache vector will also get the same SSA_NAME.
74*e4b17023SJohn Marino
75*e4b17023SJohn Marino i.e., if a stmt had a VUSE of 'a_5', and 'a' occurs in the new
76*e4b17023SJohn Marino operand vector for VUSE, then the new vector will also be modified
77*e4b17023SJohn Marino such that it contains 'a_5' rather than 'a'. */
78*e4b17023SJohn Marino
79*e4b17023SJohn Marino /* Structure storing statistics on how many call clobbers we have, and
80*e4b17023SJohn Marino how many where avoided. */
81*e4b17023SJohn Marino
82*e4b17023SJohn Marino static struct
83*e4b17023SJohn Marino {
84*e4b17023SJohn Marino /* Number of call-clobbered ops we attempt to add to calls in
85*e4b17023SJohn Marino add_call_clobbered_mem_symbols. */
86*e4b17023SJohn Marino unsigned int clobbered_vars;
87*e4b17023SJohn Marino
88*e4b17023SJohn Marino /* Number of write-clobbers (VDEFs) avoided by using
89*e4b17023SJohn Marino not_written information. */
90*e4b17023SJohn Marino unsigned int static_write_clobbers_avoided;
91*e4b17023SJohn Marino
92*e4b17023SJohn Marino /* Number of reads (VUSEs) avoided by using not_read information. */
93*e4b17023SJohn Marino unsigned int static_read_clobbers_avoided;
94*e4b17023SJohn Marino
95*e4b17023SJohn Marino /* Number of write-clobbers avoided because the variable can't escape to
96*e4b17023SJohn Marino this call. */
97*e4b17023SJohn Marino unsigned int unescapable_clobbers_avoided;
98*e4b17023SJohn Marino
99*e4b17023SJohn Marino /* Number of read-only uses we attempt to add to calls in
100*e4b17023SJohn Marino add_call_read_mem_symbols. */
101*e4b17023SJohn Marino unsigned int readonly_clobbers;
102*e4b17023SJohn Marino
103*e4b17023SJohn Marino /* Number of read-only uses we avoid using not_read information. */
104*e4b17023SJohn Marino unsigned int static_readonly_clobbers_avoided;
105*e4b17023SJohn Marino } clobber_stats;
106*e4b17023SJohn Marino
107*e4b17023SJohn Marino
108*e4b17023SJohn Marino /* Flags to describe operand properties in helpers. */
109*e4b17023SJohn Marino
110*e4b17023SJohn Marino /* By default, operands are loaded. */
111*e4b17023SJohn Marino #define opf_use 0
112*e4b17023SJohn Marino
113*e4b17023SJohn Marino /* Operand is the target of an assignment expression or a
114*e4b17023SJohn Marino call-clobbered variable. */
115*e4b17023SJohn Marino #define opf_def (1 << 0)
116*e4b17023SJohn Marino
117*e4b17023SJohn Marino /* No virtual operands should be created in the expression. This is used
118*e4b17023SJohn Marino when traversing ADDR_EXPR nodes which have different semantics than
119*e4b17023SJohn Marino other expressions. Inside an ADDR_EXPR node, the only operands that we
120*e4b17023SJohn Marino need to consider are indices into arrays. For instance, &a.b[i] should
121*e4b17023SJohn Marino generate a USE of 'i' but it should not generate a VUSE for 'a' nor a
122*e4b17023SJohn Marino VUSE for 'b'. */
123*e4b17023SJohn Marino #define opf_no_vops (1 << 1)
124*e4b17023SJohn Marino
125*e4b17023SJohn Marino /* Operand is an implicit reference. This is used to distinguish
126*e4b17023SJohn Marino explicit assignments in the form of MODIFY_EXPR from
127*e4b17023SJohn Marino clobbering sites like function calls or ASM_EXPRs. */
128*e4b17023SJohn Marino #define opf_implicit (1 << 2)
129*e4b17023SJohn Marino
130*e4b17023SJohn Marino /* Operand is in a place where address-taken does not imply addressable. */
131*e4b17023SJohn Marino #define opf_non_addressable (1 << 3)
132*e4b17023SJohn Marino
133*e4b17023SJohn Marino /* Operand is in a place where opf_non_addressable does not apply. */
134*e4b17023SJohn Marino #define opf_not_non_addressable (1 << 4)
135*e4b17023SJohn Marino
136*e4b17023SJohn Marino /* Array for building all the def operands. */
137*e4b17023SJohn Marino static VEC(tree,heap) *build_defs;
138*e4b17023SJohn Marino
139*e4b17023SJohn Marino /* Array for building all the use operands. */
140*e4b17023SJohn Marino static VEC(tree,heap) *build_uses;
141*e4b17023SJohn Marino
142*e4b17023SJohn Marino /* The built VDEF operand. */
143*e4b17023SJohn Marino static tree build_vdef;
144*e4b17023SJohn Marino
145*e4b17023SJohn Marino /* The built VUSE operand. */
146*e4b17023SJohn Marino static tree build_vuse;
147*e4b17023SJohn Marino
148*e4b17023SJohn Marino /* Bitmap obstack for our datastructures that needs to survive across
149*e4b17023SJohn Marino compilations of multiple functions. */
150*e4b17023SJohn Marino static bitmap_obstack operands_bitmap_obstack;
151*e4b17023SJohn Marino
152*e4b17023SJohn Marino static void get_expr_operands (gimple, tree *, int);
153*e4b17023SJohn Marino
154*e4b17023SJohn Marino /* Number of functions with initialized ssa_operands. */
155*e4b17023SJohn Marino static int n_initialized = 0;
156*e4b17023SJohn Marino
157*e4b17023SJohn Marino /* Return the DECL_UID of the base variable of T. */
158*e4b17023SJohn Marino
159*e4b17023SJohn Marino static inline unsigned
get_name_decl(const_tree t)160*e4b17023SJohn Marino get_name_decl (const_tree t)
161*e4b17023SJohn Marino {
162*e4b17023SJohn Marino if (TREE_CODE (t) != SSA_NAME)
163*e4b17023SJohn Marino return DECL_UID (t);
164*e4b17023SJohn Marino else
165*e4b17023SJohn Marino return DECL_UID (SSA_NAME_VAR (t));
166*e4b17023SJohn Marino }
167*e4b17023SJohn Marino
168*e4b17023SJohn Marino
169*e4b17023SJohn Marino /* Return true if the SSA operands cache is active. */
170*e4b17023SJohn Marino
171*e4b17023SJohn Marino bool
ssa_operands_active(void)172*e4b17023SJohn Marino ssa_operands_active (void)
173*e4b17023SJohn Marino {
174*e4b17023SJohn Marino /* This function may be invoked from contexts where CFUN is NULL
175*e4b17023SJohn Marino (IPA passes), return false for now. FIXME: operands may be
176*e4b17023SJohn Marino active in each individual function, maybe this function should
177*e4b17023SJohn Marino take CFUN as a parameter. */
178*e4b17023SJohn Marino if (cfun == NULL)
179*e4b17023SJohn Marino return false;
180*e4b17023SJohn Marino
181*e4b17023SJohn Marino return cfun->gimple_df && gimple_ssa_operands (cfun)->ops_active;
182*e4b17023SJohn Marino }
183*e4b17023SJohn Marino
184*e4b17023SJohn Marino
185*e4b17023SJohn Marino /* Create the VOP variable, an artificial global variable to act as a
186*e4b17023SJohn Marino representative of all of the virtual operands FUD chain. */
187*e4b17023SJohn Marino
188*e4b17023SJohn Marino static void
create_vop_var(void)189*e4b17023SJohn Marino create_vop_var (void)
190*e4b17023SJohn Marino {
191*e4b17023SJohn Marino tree global_var;
192*e4b17023SJohn Marino
193*e4b17023SJohn Marino gcc_assert (cfun->gimple_df->vop == NULL_TREE);
194*e4b17023SJohn Marino
195*e4b17023SJohn Marino global_var = build_decl (BUILTINS_LOCATION, VAR_DECL,
196*e4b17023SJohn Marino get_identifier (".MEM"),
197*e4b17023SJohn Marino void_type_node);
198*e4b17023SJohn Marino DECL_ARTIFICIAL (global_var) = 1;
199*e4b17023SJohn Marino TREE_READONLY (global_var) = 0;
200*e4b17023SJohn Marino DECL_EXTERNAL (global_var) = 1;
201*e4b17023SJohn Marino TREE_STATIC (global_var) = 1;
202*e4b17023SJohn Marino TREE_USED (global_var) = 1;
203*e4b17023SJohn Marino DECL_CONTEXT (global_var) = NULL_TREE;
204*e4b17023SJohn Marino TREE_THIS_VOLATILE (global_var) = 0;
205*e4b17023SJohn Marino TREE_ADDRESSABLE (global_var) = 0;
206*e4b17023SJohn Marino
207*e4b17023SJohn Marino create_var_ann (global_var);
208*e4b17023SJohn Marino add_referenced_var (global_var);
209*e4b17023SJohn Marino cfun->gimple_df->vop = global_var;
210*e4b17023SJohn Marino }
211*e4b17023SJohn Marino
212*e4b17023SJohn Marino /* These are the sizes of the operand memory buffer in bytes which gets
213*e4b17023SJohn Marino allocated each time more operands space is required. The final value is
214*e4b17023SJohn Marino the amount that is allocated every time after that.
215*e4b17023SJohn Marino In 1k we can fit 25 use operands (or 63 def operands) on a host with
216*e4b17023SJohn Marino 8 byte pointers, that would be 10 statements each with 1 def and 2
217*e4b17023SJohn Marino uses. */
218*e4b17023SJohn Marino
219*e4b17023SJohn Marino #define OP_SIZE_INIT 0
220*e4b17023SJohn Marino #define OP_SIZE_1 (1024 - sizeof (void *))
221*e4b17023SJohn Marino #define OP_SIZE_2 (1024 * 4 - sizeof (void *))
222*e4b17023SJohn Marino #define OP_SIZE_3 (1024 * 16 - sizeof (void *))
223*e4b17023SJohn Marino
224*e4b17023SJohn Marino /* Initialize the operand cache routines. */
225*e4b17023SJohn Marino
226*e4b17023SJohn Marino void
init_ssa_operands(void)227*e4b17023SJohn Marino init_ssa_operands (void)
228*e4b17023SJohn Marino {
229*e4b17023SJohn Marino if (!n_initialized++)
230*e4b17023SJohn Marino {
231*e4b17023SJohn Marino build_defs = VEC_alloc (tree, heap, 5);
232*e4b17023SJohn Marino build_uses = VEC_alloc (tree, heap, 10);
233*e4b17023SJohn Marino build_vuse = NULL_TREE;
234*e4b17023SJohn Marino build_vdef = NULL_TREE;
235*e4b17023SJohn Marino bitmap_obstack_initialize (&operands_bitmap_obstack);
236*e4b17023SJohn Marino }
237*e4b17023SJohn Marino
238*e4b17023SJohn Marino gcc_assert (gimple_ssa_operands (cfun)->operand_memory == NULL);
239*e4b17023SJohn Marino gimple_ssa_operands (cfun)->operand_memory_index
240*e4b17023SJohn Marino = gimple_ssa_operands (cfun)->ssa_operand_mem_size;
241*e4b17023SJohn Marino gimple_ssa_operands (cfun)->ops_active = true;
242*e4b17023SJohn Marino memset (&clobber_stats, 0, sizeof (clobber_stats));
243*e4b17023SJohn Marino gimple_ssa_operands (cfun)->ssa_operand_mem_size = OP_SIZE_INIT;
244*e4b17023SJohn Marino create_vop_var ();
245*e4b17023SJohn Marino }
246*e4b17023SJohn Marino
247*e4b17023SJohn Marino
248*e4b17023SJohn Marino /* Dispose of anything required by the operand routines. */
249*e4b17023SJohn Marino
250*e4b17023SJohn Marino void
fini_ssa_operands(void)251*e4b17023SJohn Marino fini_ssa_operands (void)
252*e4b17023SJohn Marino {
253*e4b17023SJohn Marino struct ssa_operand_memory_d *ptr;
254*e4b17023SJohn Marino
255*e4b17023SJohn Marino if (!--n_initialized)
256*e4b17023SJohn Marino {
257*e4b17023SJohn Marino VEC_free (tree, heap, build_defs);
258*e4b17023SJohn Marino VEC_free (tree, heap, build_uses);
259*e4b17023SJohn Marino build_vdef = NULL_TREE;
260*e4b17023SJohn Marino build_vuse = NULL_TREE;
261*e4b17023SJohn Marino }
262*e4b17023SJohn Marino
263*e4b17023SJohn Marino gimple_ssa_operands (cfun)->free_defs = NULL;
264*e4b17023SJohn Marino gimple_ssa_operands (cfun)->free_uses = NULL;
265*e4b17023SJohn Marino
266*e4b17023SJohn Marino while ((ptr = gimple_ssa_operands (cfun)->operand_memory) != NULL)
267*e4b17023SJohn Marino {
268*e4b17023SJohn Marino gimple_ssa_operands (cfun)->operand_memory
269*e4b17023SJohn Marino = gimple_ssa_operands (cfun)->operand_memory->next;
270*e4b17023SJohn Marino ggc_free (ptr);
271*e4b17023SJohn Marino }
272*e4b17023SJohn Marino
273*e4b17023SJohn Marino gimple_ssa_operands (cfun)->ops_active = false;
274*e4b17023SJohn Marino
275*e4b17023SJohn Marino if (!n_initialized)
276*e4b17023SJohn Marino bitmap_obstack_release (&operands_bitmap_obstack);
277*e4b17023SJohn Marino
278*e4b17023SJohn Marino cfun->gimple_df->vop = NULL_TREE;
279*e4b17023SJohn Marino
280*e4b17023SJohn Marino if (dump_file && (dump_flags & TDF_STATS))
281*e4b17023SJohn Marino {
282*e4b17023SJohn Marino fprintf (dump_file, "Original clobbered vars: %d\n",
283*e4b17023SJohn Marino clobber_stats.clobbered_vars);
284*e4b17023SJohn Marino fprintf (dump_file, "Static write clobbers avoided: %d\n",
285*e4b17023SJohn Marino clobber_stats.static_write_clobbers_avoided);
286*e4b17023SJohn Marino fprintf (dump_file, "Static read clobbers avoided: %d\n",
287*e4b17023SJohn Marino clobber_stats.static_read_clobbers_avoided);
288*e4b17023SJohn Marino fprintf (dump_file, "Unescapable clobbers avoided: %d\n",
289*e4b17023SJohn Marino clobber_stats.unescapable_clobbers_avoided);
290*e4b17023SJohn Marino fprintf (dump_file, "Original read-only clobbers: %d\n",
291*e4b17023SJohn Marino clobber_stats.readonly_clobbers);
292*e4b17023SJohn Marino fprintf (dump_file, "Static read-only clobbers avoided: %d\n",
293*e4b17023SJohn Marino clobber_stats.static_readonly_clobbers_avoided);
294*e4b17023SJohn Marino }
295*e4b17023SJohn Marino }
296*e4b17023SJohn Marino
297*e4b17023SJohn Marino
298*e4b17023SJohn Marino /* Return memory for an operand of size SIZE. */
299*e4b17023SJohn Marino
300*e4b17023SJohn Marino static inline void *
ssa_operand_alloc(unsigned size)301*e4b17023SJohn Marino ssa_operand_alloc (unsigned size)
302*e4b17023SJohn Marino {
303*e4b17023SJohn Marino char *ptr;
304*e4b17023SJohn Marino
305*e4b17023SJohn Marino gcc_assert (size == sizeof (struct use_optype_d)
306*e4b17023SJohn Marino || size == sizeof (struct def_optype_d));
307*e4b17023SJohn Marino
308*e4b17023SJohn Marino if (gimple_ssa_operands (cfun)->operand_memory_index + size
309*e4b17023SJohn Marino >= gimple_ssa_operands (cfun)->ssa_operand_mem_size)
310*e4b17023SJohn Marino {
311*e4b17023SJohn Marino struct ssa_operand_memory_d *ptr;
312*e4b17023SJohn Marino
313*e4b17023SJohn Marino switch (gimple_ssa_operands (cfun)->ssa_operand_mem_size)
314*e4b17023SJohn Marino {
315*e4b17023SJohn Marino case OP_SIZE_INIT:
316*e4b17023SJohn Marino gimple_ssa_operands (cfun)->ssa_operand_mem_size = OP_SIZE_1;
317*e4b17023SJohn Marino break;
318*e4b17023SJohn Marino case OP_SIZE_1:
319*e4b17023SJohn Marino gimple_ssa_operands (cfun)->ssa_operand_mem_size = OP_SIZE_2;
320*e4b17023SJohn Marino break;
321*e4b17023SJohn Marino case OP_SIZE_2:
322*e4b17023SJohn Marino case OP_SIZE_3:
323*e4b17023SJohn Marino gimple_ssa_operands (cfun)->ssa_operand_mem_size = OP_SIZE_3;
324*e4b17023SJohn Marino break;
325*e4b17023SJohn Marino default:
326*e4b17023SJohn Marino gcc_unreachable ();
327*e4b17023SJohn Marino }
328*e4b17023SJohn Marino
329*e4b17023SJohn Marino
330*e4b17023SJohn Marino ptr = ggc_alloc_ssa_operand_memory_d (sizeof (void *)
331*e4b17023SJohn Marino + gimple_ssa_operands (cfun)->ssa_operand_mem_size);
332*e4b17023SJohn Marino
333*e4b17023SJohn Marino ptr->next = gimple_ssa_operands (cfun)->operand_memory;
334*e4b17023SJohn Marino gimple_ssa_operands (cfun)->operand_memory = ptr;
335*e4b17023SJohn Marino gimple_ssa_operands (cfun)->operand_memory_index = 0;
336*e4b17023SJohn Marino }
337*e4b17023SJohn Marino
338*e4b17023SJohn Marino ptr = &(gimple_ssa_operands (cfun)->operand_memory
339*e4b17023SJohn Marino ->mem[gimple_ssa_operands (cfun)->operand_memory_index]);
340*e4b17023SJohn Marino gimple_ssa_operands (cfun)->operand_memory_index += size;
341*e4b17023SJohn Marino return ptr;
342*e4b17023SJohn Marino }
343*e4b17023SJohn Marino
344*e4b17023SJohn Marino
345*e4b17023SJohn Marino /* Allocate a DEF operand. */
346*e4b17023SJohn Marino
347*e4b17023SJohn Marino static inline struct def_optype_d *
alloc_def(void)348*e4b17023SJohn Marino alloc_def (void)
349*e4b17023SJohn Marino {
350*e4b17023SJohn Marino struct def_optype_d *ret;
351*e4b17023SJohn Marino if (gimple_ssa_operands (cfun)->free_defs)
352*e4b17023SJohn Marino {
353*e4b17023SJohn Marino ret = gimple_ssa_operands (cfun)->free_defs;
354*e4b17023SJohn Marino gimple_ssa_operands (cfun)->free_defs
355*e4b17023SJohn Marino = gimple_ssa_operands (cfun)->free_defs->next;
356*e4b17023SJohn Marino }
357*e4b17023SJohn Marino else
358*e4b17023SJohn Marino ret = (struct def_optype_d *)
359*e4b17023SJohn Marino ssa_operand_alloc (sizeof (struct def_optype_d));
360*e4b17023SJohn Marino return ret;
361*e4b17023SJohn Marino }
362*e4b17023SJohn Marino
363*e4b17023SJohn Marino
364*e4b17023SJohn Marino /* Allocate a USE operand. */
365*e4b17023SJohn Marino
366*e4b17023SJohn Marino static inline struct use_optype_d *
alloc_use(void)367*e4b17023SJohn Marino alloc_use (void)
368*e4b17023SJohn Marino {
369*e4b17023SJohn Marino struct use_optype_d *ret;
370*e4b17023SJohn Marino if (gimple_ssa_operands (cfun)->free_uses)
371*e4b17023SJohn Marino {
372*e4b17023SJohn Marino ret = gimple_ssa_operands (cfun)->free_uses;
373*e4b17023SJohn Marino gimple_ssa_operands (cfun)->free_uses
374*e4b17023SJohn Marino = gimple_ssa_operands (cfun)->free_uses->next;
375*e4b17023SJohn Marino }
376*e4b17023SJohn Marino else
377*e4b17023SJohn Marino ret = (struct use_optype_d *)
378*e4b17023SJohn Marino ssa_operand_alloc (sizeof (struct use_optype_d));
379*e4b17023SJohn Marino return ret;
380*e4b17023SJohn Marino }
381*e4b17023SJohn Marino
382*e4b17023SJohn Marino
383*e4b17023SJohn Marino /* Adds OP to the list of defs after LAST. */
384*e4b17023SJohn Marino
385*e4b17023SJohn Marino static inline def_optype_p
add_def_op(tree * op,def_optype_p last)386*e4b17023SJohn Marino add_def_op (tree *op, def_optype_p last)
387*e4b17023SJohn Marino {
388*e4b17023SJohn Marino def_optype_p new_def;
389*e4b17023SJohn Marino
390*e4b17023SJohn Marino new_def = alloc_def ();
391*e4b17023SJohn Marino DEF_OP_PTR (new_def) = op;
392*e4b17023SJohn Marino last->next = new_def;
393*e4b17023SJohn Marino new_def->next = NULL;
394*e4b17023SJohn Marino return new_def;
395*e4b17023SJohn Marino }
396*e4b17023SJohn Marino
397*e4b17023SJohn Marino
398*e4b17023SJohn Marino /* Adds OP to the list of uses of statement STMT after LAST. */
399*e4b17023SJohn Marino
400*e4b17023SJohn Marino static inline use_optype_p
add_use_op(gimple stmt,tree * op,use_optype_p last)401*e4b17023SJohn Marino add_use_op (gimple stmt, tree *op, use_optype_p last)
402*e4b17023SJohn Marino {
403*e4b17023SJohn Marino use_optype_p new_use;
404*e4b17023SJohn Marino
405*e4b17023SJohn Marino new_use = alloc_use ();
406*e4b17023SJohn Marino USE_OP_PTR (new_use)->use = op;
407*e4b17023SJohn Marino link_imm_use_stmt (USE_OP_PTR (new_use), *op, stmt);
408*e4b17023SJohn Marino last->next = new_use;
409*e4b17023SJohn Marino new_use->next = NULL;
410*e4b17023SJohn Marino return new_use;
411*e4b17023SJohn Marino }
412*e4b17023SJohn Marino
413*e4b17023SJohn Marino
414*e4b17023SJohn Marino
415*e4b17023SJohn Marino /* Takes elements from build_defs and turns them into def operands of STMT.
416*e4b17023SJohn Marino TODO -- Make build_defs VEC of tree *. */
417*e4b17023SJohn Marino
418*e4b17023SJohn Marino static inline void
finalize_ssa_defs(gimple stmt)419*e4b17023SJohn Marino finalize_ssa_defs (gimple stmt)
420*e4b17023SJohn Marino {
421*e4b17023SJohn Marino unsigned new_i;
422*e4b17023SJohn Marino struct def_optype_d new_list;
423*e4b17023SJohn Marino def_optype_p old_ops, last;
424*e4b17023SJohn Marino unsigned int num = VEC_length (tree, build_defs);
425*e4b17023SJohn Marino
426*e4b17023SJohn Marino /* There should only be a single real definition per assignment. */
427*e4b17023SJohn Marino gcc_assert ((stmt && gimple_code (stmt) != GIMPLE_ASSIGN) || num <= 1);
428*e4b17023SJohn Marino
429*e4b17023SJohn Marino /* Pre-pend the vdef we may have built. */
430*e4b17023SJohn Marino if (build_vdef != NULL_TREE)
431*e4b17023SJohn Marino {
432*e4b17023SJohn Marino tree oldvdef = gimple_vdef (stmt);
433*e4b17023SJohn Marino if (oldvdef
434*e4b17023SJohn Marino && TREE_CODE (oldvdef) == SSA_NAME)
435*e4b17023SJohn Marino oldvdef = SSA_NAME_VAR (oldvdef);
436*e4b17023SJohn Marino if (oldvdef != build_vdef)
437*e4b17023SJohn Marino gimple_set_vdef (stmt, build_vdef);
438*e4b17023SJohn Marino VEC_safe_insert (tree, heap, build_defs, 0, (tree)gimple_vdef_ptr (stmt));
439*e4b17023SJohn Marino ++num;
440*e4b17023SJohn Marino }
441*e4b17023SJohn Marino
442*e4b17023SJohn Marino new_list.next = NULL;
443*e4b17023SJohn Marino last = &new_list;
444*e4b17023SJohn Marino
445*e4b17023SJohn Marino old_ops = gimple_def_ops (stmt);
446*e4b17023SJohn Marino
447*e4b17023SJohn Marino new_i = 0;
448*e4b17023SJohn Marino
449*e4b17023SJohn Marino /* Clear and unlink a no longer necessary VDEF. */
450*e4b17023SJohn Marino if (build_vdef == NULL_TREE
451*e4b17023SJohn Marino && gimple_vdef (stmt) != NULL_TREE)
452*e4b17023SJohn Marino {
453*e4b17023SJohn Marino if (TREE_CODE (gimple_vdef (stmt)) == SSA_NAME)
454*e4b17023SJohn Marino {
455*e4b17023SJohn Marino unlink_stmt_vdef (stmt);
456*e4b17023SJohn Marino release_ssa_name (gimple_vdef (stmt));
457*e4b17023SJohn Marino }
458*e4b17023SJohn Marino gimple_set_vdef (stmt, NULL_TREE);
459*e4b17023SJohn Marino }
460*e4b17023SJohn Marino
461*e4b17023SJohn Marino /* If we have a non-SSA_NAME VDEF, mark it for renaming. */
462*e4b17023SJohn Marino if (gimple_vdef (stmt)
463*e4b17023SJohn Marino && TREE_CODE (gimple_vdef (stmt)) != SSA_NAME)
464*e4b17023SJohn Marino mark_sym_for_renaming (gimple_vdef (stmt));
465*e4b17023SJohn Marino
466*e4b17023SJohn Marino /* Check for the common case of 1 def that hasn't changed. */
467*e4b17023SJohn Marino if (old_ops && old_ops->next == NULL && num == 1
468*e4b17023SJohn Marino && (tree *) VEC_index (tree, build_defs, 0) == DEF_OP_PTR (old_ops))
469*e4b17023SJohn Marino return;
470*e4b17023SJohn Marino
471*e4b17023SJohn Marino /* If there is anything in the old list, free it. */
472*e4b17023SJohn Marino if (old_ops)
473*e4b17023SJohn Marino {
474*e4b17023SJohn Marino old_ops->next = gimple_ssa_operands (cfun)->free_defs;
475*e4b17023SJohn Marino gimple_ssa_operands (cfun)->free_defs = old_ops;
476*e4b17023SJohn Marino }
477*e4b17023SJohn Marino
478*e4b17023SJohn Marino /* If there is anything remaining in the build_defs list, simply emit it. */
479*e4b17023SJohn Marino for ( ; new_i < num; new_i++)
480*e4b17023SJohn Marino last = add_def_op ((tree *) VEC_index (tree, build_defs, new_i), last);
481*e4b17023SJohn Marino
482*e4b17023SJohn Marino /* Now set the stmt's operands. */
483*e4b17023SJohn Marino gimple_set_def_ops (stmt, new_list.next);
484*e4b17023SJohn Marino }
485*e4b17023SJohn Marino
486*e4b17023SJohn Marino
487*e4b17023SJohn Marino /* Takes elements from build_uses and turns them into use operands of STMT.
488*e4b17023SJohn Marino TODO -- Make build_uses VEC of tree *. */
489*e4b17023SJohn Marino
490*e4b17023SJohn Marino static inline void
finalize_ssa_uses(gimple stmt)491*e4b17023SJohn Marino finalize_ssa_uses (gimple stmt)
492*e4b17023SJohn Marino {
493*e4b17023SJohn Marino unsigned new_i;
494*e4b17023SJohn Marino struct use_optype_d new_list;
495*e4b17023SJohn Marino use_optype_p old_ops, ptr, last;
496*e4b17023SJohn Marino
497*e4b17023SJohn Marino /* Pre-pend the VUSE we may have built. */
498*e4b17023SJohn Marino if (build_vuse != NULL_TREE)
499*e4b17023SJohn Marino {
500*e4b17023SJohn Marino tree oldvuse = gimple_vuse (stmt);
501*e4b17023SJohn Marino if (oldvuse
502*e4b17023SJohn Marino && TREE_CODE (oldvuse) == SSA_NAME)
503*e4b17023SJohn Marino oldvuse = SSA_NAME_VAR (oldvuse);
504*e4b17023SJohn Marino if (oldvuse != (build_vuse != NULL_TREE
505*e4b17023SJohn Marino ? build_vuse : build_vdef))
506*e4b17023SJohn Marino gimple_set_vuse (stmt, NULL_TREE);
507*e4b17023SJohn Marino VEC_safe_insert (tree, heap, build_uses, 0, (tree)gimple_vuse_ptr (stmt));
508*e4b17023SJohn Marino }
509*e4b17023SJohn Marino
510*e4b17023SJohn Marino new_list.next = NULL;
511*e4b17023SJohn Marino last = &new_list;
512*e4b17023SJohn Marino
513*e4b17023SJohn Marino old_ops = gimple_use_ops (stmt);
514*e4b17023SJohn Marino
515*e4b17023SJohn Marino /* Clear a no longer necessary VUSE. */
516*e4b17023SJohn Marino if (build_vuse == NULL_TREE
517*e4b17023SJohn Marino && gimple_vuse (stmt) != NULL_TREE)
518*e4b17023SJohn Marino gimple_set_vuse (stmt, NULL_TREE);
519*e4b17023SJohn Marino
520*e4b17023SJohn Marino /* If there is anything in the old list, free it. */
521*e4b17023SJohn Marino if (old_ops)
522*e4b17023SJohn Marino {
523*e4b17023SJohn Marino for (ptr = old_ops; ptr; ptr = ptr->next)
524*e4b17023SJohn Marino delink_imm_use (USE_OP_PTR (ptr));
525*e4b17023SJohn Marino old_ops->next = gimple_ssa_operands (cfun)->free_uses;
526*e4b17023SJohn Marino gimple_ssa_operands (cfun)->free_uses = old_ops;
527*e4b17023SJohn Marino }
528*e4b17023SJohn Marino
529*e4b17023SJohn Marino /* If we added a VUSE, make sure to set the operand if it is not already
530*e4b17023SJohn Marino present and mark it for renaming. */
531*e4b17023SJohn Marino if (build_vuse != NULL_TREE
532*e4b17023SJohn Marino && gimple_vuse (stmt) == NULL_TREE)
533*e4b17023SJohn Marino {
534*e4b17023SJohn Marino gimple_set_vuse (stmt, gimple_vop (cfun));
535*e4b17023SJohn Marino mark_sym_for_renaming (gimple_vop (cfun));
536*e4b17023SJohn Marino }
537*e4b17023SJohn Marino
538*e4b17023SJohn Marino /* Now create nodes for all the new nodes. */
539*e4b17023SJohn Marino for (new_i = 0; new_i < VEC_length (tree, build_uses); new_i++)
540*e4b17023SJohn Marino last = add_use_op (stmt,
541*e4b17023SJohn Marino (tree *) VEC_index (tree, build_uses, new_i),
542*e4b17023SJohn Marino last);
543*e4b17023SJohn Marino
544*e4b17023SJohn Marino /* Now set the stmt's operands. */
545*e4b17023SJohn Marino gimple_set_use_ops (stmt, new_list.next);
546*e4b17023SJohn Marino }
547*e4b17023SJohn Marino
548*e4b17023SJohn Marino
549*e4b17023SJohn Marino /* Clear the in_list bits and empty the build array for VDEFs and
550*e4b17023SJohn Marino VUSEs. */
551*e4b17023SJohn Marino
552*e4b17023SJohn Marino static inline void
cleanup_build_arrays(void)553*e4b17023SJohn Marino cleanup_build_arrays (void)
554*e4b17023SJohn Marino {
555*e4b17023SJohn Marino build_vdef = NULL_TREE;
556*e4b17023SJohn Marino build_vuse = NULL_TREE;
557*e4b17023SJohn Marino VEC_truncate (tree, build_defs, 0);
558*e4b17023SJohn Marino VEC_truncate (tree, build_uses, 0);
559*e4b17023SJohn Marino }
560*e4b17023SJohn Marino
561*e4b17023SJohn Marino
562*e4b17023SJohn Marino /* Finalize all the build vectors, fill the new ones into INFO. */
563*e4b17023SJohn Marino
564*e4b17023SJohn Marino static inline void
finalize_ssa_stmt_operands(gimple stmt)565*e4b17023SJohn Marino finalize_ssa_stmt_operands (gimple stmt)
566*e4b17023SJohn Marino {
567*e4b17023SJohn Marino finalize_ssa_defs (stmt);
568*e4b17023SJohn Marino finalize_ssa_uses (stmt);
569*e4b17023SJohn Marino cleanup_build_arrays ();
570*e4b17023SJohn Marino }
571*e4b17023SJohn Marino
572*e4b17023SJohn Marino
573*e4b17023SJohn Marino /* Start the process of building up operands vectors in INFO. */
574*e4b17023SJohn Marino
575*e4b17023SJohn Marino static inline void
start_ssa_stmt_operands(void)576*e4b17023SJohn Marino start_ssa_stmt_operands (void)
577*e4b17023SJohn Marino {
578*e4b17023SJohn Marino gcc_assert (VEC_length (tree, build_defs) == 0);
579*e4b17023SJohn Marino gcc_assert (VEC_length (tree, build_uses) == 0);
580*e4b17023SJohn Marino gcc_assert (build_vuse == NULL_TREE);
581*e4b17023SJohn Marino gcc_assert (build_vdef == NULL_TREE);
582*e4b17023SJohn Marino }
583*e4b17023SJohn Marino
584*e4b17023SJohn Marino
585*e4b17023SJohn Marino /* Add DEF_P to the list of pointers to operands. */
586*e4b17023SJohn Marino
587*e4b17023SJohn Marino static inline void
append_def(tree * def_p)588*e4b17023SJohn Marino append_def (tree *def_p)
589*e4b17023SJohn Marino {
590*e4b17023SJohn Marino VEC_safe_push (tree, heap, build_defs, (tree) def_p);
591*e4b17023SJohn Marino }
592*e4b17023SJohn Marino
593*e4b17023SJohn Marino
594*e4b17023SJohn Marino /* Add USE_P to the list of pointers to operands. */
595*e4b17023SJohn Marino
596*e4b17023SJohn Marino static inline void
append_use(tree * use_p)597*e4b17023SJohn Marino append_use (tree *use_p)
598*e4b17023SJohn Marino {
599*e4b17023SJohn Marino VEC_safe_push (tree, heap, build_uses, (tree) use_p);
600*e4b17023SJohn Marino }
601*e4b17023SJohn Marino
602*e4b17023SJohn Marino
603*e4b17023SJohn Marino /* Add VAR to the set of variables that require a VDEF operator. */
604*e4b17023SJohn Marino
605*e4b17023SJohn Marino static inline void
append_vdef(tree var)606*e4b17023SJohn Marino append_vdef (tree var)
607*e4b17023SJohn Marino {
608*e4b17023SJohn Marino if (!optimize)
609*e4b17023SJohn Marino return;
610*e4b17023SJohn Marino
611*e4b17023SJohn Marino gcc_assert ((build_vdef == NULL_TREE
612*e4b17023SJohn Marino || build_vdef == var)
613*e4b17023SJohn Marino && (build_vuse == NULL_TREE
614*e4b17023SJohn Marino || build_vuse == var));
615*e4b17023SJohn Marino
616*e4b17023SJohn Marino build_vdef = var;
617*e4b17023SJohn Marino build_vuse = var;
618*e4b17023SJohn Marino }
619*e4b17023SJohn Marino
620*e4b17023SJohn Marino
621*e4b17023SJohn Marino /* Add VAR to the set of variables that require a VUSE operator. */
622*e4b17023SJohn Marino
623*e4b17023SJohn Marino static inline void
append_vuse(tree var)624*e4b17023SJohn Marino append_vuse (tree var)
625*e4b17023SJohn Marino {
626*e4b17023SJohn Marino if (!optimize)
627*e4b17023SJohn Marino return;
628*e4b17023SJohn Marino
629*e4b17023SJohn Marino gcc_assert (build_vuse == NULL_TREE
630*e4b17023SJohn Marino || build_vuse == var);
631*e4b17023SJohn Marino
632*e4b17023SJohn Marino build_vuse = var;
633*e4b17023SJohn Marino }
634*e4b17023SJohn Marino
635*e4b17023SJohn Marino /* Add virtual operands for STMT. FLAGS is as in get_expr_operands. */
636*e4b17023SJohn Marino
637*e4b17023SJohn Marino static void
add_virtual_operand(gimple stmt ATTRIBUTE_UNUSED,int flags)638*e4b17023SJohn Marino add_virtual_operand (gimple stmt ATTRIBUTE_UNUSED, int flags)
639*e4b17023SJohn Marino {
640*e4b17023SJohn Marino /* Add virtual operands to the stmt, unless the caller has specifically
641*e4b17023SJohn Marino requested not to do that (used when adding operands inside an
642*e4b17023SJohn Marino ADDR_EXPR expression). */
643*e4b17023SJohn Marino if (flags & opf_no_vops)
644*e4b17023SJohn Marino return;
645*e4b17023SJohn Marino
646*e4b17023SJohn Marino gcc_assert (!is_gimple_debug (stmt));
647*e4b17023SJohn Marino
648*e4b17023SJohn Marino if (flags & opf_def)
649*e4b17023SJohn Marino append_vdef (gimple_vop (cfun));
650*e4b17023SJohn Marino else
651*e4b17023SJohn Marino append_vuse (gimple_vop (cfun));
652*e4b17023SJohn Marino }
653*e4b17023SJohn Marino
654*e4b17023SJohn Marino
655*e4b17023SJohn Marino /* Add *VAR_P to the appropriate operand array for statement STMT.
656*e4b17023SJohn Marino FLAGS is as in get_expr_operands. If *VAR_P is a GIMPLE register,
657*e4b17023SJohn Marino it will be added to the statement's real operands, otherwise it is
658*e4b17023SJohn Marino added to virtual operands. */
659*e4b17023SJohn Marino
660*e4b17023SJohn Marino static void
add_stmt_operand(tree * var_p,gimple stmt,int flags)661*e4b17023SJohn Marino add_stmt_operand (tree *var_p, gimple stmt, int flags)
662*e4b17023SJohn Marino {
663*e4b17023SJohn Marino tree var, sym;
664*e4b17023SJohn Marino
665*e4b17023SJohn Marino gcc_assert (SSA_VAR_P (*var_p));
666*e4b17023SJohn Marino
667*e4b17023SJohn Marino var = *var_p;
668*e4b17023SJohn Marino sym = (TREE_CODE (var) == SSA_NAME ? SSA_NAME_VAR (var) : var);
669*e4b17023SJohn Marino
670*e4b17023SJohn Marino /* Mark statements with volatile operands. */
671*e4b17023SJohn Marino if (!(flags & opf_no_vops)
672*e4b17023SJohn Marino && TREE_THIS_VOLATILE (sym))
673*e4b17023SJohn Marino gimple_set_has_volatile_ops (stmt, true);
674*e4b17023SJohn Marino
675*e4b17023SJohn Marino if (is_gimple_reg (sym))
676*e4b17023SJohn Marino {
677*e4b17023SJohn Marino /* The variable is a GIMPLE register. Add it to real operands. */
678*e4b17023SJohn Marino if (flags & opf_def)
679*e4b17023SJohn Marino append_def (var_p);
680*e4b17023SJohn Marino else
681*e4b17023SJohn Marino append_use (var_p);
682*e4b17023SJohn Marino }
683*e4b17023SJohn Marino else
684*e4b17023SJohn Marino add_virtual_operand (stmt, flags);
685*e4b17023SJohn Marino }
686*e4b17023SJohn Marino
687*e4b17023SJohn Marino /* Mark the base address of REF as having its address taken.
688*e4b17023SJohn Marino REF may be a single variable whose address has been taken or any
689*e4b17023SJohn Marino other valid GIMPLE memory reference (structure reference, array,
690*e4b17023SJohn Marino etc). */
691*e4b17023SJohn Marino
692*e4b17023SJohn Marino static void
mark_address_taken(tree ref)693*e4b17023SJohn Marino mark_address_taken (tree ref)
694*e4b17023SJohn Marino {
695*e4b17023SJohn Marino tree var;
696*e4b17023SJohn Marino
697*e4b17023SJohn Marino /* Note that it is *NOT OKAY* to use the target of a COMPONENT_REF
698*e4b17023SJohn Marino as the only thing we take the address of. If VAR is a structure,
699*e4b17023SJohn Marino taking the address of a field means that the whole structure may
700*e4b17023SJohn Marino be referenced using pointer arithmetic. See PR 21407 and the
701*e4b17023SJohn Marino ensuing mailing list discussion. */
702*e4b17023SJohn Marino var = get_base_address (ref);
703*e4b17023SJohn Marino if (var)
704*e4b17023SJohn Marino {
705*e4b17023SJohn Marino if (DECL_P (var))
706*e4b17023SJohn Marino TREE_ADDRESSABLE (var) = 1;
707*e4b17023SJohn Marino else if (TREE_CODE (var) == MEM_REF
708*e4b17023SJohn Marino && TREE_CODE (TREE_OPERAND (var, 0)) == ADDR_EXPR
709*e4b17023SJohn Marino && DECL_P (TREE_OPERAND (TREE_OPERAND (var, 0), 0)))
710*e4b17023SJohn Marino TREE_ADDRESSABLE (TREE_OPERAND (TREE_OPERAND (var, 0), 0)) = 1;
711*e4b17023SJohn Marino }
712*e4b17023SJohn Marino }
713*e4b17023SJohn Marino
714*e4b17023SJohn Marino
715*e4b17023SJohn Marino /* A subroutine of get_expr_operands to handle MEM_REF.
716*e4b17023SJohn Marino
717*e4b17023SJohn Marino STMT is the statement being processed, EXPR is the MEM_REF
718*e4b17023SJohn Marino that got us here.
719*e4b17023SJohn Marino
720*e4b17023SJohn Marino FLAGS is as in get_expr_operands.
721*e4b17023SJohn Marino
722*e4b17023SJohn Marino RECURSE_ON_BASE should be set to true if we want to continue
723*e4b17023SJohn Marino calling get_expr_operands on the base pointer, and false if
724*e4b17023SJohn Marino something else will do it for us. */
725*e4b17023SJohn Marino
726*e4b17023SJohn Marino static void
get_indirect_ref_operands(gimple stmt,tree expr,int flags,bool recurse_on_base)727*e4b17023SJohn Marino get_indirect_ref_operands (gimple stmt, tree expr, int flags,
728*e4b17023SJohn Marino bool recurse_on_base)
729*e4b17023SJohn Marino {
730*e4b17023SJohn Marino tree *pptr = &TREE_OPERAND (expr, 0);
731*e4b17023SJohn Marino
732*e4b17023SJohn Marino if (!(flags & opf_no_vops)
733*e4b17023SJohn Marino && TREE_THIS_VOLATILE (expr))
734*e4b17023SJohn Marino gimple_set_has_volatile_ops (stmt, true);
735*e4b17023SJohn Marino
736*e4b17023SJohn Marino /* Add the VOP. */
737*e4b17023SJohn Marino add_virtual_operand (stmt, flags);
738*e4b17023SJohn Marino
739*e4b17023SJohn Marino /* If requested, add a USE operand for the base pointer. */
740*e4b17023SJohn Marino if (recurse_on_base)
741*e4b17023SJohn Marino get_expr_operands (stmt, pptr,
742*e4b17023SJohn Marino opf_non_addressable | opf_use
743*e4b17023SJohn Marino | (flags & (opf_no_vops|opf_not_non_addressable)));
744*e4b17023SJohn Marino }
745*e4b17023SJohn Marino
746*e4b17023SJohn Marino
747*e4b17023SJohn Marino /* A subroutine of get_expr_operands to handle TARGET_MEM_REF. */
748*e4b17023SJohn Marino
749*e4b17023SJohn Marino static void
get_tmr_operands(gimple stmt,tree expr,int flags)750*e4b17023SJohn Marino get_tmr_operands (gimple stmt, tree expr, int flags)
751*e4b17023SJohn Marino {
752*e4b17023SJohn Marino if (!(flags & opf_no_vops)
753*e4b17023SJohn Marino && TREE_THIS_VOLATILE (expr))
754*e4b17023SJohn Marino gimple_set_has_volatile_ops (stmt, true);
755*e4b17023SJohn Marino
756*e4b17023SJohn Marino /* First record the real operands. */
757*e4b17023SJohn Marino get_expr_operands (stmt, &TMR_BASE (expr), opf_use | (flags & opf_no_vops));
758*e4b17023SJohn Marino get_expr_operands (stmt, &TMR_INDEX (expr), opf_use | (flags & opf_no_vops));
759*e4b17023SJohn Marino get_expr_operands (stmt, &TMR_INDEX2 (expr), opf_use | (flags & opf_no_vops));
760*e4b17023SJohn Marino
761*e4b17023SJohn Marino add_virtual_operand (stmt, flags);
762*e4b17023SJohn Marino }
763*e4b17023SJohn Marino
764*e4b17023SJohn Marino
765*e4b17023SJohn Marino /* If STMT is a call that may clobber globals and other symbols that
766*e4b17023SJohn Marino escape, add them to the VDEF/VUSE lists for it. */
767*e4b17023SJohn Marino
768*e4b17023SJohn Marino static void
maybe_add_call_vops(gimple stmt)769*e4b17023SJohn Marino maybe_add_call_vops (gimple stmt)
770*e4b17023SJohn Marino {
771*e4b17023SJohn Marino int call_flags = gimple_call_flags (stmt);
772*e4b17023SJohn Marino
773*e4b17023SJohn Marino /* If aliases have been computed already, add VDEF or VUSE
774*e4b17023SJohn Marino operands for all the symbols that have been found to be
775*e4b17023SJohn Marino call-clobbered. */
776*e4b17023SJohn Marino if (!(call_flags & ECF_NOVOPS))
777*e4b17023SJohn Marino {
778*e4b17023SJohn Marino /* A 'pure' or a 'const' function never call-clobbers anything.
779*e4b17023SJohn Marino A 'noreturn' function might, but since we don't return anyway
780*e4b17023SJohn Marino there is no point in recording that. */
781*e4b17023SJohn Marino if (!(call_flags & (ECF_PURE | ECF_CONST | ECF_NORETURN)))
782*e4b17023SJohn Marino add_virtual_operand (stmt, opf_def);
783*e4b17023SJohn Marino else if (!(call_flags & ECF_CONST))
784*e4b17023SJohn Marino add_virtual_operand (stmt, opf_use);
785*e4b17023SJohn Marino }
786*e4b17023SJohn Marino }
787*e4b17023SJohn Marino
788*e4b17023SJohn Marino
789*e4b17023SJohn Marino /* Scan operands in the ASM_EXPR stmt referred to in INFO. */
790*e4b17023SJohn Marino
791*e4b17023SJohn Marino static void
get_asm_expr_operands(gimple stmt)792*e4b17023SJohn Marino get_asm_expr_operands (gimple stmt)
793*e4b17023SJohn Marino {
794*e4b17023SJohn Marino size_t i, noutputs;
795*e4b17023SJohn Marino const char **oconstraints;
796*e4b17023SJohn Marino const char *constraint;
797*e4b17023SJohn Marino bool allows_mem, allows_reg, is_inout;
798*e4b17023SJohn Marino
799*e4b17023SJohn Marino noutputs = gimple_asm_noutputs (stmt);
800*e4b17023SJohn Marino oconstraints = (const char **) alloca ((noutputs) * sizeof (const char *));
801*e4b17023SJohn Marino
802*e4b17023SJohn Marino /* Gather all output operands. */
803*e4b17023SJohn Marino for (i = 0; i < gimple_asm_noutputs (stmt); i++)
804*e4b17023SJohn Marino {
805*e4b17023SJohn Marino tree link = gimple_asm_output_op (stmt, i);
806*e4b17023SJohn Marino constraint = TREE_STRING_POINTER (TREE_VALUE (TREE_PURPOSE (link)));
807*e4b17023SJohn Marino oconstraints[i] = constraint;
808*e4b17023SJohn Marino parse_output_constraint (&constraint, i, 0, 0, &allows_mem,
809*e4b17023SJohn Marino &allows_reg, &is_inout);
810*e4b17023SJohn Marino
811*e4b17023SJohn Marino /* This should have been split in gimplify_asm_expr. */
812*e4b17023SJohn Marino gcc_assert (!allows_reg || !is_inout);
813*e4b17023SJohn Marino
814*e4b17023SJohn Marino /* Memory operands are addressable. Note that STMT needs the
815*e4b17023SJohn Marino address of this operand. */
816*e4b17023SJohn Marino if (!allows_reg && allows_mem)
817*e4b17023SJohn Marino mark_address_taken (TREE_VALUE (link));
818*e4b17023SJohn Marino
819*e4b17023SJohn Marino get_expr_operands (stmt, &TREE_VALUE (link), opf_def | opf_not_non_addressable);
820*e4b17023SJohn Marino }
821*e4b17023SJohn Marino
822*e4b17023SJohn Marino /* Gather all input operands. */
823*e4b17023SJohn Marino for (i = 0; i < gimple_asm_ninputs (stmt); i++)
824*e4b17023SJohn Marino {
825*e4b17023SJohn Marino tree link = gimple_asm_input_op (stmt, i);
826*e4b17023SJohn Marino constraint = TREE_STRING_POINTER (TREE_VALUE (TREE_PURPOSE (link)));
827*e4b17023SJohn Marino parse_input_constraint (&constraint, 0, 0, noutputs, 0, oconstraints,
828*e4b17023SJohn Marino &allows_mem, &allows_reg);
829*e4b17023SJohn Marino
830*e4b17023SJohn Marino /* Memory operands are addressable. Note that STMT needs the
831*e4b17023SJohn Marino address of this operand. */
832*e4b17023SJohn Marino if (!allows_reg && allows_mem)
833*e4b17023SJohn Marino mark_address_taken (TREE_VALUE (link));
834*e4b17023SJohn Marino
835*e4b17023SJohn Marino get_expr_operands (stmt, &TREE_VALUE (link), opf_not_non_addressable);
836*e4b17023SJohn Marino }
837*e4b17023SJohn Marino
838*e4b17023SJohn Marino /* Clobber all memory and addressable symbols for asm ("" : : : "memory"); */
839*e4b17023SJohn Marino if (gimple_asm_clobbers_memory_p (stmt))
840*e4b17023SJohn Marino add_virtual_operand (stmt, opf_def);
841*e4b17023SJohn Marino }
842*e4b17023SJohn Marino
843*e4b17023SJohn Marino
844*e4b17023SJohn Marino /* Recursively scan the expression pointed to by EXPR_P in statement
845*e4b17023SJohn Marino STMT. FLAGS is one of the OPF_* constants modifying how to
846*e4b17023SJohn Marino interpret the operands found. */
847*e4b17023SJohn Marino
848*e4b17023SJohn Marino static void
get_expr_operands(gimple stmt,tree * expr_p,int flags)849*e4b17023SJohn Marino get_expr_operands (gimple stmt, tree *expr_p, int flags)
850*e4b17023SJohn Marino {
851*e4b17023SJohn Marino enum tree_code code;
852*e4b17023SJohn Marino enum tree_code_class codeclass;
853*e4b17023SJohn Marino tree expr = *expr_p;
854*e4b17023SJohn Marino int uflags = opf_use;
855*e4b17023SJohn Marino
856*e4b17023SJohn Marino if (expr == NULL)
857*e4b17023SJohn Marino return;
858*e4b17023SJohn Marino
859*e4b17023SJohn Marino if (is_gimple_debug (stmt))
860*e4b17023SJohn Marino uflags |= (flags & opf_no_vops);
861*e4b17023SJohn Marino
862*e4b17023SJohn Marino code = TREE_CODE (expr);
863*e4b17023SJohn Marino codeclass = TREE_CODE_CLASS (code);
864*e4b17023SJohn Marino
865*e4b17023SJohn Marino switch (code)
866*e4b17023SJohn Marino {
867*e4b17023SJohn Marino case ADDR_EXPR:
868*e4b17023SJohn Marino /* Taking the address of a variable does not represent a
869*e4b17023SJohn Marino reference to it, but the fact that the statement takes its
870*e4b17023SJohn Marino address will be of interest to some passes (e.g. alias
871*e4b17023SJohn Marino resolution). */
872*e4b17023SJohn Marino if ((!(flags & opf_non_addressable)
873*e4b17023SJohn Marino || (flags & opf_not_non_addressable))
874*e4b17023SJohn Marino && !is_gimple_debug (stmt))
875*e4b17023SJohn Marino mark_address_taken (TREE_OPERAND (expr, 0));
876*e4b17023SJohn Marino
877*e4b17023SJohn Marino /* If the address is invariant, there may be no interesting
878*e4b17023SJohn Marino variable references inside. */
879*e4b17023SJohn Marino if (is_gimple_min_invariant (expr))
880*e4b17023SJohn Marino return;
881*e4b17023SJohn Marino
882*e4b17023SJohn Marino /* Otherwise, there may be variables referenced inside but there
883*e4b17023SJohn Marino should be no VUSEs created, since the referenced objects are
884*e4b17023SJohn Marino not really accessed. The only operands that we should find
885*e4b17023SJohn Marino here are ARRAY_REF indices which will always be real operands
886*e4b17023SJohn Marino (GIMPLE does not allow non-registers as array indices). */
887*e4b17023SJohn Marino flags |= opf_no_vops;
888*e4b17023SJohn Marino get_expr_operands (stmt, &TREE_OPERAND (expr, 0),
889*e4b17023SJohn Marino flags | opf_not_non_addressable);
890*e4b17023SJohn Marino return;
891*e4b17023SJohn Marino
892*e4b17023SJohn Marino case SSA_NAME:
893*e4b17023SJohn Marino add_stmt_operand (expr_p, stmt, flags);
894*e4b17023SJohn Marino return;
895*e4b17023SJohn Marino
896*e4b17023SJohn Marino case VAR_DECL:
897*e4b17023SJohn Marino case PARM_DECL:
898*e4b17023SJohn Marino case RESULT_DECL:
899*e4b17023SJohn Marino add_stmt_operand (expr_p, stmt, flags);
900*e4b17023SJohn Marino return;
901*e4b17023SJohn Marino
902*e4b17023SJohn Marino case DEBUG_EXPR_DECL:
903*e4b17023SJohn Marino gcc_assert (gimple_debug_bind_p (stmt));
904*e4b17023SJohn Marino return;
905*e4b17023SJohn Marino
906*e4b17023SJohn Marino case MEM_REF:
907*e4b17023SJohn Marino get_indirect_ref_operands (stmt, expr, flags, true);
908*e4b17023SJohn Marino return;
909*e4b17023SJohn Marino
910*e4b17023SJohn Marino case TARGET_MEM_REF:
911*e4b17023SJohn Marino get_tmr_operands (stmt, expr, flags);
912*e4b17023SJohn Marino return;
913*e4b17023SJohn Marino
914*e4b17023SJohn Marino case ARRAY_REF:
915*e4b17023SJohn Marino case ARRAY_RANGE_REF:
916*e4b17023SJohn Marino case COMPONENT_REF:
917*e4b17023SJohn Marino case REALPART_EXPR:
918*e4b17023SJohn Marino case IMAGPART_EXPR:
919*e4b17023SJohn Marino {
920*e4b17023SJohn Marino if (!(flags & opf_no_vops)
921*e4b17023SJohn Marino && TREE_THIS_VOLATILE (expr))
922*e4b17023SJohn Marino gimple_set_has_volatile_ops (stmt, true);
923*e4b17023SJohn Marino
924*e4b17023SJohn Marino get_expr_operands (stmt, &TREE_OPERAND (expr, 0), flags);
925*e4b17023SJohn Marino
926*e4b17023SJohn Marino if (code == COMPONENT_REF)
927*e4b17023SJohn Marino {
928*e4b17023SJohn Marino if (!(flags & opf_no_vops)
929*e4b17023SJohn Marino && TREE_THIS_VOLATILE (TREE_OPERAND (expr, 1)))
930*e4b17023SJohn Marino gimple_set_has_volatile_ops (stmt, true);
931*e4b17023SJohn Marino get_expr_operands (stmt, &TREE_OPERAND (expr, 2), uflags);
932*e4b17023SJohn Marino }
933*e4b17023SJohn Marino else if (code == ARRAY_REF || code == ARRAY_RANGE_REF)
934*e4b17023SJohn Marino {
935*e4b17023SJohn Marino get_expr_operands (stmt, &TREE_OPERAND (expr, 1), uflags);
936*e4b17023SJohn Marino get_expr_operands (stmt, &TREE_OPERAND (expr, 2), uflags);
937*e4b17023SJohn Marino get_expr_operands (stmt, &TREE_OPERAND (expr, 3), uflags);
938*e4b17023SJohn Marino }
939*e4b17023SJohn Marino
940*e4b17023SJohn Marino return;
941*e4b17023SJohn Marino }
942*e4b17023SJohn Marino
943*e4b17023SJohn Marino case WITH_SIZE_EXPR:
944*e4b17023SJohn Marino /* WITH_SIZE_EXPR is a pass-through reference to its first argument,
945*e4b17023SJohn Marino and an rvalue reference to its second argument. */
946*e4b17023SJohn Marino get_expr_operands (stmt, &TREE_OPERAND (expr, 1), uflags);
947*e4b17023SJohn Marino get_expr_operands (stmt, &TREE_OPERAND (expr, 0), flags);
948*e4b17023SJohn Marino return;
949*e4b17023SJohn Marino
950*e4b17023SJohn Marino case COND_EXPR:
951*e4b17023SJohn Marino case VEC_COND_EXPR:
952*e4b17023SJohn Marino case VEC_PERM_EXPR:
953*e4b17023SJohn Marino get_expr_operands (stmt, &TREE_OPERAND (expr, 0), uflags);
954*e4b17023SJohn Marino get_expr_operands (stmt, &TREE_OPERAND (expr, 1), uflags);
955*e4b17023SJohn Marino get_expr_operands (stmt, &TREE_OPERAND (expr, 2), uflags);
956*e4b17023SJohn Marino return;
957*e4b17023SJohn Marino
958*e4b17023SJohn Marino case CONSTRUCTOR:
959*e4b17023SJohn Marino {
960*e4b17023SJohn Marino /* General aggregate CONSTRUCTORs have been decomposed, but they
961*e4b17023SJohn Marino are still in use as the COMPLEX_EXPR equivalent for vectors. */
962*e4b17023SJohn Marino constructor_elt *ce;
963*e4b17023SJohn Marino unsigned HOST_WIDE_INT idx;
964*e4b17023SJohn Marino
965*e4b17023SJohn Marino /* A volatile constructor is actually TREE_CLOBBER_P, transfer
966*e4b17023SJohn Marino the volatility to the statement, don't use TREE_CLOBBER_P for
967*e4b17023SJohn Marino mirroring the other uses of THIS_VOLATILE in this file. */
968*e4b17023SJohn Marino if (!(flags & opf_no_vops)
969*e4b17023SJohn Marino && TREE_THIS_VOLATILE (expr))
970*e4b17023SJohn Marino gimple_set_has_volatile_ops (stmt, true);
971*e4b17023SJohn Marino
972*e4b17023SJohn Marino for (idx = 0;
973*e4b17023SJohn Marino VEC_iterate (constructor_elt, CONSTRUCTOR_ELTS (expr), idx, ce);
974*e4b17023SJohn Marino idx++)
975*e4b17023SJohn Marino get_expr_operands (stmt, &ce->value, uflags);
976*e4b17023SJohn Marino
977*e4b17023SJohn Marino return;
978*e4b17023SJohn Marino }
979*e4b17023SJohn Marino
980*e4b17023SJohn Marino case BIT_FIELD_REF:
981*e4b17023SJohn Marino if (!(flags & opf_no_vops)
982*e4b17023SJohn Marino && TREE_THIS_VOLATILE (expr))
983*e4b17023SJohn Marino gimple_set_has_volatile_ops (stmt, true);
984*e4b17023SJohn Marino /* FALLTHRU */
985*e4b17023SJohn Marino
986*e4b17023SJohn Marino case VIEW_CONVERT_EXPR:
987*e4b17023SJohn Marino do_unary:
988*e4b17023SJohn Marino get_expr_operands (stmt, &TREE_OPERAND (expr, 0), flags);
989*e4b17023SJohn Marino return;
990*e4b17023SJohn Marino
991*e4b17023SJohn Marino case COMPOUND_EXPR:
992*e4b17023SJohn Marino case OBJ_TYPE_REF:
993*e4b17023SJohn Marino case ASSERT_EXPR:
994*e4b17023SJohn Marino do_binary:
995*e4b17023SJohn Marino {
996*e4b17023SJohn Marino get_expr_operands (stmt, &TREE_OPERAND (expr, 0), flags);
997*e4b17023SJohn Marino get_expr_operands (stmt, &TREE_OPERAND (expr, 1), flags);
998*e4b17023SJohn Marino return;
999*e4b17023SJohn Marino }
1000*e4b17023SJohn Marino
1001*e4b17023SJohn Marino case DOT_PROD_EXPR:
1002*e4b17023SJohn Marino case REALIGN_LOAD_EXPR:
1003*e4b17023SJohn Marino case WIDEN_MULT_PLUS_EXPR:
1004*e4b17023SJohn Marino case WIDEN_MULT_MINUS_EXPR:
1005*e4b17023SJohn Marino case FMA_EXPR:
1006*e4b17023SJohn Marino {
1007*e4b17023SJohn Marino get_expr_operands (stmt, &TREE_OPERAND (expr, 0), flags);
1008*e4b17023SJohn Marino get_expr_operands (stmt, &TREE_OPERAND (expr, 1), flags);
1009*e4b17023SJohn Marino get_expr_operands (stmt, &TREE_OPERAND (expr, 2), flags);
1010*e4b17023SJohn Marino return;
1011*e4b17023SJohn Marino }
1012*e4b17023SJohn Marino
1013*e4b17023SJohn Marino case FUNCTION_DECL:
1014*e4b17023SJohn Marino case LABEL_DECL:
1015*e4b17023SJohn Marino case CONST_DECL:
1016*e4b17023SJohn Marino case CASE_LABEL_EXPR:
1017*e4b17023SJohn Marino /* Expressions that make no memory references. */
1018*e4b17023SJohn Marino return;
1019*e4b17023SJohn Marino
1020*e4b17023SJohn Marino default:
1021*e4b17023SJohn Marino if (codeclass == tcc_unary)
1022*e4b17023SJohn Marino goto do_unary;
1023*e4b17023SJohn Marino if (codeclass == tcc_binary || codeclass == tcc_comparison)
1024*e4b17023SJohn Marino goto do_binary;
1025*e4b17023SJohn Marino if (codeclass == tcc_constant || codeclass == tcc_type)
1026*e4b17023SJohn Marino return;
1027*e4b17023SJohn Marino }
1028*e4b17023SJohn Marino
1029*e4b17023SJohn Marino /* If we get here, something has gone wrong. */
1030*e4b17023SJohn Marino #ifdef ENABLE_CHECKING
1031*e4b17023SJohn Marino fprintf (stderr, "unhandled expression in get_expr_operands():\n");
1032*e4b17023SJohn Marino debug_tree (expr);
1033*e4b17023SJohn Marino fputs ("\n", stderr);
1034*e4b17023SJohn Marino #endif
1035*e4b17023SJohn Marino gcc_unreachable ();
1036*e4b17023SJohn Marino }
1037*e4b17023SJohn Marino
1038*e4b17023SJohn Marino
1039*e4b17023SJohn Marino /* Parse STMT looking for operands. When finished, the various
1040*e4b17023SJohn Marino build_* operand vectors will have potential operands in them. */
1041*e4b17023SJohn Marino
1042*e4b17023SJohn Marino static void
parse_ssa_operands(gimple stmt)1043*e4b17023SJohn Marino parse_ssa_operands (gimple stmt)
1044*e4b17023SJohn Marino {
1045*e4b17023SJohn Marino enum gimple_code code = gimple_code (stmt);
1046*e4b17023SJohn Marino size_t i, n, start = 0;
1047*e4b17023SJohn Marino
1048*e4b17023SJohn Marino switch (code)
1049*e4b17023SJohn Marino {
1050*e4b17023SJohn Marino case GIMPLE_ASM:
1051*e4b17023SJohn Marino get_asm_expr_operands (stmt);
1052*e4b17023SJohn Marino break;
1053*e4b17023SJohn Marino
1054*e4b17023SJohn Marino case GIMPLE_TRANSACTION:
1055*e4b17023SJohn Marino /* The start of a transaction is a memory barrier. */
1056*e4b17023SJohn Marino add_virtual_operand (stmt, opf_def | opf_use);
1057*e4b17023SJohn Marino break;
1058*e4b17023SJohn Marino
1059*e4b17023SJohn Marino case GIMPLE_DEBUG:
1060*e4b17023SJohn Marino if (gimple_debug_bind_p (stmt)
1061*e4b17023SJohn Marino && gimple_debug_bind_has_value_p (stmt))
1062*e4b17023SJohn Marino get_expr_operands (stmt, gimple_debug_bind_get_value_ptr (stmt),
1063*e4b17023SJohn Marino opf_use | opf_no_vops);
1064*e4b17023SJohn Marino break;
1065*e4b17023SJohn Marino
1066*e4b17023SJohn Marino case GIMPLE_RETURN:
1067*e4b17023SJohn Marino append_vuse (gimple_vop (cfun));
1068*e4b17023SJohn Marino goto do_default;
1069*e4b17023SJohn Marino
1070*e4b17023SJohn Marino case GIMPLE_CALL:
1071*e4b17023SJohn Marino /* Add call-clobbered operands, if needed. */
1072*e4b17023SJohn Marino maybe_add_call_vops (stmt);
1073*e4b17023SJohn Marino /* FALLTHRU */
1074*e4b17023SJohn Marino
1075*e4b17023SJohn Marino case GIMPLE_ASSIGN:
1076*e4b17023SJohn Marino get_expr_operands (stmt, gimple_op_ptr (stmt, 0), opf_def);
1077*e4b17023SJohn Marino start = 1;
1078*e4b17023SJohn Marino /* FALLTHRU */
1079*e4b17023SJohn Marino
1080*e4b17023SJohn Marino default:
1081*e4b17023SJohn Marino do_default:
1082*e4b17023SJohn Marino n = gimple_num_ops (stmt);
1083*e4b17023SJohn Marino for (i = start; i < n; i++)
1084*e4b17023SJohn Marino get_expr_operands (stmt, gimple_op_ptr (stmt, i), opf_use);
1085*e4b17023SJohn Marino break;
1086*e4b17023SJohn Marino }
1087*e4b17023SJohn Marino }
1088*e4b17023SJohn Marino
1089*e4b17023SJohn Marino
1090*e4b17023SJohn Marino /* Create an operands cache for STMT. */
1091*e4b17023SJohn Marino
1092*e4b17023SJohn Marino static void
build_ssa_operands(gimple stmt)1093*e4b17023SJohn Marino build_ssa_operands (gimple stmt)
1094*e4b17023SJohn Marino {
1095*e4b17023SJohn Marino /* Initially assume that the statement has no volatile operands. */
1096*e4b17023SJohn Marino gimple_set_has_volatile_ops (stmt, false);
1097*e4b17023SJohn Marino
1098*e4b17023SJohn Marino start_ssa_stmt_operands ();
1099*e4b17023SJohn Marino parse_ssa_operands (stmt);
1100*e4b17023SJohn Marino finalize_ssa_stmt_operands (stmt);
1101*e4b17023SJohn Marino }
1102*e4b17023SJohn Marino
1103*e4b17023SJohn Marino /* Verifies SSA statement operands. */
1104*e4b17023SJohn Marino
1105*e4b17023SJohn Marino DEBUG_FUNCTION bool
verify_ssa_operands(gimple stmt)1106*e4b17023SJohn Marino verify_ssa_operands (gimple stmt)
1107*e4b17023SJohn Marino {
1108*e4b17023SJohn Marino use_operand_p use_p;
1109*e4b17023SJohn Marino def_operand_p def_p;
1110*e4b17023SJohn Marino ssa_op_iter iter;
1111*e4b17023SJohn Marino unsigned i;
1112*e4b17023SJohn Marino tree use, def;
1113*e4b17023SJohn Marino bool volatile_p = gimple_has_volatile_ops (stmt);
1114*e4b17023SJohn Marino
1115*e4b17023SJohn Marino /* build_ssa_operands w/o finalizing them. */
1116*e4b17023SJohn Marino gimple_set_has_volatile_ops (stmt, false);
1117*e4b17023SJohn Marino start_ssa_stmt_operands ();
1118*e4b17023SJohn Marino parse_ssa_operands (stmt);
1119*e4b17023SJohn Marino
1120*e4b17023SJohn Marino /* Now verify the built operands are the same as present in STMT. */
1121*e4b17023SJohn Marino def = gimple_vdef (stmt);
1122*e4b17023SJohn Marino if (def
1123*e4b17023SJohn Marino && TREE_CODE (def) == SSA_NAME)
1124*e4b17023SJohn Marino def = SSA_NAME_VAR (def);
1125*e4b17023SJohn Marino if (build_vdef != def)
1126*e4b17023SJohn Marino {
1127*e4b17023SJohn Marino error ("virtual definition of statement not up-to-date");
1128*e4b17023SJohn Marino return true;
1129*e4b17023SJohn Marino }
1130*e4b17023SJohn Marino if (gimple_vdef (stmt)
1131*e4b17023SJohn Marino && ((def_p = gimple_vdef_op (stmt)) == NULL_DEF_OPERAND_P
1132*e4b17023SJohn Marino || DEF_FROM_PTR (def_p) != gimple_vdef (stmt)))
1133*e4b17023SJohn Marino {
1134*e4b17023SJohn Marino error ("virtual def operand missing for stmt");
1135*e4b17023SJohn Marino return true;
1136*e4b17023SJohn Marino }
1137*e4b17023SJohn Marino
1138*e4b17023SJohn Marino use = gimple_vuse (stmt);
1139*e4b17023SJohn Marino if (use
1140*e4b17023SJohn Marino && TREE_CODE (use) == SSA_NAME)
1141*e4b17023SJohn Marino use = SSA_NAME_VAR (use);
1142*e4b17023SJohn Marino if (build_vuse != use)
1143*e4b17023SJohn Marino {
1144*e4b17023SJohn Marino error ("virtual use of statement not up-to-date");
1145*e4b17023SJohn Marino return true;
1146*e4b17023SJohn Marino }
1147*e4b17023SJohn Marino if (gimple_vuse (stmt)
1148*e4b17023SJohn Marino && ((use_p = gimple_vuse_op (stmt)) == NULL_USE_OPERAND_P
1149*e4b17023SJohn Marino || USE_FROM_PTR (use_p) != gimple_vuse (stmt)))
1150*e4b17023SJohn Marino {
1151*e4b17023SJohn Marino error ("virtual use operand missing for stmt");
1152*e4b17023SJohn Marino return true;
1153*e4b17023SJohn Marino }
1154*e4b17023SJohn Marino
1155*e4b17023SJohn Marino FOR_EACH_SSA_USE_OPERAND (use_p, stmt, iter, SSA_OP_USE)
1156*e4b17023SJohn Marino {
1157*e4b17023SJohn Marino FOR_EACH_VEC_ELT (tree, build_uses, i, use)
1158*e4b17023SJohn Marino {
1159*e4b17023SJohn Marino if (use_p->use == (tree *)use)
1160*e4b17023SJohn Marino {
1161*e4b17023SJohn Marino VEC_replace (tree, build_uses, i, NULL_TREE);
1162*e4b17023SJohn Marino break;
1163*e4b17023SJohn Marino }
1164*e4b17023SJohn Marino }
1165*e4b17023SJohn Marino if (i == VEC_length (tree, build_uses))
1166*e4b17023SJohn Marino {
1167*e4b17023SJohn Marino error ("excess use operand for stmt");
1168*e4b17023SJohn Marino debug_generic_expr (USE_FROM_PTR (use_p));
1169*e4b17023SJohn Marino return true;
1170*e4b17023SJohn Marino }
1171*e4b17023SJohn Marino }
1172*e4b17023SJohn Marino FOR_EACH_VEC_ELT (tree, build_uses, i, use)
1173*e4b17023SJohn Marino if (use != NULL_TREE)
1174*e4b17023SJohn Marino {
1175*e4b17023SJohn Marino error ("use operand missing for stmt");
1176*e4b17023SJohn Marino debug_generic_expr (*(tree *)use);
1177*e4b17023SJohn Marino return true;
1178*e4b17023SJohn Marino }
1179*e4b17023SJohn Marino
1180*e4b17023SJohn Marino FOR_EACH_SSA_DEF_OPERAND (def_p, stmt, iter, SSA_OP_DEF)
1181*e4b17023SJohn Marino {
1182*e4b17023SJohn Marino FOR_EACH_VEC_ELT (tree, build_defs, i, def)
1183*e4b17023SJohn Marino {
1184*e4b17023SJohn Marino if (def_p == (tree *)def)
1185*e4b17023SJohn Marino {
1186*e4b17023SJohn Marino VEC_replace (tree, build_defs, i, NULL_TREE);
1187*e4b17023SJohn Marino break;
1188*e4b17023SJohn Marino }
1189*e4b17023SJohn Marino }
1190*e4b17023SJohn Marino if (i == VEC_length (tree, build_defs))
1191*e4b17023SJohn Marino {
1192*e4b17023SJohn Marino error ("excess def operand for stmt");
1193*e4b17023SJohn Marino debug_generic_expr (DEF_FROM_PTR (def_p));
1194*e4b17023SJohn Marino return true;
1195*e4b17023SJohn Marino }
1196*e4b17023SJohn Marino }
1197*e4b17023SJohn Marino FOR_EACH_VEC_ELT (tree, build_defs, i, def)
1198*e4b17023SJohn Marino if (def != NULL_TREE)
1199*e4b17023SJohn Marino {
1200*e4b17023SJohn Marino error ("def operand missing for stmt");
1201*e4b17023SJohn Marino debug_generic_expr (*(tree *)def);
1202*e4b17023SJohn Marino return true;
1203*e4b17023SJohn Marino }
1204*e4b17023SJohn Marino
1205*e4b17023SJohn Marino if (gimple_has_volatile_ops (stmt) != volatile_p)
1206*e4b17023SJohn Marino {
1207*e4b17023SJohn Marino error ("stmt volatile flag not up-to-date");
1208*e4b17023SJohn Marino return true;
1209*e4b17023SJohn Marino }
1210*e4b17023SJohn Marino
1211*e4b17023SJohn Marino cleanup_build_arrays ();
1212*e4b17023SJohn Marino return false;
1213*e4b17023SJohn Marino }
1214*e4b17023SJohn Marino
1215*e4b17023SJohn Marino
1216*e4b17023SJohn Marino /* Releases the operands of STMT back to their freelists, and clears
1217*e4b17023SJohn Marino the stmt operand lists. */
1218*e4b17023SJohn Marino
1219*e4b17023SJohn Marino void
free_stmt_operands(gimple stmt)1220*e4b17023SJohn Marino free_stmt_operands (gimple stmt)
1221*e4b17023SJohn Marino {
1222*e4b17023SJohn Marino def_optype_p defs = gimple_def_ops (stmt), last_def;
1223*e4b17023SJohn Marino use_optype_p uses = gimple_use_ops (stmt), last_use;
1224*e4b17023SJohn Marino
1225*e4b17023SJohn Marino if (defs)
1226*e4b17023SJohn Marino {
1227*e4b17023SJohn Marino for (last_def = defs; last_def->next; last_def = last_def->next)
1228*e4b17023SJohn Marino continue;
1229*e4b17023SJohn Marino last_def->next = gimple_ssa_operands (cfun)->free_defs;
1230*e4b17023SJohn Marino gimple_ssa_operands (cfun)->free_defs = defs;
1231*e4b17023SJohn Marino gimple_set_def_ops (stmt, NULL);
1232*e4b17023SJohn Marino }
1233*e4b17023SJohn Marino
1234*e4b17023SJohn Marino if (uses)
1235*e4b17023SJohn Marino {
1236*e4b17023SJohn Marino for (last_use = uses; last_use->next; last_use = last_use->next)
1237*e4b17023SJohn Marino delink_imm_use (USE_OP_PTR (last_use));
1238*e4b17023SJohn Marino delink_imm_use (USE_OP_PTR (last_use));
1239*e4b17023SJohn Marino last_use->next = gimple_ssa_operands (cfun)->free_uses;
1240*e4b17023SJohn Marino gimple_ssa_operands (cfun)->free_uses = uses;
1241*e4b17023SJohn Marino gimple_set_use_ops (stmt, NULL);
1242*e4b17023SJohn Marino }
1243*e4b17023SJohn Marino
1244*e4b17023SJohn Marino if (gimple_has_mem_ops (stmt))
1245*e4b17023SJohn Marino {
1246*e4b17023SJohn Marino gimple_set_vuse (stmt, NULL_TREE);
1247*e4b17023SJohn Marino gimple_set_vdef (stmt, NULL_TREE);
1248*e4b17023SJohn Marino }
1249*e4b17023SJohn Marino }
1250*e4b17023SJohn Marino
1251*e4b17023SJohn Marino
1252*e4b17023SJohn Marino /* Get the operands of statement STMT. */
1253*e4b17023SJohn Marino
1254*e4b17023SJohn Marino void
update_stmt_operands(gimple stmt)1255*e4b17023SJohn Marino update_stmt_operands (gimple stmt)
1256*e4b17023SJohn Marino {
1257*e4b17023SJohn Marino /* If update_stmt_operands is called before SSA is initialized, do
1258*e4b17023SJohn Marino nothing. */
1259*e4b17023SJohn Marino if (!ssa_operands_active ())
1260*e4b17023SJohn Marino return;
1261*e4b17023SJohn Marino
1262*e4b17023SJohn Marino timevar_push (TV_TREE_OPS);
1263*e4b17023SJohn Marino
1264*e4b17023SJohn Marino /* If the stmt is a noreturn call queue it to be processed by
1265*e4b17023SJohn Marino split_bbs_on_noreturn_calls during cfg cleanup. */
1266*e4b17023SJohn Marino if (is_gimple_call (stmt)
1267*e4b17023SJohn Marino && gimple_call_noreturn_p (stmt))
1268*e4b17023SJohn Marino VEC_safe_push (gimple, gc, MODIFIED_NORETURN_CALLS (cfun), stmt);
1269*e4b17023SJohn Marino
1270*e4b17023SJohn Marino gcc_assert (gimple_modified_p (stmt));
1271*e4b17023SJohn Marino build_ssa_operands (stmt);
1272*e4b17023SJohn Marino gimple_set_modified (stmt, false);
1273*e4b17023SJohn Marino
1274*e4b17023SJohn Marino timevar_pop (TV_TREE_OPS);
1275*e4b17023SJohn Marino }
1276*e4b17023SJohn Marino
1277*e4b17023SJohn Marino
1278*e4b17023SJohn Marino /* Swap operands EXP0 and EXP1 in statement STMT. No attempt is done
1279*e4b17023SJohn Marino to test the validity of the swap operation. */
1280*e4b17023SJohn Marino
1281*e4b17023SJohn Marino void
swap_tree_operands(gimple stmt,tree * exp0,tree * exp1)1282*e4b17023SJohn Marino swap_tree_operands (gimple stmt, tree *exp0, tree *exp1)
1283*e4b17023SJohn Marino {
1284*e4b17023SJohn Marino tree op0, op1;
1285*e4b17023SJohn Marino op0 = *exp0;
1286*e4b17023SJohn Marino op1 = *exp1;
1287*e4b17023SJohn Marino
1288*e4b17023SJohn Marino /* If the operand cache is active, attempt to preserve the relative
1289*e4b17023SJohn Marino positions of these two operands in their respective immediate use
1290*e4b17023SJohn Marino lists by adjusting their use pointer to point to the new
1291*e4b17023SJohn Marino operand position. */
1292*e4b17023SJohn Marino if (ssa_operands_active () && op0 != op1)
1293*e4b17023SJohn Marino {
1294*e4b17023SJohn Marino use_optype_p use0, use1, ptr;
1295*e4b17023SJohn Marino use0 = use1 = NULL;
1296*e4b17023SJohn Marino
1297*e4b17023SJohn Marino /* Find the 2 operands in the cache, if they are there. */
1298*e4b17023SJohn Marino for (ptr = gimple_use_ops (stmt); ptr; ptr = ptr->next)
1299*e4b17023SJohn Marino if (USE_OP_PTR (ptr)->use == exp0)
1300*e4b17023SJohn Marino {
1301*e4b17023SJohn Marino use0 = ptr;
1302*e4b17023SJohn Marino break;
1303*e4b17023SJohn Marino }
1304*e4b17023SJohn Marino
1305*e4b17023SJohn Marino for (ptr = gimple_use_ops (stmt); ptr; ptr = ptr->next)
1306*e4b17023SJohn Marino if (USE_OP_PTR (ptr)->use == exp1)
1307*e4b17023SJohn Marino {
1308*e4b17023SJohn Marino use1 = ptr;
1309*e4b17023SJohn Marino break;
1310*e4b17023SJohn Marino }
1311*e4b17023SJohn Marino
1312*e4b17023SJohn Marino /* And adjust their location to point to the new position of the
1313*e4b17023SJohn Marino operand. */
1314*e4b17023SJohn Marino if (use0)
1315*e4b17023SJohn Marino USE_OP_PTR (use0)->use = exp1;
1316*e4b17023SJohn Marino if (use1)
1317*e4b17023SJohn Marino USE_OP_PTR (use1)->use = exp0;
1318*e4b17023SJohn Marino }
1319*e4b17023SJohn Marino
1320*e4b17023SJohn Marino /* Now swap the data. */
1321*e4b17023SJohn Marino *exp0 = op1;
1322*e4b17023SJohn Marino *exp1 = op0;
1323*e4b17023SJohn Marino }
1324*e4b17023SJohn Marino
1325*e4b17023SJohn Marino
1326*e4b17023SJohn Marino /* Scan the immediate_use list for VAR making sure its linked properly.
1327*e4b17023SJohn Marino Return TRUE if there is a problem and emit an error message to F. */
1328*e4b17023SJohn Marino
1329*e4b17023SJohn Marino DEBUG_FUNCTION bool
verify_imm_links(FILE * f,tree var)1330*e4b17023SJohn Marino verify_imm_links (FILE *f, tree var)
1331*e4b17023SJohn Marino {
1332*e4b17023SJohn Marino use_operand_p ptr, prev, list;
1333*e4b17023SJohn Marino int count;
1334*e4b17023SJohn Marino
1335*e4b17023SJohn Marino gcc_assert (TREE_CODE (var) == SSA_NAME);
1336*e4b17023SJohn Marino
1337*e4b17023SJohn Marino list = &(SSA_NAME_IMM_USE_NODE (var));
1338*e4b17023SJohn Marino gcc_assert (list->use == NULL);
1339*e4b17023SJohn Marino
1340*e4b17023SJohn Marino if (list->prev == NULL)
1341*e4b17023SJohn Marino {
1342*e4b17023SJohn Marino gcc_assert (list->next == NULL);
1343*e4b17023SJohn Marino return false;
1344*e4b17023SJohn Marino }
1345*e4b17023SJohn Marino
1346*e4b17023SJohn Marino prev = list;
1347*e4b17023SJohn Marino count = 0;
1348*e4b17023SJohn Marino for (ptr = list->next; ptr != list; )
1349*e4b17023SJohn Marino {
1350*e4b17023SJohn Marino if (prev != ptr->prev)
1351*e4b17023SJohn Marino goto error;
1352*e4b17023SJohn Marino
1353*e4b17023SJohn Marino if (ptr->use == NULL)
1354*e4b17023SJohn Marino goto error; /* 2 roots, or SAFE guard node. */
1355*e4b17023SJohn Marino else if (*(ptr->use) != var)
1356*e4b17023SJohn Marino goto error;
1357*e4b17023SJohn Marino
1358*e4b17023SJohn Marino prev = ptr;
1359*e4b17023SJohn Marino ptr = ptr->next;
1360*e4b17023SJohn Marino
1361*e4b17023SJohn Marino /* Avoid infinite loops. 50,000,000 uses probably indicates a
1362*e4b17023SJohn Marino problem. */
1363*e4b17023SJohn Marino if (count++ > 50000000)
1364*e4b17023SJohn Marino goto error;
1365*e4b17023SJohn Marino }
1366*e4b17023SJohn Marino
1367*e4b17023SJohn Marino /* Verify list in the other direction. */
1368*e4b17023SJohn Marino prev = list;
1369*e4b17023SJohn Marino for (ptr = list->prev; ptr != list; )
1370*e4b17023SJohn Marino {
1371*e4b17023SJohn Marino if (prev != ptr->next)
1372*e4b17023SJohn Marino goto error;
1373*e4b17023SJohn Marino prev = ptr;
1374*e4b17023SJohn Marino ptr = ptr->prev;
1375*e4b17023SJohn Marino if (count-- < 0)
1376*e4b17023SJohn Marino goto error;
1377*e4b17023SJohn Marino }
1378*e4b17023SJohn Marino
1379*e4b17023SJohn Marino if (count != 0)
1380*e4b17023SJohn Marino goto error;
1381*e4b17023SJohn Marino
1382*e4b17023SJohn Marino return false;
1383*e4b17023SJohn Marino
1384*e4b17023SJohn Marino error:
1385*e4b17023SJohn Marino if (ptr->loc.stmt && gimple_modified_p (ptr->loc.stmt))
1386*e4b17023SJohn Marino {
1387*e4b17023SJohn Marino fprintf (f, " STMT MODIFIED. - <%p> ", (void *)ptr->loc.stmt);
1388*e4b17023SJohn Marino print_gimple_stmt (f, ptr->loc.stmt, 0, TDF_SLIM);
1389*e4b17023SJohn Marino }
1390*e4b17023SJohn Marino fprintf (f, " IMM ERROR : (use_p : tree - %p:%p)", (void *)ptr,
1391*e4b17023SJohn Marino (void *)ptr->use);
1392*e4b17023SJohn Marino print_generic_expr (f, USE_FROM_PTR (ptr), TDF_SLIM);
1393*e4b17023SJohn Marino fprintf(f, "\n");
1394*e4b17023SJohn Marino return true;
1395*e4b17023SJohn Marino }
1396*e4b17023SJohn Marino
1397*e4b17023SJohn Marino
1398*e4b17023SJohn Marino /* Dump all the immediate uses to FILE. */
1399*e4b17023SJohn Marino
1400*e4b17023SJohn Marino void
dump_immediate_uses_for(FILE * file,tree var)1401*e4b17023SJohn Marino dump_immediate_uses_for (FILE *file, tree var)
1402*e4b17023SJohn Marino {
1403*e4b17023SJohn Marino imm_use_iterator iter;
1404*e4b17023SJohn Marino use_operand_p use_p;
1405*e4b17023SJohn Marino
1406*e4b17023SJohn Marino gcc_assert (var && TREE_CODE (var) == SSA_NAME);
1407*e4b17023SJohn Marino
1408*e4b17023SJohn Marino print_generic_expr (file, var, TDF_SLIM);
1409*e4b17023SJohn Marino fprintf (file, " : -->");
1410*e4b17023SJohn Marino if (has_zero_uses (var))
1411*e4b17023SJohn Marino fprintf (file, " no uses.\n");
1412*e4b17023SJohn Marino else
1413*e4b17023SJohn Marino if (has_single_use (var))
1414*e4b17023SJohn Marino fprintf (file, " single use.\n");
1415*e4b17023SJohn Marino else
1416*e4b17023SJohn Marino fprintf (file, "%d uses.\n", num_imm_uses (var));
1417*e4b17023SJohn Marino
1418*e4b17023SJohn Marino FOR_EACH_IMM_USE_FAST (use_p, iter, var)
1419*e4b17023SJohn Marino {
1420*e4b17023SJohn Marino if (use_p->loc.stmt == NULL && use_p->use == NULL)
1421*e4b17023SJohn Marino fprintf (file, "***end of stmt iterator marker***\n");
1422*e4b17023SJohn Marino else
1423*e4b17023SJohn Marino if (!is_gimple_reg (USE_FROM_PTR (use_p)))
1424*e4b17023SJohn Marino print_gimple_stmt (file, USE_STMT (use_p), 0, TDF_VOPS|TDF_MEMSYMS);
1425*e4b17023SJohn Marino else
1426*e4b17023SJohn Marino print_gimple_stmt (file, USE_STMT (use_p), 0, TDF_SLIM);
1427*e4b17023SJohn Marino }
1428*e4b17023SJohn Marino fprintf(file, "\n");
1429*e4b17023SJohn Marino }
1430*e4b17023SJohn Marino
1431*e4b17023SJohn Marino
1432*e4b17023SJohn Marino /* Dump all the immediate uses to FILE. */
1433*e4b17023SJohn Marino
1434*e4b17023SJohn Marino void
dump_immediate_uses(FILE * file)1435*e4b17023SJohn Marino dump_immediate_uses (FILE *file)
1436*e4b17023SJohn Marino {
1437*e4b17023SJohn Marino tree var;
1438*e4b17023SJohn Marino unsigned int x;
1439*e4b17023SJohn Marino
1440*e4b17023SJohn Marino fprintf (file, "Immediate_uses: \n\n");
1441*e4b17023SJohn Marino for (x = 1; x < num_ssa_names; x++)
1442*e4b17023SJohn Marino {
1443*e4b17023SJohn Marino var = ssa_name(x);
1444*e4b17023SJohn Marino if (!var)
1445*e4b17023SJohn Marino continue;
1446*e4b17023SJohn Marino dump_immediate_uses_for (file, var);
1447*e4b17023SJohn Marino }
1448*e4b17023SJohn Marino }
1449*e4b17023SJohn Marino
1450*e4b17023SJohn Marino
1451*e4b17023SJohn Marino /* Dump def-use edges on stderr. */
1452*e4b17023SJohn Marino
1453*e4b17023SJohn Marino DEBUG_FUNCTION void
debug_immediate_uses(void)1454*e4b17023SJohn Marino debug_immediate_uses (void)
1455*e4b17023SJohn Marino {
1456*e4b17023SJohn Marino dump_immediate_uses (stderr);
1457*e4b17023SJohn Marino }
1458*e4b17023SJohn Marino
1459*e4b17023SJohn Marino
1460*e4b17023SJohn Marino /* Dump def-use edges on stderr. */
1461*e4b17023SJohn Marino
1462*e4b17023SJohn Marino DEBUG_FUNCTION void
debug_immediate_uses_for(tree var)1463*e4b17023SJohn Marino debug_immediate_uses_for (tree var)
1464*e4b17023SJohn Marino {
1465*e4b17023SJohn Marino dump_immediate_uses_for (stderr, var);
1466*e4b17023SJohn Marino }
1467*e4b17023SJohn Marino
1468*e4b17023SJohn Marino
1469*e4b17023SJohn Marino /* Unlink STMTs virtual definition from the IL by propagating its use. */
1470*e4b17023SJohn Marino
1471*e4b17023SJohn Marino void
unlink_stmt_vdef(gimple stmt)1472*e4b17023SJohn Marino unlink_stmt_vdef (gimple stmt)
1473*e4b17023SJohn Marino {
1474*e4b17023SJohn Marino use_operand_p use_p;
1475*e4b17023SJohn Marino imm_use_iterator iter;
1476*e4b17023SJohn Marino gimple use_stmt;
1477*e4b17023SJohn Marino tree vdef = gimple_vdef (stmt);
1478*e4b17023SJohn Marino
1479*e4b17023SJohn Marino if (!vdef
1480*e4b17023SJohn Marino || TREE_CODE (vdef) != SSA_NAME)
1481*e4b17023SJohn Marino return;
1482*e4b17023SJohn Marino
1483*e4b17023SJohn Marino FOR_EACH_IMM_USE_STMT (use_stmt, iter, gimple_vdef (stmt))
1484*e4b17023SJohn Marino {
1485*e4b17023SJohn Marino FOR_EACH_IMM_USE_ON_STMT (use_p, iter)
1486*e4b17023SJohn Marino SET_USE (use_p, gimple_vuse (stmt));
1487*e4b17023SJohn Marino }
1488*e4b17023SJohn Marino
1489*e4b17023SJohn Marino if (SSA_NAME_OCCURS_IN_ABNORMAL_PHI (gimple_vdef (stmt)))
1490*e4b17023SJohn Marino SSA_NAME_OCCURS_IN_ABNORMAL_PHI (gimple_vuse (stmt)) = 1;
1491*e4b17023SJohn Marino }
1492*e4b17023SJohn Marino
1493