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