110d565efSmrg /* Gimple decl, type, and expression support functions.
210d565efSmrg
3*ec02198aSmrg Copyright (C) 2007-2020 Free Software Foundation, Inc.
410d565efSmrg Contributed by Aldy Hernandez <aldyh@redhat.com>
510d565efSmrg
610d565efSmrg This file is part of GCC.
710d565efSmrg
810d565efSmrg GCC is free software; you can redistribute it and/or modify it under
910d565efSmrg the terms of the GNU General Public License as published by the Free
1010d565efSmrg Software Foundation; either version 3, or (at your option) any later
1110d565efSmrg version.
1210d565efSmrg
1310d565efSmrg GCC is distributed in the hope that it will be useful, but WITHOUT ANY
1410d565efSmrg WARRANTY; without even the implied warranty of MERCHANTABILITY or
1510d565efSmrg FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
1610d565efSmrg for more details.
1710d565efSmrg
1810d565efSmrg You should have received a copy of the GNU General Public License
1910d565efSmrg along with GCC; see the file COPYING3. If not see
2010d565efSmrg <http://www.gnu.org/licenses/>. */
2110d565efSmrg
2210d565efSmrg #include "config.h"
2310d565efSmrg #include "system.h"
2410d565efSmrg #include "coretypes.h"
2510d565efSmrg #include "backend.h"
2610d565efSmrg #include "tree.h"
2710d565efSmrg #include "gimple.h"
2810d565efSmrg #include "stringpool.h"
2910d565efSmrg #include "gimple-ssa.h"
3010d565efSmrg #include "fold-const.h"
3110d565efSmrg #include "tree-eh.h"
3210d565efSmrg #include "gimplify.h"
3310d565efSmrg #include "stor-layout.h"
3410d565efSmrg #include "demangle.h"
3510d565efSmrg #include "hash-set.h"
3610d565efSmrg #include "rtl.h"
3710d565efSmrg #include "tree-pass.h"
38c7a68eb7Smrg #include "stringpool.h"
39c7a68eb7Smrg #include "attribs.h"
40*ec02198aSmrg #include "target.h"
4110d565efSmrg
4210d565efSmrg /* ----- Type related ----- */
4310d565efSmrg
4410d565efSmrg /* Return true if the conversion from INNER_TYPE to OUTER_TYPE is a
4510d565efSmrg useless type conversion, otherwise return false.
4610d565efSmrg
4710d565efSmrg This function implicitly defines the middle-end type system. With
4810d565efSmrg the notion of 'a < b' meaning that useless_type_conversion_p (a, b)
4910d565efSmrg holds and 'a > b' meaning that useless_type_conversion_p (b, a) holds,
5010d565efSmrg the following invariants shall be fulfilled:
5110d565efSmrg
5210d565efSmrg 1) useless_type_conversion_p is transitive.
5310d565efSmrg If a < b and b < c then a < c.
5410d565efSmrg
5510d565efSmrg 2) useless_type_conversion_p is not symmetric.
5610d565efSmrg From a < b does not follow a > b.
5710d565efSmrg
5810d565efSmrg 3) Types define the available set of operations applicable to values.
5910d565efSmrg A type conversion is useless if the operations for the target type
6010d565efSmrg is a subset of the operations for the source type. For example
6110d565efSmrg casts to void* are useless, casts from void* are not (void* can't
6210d565efSmrg be dereferenced or offsetted, but copied, hence its set of operations
6310d565efSmrg is a strict subset of that of all other data pointer types). Casts
6410d565efSmrg to const T* are useless (can't be written to), casts from const T*
6510d565efSmrg to T* are not. */
6610d565efSmrg
6710d565efSmrg bool
useless_type_conversion_p(tree outer_type,tree inner_type)6810d565efSmrg useless_type_conversion_p (tree outer_type, tree inner_type)
6910d565efSmrg {
7010d565efSmrg /* Do the following before stripping toplevel qualifiers. */
7110d565efSmrg if (POINTER_TYPE_P (inner_type)
7210d565efSmrg && POINTER_TYPE_P (outer_type))
7310d565efSmrg {
7410d565efSmrg /* Do not lose casts between pointers to different address spaces. */
7510d565efSmrg if (TYPE_ADDR_SPACE (TREE_TYPE (outer_type))
7610d565efSmrg != TYPE_ADDR_SPACE (TREE_TYPE (inner_type)))
7710d565efSmrg return false;
7810d565efSmrg /* Do not lose casts to function pointer types. */
7910d565efSmrg if ((TREE_CODE (TREE_TYPE (outer_type)) == FUNCTION_TYPE
8010d565efSmrg || TREE_CODE (TREE_TYPE (outer_type)) == METHOD_TYPE)
8110d565efSmrg && !(TREE_CODE (TREE_TYPE (inner_type)) == FUNCTION_TYPE
8210d565efSmrg || TREE_CODE (TREE_TYPE (inner_type)) == METHOD_TYPE))
8310d565efSmrg return false;
8410d565efSmrg }
8510d565efSmrg
8610d565efSmrg /* From now on qualifiers on value types do not matter. */
8710d565efSmrg inner_type = TYPE_MAIN_VARIANT (inner_type);
8810d565efSmrg outer_type = TYPE_MAIN_VARIANT (outer_type);
8910d565efSmrg
9010d565efSmrg if (inner_type == outer_type)
9110d565efSmrg return true;
9210d565efSmrg
9310d565efSmrg /* Changes in machine mode are never useless conversions because the RTL
9410d565efSmrg middle-end expects explicit conversions between modes. */
9510d565efSmrg if (TYPE_MODE (inner_type) != TYPE_MODE (outer_type))
9610d565efSmrg return false;
9710d565efSmrg
9810d565efSmrg /* If both the inner and outer types are integral types, then the
9910d565efSmrg conversion is not necessary if they have the same mode and
10010d565efSmrg signedness and precision, and both or neither are boolean. */
10110d565efSmrg if (INTEGRAL_TYPE_P (inner_type)
10210d565efSmrg && INTEGRAL_TYPE_P (outer_type))
10310d565efSmrg {
10410d565efSmrg /* Preserve changes in signedness or precision. */
10510d565efSmrg if (TYPE_UNSIGNED (inner_type) != TYPE_UNSIGNED (outer_type)
10610d565efSmrg || TYPE_PRECISION (inner_type) != TYPE_PRECISION (outer_type))
10710d565efSmrg return false;
10810d565efSmrg
10910d565efSmrg /* Preserve conversions to/from BOOLEAN_TYPE if types are not
11010d565efSmrg of precision one. */
11110d565efSmrg if (((TREE_CODE (inner_type) == BOOLEAN_TYPE)
11210d565efSmrg != (TREE_CODE (outer_type) == BOOLEAN_TYPE))
11310d565efSmrg && TYPE_PRECISION (outer_type) != 1)
11410d565efSmrg return false;
11510d565efSmrg
11610d565efSmrg /* We don't need to preserve changes in the types minimum or
11710d565efSmrg maximum value in general as these do not generate code
11810d565efSmrg unless the types precisions are different. */
11910d565efSmrg return true;
12010d565efSmrg }
12110d565efSmrg
12210d565efSmrg /* Scalar floating point types with the same mode are compatible. */
12310d565efSmrg else if (SCALAR_FLOAT_TYPE_P (inner_type)
12410d565efSmrg && SCALAR_FLOAT_TYPE_P (outer_type))
12510d565efSmrg return true;
12610d565efSmrg
12710d565efSmrg /* Fixed point types with the same mode are compatible. */
12810d565efSmrg else if (FIXED_POINT_TYPE_P (inner_type)
12910d565efSmrg && FIXED_POINT_TYPE_P (outer_type))
13010d565efSmrg return TYPE_SATURATING (inner_type) == TYPE_SATURATING (outer_type);
13110d565efSmrg
13210d565efSmrg /* We need to take special care recursing to pointed-to types. */
13310d565efSmrg else if (POINTER_TYPE_P (inner_type)
13410d565efSmrg && POINTER_TYPE_P (outer_type))
13510d565efSmrg {
13610d565efSmrg /* We do not care for const qualification of the pointed-to types
13710d565efSmrg as const qualification has no semantic value to the middle-end. */
13810d565efSmrg
13910d565efSmrg /* Otherwise pointers/references are equivalent. */
14010d565efSmrg return true;
14110d565efSmrg }
14210d565efSmrg
14310d565efSmrg /* Recurse for complex types. */
14410d565efSmrg else if (TREE_CODE (inner_type) == COMPLEX_TYPE
14510d565efSmrg && TREE_CODE (outer_type) == COMPLEX_TYPE)
14610d565efSmrg return useless_type_conversion_p (TREE_TYPE (outer_type),
14710d565efSmrg TREE_TYPE (inner_type));
14810d565efSmrg
14910d565efSmrg /* Recurse for vector types with the same number of subparts. */
15010d565efSmrg else if (TREE_CODE (inner_type) == VECTOR_TYPE
151*ec02198aSmrg && TREE_CODE (outer_type) == VECTOR_TYPE)
152*ec02198aSmrg return (known_eq (TYPE_VECTOR_SUBPARTS (inner_type),
153*ec02198aSmrg TYPE_VECTOR_SUBPARTS (outer_type))
154*ec02198aSmrg && useless_type_conversion_p (TREE_TYPE (outer_type),
155*ec02198aSmrg TREE_TYPE (inner_type))
156*ec02198aSmrg && targetm.compatible_vector_types_p (inner_type, outer_type));
15710d565efSmrg
15810d565efSmrg else if (TREE_CODE (inner_type) == ARRAY_TYPE
15910d565efSmrg && TREE_CODE (outer_type) == ARRAY_TYPE)
16010d565efSmrg {
16110d565efSmrg /* Preserve various attributes. */
16210d565efSmrg if (TYPE_REVERSE_STORAGE_ORDER (inner_type)
16310d565efSmrg != TYPE_REVERSE_STORAGE_ORDER (outer_type))
16410d565efSmrg return false;
16510d565efSmrg if (TYPE_STRING_FLAG (inner_type) != TYPE_STRING_FLAG (outer_type))
16610d565efSmrg return false;
16710d565efSmrg
16810d565efSmrg /* Conversions from array types with unknown extent to
16910d565efSmrg array types with known extent are not useless. */
17010d565efSmrg if (!TYPE_DOMAIN (inner_type) && TYPE_DOMAIN (outer_type))
17110d565efSmrg return false;
17210d565efSmrg
17310d565efSmrg /* Nor are conversions from array types with non-constant size to
17410d565efSmrg array types with constant size or to different size. */
17510d565efSmrg if (TYPE_SIZE (outer_type)
17610d565efSmrg && TREE_CODE (TYPE_SIZE (outer_type)) == INTEGER_CST
17710d565efSmrg && (!TYPE_SIZE (inner_type)
17810d565efSmrg || TREE_CODE (TYPE_SIZE (inner_type)) != INTEGER_CST
17910d565efSmrg || !tree_int_cst_equal (TYPE_SIZE (outer_type),
18010d565efSmrg TYPE_SIZE (inner_type))))
18110d565efSmrg return false;
18210d565efSmrg
18310d565efSmrg /* Check conversions between arrays with partially known extents.
18410d565efSmrg If the array min/max values are constant they have to match.
18510d565efSmrg Otherwise allow conversions to unknown and variable extents.
18610d565efSmrg In particular this declares conversions that may change the
18710d565efSmrg mode to BLKmode as useless. */
18810d565efSmrg if (TYPE_DOMAIN (inner_type)
18910d565efSmrg && TYPE_DOMAIN (outer_type)
19010d565efSmrg && TYPE_DOMAIN (inner_type) != TYPE_DOMAIN (outer_type))
19110d565efSmrg {
19210d565efSmrg tree inner_min = TYPE_MIN_VALUE (TYPE_DOMAIN (inner_type));
19310d565efSmrg tree outer_min = TYPE_MIN_VALUE (TYPE_DOMAIN (outer_type));
19410d565efSmrg tree inner_max = TYPE_MAX_VALUE (TYPE_DOMAIN (inner_type));
19510d565efSmrg tree outer_max = TYPE_MAX_VALUE (TYPE_DOMAIN (outer_type));
19610d565efSmrg
19710d565efSmrg /* After gimplification a variable min/max value carries no
19810d565efSmrg additional information compared to a NULL value. All that
19910d565efSmrg matters has been lowered to be part of the IL. */
20010d565efSmrg if (inner_min && TREE_CODE (inner_min) != INTEGER_CST)
20110d565efSmrg inner_min = NULL_TREE;
20210d565efSmrg if (outer_min && TREE_CODE (outer_min) != INTEGER_CST)
20310d565efSmrg outer_min = NULL_TREE;
20410d565efSmrg if (inner_max && TREE_CODE (inner_max) != INTEGER_CST)
20510d565efSmrg inner_max = NULL_TREE;
20610d565efSmrg if (outer_max && TREE_CODE (outer_max) != INTEGER_CST)
20710d565efSmrg outer_max = NULL_TREE;
20810d565efSmrg
20910d565efSmrg /* Conversions NULL / variable <- cst are useless, but not
21010d565efSmrg the other way around. */
21110d565efSmrg if (outer_min
21210d565efSmrg && (!inner_min
21310d565efSmrg || !tree_int_cst_equal (inner_min, outer_min)))
21410d565efSmrg return false;
21510d565efSmrg if (outer_max
21610d565efSmrg && (!inner_max
21710d565efSmrg || !tree_int_cst_equal (inner_max, outer_max)))
21810d565efSmrg return false;
21910d565efSmrg }
22010d565efSmrg
22110d565efSmrg /* Recurse on the element check. */
22210d565efSmrg return useless_type_conversion_p (TREE_TYPE (outer_type),
22310d565efSmrg TREE_TYPE (inner_type));
22410d565efSmrg }
22510d565efSmrg
22610d565efSmrg else if ((TREE_CODE (inner_type) == FUNCTION_TYPE
22710d565efSmrg || TREE_CODE (inner_type) == METHOD_TYPE)
22810d565efSmrg && TREE_CODE (inner_type) == TREE_CODE (outer_type))
22910d565efSmrg {
23010d565efSmrg tree outer_parm, inner_parm;
23110d565efSmrg
23210d565efSmrg /* If the return types are not compatible bail out. */
23310d565efSmrg if (!useless_type_conversion_p (TREE_TYPE (outer_type),
23410d565efSmrg TREE_TYPE (inner_type)))
23510d565efSmrg return false;
23610d565efSmrg
23710d565efSmrg /* Method types should belong to a compatible base class. */
23810d565efSmrg if (TREE_CODE (inner_type) == METHOD_TYPE
23910d565efSmrg && !useless_type_conversion_p (TYPE_METHOD_BASETYPE (outer_type),
24010d565efSmrg TYPE_METHOD_BASETYPE (inner_type)))
24110d565efSmrg return false;
24210d565efSmrg
24310d565efSmrg /* A conversion to an unprototyped argument list is ok. */
24410d565efSmrg if (!prototype_p (outer_type))
24510d565efSmrg return true;
24610d565efSmrg
24710d565efSmrg /* If the unqualified argument types are compatible the conversion
24810d565efSmrg is useless. */
24910d565efSmrg if (TYPE_ARG_TYPES (outer_type) == TYPE_ARG_TYPES (inner_type))
25010d565efSmrg return true;
25110d565efSmrg
25210d565efSmrg for (outer_parm = TYPE_ARG_TYPES (outer_type),
25310d565efSmrg inner_parm = TYPE_ARG_TYPES (inner_type);
25410d565efSmrg outer_parm && inner_parm;
25510d565efSmrg outer_parm = TREE_CHAIN (outer_parm),
25610d565efSmrg inner_parm = TREE_CHAIN (inner_parm))
25710d565efSmrg if (!useless_type_conversion_p
25810d565efSmrg (TYPE_MAIN_VARIANT (TREE_VALUE (outer_parm)),
25910d565efSmrg TYPE_MAIN_VARIANT (TREE_VALUE (inner_parm))))
26010d565efSmrg return false;
26110d565efSmrg
26210d565efSmrg /* If there is a mismatch in the number of arguments the functions
26310d565efSmrg are not compatible. */
26410d565efSmrg if (outer_parm || inner_parm)
26510d565efSmrg return false;
26610d565efSmrg
26710d565efSmrg /* Defer to the target if necessary. */
26810d565efSmrg if (TYPE_ATTRIBUTES (inner_type) || TYPE_ATTRIBUTES (outer_type))
26910d565efSmrg return comp_type_attributes (outer_type, inner_type) != 0;
27010d565efSmrg
27110d565efSmrg return true;
27210d565efSmrg }
27310d565efSmrg
27410d565efSmrg /* For aggregates we rely on TYPE_CANONICAL exclusively and require
27510d565efSmrg explicit conversions for types involving to be structurally
27610d565efSmrg compared types. */
27710d565efSmrg else if (AGGREGATE_TYPE_P (inner_type)
27810d565efSmrg && TREE_CODE (inner_type) == TREE_CODE (outer_type))
27910d565efSmrg return TYPE_CANONICAL (inner_type)
28010d565efSmrg && TYPE_CANONICAL (inner_type) == TYPE_CANONICAL (outer_type);
28110d565efSmrg
28210d565efSmrg else if (TREE_CODE (inner_type) == OFFSET_TYPE
28310d565efSmrg && TREE_CODE (outer_type) == OFFSET_TYPE)
28410d565efSmrg return useless_type_conversion_p (TREE_TYPE (outer_type),
28510d565efSmrg TREE_TYPE (inner_type))
28610d565efSmrg && useless_type_conversion_p
28710d565efSmrg (TYPE_OFFSET_BASETYPE (outer_type),
28810d565efSmrg TYPE_OFFSET_BASETYPE (inner_type));
28910d565efSmrg
29010d565efSmrg return false;
29110d565efSmrg }
29210d565efSmrg
29310d565efSmrg
29410d565efSmrg /* ----- Decl related ----- */
29510d565efSmrg
29610d565efSmrg /* Set sequence SEQ to be the GIMPLE body for function FN. */
29710d565efSmrg
29810d565efSmrg void
gimple_set_body(tree fndecl,gimple_seq seq)29910d565efSmrg gimple_set_body (tree fndecl, gimple_seq seq)
30010d565efSmrg {
30110d565efSmrg struct function *fn = DECL_STRUCT_FUNCTION (fndecl);
30210d565efSmrg if (fn == NULL)
30310d565efSmrg {
30410d565efSmrg /* If FNDECL still does not have a function structure associated
30510d565efSmrg with it, then it does not make sense for it to receive a
30610d565efSmrg GIMPLE body. */
30710d565efSmrg gcc_assert (seq == NULL);
30810d565efSmrg }
30910d565efSmrg else
31010d565efSmrg fn->gimple_body = seq;
31110d565efSmrg }
31210d565efSmrg
31310d565efSmrg
31410d565efSmrg /* Return the body of GIMPLE statements for function FN. After the
31510d565efSmrg CFG pass, the function body doesn't exist anymore because it has
31610d565efSmrg been split up into basic blocks. In this case, it returns
31710d565efSmrg NULL. */
31810d565efSmrg
31910d565efSmrg gimple_seq
gimple_body(tree fndecl)32010d565efSmrg gimple_body (tree fndecl)
32110d565efSmrg {
32210d565efSmrg struct function *fn = DECL_STRUCT_FUNCTION (fndecl);
32310d565efSmrg return fn ? fn->gimple_body : NULL;
32410d565efSmrg }
32510d565efSmrg
32610d565efSmrg /* Return true when FNDECL has Gimple body either in unlowered
32710d565efSmrg or CFG form. */
32810d565efSmrg bool
gimple_has_body_p(tree fndecl)32910d565efSmrg gimple_has_body_p (tree fndecl)
33010d565efSmrg {
33110d565efSmrg struct function *fn = DECL_STRUCT_FUNCTION (fndecl);
33210d565efSmrg return (gimple_body (fndecl) || (fn && fn->cfg && !(fn->curr_properties & PROP_rtl)));
33310d565efSmrg }
33410d565efSmrg
33510d565efSmrg /* Return a printable name for symbol DECL. */
33610d565efSmrg
33710d565efSmrg const char *
gimple_decl_printable_name(tree decl,int verbosity)33810d565efSmrg gimple_decl_printable_name (tree decl, int verbosity)
33910d565efSmrg {
34010d565efSmrg if (!DECL_NAME (decl))
34110d565efSmrg return NULL;
34210d565efSmrg
343c7a68eb7Smrg if (HAS_DECL_ASSEMBLER_NAME_P (decl) && DECL_ASSEMBLER_NAME_SET_P (decl))
34410d565efSmrg {
34510d565efSmrg int dmgl_opts = DMGL_NO_OPTS;
34610d565efSmrg
34710d565efSmrg if (verbosity >= 2)
34810d565efSmrg {
34910d565efSmrg dmgl_opts = DMGL_VERBOSE
35010d565efSmrg | DMGL_ANSI
35110d565efSmrg | DMGL_GNU_V3
35210d565efSmrg | DMGL_RET_POSTFIX;
35310d565efSmrg if (TREE_CODE (decl) == FUNCTION_DECL)
35410d565efSmrg dmgl_opts |= DMGL_PARAMS;
35510d565efSmrg }
35610d565efSmrg
357c7a68eb7Smrg const char *mangled_str
358c7a68eb7Smrg = IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME_RAW (decl));
359c7a68eb7Smrg const char *str = cplus_demangle_v3 (mangled_str, dmgl_opts);
360c7a68eb7Smrg return str ? str : mangled_str;
36110d565efSmrg }
36210d565efSmrg
36310d565efSmrg return IDENTIFIER_POINTER (DECL_NAME (decl));
36410d565efSmrg }
36510d565efSmrg
36610d565efSmrg
36710d565efSmrg /* Create a new VAR_DECL and copy information from VAR to it. */
36810d565efSmrg
36910d565efSmrg tree
copy_var_decl(tree var,tree name,tree type)37010d565efSmrg copy_var_decl (tree var, tree name, tree type)
37110d565efSmrg {
37210d565efSmrg tree copy = build_decl (DECL_SOURCE_LOCATION (var), VAR_DECL, name, type);
37310d565efSmrg
37410d565efSmrg TREE_ADDRESSABLE (copy) = TREE_ADDRESSABLE (var);
37510d565efSmrg TREE_THIS_VOLATILE (copy) = TREE_THIS_VOLATILE (var);
37610d565efSmrg DECL_GIMPLE_REG_P (copy) = DECL_GIMPLE_REG_P (var);
37710d565efSmrg DECL_ARTIFICIAL (copy) = DECL_ARTIFICIAL (var);
37810d565efSmrg DECL_IGNORED_P (copy) = DECL_IGNORED_P (var);
37910d565efSmrg DECL_CONTEXT (copy) = DECL_CONTEXT (var);
38010d565efSmrg TREE_NO_WARNING (copy) = TREE_NO_WARNING (var);
38110d565efSmrg TREE_USED (copy) = 1;
38210d565efSmrg DECL_SEEN_IN_BIND_EXPR_P (copy) = 1;
38310d565efSmrg DECL_ATTRIBUTES (copy) = DECL_ATTRIBUTES (var);
38410d565efSmrg if (DECL_USER_ALIGN (var))
38510d565efSmrg {
38610d565efSmrg SET_DECL_ALIGN (copy, DECL_ALIGN (var));
38710d565efSmrg DECL_USER_ALIGN (copy) = 1;
38810d565efSmrg }
38910d565efSmrg
39010d565efSmrg return copy;
39110d565efSmrg }
39210d565efSmrg
39310d565efSmrg /* Strip off a legitimate source ending from the input string NAME of
39410d565efSmrg length LEN. Rather than having to know the names used by all of
39510d565efSmrg our front ends, we strip off an ending of a period followed by
396c7a68eb7Smrg up to four characters. (like ".cpp".) */
39710d565efSmrg
39810d565efSmrg static inline void
remove_suffix(char * name,int len)39910d565efSmrg remove_suffix (char *name, int len)
40010d565efSmrg {
40110d565efSmrg int i;
40210d565efSmrg
403c7a68eb7Smrg for (i = 2; i < 7 && len > i; i++)
40410d565efSmrg {
40510d565efSmrg if (name[len - i] == '.')
40610d565efSmrg {
40710d565efSmrg name[len - i] = '\0';
40810d565efSmrg break;
40910d565efSmrg }
41010d565efSmrg }
41110d565efSmrg }
41210d565efSmrg
41310d565efSmrg /* Create a new temporary name with PREFIX. Return an identifier. */
41410d565efSmrg
41510d565efSmrg static GTY(()) unsigned int tmp_var_id_num;
41610d565efSmrg
41710d565efSmrg tree
create_tmp_var_name(const char * prefix)41810d565efSmrg create_tmp_var_name (const char *prefix)
41910d565efSmrg {
42010d565efSmrg char *tmp_name;
42110d565efSmrg
42210d565efSmrg if (prefix)
42310d565efSmrg {
42410d565efSmrg char *preftmp = ASTRDUP (prefix);
42510d565efSmrg
42610d565efSmrg remove_suffix (preftmp, strlen (preftmp));
42710d565efSmrg clean_symbol_name (preftmp);
42810d565efSmrg
42910d565efSmrg prefix = preftmp;
43010d565efSmrg }
43110d565efSmrg
43210d565efSmrg ASM_FORMAT_PRIVATE_NAME (tmp_name, prefix ? prefix : "T", tmp_var_id_num++);
43310d565efSmrg return get_identifier (tmp_name);
43410d565efSmrg }
43510d565efSmrg
43610d565efSmrg /* Create a new temporary variable declaration of type TYPE.
43710d565efSmrg Do NOT push it into the current binding. */
43810d565efSmrg
43910d565efSmrg tree
create_tmp_var_raw(tree type,const char * prefix)44010d565efSmrg create_tmp_var_raw (tree type, const char *prefix)
44110d565efSmrg {
44210d565efSmrg tree tmp_var;
44310d565efSmrg
44410d565efSmrg tmp_var = build_decl (input_location,
44510d565efSmrg VAR_DECL, prefix ? create_tmp_var_name (prefix) : NULL,
44610d565efSmrg type);
44710d565efSmrg
44810d565efSmrg /* The variable was declared by the compiler. */
44910d565efSmrg DECL_ARTIFICIAL (tmp_var) = 1;
45010d565efSmrg /* And we don't want debug info for it. */
45110d565efSmrg DECL_IGNORED_P (tmp_var) = 1;
452c7a68eb7Smrg /* And we don't want even the fancy names of those printed in
453c7a68eb7Smrg -fdump-final-insns= dumps. */
454c7a68eb7Smrg DECL_NAMELESS (tmp_var) = 1;
45510d565efSmrg
45610d565efSmrg /* Make the variable writable. */
45710d565efSmrg TREE_READONLY (tmp_var) = 0;
45810d565efSmrg
45910d565efSmrg DECL_EXTERNAL (tmp_var) = 0;
46010d565efSmrg TREE_STATIC (tmp_var) = 0;
46110d565efSmrg TREE_USED (tmp_var) = 1;
46210d565efSmrg
46310d565efSmrg return tmp_var;
46410d565efSmrg }
46510d565efSmrg
46610d565efSmrg /* Create a new temporary variable declaration of type TYPE. DO push the
46710d565efSmrg variable into the current binding. Further, assume that this is called
46810d565efSmrg only from gimplification or optimization, at which point the creation of
46910d565efSmrg certain types are bugs. */
47010d565efSmrg
47110d565efSmrg tree
create_tmp_var(tree type,const char * prefix)47210d565efSmrg create_tmp_var (tree type, const char *prefix)
47310d565efSmrg {
47410d565efSmrg tree tmp_var;
47510d565efSmrg
47610d565efSmrg /* We don't allow types that are addressable (meaning we can't make copies),
47710d565efSmrg or incomplete. We also used to reject every variable size objects here,
47810d565efSmrg but now support those for which a constant upper bound can be obtained.
47910d565efSmrg The processing for variable sizes is performed in gimple_add_tmp_var,
48010d565efSmrg point at which it really matters and possibly reached via paths not going
48110d565efSmrg through this function, e.g. after direct calls to create_tmp_var_raw. */
48210d565efSmrg gcc_assert (!TREE_ADDRESSABLE (type) && COMPLETE_TYPE_P (type));
48310d565efSmrg
48410d565efSmrg tmp_var = create_tmp_var_raw (type, prefix);
48510d565efSmrg gimple_add_tmp_var (tmp_var);
48610d565efSmrg return tmp_var;
48710d565efSmrg }
48810d565efSmrg
48910d565efSmrg /* Create a new temporary variable declaration of type TYPE by calling
49010d565efSmrg create_tmp_var and if TYPE is a vector or a complex number, mark the new
49110d565efSmrg temporary as gimple register. */
49210d565efSmrg
49310d565efSmrg tree
create_tmp_reg(tree type,const char * prefix)49410d565efSmrg create_tmp_reg (tree type, const char *prefix)
49510d565efSmrg {
49610d565efSmrg tree tmp;
49710d565efSmrg
49810d565efSmrg tmp = create_tmp_var (type, prefix);
49910d565efSmrg if (TREE_CODE (type) == COMPLEX_TYPE
50010d565efSmrg || TREE_CODE (type) == VECTOR_TYPE)
50110d565efSmrg DECL_GIMPLE_REG_P (tmp) = 1;
50210d565efSmrg
50310d565efSmrg return tmp;
50410d565efSmrg }
50510d565efSmrg
50610d565efSmrg /* Create a new temporary variable declaration of type TYPE by calling
50710d565efSmrg create_tmp_var and if TYPE is a vector or a complex number, mark the new
50810d565efSmrg temporary as gimple register. */
50910d565efSmrg
51010d565efSmrg tree
create_tmp_reg_fn(struct function * fn,tree type,const char * prefix)51110d565efSmrg create_tmp_reg_fn (struct function *fn, tree type, const char *prefix)
51210d565efSmrg {
51310d565efSmrg tree tmp;
51410d565efSmrg
51510d565efSmrg tmp = create_tmp_var_raw (type, prefix);
51610d565efSmrg gimple_add_tmp_var_fn (fn, tmp);
51710d565efSmrg if (TREE_CODE (type) == COMPLEX_TYPE
51810d565efSmrg || TREE_CODE (type) == VECTOR_TYPE)
51910d565efSmrg DECL_GIMPLE_REG_P (tmp) = 1;
52010d565efSmrg
52110d565efSmrg return tmp;
52210d565efSmrg }
52310d565efSmrg
52410d565efSmrg
52510d565efSmrg /* ----- Expression related ----- */
52610d565efSmrg
52710d565efSmrg /* Extract the operands and code for expression EXPR into *SUBCODE_P,
52810d565efSmrg *OP1_P, *OP2_P and *OP3_P respectively. */
52910d565efSmrg
53010d565efSmrg void
extract_ops_from_tree(tree expr,enum tree_code * subcode_p,tree * op1_p,tree * op2_p,tree * op3_p)53110d565efSmrg extract_ops_from_tree (tree expr, enum tree_code *subcode_p, tree *op1_p,
53210d565efSmrg tree *op2_p, tree *op3_p)
53310d565efSmrg {
53410d565efSmrg *subcode_p = TREE_CODE (expr);
535*ec02198aSmrg switch (get_gimple_rhs_class (*subcode_p))
536*ec02198aSmrg {
537*ec02198aSmrg case GIMPLE_TERNARY_RHS:
53810d565efSmrg {
53910d565efSmrg *op1_p = TREE_OPERAND (expr, 0);
54010d565efSmrg *op2_p = TREE_OPERAND (expr, 1);
54110d565efSmrg *op3_p = TREE_OPERAND (expr, 2);
542*ec02198aSmrg break;
54310d565efSmrg }
544*ec02198aSmrg case GIMPLE_BINARY_RHS:
54510d565efSmrg {
54610d565efSmrg *op1_p = TREE_OPERAND (expr, 0);
54710d565efSmrg *op2_p = TREE_OPERAND (expr, 1);
54810d565efSmrg *op3_p = NULL_TREE;
549*ec02198aSmrg break;
55010d565efSmrg }
551*ec02198aSmrg case GIMPLE_UNARY_RHS:
55210d565efSmrg {
55310d565efSmrg *op1_p = TREE_OPERAND (expr, 0);
55410d565efSmrg *op2_p = NULL_TREE;
55510d565efSmrg *op3_p = NULL_TREE;
556*ec02198aSmrg break;
55710d565efSmrg }
558*ec02198aSmrg case GIMPLE_SINGLE_RHS:
55910d565efSmrg {
56010d565efSmrg *op1_p = expr;
56110d565efSmrg *op2_p = NULL_TREE;
56210d565efSmrg *op3_p = NULL_TREE;
563*ec02198aSmrg break;
56410d565efSmrg }
565*ec02198aSmrg default:
56610d565efSmrg gcc_unreachable ();
56710d565efSmrg }
568*ec02198aSmrg }
56910d565efSmrg
57010d565efSmrg /* Extract operands for a GIMPLE_COND statement out of COND_EXPR tree COND. */
57110d565efSmrg
57210d565efSmrg void
gimple_cond_get_ops_from_tree(tree cond,enum tree_code * code_p,tree * lhs_p,tree * rhs_p)57310d565efSmrg gimple_cond_get_ops_from_tree (tree cond, enum tree_code *code_p,
57410d565efSmrg tree *lhs_p, tree *rhs_p)
57510d565efSmrg {
57610d565efSmrg gcc_assert (COMPARISON_CLASS_P (cond)
57710d565efSmrg || TREE_CODE (cond) == TRUTH_NOT_EXPR
57810d565efSmrg || is_gimple_min_invariant (cond)
57910d565efSmrg || SSA_VAR_P (cond));
580*ec02198aSmrg gcc_checking_assert (!tree_could_throw_p (cond));
58110d565efSmrg
58210d565efSmrg extract_ops_from_tree (cond, code_p, lhs_p, rhs_p);
58310d565efSmrg
58410d565efSmrg /* Canonicalize conditionals of the form 'if (!VAL)'. */
58510d565efSmrg if (*code_p == TRUTH_NOT_EXPR)
58610d565efSmrg {
58710d565efSmrg *code_p = EQ_EXPR;
58810d565efSmrg gcc_assert (*lhs_p && *rhs_p == NULL_TREE);
58910d565efSmrg *rhs_p = build_zero_cst (TREE_TYPE (*lhs_p));
59010d565efSmrg }
59110d565efSmrg /* Canonicalize conditionals of the form 'if (VAL)' */
59210d565efSmrg else if (TREE_CODE_CLASS (*code_p) != tcc_comparison)
59310d565efSmrg {
59410d565efSmrg *code_p = NE_EXPR;
59510d565efSmrg gcc_assert (*lhs_p && *rhs_p == NULL_TREE);
59610d565efSmrg *rhs_p = build_zero_cst (TREE_TYPE (*lhs_p));
59710d565efSmrg }
59810d565efSmrg }
59910d565efSmrg
60010d565efSmrg /* Return true if T is a valid LHS for a GIMPLE assignment expression. */
60110d565efSmrg
60210d565efSmrg bool
is_gimple_lvalue(tree t)60310d565efSmrg is_gimple_lvalue (tree t)
60410d565efSmrg {
60510d565efSmrg return (is_gimple_addressable (t)
60610d565efSmrg || TREE_CODE (t) == WITH_SIZE_EXPR
60710d565efSmrg /* These are complex lvalues, but don't have addresses, so they
60810d565efSmrg go here. */
60910d565efSmrg || TREE_CODE (t) == BIT_FIELD_REF);
61010d565efSmrg }
61110d565efSmrg
612*ec02198aSmrg /* Helper for is_gimple_condexpr and is_gimple_condexpr_for_cond. */
613*ec02198aSmrg
614*ec02198aSmrg static bool
is_gimple_condexpr_1(tree t,bool allow_traps,bool allow_cplx)615*ec02198aSmrg is_gimple_condexpr_1 (tree t, bool allow_traps, bool allow_cplx)
616*ec02198aSmrg {
617*ec02198aSmrg tree op0;
618*ec02198aSmrg return (is_gimple_val (t)
619*ec02198aSmrg || (COMPARISON_CLASS_P (t)
620*ec02198aSmrg && (allow_traps || !tree_could_throw_p (t))
621*ec02198aSmrg && ((op0 = TREE_OPERAND (t, 0)), true)
622*ec02198aSmrg && (allow_cplx || TREE_CODE (TREE_TYPE (op0)) != COMPLEX_TYPE)
623*ec02198aSmrg && is_gimple_val (op0)
624*ec02198aSmrg && is_gimple_val (TREE_OPERAND (t, 1))));
625*ec02198aSmrg }
626*ec02198aSmrg
62710d565efSmrg /* Return true if T is a GIMPLE condition. */
62810d565efSmrg
62910d565efSmrg bool
is_gimple_condexpr(tree t)63010d565efSmrg is_gimple_condexpr (tree t)
63110d565efSmrg {
632*ec02198aSmrg /* Always split out _Complex type compares since complex lowering
633*ec02198aSmrg doesn't handle this case. */
634*ec02198aSmrg return is_gimple_condexpr_1 (t, true, false);
635*ec02198aSmrg }
636*ec02198aSmrg
637*ec02198aSmrg /* Like is_gimple_condexpr, but does not allow T to trap. */
638*ec02198aSmrg
639*ec02198aSmrg bool
is_gimple_condexpr_for_cond(tree t)640*ec02198aSmrg is_gimple_condexpr_for_cond (tree t)
641*ec02198aSmrg {
642*ec02198aSmrg return is_gimple_condexpr_1 (t, false, true);
64310d565efSmrg }
64410d565efSmrg
64510d565efSmrg /* Return true if T is a gimple address. */
64610d565efSmrg
64710d565efSmrg bool
is_gimple_address(const_tree t)64810d565efSmrg is_gimple_address (const_tree t)
64910d565efSmrg {
65010d565efSmrg tree op;
65110d565efSmrg
65210d565efSmrg if (TREE_CODE (t) != ADDR_EXPR)
65310d565efSmrg return false;
65410d565efSmrg
65510d565efSmrg op = TREE_OPERAND (t, 0);
65610d565efSmrg while (handled_component_p (op))
65710d565efSmrg {
65810d565efSmrg if ((TREE_CODE (op) == ARRAY_REF
65910d565efSmrg || TREE_CODE (op) == ARRAY_RANGE_REF)
66010d565efSmrg && !is_gimple_val (TREE_OPERAND (op, 1)))
66110d565efSmrg return false;
66210d565efSmrg
66310d565efSmrg op = TREE_OPERAND (op, 0);
66410d565efSmrg }
66510d565efSmrg
666c7a68eb7Smrg if (CONSTANT_CLASS_P (op)
667c7a68eb7Smrg || TREE_CODE (op) == TARGET_MEM_REF
668c7a68eb7Smrg || TREE_CODE (op) == MEM_REF)
66910d565efSmrg return true;
67010d565efSmrg
67110d565efSmrg switch (TREE_CODE (op))
67210d565efSmrg {
67310d565efSmrg case PARM_DECL:
67410d565efSmrg case RESULT_DECL:
67510d565efSmrg case LABEL_DECL:
67610d565efSmrg case FUNCTION_DECL:
67710d565efSmrg case VAR_DECL:
67810d565efSmrg case CONST_DECL:
67910d565efSmrg return true;
68010d565efSmrg
68110d565efSmrg default:
68210d565efSmrg return false;
68310d565efSmrg }
68410d565efSmrg }
68510d565efSmrg
68610d565efSmrg /* Return true if T is a gimple invariant address. */
68710d565efSmrg
68810d565efSmrg bool
is_gimple_invariant_address(const_tree t)68910d565efSmrg is_gimple_invariant_address (const_tree t)
69010d565efSmrg {
69110d565efSmrg const_tree op;
69210d565efSmrg
69310d565efSmrg if (TREE_CODE (t) != ADDR_EXPR)
69410d565efSmrg return false;
69510d565efSmrg
69610d565efSmrg op = strip_invariant_refs (TREE_OPERAND (t, 0));
69710d565efSmrg if (!op)
69810d565efSmrg return false;
69910d565efSmrg
70010d565efSmrg if (TREE_CODE (op) == MEM_REF)
70110d565efSmrg {
70210d565efSmrg const_tree op0 = TREE_OPERAND (op, 0);
70310d565efSmrg return (TREE_CODE (op0) == ADDR_EXPR
70410d565efSmrg && (CONSTANT_CLASS_P (TREE_OPERAND (op0, 0))
70510d565efSmrg || decl_address_invariant_p (TREE_OPERAND (op0, 0))));
70610d565efSmrg }
70710d565efSmrg
70810d565efSmrg return CONSTANT_CLASS_P (op) || decl_address_invariant_p (op);
70910d565efSmrg }
71010d565efSmrg
71110d565efSmrg /* Return true if T is a gimple invariant address at IPA level
71210d565efSmrg (so addresses of variables on stack are not allowed). */
71310d565efSmrg
71410d565efSmrg bool
is_gimple_ip_invariant_address(const_tree t)71510d565efSmrg is_gimple_ip_invariant_address (const_tree t)
71610d565efSmrg {
71710d565efSmrg const_tree op;
71810d565efSmrg
71910d565efSmrg if (TREE_CODE (t) != ADDR_EXPR)
72010d565efSmrg return false;
72110d565efSmrg
72210d565efSmrg op = strip_invariant_refs (TREE_OPERAND (t, 0));
72310d565efSmrg if (!op)
72410d565efSmrg return false;
72510d565efSmrg
72610d565efSmrg if (TREE_CODE (op) == MEM_REF)
72710d565efSmrg {
72810d565efSmrg const_tree op0 = TREE_OPERAND (op, 0);
72910d565efSmrg return (TREE_CODE (op0) == ADDR_EXPR
73010d565efSmrg && (CONSTANT_CLASS_P (TREE_OPERAND (op0, 0))
73110d565efSmrg || decl_address_ip_invariant_p (TREE_OPERAND (op0, 0))));
73210d565efSmrg }
73310d565efSmrg
73410d565efSmrg return CONSTANT_CLASS_P (op) || decl_address_ip_invariant_p (op);
73510d565efSmrg }
73610d565efSmrg
73710d565efSmrg /* Return true if T is a GIMPLE minimal invariant. It's a restricted
73810d565efSmrg form of function invariant. */
73910d565efSmrg
74010d565efSmrg bool
is_gimple_min_invariant(const_tree t)74110d565efSmrg is_gimple_min_invariant (const_tree t)
74210d565efSmrg {
74310d565efSmrg if (TREE_CODE (t) == ADDR_EXPR)
74410d565efSmrg return is_gimple_invariant_address (t);
74510d565efSmrg
74610d565efSmrg return is_gimple_constant (t);
74710d565efSmrg }
74810d565efSmrg
74910d565efSmrg /* Return true if T is a GIMPLE interprocedural invariant. It's a restricted
75010d565efSmrg form of gimple minimal invariant. */
75110d565efSmrg
75210d565efSmrg bool
is_gimple_ip_invariant(const_tree t)75310d565efSmrg is_gimple_ip_invariant (const_tree t)
75410d565efSmrg {
75510d565efSmrg if (TREE_CODE (t) == ADDR_EXPR)
75610d565efSmrg return is_gimple_ip_invariant_address (t);
75710d565efSmrg
75810d565efSmrg return is_gimple_constant (t);
75910d565efSmrg }
76010d565efSmrg
76110d565efSmrg /* Return true if T is a non-aggregate register variable. */
76210d565efSmrg
76310d565efSmrg bool
is_gimple_reg(tree t)76410d565efSmrg is_gimple_reg (tree t)
76510d565efSmrg {
76610d565efSmrg if (virtual_operand_p (t))
76710d565efSmrg return false;
76810d565efSmrg
76910d565efSmrg if (TREE_CODE (t) == SSA_NAME)
77010d565efSmrg return true;
77110d565efSmrg
77210d565efSmrg if (!is_gimple_variable (t))
77310d565efSmrg return false;
77410d565efSmrg
77510d565efSmrg if (!is_gimple_reg_type (TREE_TYPE (t)))
77610d565efSmrg return false;
77710d565efSmrg
77810d565efSmrg /* A volatile decl is not acceptable because we can't reuse it as
77910d565efSmrg needed. We need to copy it into a temp first. */
78010d565efSmrg if (TREE_THIS_VOLATILE (t))
78110d565efSmrg return false;
78210d565efSmrg
78310d565efSmrg /* We define "registers" as things that can be renamed as needed,
78410d565efSmrg which with our infrastructure does not apply to memory. */
78510d565efSmrg if (needs_to_live_in_memory (t))
78610d565efSmrg return false;
78710d565efSmrg
78810d565efSmrg /* Hard register variables are an interesting case. For those that
78910d565efSmrg are call-clobbered, we don't know where all the calls are, since
79010d565efSmrg we don't (want to) take into account which operations will turn
79110d565efSmrg into libcalls at the rtl level. For those that are call-saved,
79210d565efSmrg we don't currently model the fact that calls may in fact change
79310d565efSmrg global hard registers, nor do we examine ASM_CLOBBERS at the tree
79410d565efSmrg level, and so miss variable changes that might imply. All around,
79510d565efSmrg it seems safest to not do too much optimization with these at the
79610d565efSmrg tree level at all. We'll have to rely on the rtl optimizers to
79710d565efSmrg clean this up, as there we've got all the appropriate bits exposed. */
79810d565efSmrg if (TREE_CODE (t) == VAR_DECL && DECL_HARD_REGISTER (t))
79910d565efSmrg return false;
80010d565efSmrg
80110d565efSmrg /* Complex and vector values must have been put into SSA-like form.
80210d565efSmrg That is, no assignments to the individual components. */
80310d565efSmrg if (TREE_CODE (TREE_TYPE (t)) == COMPLEX_TYPE
80410d565efSmrg || TREE_CODE (TREE_TYPE (t)) == VECTOR_TYPE)
80510d565efSmrg return DECL_GIMPLE_REG_P (t);
80610d565efSmrg
80710d565efSmrg return true;
80810d565efSmrg }
80910d565efSmrg
81010d565efSmrg
81110d565efSmrg /* Return true if T is a GIMPLE rvalue, i.e. an identifier or a constant. */
81210d565efSmrg
81310d565efSmrg bool
is_gimple_val(tree t)81410d565efSmrg is_gimple_val (tree t)
81510d565efSmrg {
81610d565efSmrg /* Make loads from volatiles and memory vars explicit. */
81710d565efSmrg if (is_gimple_variable (t)
81810d565efSmrg && is_gimple_reg_type (TREE_TYPE (t))
81910d565efSmrg && !is_gimple_reg (t))
82010d565efSmrg return false;
82110d565efSmrg
82210d565efSmrg return (is_gimple_variable (t) || is_gimple_min_invariant (t));
82310d565efSmrg }
82410d565efSmrg
82510d565efSmrg /* Similarly, but accept hard registers as inputs to asm statements. */
82610d565efSmrg
82710d565efSmrg bool
is_gimple_asm_val(tree t)82810d565efSmrg is_gimple_asm_val (tree t)
82910d565efSmrg {
83010d565efSmrg if (TREE_CODE (t) == VAR_DECL && DECL_HARD_REGISTER (t))
83110d565efSmrg return true;
83210d565efSmrg
83310d565efSmrg return is_gimple_val (t);
83410d565efSmrg }
83510d565efSmrg
83610d565efSmrg /* Return true if T is a GIMPLE minimal lvalue. */
83710d565efSmrg
83810d565efSmrg bool
is_gimple_min_lval(tree t)83910d565efSmrg is_gimple_min_lval (tree t)
84010d565efSmrg {
84110d565efSmrg if (!(t = CONST_CAST_TREE (strip_invariant_refs (t))))
84210d565efSmrg return false;
84310d565efSmrg return (is_gimple_id (t) || TREE_CODE (t) == MEM_REF);
84410d565efSmrg }
84510d565efSmrg
84610d565efSmrg /* Return true if T is a valid function operand of a CALL_EXPR. */
84710d565efSmrg
84810d565efSmrg bool
is_gimple_call_addr(tree t)84910d565efSmrg is_gimple_call_addr (tree t)
85010d565efSmrg {
85110d565efSmrg return (TREE_CODE (t) == OBJ_TYPE_REF || is_gimple_val (t));
85210d565efSmrg }
85310d565efSmrg
85410d565efSmrg /* Return true if T is a valid address operand of a MEM_REF. */
85510d565efSmrg
85610d565efSmrg bool
is_gimple_mem_ref_addr(tree t)85710d565efSmrg is_gimple_mem_ref_addr (tree t)
85810d565efSmrg {
85910d565efSmrg return (is_gimple_reg (t)
86010d565efSmrg || TREE_CODE (t) == INTEGER_CST
86110d565efSmrg || (TREE_CODE (t) == ADDR_EXPR
86210d565efSmrg && (CONSTANT_CLASS_P (TREE_OPERAND (t, 0))
86310d565efSmrg || decl_address_invariant_p (TREE_OPERAND (t, 0)))));
86410d565efSmrg }
86510d565efSmrg
86610d565efSmrg /* Hold trees marked addressable during expand. */
86710d565efSmrg
86810d565efSmrg static hash_set<tree> *mark_addressable_queue;
86910d565efSmrg
87010d565efSmrg /* Mark X as addressable or queue it up if called during expand. We
87110d565efSmrg don't want to apply it immediately during expand because decls are
87210d565efSmrg made addressable at that point due to RTL-only concerns, such as
87310d565efSmrg uses of memcpy for block moves, and TREE_ADDRESSABLE changes
87410d565efSmrg is_gimple_reg, which might make it seem like a variable that used
87510d565efSmrg to be a gimple_reg shouldn't have been an SSA name. So we queue up
87610d565efSmrg this flag setting and only apply it when we're done with GIMPLE and
87710d565efSmrg only RTL issues matter. */
87810d565efSmrg
87910d565efSmrg static void
mark_addressable_1(tree x)88010d565efSmrg mark_addressable_1 (tree x)
88110d565efSmrg {
88210d565efSmrg if (!currently_expanding_to_rtl)
88310d565efSmrg {
88410d565efSmrg TREE_ADDRESSABLE (x) = 1;
88510d565efSmrg return;
88610d565efSmrg }
88710d565efSmrg
88810d565efSmrg if (!mark_addressable_queue)
88910d565efSmrg mark_addressable_queue = new hash_set<tree>();
89010d565efSmrg mark_addressable_queue->add (x);
89110d565efSmrg }
89210d565efSmrg
89310d565efSmrg /* Adaptor for mark_addressable_1 for use in hash_set traversal. */
89410d565efSmrg
89510d565efSmrg bool
89610d565efSmrg mark_addressable_2 (tree const &x, void * ATTRIBUTE_UNUSED = NULL)
89710d565efSmrg {
89810d565efSmrg mark_addressable_1 (x);
89910d565efSmrg return false;
90010d565efSmrg }
90110d565efSmrg
90210d565efSmrg /* Mark all queued trees as addressable, and empty the queue. To be
90310d565efSmrg called right after clearing CURRENTLY_EXPANDING_TO_RTL. */
90410d565efSmrg
90510d565efSmrg void
flush_mark_addressable_queue()90610d565efSmrg flush_mark_addressable_queue ()
90710d565efSmrg {
90810d565efSmrg gcc_assert (!currently_expanding_to_rtl);
90910d565efSmrg if (mark_addressable_queue)
91010d565efSmrg {
91110d565efSmrg mark_addressable_queue->traverse<void*, mark_addressable_2> (NULL);
91210d565efSmrg delete mark_addressable_queue;
91310d565efSmrg mark_addressable_queue = NULL;
91410d565efSmrg }
91510d565efSmrg }
91610d565efSmrg
91710d565efSmrg /* Mark X addressable. Unlike the langhook we expect X to be in gimple
91810d565efSmrg form and we don't do any syntax checking. */
91910d565efSmrg
92010d565efSmrg void
mark_addressable(tree x)92110d565efSmrg mark_addressable (tree x)
92210d565efSmrg {
92310d565efSmrg while (handled_component_p (x))
92410d565efSmrg x = TREE_OPERAND (x, 0);
92510d565efSmrg if (TREE_CODE (x) == MEM_REF
92610d565efSmrg && TREE_CODE (TREE_OPERAND (x, 0)) == ADDR_EXPR)
92710d565efSmrg x = TREE_OPERAND (TREE_OPERAND (x, 0), 0);
92810d565efSmrg if (!VAR_P (x)
92910d565efSmrg && TREE_CODE (x) != PARM_DECL
93010d565efSmrg && TREE_CODE (x) != RESULT_DECL)
93110d565efSmrg return;
93210d565efSmrg mark_addressable_1 (x);
93310d565efSmrg
93410d565efSmrg /* Also mark the artificial SSA_NAME that points to the partition of X. */
93510d565efSmrg if (TREE_CODE (x) == VAR_DECL
93610d565efSmrg && !DECL_EXTERNAL (x)
93710d565efSmrg && !TREE_STATIC (x)
93810d565efSmrg && cfun->gimple_df != NULL
93910d565efSmrg && cfun->gimple_df->decls_to_pointers != NULL)
94010d565efSmrg {
94110d565efSmrg tree *namep = cfun->gimple_df->decls_to_pointers->get (x);
94210d565efSmrg if (namep)
94310d565efSmrg mark_addressable_1 (*namep);
94410d565efSmrg }
94510d565efSmrg }
94610d565efSmrg
94710d565efSmrg /* Returns true iff T is a valid RHS for an assignment to a renamed
94810d565efSmrg user -- or front-end generated artificial -- variable. */
94910d565efSmrg
95010d565efSmrg bool
is_gimple_reg_rhs(tree t)95110d565efSmrg is_gimple_reg_rhs (tree t)
95210d565efSmrg {
95310d565efSmrg return get_gimple_rhs_class (TREE_CODE (t)) != GIMPLE_INVALID_RHS;
95410d565efSmrg }
95510d565efSmrg
95610d565efSmrg #include "gt-gimple-expr.h"
957