1169689Skan/* Functions to analyze and validate GIMPLE trees.
2169689Skan   Copyright (C) 2002, 2003, 2005 Free Software Foundation, Inc.
3169689Skan   Contributed by Diego Novillo <dnovillo@redhat.com>
4169689Skan
5169689SkanThis file is part of GCC.
6169689Skan
7169689SkanGCC is free software; you can redistribute it and/or modify
8169689Skanit under the terms of the GNU General Public License as published by
9169689Skanthe Free Software Foundation; either version 2, or (at your option)
10169689Skanany later version.
11169689Skan
12169689SkanGCC is distributed in the hope that it will be useful,
13169689Skanbut WITHOUT ANY WARRANTY; without even the implied warranty of
14169689SkanMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15169689SkanGNU General Public License for more details.
16169689Skan
17169689SkanYou should have received a copy of the GNU General Public License
18169689Skanalong with GCC; see the file COPYING.  If not, write to
19169689Skanthe Free Software Foundation, 51 Franklin Street, Fifth Floor,
20169689SkanBoston, MA 02110-1301, USA.  */
21169689Skan
22169689Skan#ifndef _TREE_SIMPLE_H
23169689Skan#define _TREE_SIMPLE_H 1
24169689Skan
25169689Skan
26169689Skan#include "tree-iterator.h"
27169689Skan
28169689Skanextern tree create_tmp_var_raw (tree, const char *);
29169689Skanextern tree create_tmp_var_name (const char *);
30169689Skanextern tree create_tmp_var (tree, const char *);
31169689Skanextern tree get_initialized_tmp_var (tree, tree *, tree *);
32169689Skanextern tree get_formal_tmp_var (tree, tree *);
33169689Skan
34169689Skanextern void declare_vars (tree, tree, bool);
35169689Skan
36169689Skanextern void annotate_all_with_locus (tree *, location_t);
37169689Skan
38169689Skan/* Validation of GIMPLE expressions.  Note that these predicates only check
39169689Skan   the basic form of the expression, they don't recurse to make sure that
40169689Skan   underlying nodes are also of the right form.  */
41169689Skan
42169689Skantypedef bool (*gimple_predicate)(tree);
43169689Skan
44169689Skan/* Returns true iff T is a valid GIMPLE statement.  */
45169689Skanextern bool is_gimple_stmt (tree);
46169689Skan
47169689Skan/* Returns true iff TYPE is a valid type for a scalar register variable.  */
48169689Skanextern bool is_gimple_reg_type (tree);
49169689Skan/* Returns true iff T is a scalar register variable.  */
50169689Skanextern bool is_gimple_reg (tree);
51169689Skan/* Returns true if T is a GIMPLE temporary variable, false otherwise.  */
52169689Skanextern bool is_gimple_formal_tmp_var (tree);
53169689Skan/* Returns true if T is a GIMPLE temporary register variable.  */
54169689Skanextern bool is_gimple_formal_tmp_reg (tree);
55169689Skan/* Returns true iff T is any sort of variable.  */
56169689Skanextern bool is_gimple_variable (tree);
57169689Skan/* Returns true iff T is any sort of symbol.  */
58169689Skanextern bool is_gimple_id (tree);
59169689Skan/* Returns true iff T is a variable or an INDIRECT_REF (of a variable).  */
60169689Skanextern bool is_gimple_min_lval (tree);
61169689Skan/* Returns true iff T is something whose address can be taken.  */
62169689Skanextern bool is_gimple_addressable (tree);
63169689Skan/* Returns true iff T is any valid GIMPLE lvalue.  */
64169689Skanextern bool is_gimple_lvalue (tree);
65169689Skan
66169689Skan/* Returns true iff T is a GIMPLE restricted function invariant.  */
67169689Skanextern bool is_gimple_min_invariant (tree);
68169689Skan/* Returns true iff T is a GIMPLE rvalue.  */
69169689Skanextern bool is_gimple_val (tree);
70169689Skan/* Returns true iff T is a GIMPLE asm statement input.  */
71169689Skanextern bool is_gimple_asm_val (tree);
72169689Skan/* Returns true iff T is a valid rhs for a MODIFY_EXPR where the LHS is a
73169689Skan   GIMPLE temporary, a renamed user variable, or something else,
74169689Skan   respectively.  */
75169689Skanextern bool is_gimple_formal_tmp_rhs (tree);
76169689Skanextern bool is_gimple_reg_rhs (tree);
77169689Skanextern bool is_gimple_mem_rhs (tree);
78169689Skan/* Returns the appropriate one of the above three predicates for the LHS
79169689Skan   T.  */
80169689Skanextern gimple_predicate rhs_predicate_for (tree);
81169689Skan
82169689Skan/* Returns true iff T is a valid if-statement condition.  */
83169689Skanextern bool is_gimple_condexpr (tree);
84169689Skan
85169689Skan/* Returns true iff T is a type conversion.  */
86169689Skanextern bool is_gimple_cast (tree);
87169689Skan/* Returns true iff T is a variable that does not need to live in memory.  */
88169689Skanextern bool is_gimple_non_addressable (tree t);
89169689Skan
90169689Skan/* Returns true iff T is a valid call address expression.  */
91169689Skanextern bool is_gimple_call_addr (tree);
92169689Skan/* If T makes a function call, returns the CALL_EXPR operand.  */
93169689Skanextern tree get_call_expr_in (tree t);
94169689Skan
95169689Skanextern void recalculate_side_effects (tree);
96169689Skan
97169689Skan/* FIXME we should deduce this from the predicate.  */
98169689Skantypedef enum fallback_t {
99169689Skan  fb_none = 0,
100169689Skan  fb_rvalue = 1,
101169689Skan  fb_lvalue = 2,
102169689Skan  fb_mayfail = 4,
103169689Skan  fb_either= fb_rvalue | fb_lvalue
104169689Skan} fallback_t;
105169689Skan
106169689Skanenum gimplify_status {
107169689Skan  GS_ERROR	= -2,	/* Something Bad Seen.  */
108169689Skan  GS_UNHANDLED	= -1,	/* A langhook result for "I dunno".  */
109169689Skan  GS_OK		= 0,	/* We did something, maybe more to do.  */
110169689Skan  GS_ALL_DONE	= 1	/* The expression is fully gimplified.  */
111169689Skan};
112169689Skan
113169689Skanextern enum gimplify_status gimplify_expr (tree *, tree *, tree *,
114169689Skan					   bool (*) (tree), fallback_t);
115169689Skanextern void gimplify_type_sizes (tree, tree *);
116169689Skanextern void gimplify_one_sizepos (tree *, tree *);
117169689Skanextern void gimplify_stmt (tree *);
118169689Skanextern void gimplify_to_stmt_list (tree *);
119169689Skanextern void gimplify_body (tree *, tree, bool);
120169689Skanextern void push_gimplify_context (void);
121169689Skanextern void pop_gimplify_context (tree);
122169689Skanextern void gimplify_and_add (tree, tree *);
123169689Skan
124169689Skan/* Miscellaneous helpers.  */
125169689Skanextern void gimple_add_tmp_var (tree);
126169689Skanextern tree gimple_current_bind_expr (void);
127169689Skanextern tree voidify_wrapper_expr (tree, tree);
128169689Skanextern tree gimple_build_eh_filter (tree, tree, tree);
129169689Skanextern tree build_and_jump (tree *);
130169689Skanextern tree alloc_stmt_list (void);
131169689Skanextern void free_stmt_list (tree);
132169689Skanextern tree force_labels_r (tree *, int *, void *);
133169689Skanextern enum gimplify_status gimplify_va_arg_expr (tree *, tree *, tree *);
134169689Skanstruct gimplify_omp_ctx;
135169689Skanextern void omp_firstprivatize_variable (struct gimplify_omp_ctx *, tree);
136169689Skanextern tree gimple_boolify (tree);
137169689Skan
138169689Skan/* In omp-low.c.  */
139169689Skanextern void diagnose_omp_structured_block_errors (tree);
140169689Skanextern tree omp_reduction_init (tree, tree);
141169689Skan
142169689Skan/* In tree-nested.c.  */
143261188Spfg/* APPLE LOCAL radar 6305545 */
144261188Spfgextern void lower_nested_functions (tree, bool);
145169689Skanextern void insert_field_into_struct (tree, tree);
146169689Skan
147169689Skan/* Convenience routines to walk all statements of a gimple function.
148169689Skan   The difference between these walkers and the generic walk_tree is
149169689Skan   that walk_stmt provides context information to the callback
150169689Skan   routine to know whether it is currently on the LHS or RHS of an
151169689Skan   assignment (IS_LHS) or contexts where only GIMPLE values are
152169689Skan   allowed (VAL_ONLY).
153169689Skan
154169689Skan   This is useful in walkers that need to re-write sub-expressions
155169689Skan   inside statements while making sure the result is still in GIMPLE
156169689Skan   form.
157169689Skan
158169689Skan   Note that this is useful exclusively before the code is converted
159169689Skan   into SSA form.  Once the program is in SSA form, the standard
160169689Skan   operand interface should be used to analyze/modify statements.  */
161169689Skan
162169689Skanstruct walk_stmt_info
163169689Skan{
164169689Skan  /* For each statement, we invoke CALLBACK via walk_tree.  The passed
165169689Skan     data is a walk_stmt_info structure.  */
166169689Skan  walk_tree_fn callback;
167169689Skan
168169689Skan  /* Points to the current statement being walked.  */
169169689Skan  tree_stmt_iterator tsi;
170169689Skan
171169689Skan  /* Additional data that CALLBACK may want to carry through the
172169689Skan     recursion.  */
173169689Skan  void *info;
174169689Skan
175169689Skan  /* Indicates whether the *TP being examined may be replaced
176169689Skan     with something that matches is_gimple_val (if true) or something
177169689Skan     slightly more complicated (if false).  "Something" technically
178169689Skan     means the common subset of is_gimple_lvalue and is_gimple_rhs,
179169689Skan     but we never try to form anything more complicated than that, so
180169689Skan     we don't bother checking.
181169689Skan
182169689Skan     Also note that CALLBACK should update this flag while walking the
183169689Skan     sub-expressions of a statement.  For instance, when walking the
184169689Skan     statement 'foo (&var)', the flag VAL_ONLY will initially be set
185169689Skan     to true, however, when walking &var, the operand of that
186169689Skan     ADDR_EXPR does not need to be a GIMPLE value.  */
187169689Skan  bool val_only;
188169689Skan
189169689Skan  /* True if we are currently walking the LHS of an assignment.  */
190169689Skan  bool is_lhs;
191169689Skan
192169689Skan  /* Optional.  Set to true by CALLBACK if it made any changes.  */
193169689Skan  bool changed;
194169689Skan
195169689Skan  /* True if we're interested in seeing BIND_EXPRs.  */
196169689Skan  bool want_bind_expr;
197169689Skan
198169689Skan  /* True if we're interested in seeing RETURN_EXPRs.  */
199169689Skan  bool want_return_expr;
200169689Skan
201169689Skan  /* True if we're interested in location information.  */
202169689Skan  bool want_locations;
203169689Skan};
204169689Skan
205169689Skanvoid walk_stmts (struct walk_stmt_info *, tree *);
206169689Skan
207169689Skan#endif /* _TREE_SIMPLE_H  */
208