xref: /netbsd-src/external/gpl3/gcc.old/dist/gcc/tree-ssa.c (revision 23f5f46327e37e7811da3520f4bb933f9489322f)
11debfc3dSmrg /* Miscellaneous SSA utility functions.
28feb0f0bSmrg    Copyright (C) 2001-2020 Free Software Foundation, Inc.
31debfc3dSmrg 
41debfc3dSmrg This file is part of GCC.
51debfc3dSmrg 
61debfc3dSmrg GCC is free software; you can redistribute it and/or modify
71debfc3dSmrg it under the terms of the GNU General Public License as published by
81debfc3dSmrg the Free Software Foundation; either version 3, or (at your option)
91debfc3dSmrg any later version.
101debfc3dSmrg 
111debfc3dSmrg GCC is distributed in the hope that it will be useful,
121debfc3dSmrg but WITHOUT ANY WARRANTY; without even the implied warranty of
131debfc3dSmrg MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
141debfc3dSmrg GNU General Public License for more details.
151debfc3dSmrg 
161debfc3dSmrg You should have received a copy of the GNU General Public License
171debfc3dSmrg along with GCC; see the file COPYING3.  If not see
181debfc3dSmrg <http://www.gnu.org/licenses/>.  */
191debfc3dSmrg 
201debfc3dSmrg #include "config.h"
211debfc3dSmrg #include "system.h"
221debfc3dSmrg #include "coretypes.h"
231debfc3dSmrg #include "backend.h"
241debfc3dSmrg #include "tree.h"
251debfc3dSmrg #include "gimple.h"
261debfc3dSmrg #include "cfghooks.h"
271debfc3dSmrg #include "tree-pass.h"
281debfc3dSmrg #include "ssa.h"
291debfc3dSmrg #include "gimple-pretty-print.h"
301debfc3dSmrg #include "diagnostic-core.h"
311debfc3dSmrg #include "fold-const.h"
321debfc3dSmrg #include "stor-layout.h"
331debfc3dSmrg #include "gimple-fold.h"
341debfc3dSmrg #include "gimplify.h"
351debfc3dSmrg #include "gimple-iterator.h"
361debfc3dSmrg #include "gimple-walk.h"
371debfc3dSmrg #include "tree-ssa-loop-manip.h"
381debfc3dSmrg #include "tree-into-ssa.h"
391debfc3dSmrg #include "tree-ssa.h"
401debfc3dSmrg #include "cfgloop.h"
411debfc3dSmrg #include "cfgexpand.h"
421debfc3dSmrg #include "tree-cfg.h"
431debfc3dSmrg #include "tree-dfa.h"
44a2dc1f3fSmrg #include "stringpool.h"
45a2dc1f3fSmrg #include "attribs.h"
461debfc3dSmrg #include "asan.h"
471debfc3dSmrg 
481debfc3dSmrg /* Pointer map of variable mappings, keyed by edge.  */
491debfc3dSmrg static hash_map<edge, auto_vec<edge_var_map> > *edge_var_maps;
501debfc3dSmrg 
511debfc3dSmrg 
521debfc3dSmrg /* Add a mapping with PHI RESULT and PHI DEF associated with edge E.  */
531debfc3dSmrg 
541debfc3dSmrg void
redirect_edge_var_map_add(edge e,tree result,tree def,location_t locus)55c0a68be4Smrg redirect_edge_var_map_add (edge e, tree result, tree def, location_t locus)
561debfc3dSmrg {
571debfc3dSmrg   edge_var_map new_node;
581debfc3dSmrg 
591debfc3dSmrg   if (edge_var_maps == NULL)
601debfc3dSmrg     edge_var_maps = new hash_map<edge, auto_vec<edge_var_map> >;
611debfc3dSmrg 
621debfc3dSmrg   auto_vec<edge_var_map> &slot = edge_var_maps->get_or_insert (e);
631debfc3dSmrg   new_node.def = def;
641debfc3dSmrg   new_node.result = result;
651debfc3dSmrg   new_node.locus = locus;
661debfc3dSmrg 
671debfc3dSmrg   slot.safe_push (new_node);
681debfc3dSmrg }
691debfc3dSmrg 
701debfc3dSmrg 
711debfc3dSmrg /* Clear the var mappings in edge E.  */
721debfc3dSmrg 
731debfc3dSmrg void
redirect_edge_var_map_clear(edge e)741debfc3dSmrg redirect_edge_var_map_clear (edge e)
751debfc3dSmrg {
761debfc3dSmrg   if (!edge_var_maps)
771debfc3dSmrg     return;
781debfc3dSmrg 
791debfc3dSmrg   auto_vec<edge_var_map> *head = edge_var_maps->get (e);
801debfc3dSmrg 
811debfc3dSmrg   if (head)
821debfc3dSmrg     head->release ();
831debfc3dSmrg }
841debfc3dSmrg 
851debfc3dSmrg 
861debfc3dSmrg /* Duplicate the redirected var mappings in OLDE in NEWE.
871debfc3dSmrg 
881debfc3dSmrg    This assumes a hash_map can have multiple edges mapping to the same
891debfc3dSmrg    var_map (many to one mapping), since we don't remove the previous mappings.
901debfc3dSmrg    */
911debfc3dSmrg 
921debfc3dSmrg void
redirect_edge_var_map_dup(edge newe,edge olde)931debfc3dSmrg redirect_edge_var_map_dup (edge newe, edge olde)
941debfc3dSmrg {
951debfc3dSmrg   if (!edge_var_maps)
961debfc3dSmrg     return;
971debfc3dSmrg 
981debfc3dSmrg   auto_vec<edge_var_map> *new_head = &edge_var_maps->get_or_insert (newe);
991debfc3dSmrg   auto_vec<edge_var_map> *old_head = edge_var_maps->get (olde);
1001debfc3dSmrg   if (!old_head)
1011debfc3dSmrg     return;
1021debfc3dSmrg 
1031debfc3dSmrg   new_head->safe_splice (*old_head);
1041debfc3dSmrg }
1051debfc3dSmrg 
1061debfc3dSmrg 
1071debfc3dSmrg /* Return the variable mappings for a given edge.  If there is none, return
1081debfc3dSmrg    NULL.  */
1091debfc3dSmrg 
1101debfc3dSmrg vec<edge_var_map> *
redirect_edge_var_map_vector(edge e)1111debfc3dSmrg redirect_edge_var_map_vector (edge e)
1121debfc3dSmrg {
1131debfc3dSmrg   /* Hey, what kind of idiot would... you'd be surprised.  */
1141debfc3dSmrg   if (!edge_var_maps)
1151debfc3dSmrg     return NULL;
1161debfc3dSmrg 
1171debfc3dSmrg   auto_vec<edge_var_map> *slot = edge_var_maps->get (e);
1181debfc3dSmrg   if (!slot)
1191debfc3dSmrg     return NULL;
1201debfc3dSmrg 
1211debfc3dSmrg   return slot;
1221debfc3dSmrg }
1231debfc3dSmrg 
1241debfc3dSmrg /* Clear the edge variable mappings.  */
1251debfc3dSmrg 
1261debfc3dSmrg void
redirect_edge_var_map_empty(void)1271debfc3dSmrg redirect_edge_var_map_empty (void)
1281debfc3dSmrg {
1291debfc3dSmrg   if (edge_var_maps)
1301debfc3dSmrg     edge_var_maps->empty ();
1311debfc3dSmrg }
1321debfc3dSmrg 
1331debfc3dSmrg 
1341debfc3dSmrg /* Remove the corresponding arguments from the PHI nodes in E's
1351debfc3dSmrg    destination block and redirect it to DEST.  Return redirected edge.
1361debfc3dSmrg    The list of removed arguments is stored in a vector accessed
1371debfc3dSmrg    through edge_var_maps.  */
1381debfc3dSmrg 
1391debfc3dSmrg edge
ssa_redirect_edge(edge e,basic_block dest)1401debfc3dSmrg ssa_redirect_edge (edge e, basic_block dest)
1411debfc3dSmrg {
1421debfc3dSmrg   gphi_iterator gsi;
1431debfc3dSmrg   gphi *phi;
1441debfc3dSmrg 
1451debfc3dSmrg   redirect_edge_var_map_clear (e);
1461debfc3dSmrg 
147a2dc1f3fSmrg   /* Remove the appropriate PHI arguments in E's destination block.
148a2dc1f3fSmrg      If we are redirecting a copied edge the destination has not
149a2dc1f3fSmrg      got PHI argument space reserved nor an interesting argument.  */
150a2dc1f3fSmrg   if (! (e->dest->flags & BB_DUPLICATED))
1511debfc3dSmrg     for (gsi = gsi_start_phis (e->dest); !gsi_end_p (gsi); gsi_next (&gsi))
1521debfc3dSmrg       {
1531debfc3dSmrg 	tree def;
154c0a68be4Smrg 	location_t locus;
1551debfc3dSmrg 
1561debfc3dSmrg 	phi = gsi.phi ();
1571debfc3dSmrg 	def = gimple_phi_arg_def (phi, e->dest_idx);
1581debfc3dSmrg 	locus = gimple_phi_arg_location (phi, e->dest_idx);
1591debfc3dSmrg 
1601debfc3dSmrg 	if (def == NULL_TREE)
1611debfc3dSmrg 	  continue;
1621debfc3dSmrg 
1631debfc3dSmrg 	redirect_edge_var_map_add (e, gimple_phi_result (phi), def, locus);
1641debfc3dSmrg       }
1651debfc3dSmrg 
1661debfc3dSmrg   e = redirect_edge_succ_nodup (e, dest);
1671debfc3dSmrg 
1681debfc3dSmrg   return e;
1691debfc3dSmrg }
1701debfc3dSmrg 
1711debfc3dSmrg 
1721debfc3dSmrg /* Add PHI arguments queued in PENDING_STMT list on edge E to edge
1731debfc3dSmrg    E->dest.  */
1741debfc3dSmrg 
1751debfc3dSmrg void
flush_pending_stmts(edge e)1761debfc3dSmrg flush_pending_stmts (edge e)
1771debfc3dSmrg {
1781debfc3dSmrg   gphi *phi;
1791debfc3dSmrg   edge_var_map *vm;
1801debfc3dSmrg   int i;
1811debfc3dSmrg   gphi_iterator gsi;
1821debfc3dSmrg 
1831debfc3dSmrg   vec<edge_var_map> *v = redirect_edge_var_map_vector (e);
1841debfc3dSmrg   if (!v)
1851debfc3dSmrg     return;
1861debfc3dSmrg 
1871debfc3dSmrg   for (gsi = gsi_start_phis (e->dest), i = 0;
1881debfc3dSmrg        !gsi_end_p (gsi) && v->iterate (i, &vm);
1891debfc3dSmrg        gsi_next (&gsi), i++)
1901debfc3dSmrg     {
1911debfc3dSmrg       tree def;
1921debfc3dSmrg 
1931debfc3dSmrg       phi = gsi.phi ();
1941debfc3dSmrg       def = redirect_edge_var_map_def (vm);
1951debfc3dSmrg       add_phi_arg (phi, def, e, redirect_edge_var_map_location (vm));
1961debfc3dSmrg     }
1971debfc3dSmrg 
1981debfc3dSmrg   redirect_edge_var_map_clear (e);
1991debfc3dSmrg }
2001debfc3dSmrg 
2011debfc3dSmrg /* Replace the LHS of STMT, an assignment, either a GIMPLE_ASSIGN or a
2021debfc3dSmrg    GIMPLE_CALL, with NLHS, in preparation for modifying the RHS to an
2031debfc3dSmrg    expression with a different value.
2041debfc3dSmrg 
2051debfc3dSmrg    This will update any annotations (say debug bind stmts) referring
2061debfc3dSmrg    to the original LHS, so that they use the RHS instead.  This is
2071debfc3dSmrg    done even if NLHS and LHS are the same, for it is understood that
2081debfc3dSmrg    the RHS will be modified afterwards, and NLHS will not be assigned
2091debfc3dSmrg    an equivalent value.
2101debfc3dSmrg 
2111debfc3dSmrg    Adjusting any non-annotation uses of the LHS, if needed, is a
2121debfc3dSmrg    responsibility of the caller.
2131debfc3dSmrg 
2141debfc3dSmrg    The effect of this call should be pretty much the same as that of
2151debfc3dSmrg    inserting a copy of STMT before STMT, and then removing the
2161debfc3dSmrg    original stmt, at which time gsi_remove() would have update
2171debfc3dSmrg    annotations, but using this function saves all the inserting,
2181debfc3dSmrg    copying and removing.  */
2191debfc3dSmrg 
2201debfc3dSmrg void
gimple_replace_ssa_lhs(gimple * stmt,tree nlhs)2211debfc3dSmrg gimple_replace_ssa_lhs (gimple *stmt, tree nlhs)
2221debfc3dSmrg {
223a2dc1f3fSmrg   if (MAY_HAVE_DEBUG_BIND_STMTS)
2241debfc3dSmrg     {
2251debfc3dSmrg       tree lhs = gimple_get_lhs (stmt);
2261debfc3dSmrg 
2271debfc3dSmrg       gcc_assert (SSA_NAME_DEF_STMT (lhs) == stmt);
2281debfc3dSmrg 
2291debfc3dSmrg       insert_debug_temp_for_var_def (NULL, lhs);
2301debfc3dSmrg     }
2311debfc3dSmrg 
2321debfc3dSmrg   gimple_set_lhs (stmt, nlhs);
2331debfc3dSmrg }
2341debfc3dSmrg 
2351debfc3dSmrg 
2361debfc3dSmrg /* Given a tree for an expression for which we might want to emit
2371debfc3dSmrg    locations or values in debug information (generally a variable, but
2381debfc3dSmrg    we might deal with other kinds of trees in the future), return the
2391debfc3dSmrg    tree that should be used as the variable of a DEBUG_BIND STMT or
2401debfc3dSmrg    VAR_LOCATION INSN or NOTE.  Return NULL if VAR is not to be tracked.  */
2411debfc3dSmrg 
2421debfc3dSmrg tree
target_for_debug_bind(tree var)2431debfc3dSmrg target_for_debug_bind (tree var)
2441debfc3dSmrg {
245a2dc1f3fSmrg   if (!MAY_HAVE_DEBUG_BIND_STMTS)
2461debfc3dSmrg     return NULL_TREE;
2471debfc3dSmrg 
2481debfc3dSmrg   if (TREE_CODE (var) == SSA_NAME)
2491debfc3dSmrg     {
2501debfc3dSmrg       var = SSA_NAME_VAR (var);
2511debfc3dSmrg       if (var == NULL_TREE)
2521debfc3dSmrg 	return NULL_TREE;
2531debfc3dSmrg     }
2541debfc3dSmrg 
2551debfc3dSmrg   if ((!VAR_P (var) || VAR_DECL_IS_VIRTUAL_OPERAND (var))
2561debfc3dSmrg       && TREE_CODE (var) != PARM_DECL)
2571debfc3dSmrg     return NULL_TREE;
2581debfc3dSmrg 
2591debfc3dSmrg   if (DECL_HAS_VALUE_EXPR_P (var))
2601debfc3dSmrg     return target_for_debug_bind (DECL_VALUE_EXPR (var));
2611debfc3dSmrg 
2621debfc3dSmrg   if (DECL_IGNORED_P (var))
2631debfc3dSmrg     return NULL_TREE;
2641debfc3dSmrg 
2651debfc3dSmrg   /* var-tracking only tracks registers.  */
2661debfc3dSmrg   if (!is_gimple_reg_type (TREE_TYPE (var)))
2671debfc3dSmrg     return NULL_TREE;
2681debfc3dSmrg 
2691debfc3dSmrg   return var;
2701debfc3dSmrg }
2711debfc3dSmrg 
2721debfc3dSmrg /* Called via walk_tree, look for SSA_NAMEs that have already been
2731debfc3dSmrg    released.  */
2741debfc3dSmrg 
2751debfc3dSmrg static tree
find_released_ssa_name(tree * tp,int * walk_subtrees,void * data_)2761debfc3dSmrg find_released_ssa_name (tree *tp, int *walk_subtrees, void *data_)
2771debfc3dSmrg {
2781debfc3dSmrg   struct walk_stmt_info *wi = (struct walk_stmt_info *) data_;
2791debfc3dSmrg 
2801debfc3dSmrg   if (wi && wi->is_lhs)
2811debfc3dSmrg     return NULL_TREE;
2821debfc3dSmrg 
2831debfc3dSmrg   if (TREE_CODE (*tp) == SSA_NAME)
2841debfc3dSmrg     {
2851debfc3dSmrg       if (SSA_NAME_IN_FREE_LIST (*tp))
2861debfc3dSmrg 	return *tp;
2871debfc3dSmrg 
2881debfc3dSmrg       *walk_subtrees = 0;
2891debfc3dSmrg     }
2901debfc3dSmrg   else if (IS_TYPE_OR_DECL_P (*tp))
2911debfc3dSmrg     *walk_subtrees = 0;
2921debfc3dSmrg 
2931debfc3dSmrg   return NULL_TREE;
2941debfc3dSmrg }
2951debfc3dSmrg 
2961debfc3dSmrg /* Insert a DEBUG BIND stmt before the DEF of VAR if VAR is referenced
2971debfc3dSmrg    by other DEBUG stmts, and replace uses of the DEF with the
2981debfc3dSmrg    newly-created debug temp.  */
2991debfc3dSmrg 
3001debfc3dSmrg void
insert_debug_temp_for_var_def(gimple_stmt_iterator * gsi,tree var)3011debfc3dSmrg insert_debug_temp_for_var_def (gimple_stmt_iterator *gsi, tree var)
3021debfc3dSmrg {
3031debfc3dSmrg   imm_use_iterator imm_iter;
3041debfc3dSmrg   use_operand_p use_p;
3051debfc3dSmrg   gimple *stmt;
3061debfc3dSmrg   gimple *def_stmt = NULL;
3071debfc3dSmrg   int usecount = 0;
3081debfc3dSmrg   tree value = NULL;
3091debfc3dSmrg 
310a2dc1f3fSmrg   if (!MAY_HAVE_DEBUG_BIND_STMTS)
3111debfc3dSmrg     return;
3121debfc3dSmrg 
3131debfc3dSmrg   /* If this name has already been registered for replacement, do nothing
3141debfc3dSmrg      as anything that uses this name isn't in SSA form.  */
3151debfc3dSmrg   if (name_registered_for_update_p (var))
3161debfc3dSmrg     return;
3171debfc3dSmrg 
3181debfc3dSmrg   /* Check whether there are debug stmts that reference this variable and,
3191debfc3dSmrg      if there are, decide whether we should use a debug temp.  */
3201debfc3dSmrg   FOR_EACH_IMM_USE_FAST (use_p, imm_iter, var)
3211debfc3dSmrg     {
3221debfc3dSmrg       stmt = USE_STMT (use_p);
3231debfc3dSmrg 
3241debfc3dSmrg       if (!gimple_debug_bind_p (stmt))
3251debfc3dSmrg 	continue;
3261debfc3dSmrg 
3271debfc3dSmrg       if (usecount++)
3281debfc3dSmrg 	break;
3291debfc3dSmrg 
3301debfc3dSmrg       if (gimple_debug_bind_get_value (stmt) != var)
3311debfc3dSmrg 	{
3321debfc3dSmrg 	  /* Count this as an additional use, so as to make sure we
3331debfc3dSmrg 	     use a temp unless VAR's definition has a SINGLE_RHS that
3341debfc3dSmrg 	     can be shared.  */
3351debfc3dSmrg 	  usecount++;
3361debfc3dSmrg 	  break;
3371debfc3dSmrg 	}
3381debfc3dSmrg     }
3391debfc3dSmrg 
3401debfc3dSmrg   if (!usecount)
3411debfc3dSmrg     return;
3421debfc3dSmrg 
3431debfc3dSmrg   if (gsi)
3441debfc3dSmrg     def_stmt = gsi_stmt (*gsi);
3451debfc3dSmrg   else
3461debfc3dSmrg     def_stmt = SSA_NAME_DEF_STMT (var);
3471debfc3dSmrg 
3481debfc3dSmrg   /* If we didn't get an insertion point, and the stmt has already
3491debfc3dSmrg      been removed, we won't be able to insert the debug bind stmt, so
3501debfc3dSmrg      we'll have to drop debug information.  */
3511debfc3dSmrg   if (gimple_code (def_stmt) == GIMPLE_PHI)
3521debfc3dSmrg     {
3531debfc3dSmrg       value = degenerate_phi_result (as_a <gphi *> (def_stmt));
3541debfc3dSmrg       if (value && walk_tree (&value, find_released_ssa_name, NULL, NULL))
3551debfc3dSmrg 	value = NULL;
3561debfc3dSmrg       /* error_mark_node is what fixup_noreturn_call changes PHI arguments
3571debfc3dSmrg 	 to.  */
3581debfc3dSmrg       else if (value == error_mark_node)
3591debfc3dSmrg 	value = NULL;
3601debfc3dSmrg     }
3618feb0f0bSmrg   else if (gimple_clobber_p (def_stmt))
3628feb0f0bSmrg     /* We can end up here when rewriting a decl into SSA and coming
3638feb0f0bSmrg        along a clobber for the original decl.  Turn that into
3648feb0f0bSmrg        # DEBUG decl => NULL  */
3658feb0f0bSmrg     value = NULL;
3661debfc3dSmrg   else if (is_gimple_assign (def_stmt))
3671debfc3dSmrg     {
3681debfc3dSmrg       bool no_value = false;
3691debfc3dSmrg 
3701debfc3dSmrg       if (!dom_info_available_p (CDI_DOMINATORS))
3711debfc3dSmrg 	{
3721debfc3dSmrg 	  struct walk_stmt_info wi;
3731debfc3dSmrg 
3741debfc3dSmrg 	  memset (&wi, 0, sizeof (wi));
3751debfc3dSmrg 
3761debfc3dSmrg 	  /* When removing blocks without following reverse dominance
3771debfc3dSmrg 	     order, we may sometimes encounter SSA_NAMEs that have
3781debfc3dSmrg 	     already been released, referenced in other SSA_DEFs that
3791debfc3dSmrg 	     we're about to release.  Consider:
3801debfc3dSmrg 
3811debfc3dSmrg 	     <bb X>:
3821debfc3dSmrg 	     v_1 = foo;
3831debfc3dSmrg 
3841debfc3dSmrg 	     <bb Y>:
3851debfc3dSmrg 	     w_2 = v_1 + bar;
3861debfc3dSmrg 	     # DEBUG w => w_2
3871debfc3dSmrg 
3881debfc3dSmrg 	     If we deleted BB X first, propagating the value of w_2
3891debfc3dSmrg 	     won't do us any good.  It's too late to recover their
3901debfc3dSmrg 	     original definition of v_1: when it was deleted, it was
3911debfc3dSmrg 	     only referenced in other DEFs, it couldn't possibly know
3921debfc3dSmrg 	     it should have been retained, and propagating every
3931debfc3dSmrg 	     single DEF just in case it might have to be propagated
3941debfc3dSmrg 	     into a DEBUG STMT would probably be too wasteful.
3951debfc3dSmrg 
3961debfc3dSmrg 	     When dominator information is not readily available, we
3971debfc3dSmrg 	     check for and accept some loss of debug information.  But
3981debfc3dSmrg 	     if it is available, there's no excuse for us to remove
3991debfc3dSmrg 	     blocks in the wrong order, so we don't even check for
4001debfc3dSmrg 	     dead SSA NAMEs.  SSA verification shall catch any
4011debfc3dSmrg 	     errors.  */
4021debfc3dSmrg 	  if ((!gsi && !gimple_bb (def_stmt))
4031debfc3dSmrg 	      || walk_gimple_op (def_stmt, find_released_ssa_name, &wi))
4041debfc3dSmrg 	    no_value = true;
4051debfc3dSmrg 	}
4061debfc3dSmrg 
4071debfc3dSmrg       if (!no_value)
4081debfc3dSmrg 	value = gimple_assign_rhs_to_tree (def_stmt);
4091debfc3dSmrg     }
4101debfc3dSmrg 
4111debfc3dSmrg   if (value)
4121debfc3dSmrg     {
4131debfc3dSmrg       /* If there's a single use of VAR, and VAR is the entire debug
4141debfc3dSmrg 	 expression (usecount would have been incremented again
4151debfc3dSmrg 	 otherwise), and the definition involves only constants and
4161debfc3dSmrg 	 SSA names, then we can propagate VALUE into this single use,
4171debfc3dSmrg 	 avoiding the temp.
4181debfc3dSmrg 
4191debfc3dSmrg 	 We can also avoid using a temp if VALUE can be shared and
4201debfc3dSmrg 	 propagated into all uses, without generating expressions that
4211debfc3dSmrg 	 wouldn't be valid gimple RHSs.
4221debfc3dSmrg 
4231debfc3dSmrg 	 Other cases that would require unsharing or non-gimple RHSs
4241debfc3dSmrg 	 are deferred to a debug temp, although we could avoid temps
4251debfc3dSmrg 	 at the expense of duplication of expressions.  */
4261debfc3dSmrg 
4271debfc3dSmrg       if (CONSTANT_CLASS_P (value)
4281debfc3dSmrg 	  || gimple_code (def_stmt) == GIMPLE_PHI
4291debfc3dSmrg 	  || (usecount == 1
4301debfc3dSmrg 	      && (!gimple_assign_single_p (def_stmt)
4311debfc3dSmrg 		  || is_gimple_min_invariant (value)))
4321debfc3dSmrg 	  || is_gimple_reg (value))
4331debfc3dSmrg 	;
4341debfc3dSmrg       else
4351debfc3dSmrg 	{
4361debfc3dSmrg 	  gdebug *def_temp;
4371debfc3dSmrg 	  tree vexpr = make_node (DEBUG_EXPR_DECL);
4381debfc3dSmrg 
4391debfc3dSmrg 	  def_temp = gimple_build_debug_bind (vexpr,
4401debfc3dSmrg 					      unshare_expr (value),
4411debfc3dSmrg 					      def_stmt);
4421debfc3dSmrg 
4431debfc3dSmrg 	  DECL_ARTIFICIAL (vexpr) = 1;
4441debfc3dSmrg 	  TREE_TYPE (vexpr) = TREE_TYPE (value);
4451debfc3dSmrg 	  if (DECL_P (value))
4461debfc3dSmrg 	    SET_DECL_MODE (vexpr, DECL_MODE (value));
4471debfc3dSmrg 	  else
4481debfc3dSmrg 	    SET_DECL_MODE (vexpr, TYPE_MODE (TREE_TYPE (value)));
4491debfc3dSmrg 
4501debfc3dSmrg 	  if (gsi)
4511debfc3dSmrg 	    gsi_insert_before (gsi, def_temp, GSI_SAME_STMT);
4521debfc3dSmrg 	  else
4531debfc3dSmrg 	    {
4541debfc3dSmrg 	      gimple_stmt_iterator ngsi = gsi_for_stmt (def_stmt);
4551debfc3dSmrg 	      gsi_insert_before (&ngsi, def_temp, GSI_SAME_STMT);
4561debfc3dSmrg 	    }
4571debfc3dSmrg 
4581debfc3dSmrg 	  value = vexpr;
4591debfc3dSmrg 	}
4601debfc3dSmrg     }
4611debfc3dSmrg 
4621debfc3dSmrg   FOR_EACH_IMM_USE_STMT (stmt, imm_iter, var)
4631debfc3dSmrg     {
4641debfc3dSmrg       if (!gimple_debug_bind_p (stmt))
4651debfc3dSmrg 	continue;
4661debfc3dSmrg 
4671debfc3dSmrg       if (value)
4681debfc3dSmrg 	{
4691debfc3dSmrg 	  FOR_EACH_IMM_USE_ON_STMT (use_p, imm_iter)
4701debfc3dSmrg 	    /* unshare_expr is not needed here.  vexpr is either a
4711debfc3dSmrg 	       SINGLE_RHS, that can be safely shared, some other RHS
4721debfc3dSmrg 	       that was unshared when we found it had a single debug
4731debfc3dSmrg 	       use, or a DEBUG_EXPR_DECL, that can be safely
4741debfc3dSmrg 	       shared.  */
4751debfc3dSmrg 	    SET_USE (use_p, unshare_expr (value));
4761debfc3dSmrg 	  /* If we didn't replace uses with a debug decl fold the
4771debfc3dSmrg 	     resulting expression.  Otherwise we end up with invalid IL.  */
4781debfc3dSmrg 	  if (TREE_CODE (value) != DEBUG_EXPR_DECL)
4791debfc3dSmrg 	    {
4801debfc3dSmrg 	      gimple_stmt_iterator gsi = gsi_for_stmt (stmt);
4811debfc3dSmrg 	      fold_stmt_inplace (&gsi);
4821debfc3dSmrg 	    }
4831debfc3dSmrg 	}
4841debfc3dSmrg       else
4851debfc3dSmrg 	gimple_debug_bind_reset_value (stmt);
4861debfc3dSmrg 
4871debfc3dSmrg       update_stmt (stmt);
4881debfc3dSmrg     }
4891debfc3dSmrg }
4901debfc3dSmrg 
4911debfc3dSmrg 
4921debfc3dSmrg /* Insert a DEBUG BIND stmt before STMT for each DEF referenced by
4931debfc3dSmrg    other DEBUG stmts, and replace uses of the DEF with the
4941debfc3dSmrg    newly-created debug temp.  */
4951debfc3dSmrg 
4961debfc3dSmrg void
insert_debug_temps_for_defs(gimple_stmt_iterator * gsi)4971debfc3dSmrg insert_debug_temps_for_defs (gimple_stmt_iterator *gsi)
4981debfc3dSmrg {
4991debfc3dSmrg   gimple *stmt;
5001debfc3dSmrg   ssa_op_iter op_iter;
5011debfc3dSmrg   def_operand_p def_p;
5021debfc3dSmrg 
503a2dc1f3fSmrg   if (!MAY_HAVE_DEBUG_BIND_STMTS)
5041debfc3dSmrg     return;
5051debfc3dSmrg 
5061debfc3dSmrg   stmt = gsi_stmt (*gsi);
5071debfc3dSmrg 
5081debfc3dSmrg   FOR_EACH_PHI_OR_STMT_DEF (def_p, stmt, op_iter, SSA_OP_DEF)
5091debfc3dSmrg     {
5101debfc3dSmrg       tree var = DEF_FROM_PTR (def_p);
5111debfc3dSmrg 
5121debfc3dSmrg       if (TREE_CODE (var) != SSA_NAME)
5131debfc3dSmrg 	continue;
5141debfc3dSmrg 
5151debfc3dSmrg       insert_debug_temp_for_var_def (gsi, var);
5161debfc3dSmrg     }
5171debfc3dSmrg }
5181debfc3dSmrg 
5191debfc3dSmrg /* Reset all debug stmts that use SSA_NAME(s) defined in STMT.  */
5201debfc3dSmrg 
5211debfc3dSmrg void
reset_debug_uses(gimple * stmt)5221debfc3dSmrg reset_debug_uses (gimple *stmt)
5231debfc3dSmrg {
5241debfc3dSmrg   ssa_op_iter op_iter;
5251debfc3dSmrg   def_operand_p def_p;
5261debfc3dSmrg   imm_use_iterator imm_iter;
5271debfc3dSmrg   gimple *use_stmt;
5281debfc3dSmrg 
529a2dc1f3fSmrg   if (!MAY_HAVE_DEBUG_BIND_STMTS)
5301debfc3dSmrg     return;
5311debfc3dSmrg 
5321debfc3dSmrg   FOR_EACH_PHI_OR_STMT_DEF (def_p, stmt, op_iter, SSA_OP_DEF)
5331debfc3dSmrg     {
5341debfc3dSmrg       tree var = DEF_FROM_PTR (def_p);
5351debfc3dSmrg 
5361debfc3dSmrg       if (TREE_CODE (var) != SSA_NAME)
5371debfc3dSmrg 	continue;
5381debfc3dSmrg 
5391debfc3dSmrg       FOR_EACH_IMM_USE_STMT (use_stmt, imm_iter, var)
5401debfc3dSmrg 	{
5411debfc3dSmrg 	  if (!gimple_debug_bind_p (use_stmt))
5421debfc3dSmrg 	    continue;
5431debfc3dSmrg 
5441debfc3dSmrg 	  gimple_debug_bind_reset_value (use_stmt);
5451debfc3dSmrg 	  update_stmt (use_stmt);
5461debfc3dSmrg 	}
5471debfc3dSmrg     }
5481debfc3dSmrg }
5491debfc3dSmrg 
5501debfc3dSmrg /* Delete SSA DEFs for SSA versions in the TOREMOVE bitmap, removing
5511debfc3dSmrg    dominated stmts before their dominators, so that release_ssa_defs
5521debfc3dSmrg    stands a chance of propagating DEFs into debug bind stmts.  */
5531debfc3dSmrg 
5541debfc3dSmrg void
release_defs_bitset(bitmap toremove)5551debfc3dSmrg release_defs_bitset (bitmap toremove)
5561debfc3dSmrg {
5571debfc3dSmrg   unsigned j;
5581debfc3dSmrg   bitmap_iterator bi;
5591debfc3dSmrg 
5601debfc3dSmrg   /* Performing a topological sort is probably overkill, this will
5611debfc3dSmrg      most likely run in slightly superlinear time, rather than the
562c0a68be4Smrg      pathological quadratic worst case.
563c0a68be4Smrg      But iterate from max SSA name version to min one because
564c0a68be4Smrg      that mimics allocation order during code generation behavior best.
565c0a68be4Smrg      Use an array for this which we compact on-the-fly with a NULL
566c0a68be4Smrg      marker moving towards the end of the vector.  */
567c0a68be4Smrg   auto_vec<tree, 16> names;
568c0a68be4Smrg   names.reserve (bitmap_count_bits (toremove) + 1);
569c0a68be4Smrg   names.quick_push (NULL_TREE);
570c0a68be4Smrg   EXECUTE_IF_SET_IN_BITMAP (toremove, 0, j, bi)
571c0a68be4Smrg     names.quick_push (ssa_name (j));
572c0a68be4Smrg 
573c0a68be4Smrg   bitmap_tree_view (toremove);
5741debfc3dSmrg   while (!bitmap_empty_p (toremove))
5751debfc3dSmrg     {
576c0a68be4Smrg       j = names.length () - 1;
577c0a68be4Smrg       for (unsigned i = names.length () - 1; names[i];)
5781debfc3dSmrg 	{
5791debfc3dSmrg 	  bool remove_now = true;
580c0a68be4Smrg 	  tree var = names[i];
5811debfc3dSmrg 	  gimple *stmt;
5821debfc3dSmrg 	  imm_use_iterator uit;
5831debfc3dSmrg 
5841debfc3dSmrg 	  FOR_EACH_IMM_USE_STMT (stmt, uit, var)
5851debfc3dSmrg 	    {
5861debfc3dSmrg 	      ssa_op_iter dit;
5871debfc3dSmrg 	      def_operand_p def_p;
5881debfc3dSmrg 
5891debfc3dSmrg 	      /* We can't propagate PHI nodes into debug stmts.  */
5901debfc3dSmrg 	      if (gimple_code (stmt) == GIMPLE_PHI
5911debfc3dSmrg 		  || is_gimple_debug (stmt))
5921debfc3dSmrg 		continue;
5931debfc3dSmrg 
5941debfc3dSmrg 	      /* If we find another definition to remove that uses
5951debfc3dSmrg 		 the one we're looking at, defer the removal of this
5961debfc3dSmrg 		 one, so that it can be propagated into debug stmts
5971debfc3dSmrg 		 after the other is.  */
5981debfc3dSmrg 	      FOR_EACH_SSA_DEF_OPERAND (def_p, stmt, dit, SSA_OP_DEF)
5991debfc3dSmrg 		{
6001debfc3dSmrg 		  tree odef = DEF_FROM_PTR (def_p);
6011debfc3dSmrg 
6021debfc3dSmrg 		  if (bitmap_bit_p (toremove, SSA_NAME_VERSION (odef)))
6031debfc3dSmrg 		    {
6041debfc3dSmrg 		      remove_now = false;
6051debfc3dSmrg 		      break;
6061debfc3dSmrg 		    }
6071debfc3dSmrg 		}
6081debfc3dSmrg 
6091debfc3dSmrg 	      if (!remove_now)
6101debfc3dSmrg 		BREAK_FROM_IMM_USE_STMT (uit);
6111debfc3dSmrg 	    }
6121debfc3dSmrg 
6131debfc3dSmrg 	  if (remove_now)
6141debfc3dSmrg 	    {
6151debfc3dSmrg 	      gimple *def = SSA_NAME_DEF_STMT (var);
6161debfc3dSmrg 	      gimple_stmt_iterator gsi = gsi_for_stmt (def);
6171debfc3dSmrg 
6181debfc3dSmrg 	      if (gimple_code (def) == GIMPLE_PHI)
6191debfc3dSmrg 		remove_phi_node (&gsi, true);
6201debfc3dSmrg 	      else
6211debfc3dSmrg 		{
6221debfc3dSmrg 		  gsi_remove (&gsi, true);
6231debfc3dSmrg 		  release_defs (def);
6241debfc3dSmrg 		}
625c0a68be4Smrg 	      bitmap_clear_bit (toremove, SSA_NAME_VERSION (var));
626c0a68be4Smrg 	    }
627c0a68be4Smrg 	  else
628c0a68be4Smrg 	    --i;
629c0a68be4Smrg 	  if (--j != i)
630c0a68be4Smrg 	    names[i] = names[j];
6311debfc3dSmrg 	}
6321debfc3dSmrg     }
633c0a68be4Smrg   bitmap_list_view (toremove);
6341debfc3dSmrg }
6351debfc3dSmrg 
6368feb0f0bSmrg /* Disable warnings about missing quoting in GCC diagnostics for
6378feb0f0bSmrg    the verification errors.  Their format strings don't follow GCC
6388feb0f0bSmrg    diagnostic conventions and the calls are ultimately followed by
6398feb0f0bSmrg    one to internal_error.  */
6408feb0f0bSmrg #if __GNUC__ >= 10
6418feb0f0bSmrg #  pragma GCC diagnostic push
6428feb0f0bSmrg #  pragma GCC diagnostic ignored "-Wformat-diag"
6438feb0f0bSmrg #endif
6448feb0f0bSmrg 
6451debfc3dSmrg /* Verify virtual SSA form.  */
6461debfc3dSmrg 
6471debfc3dSmrg bool
verify_vssa(basic_block bb,tree current_vdef,sbitmap visited)6481debfc3dSmrg verify_vssa (basic_block bb, tree current_vdef, sbitmap visited)
6491debfc3dSmrg {
6501debfc3dSmrg   bool err = false;
6511debfc3dSmrg 
6521debfc3dSmrg   if (bitmap_bit_p (visited, bb->index))
6531debfc3dSmrg     return false;
6541debfc3dSmrg 
6551debfc3dSmrg   bitmap_set_bit (visited, bb->index);
6561debfc3dSmrg 
6571debfc3dSmrg   /* Pick up the single virtual PHI def.  */
6581debfc3dSmrg   gphi *phi = NULL;
6591debfc3dSmrg   for (gphi_iterator si = gsi_start_phis (bb); !gsi_end_p (si);
6601debfc3dSmrg        gsi_next (&si))
6611debfc3dSmrg     {
6621debfc3dSmrg       tree res = gimple_phi_result (si.phi ());
6631debfc3dSmrg       if (virtual_operand_p (res))
6641debfc3dSmrg 	{
6651debfc3dSmrg 	  if (phi)
6661debfc3dSmrg 	    {
6671debfc3dSmrg 	      error ("multiple virtual PHI nodes in BB %d", bb->index);
668a2dc1f3fSmrg 	      print_gimple_stmt (stderr, phi, 0);
669a2dc1f3fSmrg 	      print_gimple_stmt (stderr, si.phi (), 0);
6701debfc3dSmrg 	      err = true;
6711debfc3dSmrg 	    }
6721debfc3dSmrg 	  else
6731debfc3dSmrg 	    phi = si.phi ();
6741debfc3dSmrg 	}
6751debfc3dSmrg     }
6761debfc3dSmrg   if (phi)
6771debfc3dSmrg     {
6781debfc3dSmrg       current_vdef = gimple_phi_result (phi);
6791debfc3dSmrg       if (TREE_CODE (current_vdef) != SSA_NAME)
6801debfc3dSmrg 	{
6811debfc3dSmrg 	  error ("virtual definition is not an SSA name");
682a2dc1f3fSmrg 	  print_gimple_stmt (stderr, phi, 0);
6831debfc3dSmrg 	  err = true;
6841debfc3dSmrg 	}
6851debfc3dSmrg     }
6861debfc3dSmrg 
6871debfc3dSmrg   /* Verify stmts.  */
6881debfc3dSmrg   for (gimple_stmt_iterator gsi = gsi_start_bb (bb); !gsi_end_p (gsi);
6891debfc3dSmrg        gsi_next (&gsi))
6901debfc3dSmrg     {
6911debfc3dSmrg       gimple *stmt = gsi_stmt (gsi);
6921debfc3dSmrg       tree vuse = gimple_vuse (stmt);
6931debfc3dSmrg       if (vuse)
6941debfc3dSmrg 	{
6951debfc3dSmrg 	  if (vuse != current_vdef)
6961debfc3dSmrg 	    {
6971debfc3dSmrg 	      error ("stmt with wrong VUSE");
6981debfc3dSmrg 	      print_gimple_stmt (stderr, stmt, 0, TDF_VOPS);
6991debfc3dSmrg 	      fprintf (stderr, "expected ");
700a2dc1f3fSmrg 	      print_generic_expr (stderr, current_vdef);
7011debfc3dSmrg 	      fprintf (stderr, "\n");
7021debfc3dSmrg 	      err = true;
7031debfc3dSmrg 	    }
7041debfc3dSmrg 	  tree vdef = gimple_vdef (stmt);
7051debfc3dSmrg 	  if (vdef)
7061debfc3dSmrg 	    {
7071debfc3dSmrg 	      current_vdef = vdef;
7081debfc3dSmrg 	      if (TREE_CODE (current_vdef) != SSA_NAME)
7091debfc3dSmrg 		{
7101debfc3dSmrg 		  error ("virtual definition is not an SSA name");
711a2dc1f3fSmrg 		  print_gimple_stmt (stderr, phi, 0);
7121debfc3dSmrg 		  err = true;
7131debfc3dSmrg 		}
7141debfc3dSmrg 	    }
7151debfc3dSmrg 	}
7161debfc3dSmrg     }
7171debfc3dSmrg 
7181debfc3dSmrg   /* Verify destination PHI uses and recurse.  */
7191debfc3dSmrg   edge_iterator ei;
7201debfc3dSmrg   edge e;
7211debfc3dSmrg   FOR_EACH_EDGE (e, ei, bb->succs)
7221debfc3dSmrg     {
7231debfc3dSmrg       gphi *phi = get_virtual_phi (e->dest);
7241debfc3dSmrg       if (phi
7251debfc3dSmrg 	  && PHI_ARG_DEF_FROM_EDGE (phi, e) != current_vdef)
7261debfc3dSmrg 	{
7271debfc3dSmrg 	  error ("PHI node with wrong VUSE on edge from BB %d",
7281debfc3dSmrg 		 e->src->index);
7291debfc3dSmrg 	  print_gimple_stmt (stderr, phi, 0, TDF_VOPS);
7301debfc3dSmrg 	  fprintf (stderr, "expected ");
731a2dc1f3fSmrg 	  print_generic_expr (stderr, current_vdef);
7321debfc3dSmrg 	  fprintf (stderr, "\n");
7331debfc3dSmrg 	  err = true;
7341debfc3dSmrg 	}
7351debfc3dSmrg 
7361debfc3dSmrg       /* Recurse.  */
7371debfc3dSmrg       err |= verify_vssa (e->dest, current_vdef, visited);
7381debfc3dSmrg     }
7391debfc3dSmrg 
7401debfc3dSmrg   return err;
7411debfc3dSmrg }
7421debfc3dSmrg 
7431debfc3dSmrg /* Return true if SSA_NAME is malformed and mark it visited.
7441debfc3dSmrg 
7451debfc3dSmrg    IS_VIRTUAL is true if this SSA_NAME was found inside a virtual
7461debfc3dSmrg       operand.  */
7471debfc3dSmrg 
7481debfc3dSmrg static bool
verify_ssa_name(tree ssa_name,bool is_virtual)7491debfc3dSmrg verify_ssa_name (tree ssa_name, bool is_virtual)
7501debfc3dSmrg {
7511debfc3dSmrg   if (TREE_CODE (ssa_name) != SSA_NAME)
7521debfc3dSmrg     {
7531debfc3dSmrg       error ("expected an SSA_NAME object");
7541debfc3dSmrg       return true;
7551debfc3dSmrg     }
7561debfc3dSmrg 
7571debfc3dSmrg   if (SSA_NAME_IN_FREE_LIST (ssa_name))
7581debfc3dSmrg     {
7591debfc3dSmrg       error ("found an SSA_NAME that had been released into the free pool");
7601debfc3dSmrg       return true;
7611debfc3dSmrg     }
7621debfc3dSmrg 
7631debfc3dSmrg   if (SSA_NAME_VAR (ssa_name) != NULL_TREE
7641debfc3dSmrg       && TREE_TYPE (ssa_name) != TREE_TYPE (SSA_NAME_VAR (ssa_name)))
7651debfc3dSmrg     {
7661debfc3dSmrg       error ("type mismatch between an SSA_NAME and its symbol");
7671debfc3dSmrg       return true;
7681debfc3dSmrg     }
7691debfc3dSmrg 
7701debfc3dSmrg   if (is_virtual && !virtual_operand_p (ssa_name))
7711debfc3dSmrg     {
7721debfc3dSmrg       error ("found a virtual definition for a GIMPLE register");
7731debfc3dSmrg       return true;
7741debfc3dSmrg     }
7751debfc3dSmrg 
7761debfc3dSmrg   if (is_virtual && SSA_NAME_VAR (ssa_name) != gimple_vop (cfun))
7771debfc3dSmrg     {
7781debfc3dSmrg       error ("virtual SSA name for non-VOP decl");
7791debfc3dSmrg       return true;
7801debfc3dSmrg     }
7811debfc3dSmrg 
7821debfc3dSmrg   if (!is_virtual && virtual_operand_p (ssa_name))
7831debfc3dSmrg     {
7841debfc3dSmrg       error ("found a real definition for a non-register");
7851debfc3dSmrg       return true;
7861debfc3dSmrg     }
7871debfc3dSmrg 
7881debfc3dSmrg   if (SSA_NAME_IS_DEFAULT_DEF (ssa_name)
7891debfc3dSmrg       && !gimple_nop_p (SSA_NAME_DEF_STMT (ssa_name)))
7901debfc3dSmrg     {
7911debfc3dSmrg       error ("found a default name with a non-empty defining statement");
7921debfc3dSmrg       return true;
7931debfc3dSmrg     }
7941debfc3dSmrg 
7951debfc3dSmrg   return false;
7961debfc3dSmrg }
7971debfc3dSmrg 
7981debfc3dSmrg 
7991debfc3dSmrg /* Return true if the definition of SSA_NAME at block BB is malformed.
8001debfc3dSmrg 
8011debfc3dSmrg    STMT is the statement where SSA_NAME is created.
8021debfc3dSmrg 
8031debfc3dSmrg    DEFINITION_BLOCK is an array of basic blocks indexed by SSA_NAME
8041debfc3dSmrg       version numbers.  If DEFINITION_BLOCK[SSA_NAME_VERSION] is set,
8051debfc3dSmrg       it means that the block in that array slot contains the
8061debfc3dSmrg       definition of SSA_NAME.
8071debfc3dSmrg 
8081debfc3dSmrg    IS_VIRTUAL is true if SSA_NAME is created by a VDEF.  */
8091debfc3dSmrg 
8101debfc3dSmrg static bool
verify_def(basic_block bb,basic_block * definition_block,tree ssa_name,gimple * stmt,bool is_virtual)8111debfc3dSmrg verify_def (basic_block bb, basic_block *definition_block, tree ssa_name,
8121debfc3dSmrg 	    gimple *stmt, bool is_virtual)
8131debfc3dSmrg {
8141debfc3dSmrg   if (verify_ssa_name (ssa_name, is_virtual))
8151debfc3dSmrg     goto err;
8161debfc3dSmrg 
8171debfc3dSmrg   if (SSA_NAME_VAR (ssa_name)
8181debfc3dSmrg       && TREE_CODE (SSA_NAME_VAR (ssa_name)) == RESULT_DECL
8191debfc3dSmrg       && DECL_BY_REFERENCE (SSA_NAME_VAR (ssa_name)))
8201debfc3dSmrg     {
8211debfc3dSmrg       error ("RESULT_DECL should be read only when DECL_BY_REFERENCE is set");
8221debfc3dSmrg       goto err;
8231debfc3dSmrg     }
8241debfc3dSmrg 
8251debfc3dSmrg   if (definition_block[SSA_NAME_VERSION (ssa_name)])
8261debfc3dSmrg     {
8271debfc3dSmrg       error ("SSA_NAME created in two different blocks %i and %i",
8281debfc3dSmrg 	     definition_block[SSA_NAME_VERSION (ssa_name)]->index, bb->index);
8291debfc3dSmrg       goto err;
8301debfc3dSmrg     }
8311debfc3dSmrg 
8321debfc3dSmrg   definition_block[SSA_NAME_VERSION (ssa_name)] = bb;
8331debfc3dSmrg 
8341debfc3dSmrg   if (SSA_NAME_DEF_STMT (ssa_name) != stmt)
8351debfc3dSmrg     {
8361debfc3dSmrg       error ("SSA_NAME_DEF_STMT is wrong");
8371debfc3dSmrg       fprintf (stderr, "Expected definition statement:\n");
8381debfc3dSmrg       print_gimple_stmt (stderr, SSA_NAME_DEF_STMT (ssa_name), 4, TDF_VOPS);
8391debfc3dSmrg       fprintf (stderr, "\nActual definition statement:\n");
8401debfc3dSmrg       print_gimple_stmt (stderr, stmt, 4, TDF_VOPS);
8411debfc3dSmrg       goto err;
8421debfc3dSmrg     }
8431debfc3dSmrg 
8441debfc3dSmrg   return false;
8451debfc3dSmrg 
8461debfc3dSmrg err:
8471debfc3dSmrg   fprintf (stderr, "while verifying SSA_NAME ");
848a2dc1f3fSmrg   print_generic_expr (stderr, ssa_name);
8491debfc3dSmrg   fprintf (stderr, " in statement\n");
8501debfc3dSmrg   print_gimple_stmt (stderr, stmt, 4, TDF_VOPS);
8511debfc3dSmrg 
8521debfc3dSmrg   return true;
8531debfc3dSmrg }
8541debfc3dSmrg 
8551debfc3dSmrg 
8561debfc3dSmrg /* Return true if the use of SSA_NAME at statement STMT in block BB is
8571debfc3dSmrg    malformed.
8581debfc3dSmrg 
8591debfc3dSmrg    DEF_BB is the block where SSA_NAME was found to be created.
8601debfc3dSmrg 
8611debfc3dSmrg    IDOM contains immediate dominator information for the flowgraph.
8621debfc3dSmrg 
8631debfc3dSmrg    CHECK_ABNORMAL is true if the caller wants to check whether this use
8641debfc3dSmrg       is flowing through an abnormal edge (only used when checking PHI
8651debfc3dSmrg       arguments).
8661debfc3dSmrg 
8671debfc3dSmrg    If NAMES_DEFINED_IN_BB is not NULL, it contains a bitmap of ssa names
8681debfc3dSmrg      that are defined before STMT in basic block BB.  */
8691debfc3dSmrg 
8701debfc3dSmrg static bool
verify_use(basic_block bb,basic_block def_bb,use_operand_p use_p,gimple * stmt,bool check_abnormal,bitmap names_defined_in_bb)8711debfc3dSmrg verify_use (basic_block bb, basic_block def_bb, use_operand_p use_p,
8721debfc3dSmrg 	    gimple *stmt, bool check_abnormal, bitmap names_defined_in_bb)
8731debfc3dSmrg {
8741debfc3dSmrg   bool err = false;
8751debfc3dSmrg   tree ssa_name = USE_FROM_PTR (use_p);
8761debfc3dSmrg 
8771debfc3dSmrg   if (!TREE_VISITED (ssa_name))
8781debfc3dSmrg     if (verify_imm_links (stderr, ssa_name))
8791debfc3dSmrg       err = true;
8801debfc3dSmrg 
8811debfc3dSmrg   TREE_VISITED (ssa_name) = 1;
8821debfc3dSmrg 
8831debfc3dSmrg   if (gimple_nop_p (SSA_NAME_DEF_STMT (ssa_name))
8841debfc3dSmrg       && SSA_NAME_IS_DEFAULT_DEF (ssa_name))
8851debfc3dSmrg     ; /* Default definitions have empty statements.  Nothing to do.  */
8861debfc3dSmrg   else if (!def_bb)
8871debfc3dSmrg     {
8881debfc3dSmrg       error ("missing definition");
8891debfc3dSmrg       err = true;
8901debfc3dSmrg     }
8911debfc3dSmrg   else if (bb != def_bb
8921debfc3dSmrg 	   && !dominated_by_p (CDI_DOMINATORS, bb, def_bb))
8931debfc3dSmrg     {
8941debfc3dSmrg       error ("definition in block %i does not dominate use in block %i",
8951debfc3dSmrg 	     def_bb->index, bb->index);
8961debfc3dSmrg       err = true;
8971debfc3dSmrg     }
8981debfc3dSmrg   else if (bb == def_bb
8991debfc3dSmrg 	   && names_defined_in_bb != NULL
9001debfc3dSmrg 	   && !bitmap_bit_p (names_defined_in_bb, SSA_NAME_VERSION (ssa_name)))
9011debfc3dSmrg     {
9021debfc3dSmrg       error ("definition in block %i follows the use", def_bb->index);
9031debfc3dSmrg       err = true;
9041debfc3dSmrg     }
9051debfc3dSmrg 
9061debfc3dSmrg   if (check_abnormal
9071debfc3dSmrg       && !SSA_NAME_OCCURS_IN_ABNORMAL_PHI (ssa_name))
9081debfc3dSmrg     {
9091debfc3dSmrg       error ("SSA_NAME_OCCURS_IN_ABNORMAL_PHI should be set");
9101debfc3dSmrg       err = true;
9111debfc3dSmrg     }
9121debfc3dSmrg 
9131debfc3dSmrg   /* Make sure the use is in an appropriate list by checking the previous
9141debfc3dSmrg      element to make sure it's the same.  */
9151debfc3dSmrg   if (use_p->prev == NULL)
9161debfc3dSmrg     {
9171debfc3dSmrg       error ("no immediate_use list");
9181debfc3dSmrg       err = true;
9191debfc3dSmrg     }
9201debfc3dSmrg   else
9211debfc3dSmrg     {
9221debfc3dSmrg       tree listvar;
9231debfc3dSmrg       if (use_p->prev->use == NULL)
9241debfc3dSmrg 	listvar = use_p->prev->loc.ssa_name;
9251debfc3dSmrg       else
9261debfc3dSmrg 	listvar = USE_FROM_PTR (use_p->prev);
9271debfc3dSmrg       if (listvar != ssa_name)
9281debfc3dSmrg         {
9291debfc3dSmrg 	  error ("wrong immediate use list");
9301debfc3dSmrg 	  err = true;
9311debfc3dSmrg 	}
9321debfc3dSmrg     }
9331debfc3dSmrg 
9341debfc3dSmrg   if (err)
9351debfc3dSmrg     {
9361debfc3dSmrg       fprintf (stderr, "for SSA_NAME: ");
9371debfc3dSmrg       print_generic_expr (stderr, ssa_name, TDF_VOPS);
9381debfc3dSmrg       fprintf (stderr, " in statement:\n");
9391debfc3dSmrg       print_gimple_stmt (stderr, stmt, 0, TDF_VOPS);
9401debfc3dSmrg     }
9411debfc3dSmrg 
9421debfc3dSmrg   return err;
9431debfc3dSmrg }
9441debfc3dSmrg 
9451debfc3dSmrg 
9461debfc3dSmrg /* Return true if any of the arguments for PHI node PHI at block BB is
9471debfc3dSmrg    malformed.
9481debfc3dSmrg 
9491debfc3dSmrg    DEFINITION_BLOCK is an array of basic blocks indexed by SSA_NAME
9501debfc3dSmrg       version numbers.  If DEFINITION_BLOCK[SSA_NAME_VERSION] is set,
9511debfc3dSmrg       it means that the block in that array slot contains the
9521debfc3dSmrg       definition of SSA_NAME.  */
9531debfc3dSmrg 
9541debfc3dSmrg static bool
verify_phi_args(gphi * phi,basic_block bb,basic_block * definition_block)9551debfc3dSmrg verify_phi_args (gphi *phi, basic_block bb, basic_block *definition_block)
9561debfc3dSmrg {
9571debfc3dSmrg   edge e;
9581debfc3dSmrg   bool err = false;
9591debfc3dSmrg   size_t i, phi_num_args = gimple_phi_num_args (phi);
9601debfc3dSmrg 
9611debfc3dSmrg   if (EDGE_COUNT (bb->preds) != phi_num_args)
9621debfc3dSmrg     {
9631debfc3dSmrg       error ("incoming edge count does not match number of PHI arguments");
9641debfc3dSmrg       err = true;
9651debfc3dSmrg       goto error;
9661debfc3dSmrg     }
9671debfc3dSmrg 
9681debfc3dSmrg   for (i = 0; i < phi_num_args; i++)
9691debfc3dSmrg     {
9701debfc3dSmrg       use_operand_p op_p = gimple_phi_arg_imm_use_ptr (phi, i);
9711debfc3dSmrg       tree op = USE_FROM_PTR (op_p);
9721debfc3dSmrg 
9731debfc3dSmrg       e = EDGE_PRED (bb, i);
9741debfc3dSmrg 
9751debfc3dSmrg       if (op == NULL_TREE)
9761debfc3dSmrg 	{
9771debfc3dSmrg 	  error ("PHI argument is missing for edge %d->%d",
9781debfc3dSmrg 	         e->src->index,
9791debfc3dSmrg 		 e->dest->index);
9801debfc3dSmrg 	  err = true;
9811debfc3dSmrg 	  goto error;
9821debfc3dSmrg 	}
9831debfc3dSmrg 
9841debfc3dSmrg       if (TREE_CODE (op) != SSA_NAME && !is_gimple_min_invariant (op))
9851debfc3dSmrg 	{
9861debfc3dSmrg 	  error ("PHI argument is not SSA_NAME, or invariant");
9871debfc3dSmrg 	  err = true;
9881debfc3dSmrg 	}
9891debfc3dSmrg 
9901debfc3dSmrg       if (TREE_CODE (op) == SSA_NAME)
9911debfc3dSmrg 	{
9921debfc3dSmrg 	  err = verify_ssa_name (op, virtual_operand_p (gimple_phi_result (phi)));
9931debfc3dSmrg 	  err |= verify_use (e->src, definition_block[SSA_NAME_VERSION (op)],
9941debfc3dSmrg 			     op_p, phi, e->flags & EDGE_ABNORMAL, NULL);
9951debfc3dSmrg 	}
9961debfc3dSmrg 
9971debfc3dSmrg       if (TREE_CODE (op) == ADDR_EXPR)
9981debfc3dSmrg 	{
9991debfc3dSmrg 	  tree base = TREE_OPERAND (op, 0);
10001debfc3dSmrg 	  while (handled_component_p (base))
10011debfc3dSmrg 	    base = TREE_OPERAND (base, 0);
10021debfc3dSmrg 	  if ((VAR_P (base)
10031debfc3dSmrg 	       || TREE_CODE (base) == PARM_DECL
10041debfc3dSmrg 	       || TREE_CODE (base) == RESULT_DECL)
10051debfc3dSmrg 	      && !TREE_ADDRESSABLE (base))
10061debfc3dSmrg 	    {
10071debfc3dSmrg 	      error ("address taken, but ADDRESSABLE bit not set");
10081debfc3dSmrg 	      err = true;
10091debfc3dSmrg 	    }
10101debfc3dSmrg 	}
10111debfc3dSmrg 
10121debfc3dSmrg       if (e->dest != bb)
10131debfc3dSmrg 	{
10141debfc3dSmrg 	  error ("wrong edge %d->%d for PHI argument",
10151debfc3dSmrg 	         e->src->index, e->dest->index);
10161debfc3dSmrg 	  err = true;
10171debfc3dSmrg 	}
10181debfc3dSmrg 
10191debfc3dSmrg       if (err)
10201debfc3dSmrg 	{
10211debfc3dSmrg 	  fprintf (stderr, "PHI argument\n");
10221debfc3dSmrg 	  print_generic_stmt (stderr, op, TDF_VOPS);
10231debfc3dSmrg 	  goto error;
10241debfc3dSmrg 	}
10251debfc3dSmrg     }
10261debfc3dSmrg 
10271debfc3dSmrg error:
10281debfc3dSmrg   if (err)
10291debfc3dSmrg     {
10301debfc3dSmrg       fprintf (stderr, "for PHI node\n");
10311debfc3dSmrg       print_gimple_stmt (stderr, phi, 0, TDF_VOPS|TDF_MEMSYMS);
10321debfc3dSmrg     }
10331debfc3dSmrg 
10341debfc3dSmrg 
10351debfc3dSmrg   return err;
10361debfc3dSmrg }
10371debfc3dSmrg 
10381debfc3dSmrg 
10391debfc3dSmrg /* Verify common invariants in the SSA web.
10401debfc3dSmrg    TODO: verify the variable annotations.  */
10411debfc3dSmrg 
10421debfc3dSmrg DEBUG_FUNCTION void
verify_ssa(bool check_modified_stmt,bool check_ssa_operands)10431debfc3dSmrg verify_ssa (bool check_modified_stmt, bool check_ssa_operands)
10441debfc3dSmrg {
10451debfc3dSmrg   basic_block bb;
10461debfc3dSmrg   basic_block *definition_block = XCNEWVEC (basic_block, num_ssa_names);
10471debfc3dSmrg   ssa_op_iter iter;
10481debfc3dSmrg   tree op;
10491debfc3dSmrg   enum dom_state orig_dom_state = dom_info_state (CDI_DOMINATORS);
1050a2dc1f3fSmrg   auto_bitmap names_defined_in_bb;
10511debfc3dSmrg 
10521debfc3dSmrg   gcc_assert (!need_ssa_update_p (cfun));
10531debfc3dSmrg 
10541debfc3dSmrg   timevar_push (TV_TREE_SSA_VERIFY);
10551debfc3dSmrg 
10561debfc3dSmrg     {
10571debfc3dSmrg       /* Keep track of SSA names present in the IL.  */
10581debfc3dSmrg       size_t i;
10591debfc3dSmrg       tree name;
10601debfc3dSmrg       hash_map <void *, tree> ssa_info;
10611debfc3dSmrg 
10621debfc3dSmrg       FOR_EACH_SSA_NAME (i, name, cfun)
10631debfc3dSmrg 	{
10641debfc3dSmrg 	  gimple *stmt;
10651debfc3dSmrg 	  TREE_VISITED (name) = 0;
10661debfc3dSmrg 
10671debfc3dSmrg 	  verify_ssa_name (name, virtual_operand_p (name));
10681debfc3dSmrg 
10691debfc3dSmrg 	  stmt = SSA_NAME_DEF_STMT (name);
10701debfc3dSmrg 	  if (!gimple_nop_p (stmt))
10711debfc3dSmrg 	    {
10721debfc3dSmrg 	      basic_block bb = gimple_bb (stmt);
10731debfc3dSmrg 	      if (verify_def (bb, definition_block,
10741debfc3dSmrg 			      name, stmt, virtual_operand_p (name)))
10751debfc3dSmrg 		goto err;
10761debfc3dSmrg 	    }
10771debfc3dSmrg 
10781debfc3dSmrg 	  void *info = NULL;
10791debfc3dSmrg 	  if (POINTER_TYPE_P (TREE_TYPE (name)))
10801debfc3dSmrg 	    info = SSA_NAME_PTR_INFO (name);
10811debfc3dSmrg 	  else if (INTEGRAL_TYPE_P (TREE_TYPE (name)))
10821debfc3dSmrg 	    info = SSA_NAME_RANGE_INFO (name);
10831debfc3dSmrg 	  if (info)
10841debfc3dSmrg 	    {
10851debfc3dSmrg 	      bool existed;
10861debfc3dSmrg 	      tree &val = ssa_info.get_or_insert (info, &existed);
10871debfc3dSmrg 	      if (existed)
10881debfc3dSmrg 		{
10891debfc3dSmrg 		  error ("shared SSA name info");
1090a2dc1f3fSmrg 		  print_generic_expr (stderr, val);
10911debfc3dSmrg 		  fprintf (stderr, " and ");
1092a2dc1f3fSmrg 		  print_generic_expr (stderr, name);
10931debfc3dSmrg 		  fprintf (stderr, "\n");
10941debfc3dSmrg 		  goto err;
10951debfc3dSmrg 		}
10961debfc3dSmrg 	      else
10971debfc3dSmrg 		val = name;
10981debfc3dSmrg 	    }
10991debfc3dSmrg 	}
11001debfc3dSmrg     }
11011debfc3dSmrg 
11021debfc3dSmrg   calculate_dominance_info (CDI_DOMINATORS);
11031debfc3dSmrg 
11041debfc3dSmrg   /* Now verify all the uses and make sure they agree with the definitions
11051debfc3dSmrg      found in the previous pass.  */
11061debfc3dSmrg   FOR_EACH_BB_FN (bb, cfun)
11071debfc3dSmrg     {
11081debfc3dSmrg       edge e;
11091debfc3dSmrg       edge_iterator ei;
11101debfc3dSmrg 
11111debfc3dSmrg       /* Make sure that all edges have a clear 'aux' field.  */
11121debfc3dSmrg       FOR_EACH_EDGE (e, ei, bb->preds)
11131debfc3dSmrg 	{
11141debfc3dSmrg 	  if (e->aux)
11151debfc3dSmrg 	    {
11161debfc3dSmrg 	      error ("AUX pointer initialized for edge %d->%d", e->src->index,
11171debfc3dSmrg 		      e->dest->index);
11181debfc3dSmrg 	      goto err;
11191debfc3dSmrg 	    }
11201debfc3dSmrg 	}
11211debfc3dSmrg 
11221debfc3dSmrg       /* Verify the arguments for every PHI node in the block.  */
11231debfc3dSmrg       for (gphi_iterator gsi = gsi_start_phis (bb); !gsi_end_p (gsi); gsi_next (&gsi))
11241debfc3dSmrg 	{
11251debfc3dSmrg 	  gphi *phi = gsi.phi ();
11261debfc3dSmrg 	  if (verify_phi_args (phi, bb, definition_block))
11271debfc3dSmrg 	    goto err;
11281debfc3dSmrg 
11291debfc3dSmrg 	  bitmap_set_bit (names_defined_in_bb,
11301debfc3dSmrg 			  SSA_NAME_VERSION (gimple_phi_result (phi)));
11311debfc3dSmrg 	}
11321debfc3dSmrg 
11331debfc3dSmrg       /* Now verify all the uses and vuses in every statement of the block.  */
11341debfc3dSmrg       for (gimple_stmt_iterator gsi = gsi_start_bb (bb); !gsi_end_p (gsi);
11351debfc3dSmrg 	   gsi_next (&gsi))
11361debfc3dSmrg 	{
11371debfc3dSmrg 	  gimple *stmt = gsi_stmt (gsi);
11381debfc3dSmrg 	  use_operand_p use_p;
11391debfc3dSmrg 
11401debfc3dSmrg 	  if (check_modified_stmt && gimple_modified_p (stmt))
11411debfc3dSmrg 	    {
11421debfc3dSmrg 	      error ("stmt (%p) marked modified after optimization pass: ",
11431debfc3dSmrg 		     (void *)stmt);
11441debfc3dSmrg 	      print_gimple_stmt (stderr, stmt, 0, TDF_VOPS);
11451debfc3dSmrg 	      goto err;
11461debfc3dSmrg 	    }
11471debfc3dSmrg 
11481debfc3dSmrg 	  if (check_ssa_operands && verify_ssa_operands (cfun, stmt))
11491debfc3dSmrg 	    {
11501debfc3dSmrg 	      print_gimple_stmt (stderr, stmt, 0, TDF_VOPS);
11511debfc3dSmrg 	      goto err;
11521debfc3dSmrg 	    }
11531debfc3dSmrg 
11541debfc3dSmrg 	  if (gimple_debug_bind_p (stmt)
11551debfc3dSmrg 	      && !gimple_debug_bind_has_value_p (stmt))
11561debfc3dSmrg 	    continue;
11571debfc3dSmrg 
11581debfc3dSmrg 	  FOR_EACH_SSA_USE_OPERAND (use_p, stmt, iter, SSA_OP_USE|SSA_OP_VUSE)
11591debfc3dSmrg 	    {
11601debfc3dSmrg 	      op = USE_FROM_PTR (use_p);
11611debfc3dSmrg 	      if (verify_use (bb, definition_block[SSA_NAME_VERSION (op)],
11621debfc3dSmrg 			      use_p, stmt, false, names_defined_in_bb))
11631debfc3dSmrg 		goto err;
11641debfc3dSmrg 	    }
11651debfc3dSmrg 
11661debfc3dSmrg 	  FOR_EACH_SSA_TREE_OPERAND (op, stmt, iter, SSA_OP_ALL_DEFS)
11671debfc3dSmrg 	    {
11681debfc3dSmrg 	      if (SSA_NAME_DEF_STMT (op) != stmt)
11691debfc3dSmrg 		{
11701debfc3dSmrg 		  error ("SSA_NAME_DEF_STMT is wrong");
11711debfc3dSmrg 		  fprintf (stderr, "Expected definition statement:\n");
11721debfc3dSmrg 		  print_gimple_stmt (stderr, stmt, 4, TDF_VOPS);
11731debfc3dSmrg 		  fprintf (stderr, "\nActual definition statement:\n");
11741debfc3dSmrg 		  print_gimple_stmt (stderr, SSA_NAME_DEF_STMT (op),
11751debfc3dSmrg 				     4, TDF_VOPS);
11761debfc3dSmrg 		  goto err;
11771debfc3dSmrg 		}
11781debfc3dSmrg 	      bitmap_set_bit (names_defined_in_bb, SSA_NAME_VERSION (op));
11791debfc3dSmrg 	    }
11801debfc3dSmrg 	}
11811debfc3dSmrg 
11821debfc3dSmrg       bitmap_clear (names_defined_in_bb);
11831debfc3dSmrg     }
11841debfc3dSmrg 
11851debfc3dSmrg   free (definition_block);
11861debfc3dSmrg 
11871debfc3dSmrg   if (gimple_vop (cfun)
11881debfc3dSmrg       && ssa_default_def (cfun, gimple_vop (cfun)))
11891debfc3dSmrg     {
11901debfc3dSmrg       auto_sbitmap visited (last_basic_block_for_fn (cfun) + 1);
11911debfc3dSmrg       bitmap_clear (visited);
11921debfc3dSmrg       if (verify_vssa (ENTRY_BLOCK_PTR_FOR_FN (cfun),
11931debfc3dSmrg 		       ssa_default_def (cfun, gimple_vop (cfun)), visited))
11941debfc3dSmrg 	goto err;
11951debfc3dSmrg     }
11961debfc3dSmrg 
11971debfc3dSmrg   /* Restore the dominance information to its prior known state, so
11981debfc3dSmrg      that we do not perturb the compiler's subsequent behavior.  */
11991debfc3dSmrg   if (orig_dom_state == DOM_NONE)
12001debfc3dSmrg     free_dominance_info (CDI_DOMINATORS);
12011debfc3dSmrg   else
12021debfc3dSmrg     set_dom_info_availability (CDI_DOMINATORS, orig_dom_state);
12031debfc3dSmrg 
12041debfc3dSmrg   timevar_pop (TV_TREE_SSA_VERIFY);
12051debfc3dSmrg   return;
12061debfc3dSmrg 
12071debfc3dSmrg err:
12081debfc3dSmrg   internal_error ("verify_ssa failed");
12091debfc3dSmrg }
12101debfc3dSmrg 
12118feb0f0bSmrg #if __GNUC__ >= 10
12128feb0f0bSmrg #  pragma GCC diagnostic pop
12138feb0f0bSmrg #endif
12141debfc3dSmrg 
12151debfc3dSmrg /* Initialize global DFA and SSA structures.  */
12161debfc3dSmrg 
12171debfc3dSmrg void
init_tree_ssa(struct function * fn)12181debfc3dSmrg init_tree_ssa (struct function *fn)
12191debfc3dSmrg {
12201debfc3dSmrg   fn->gimple_df = ggc_cleared_alloc<gimple_df> ();
12211debfc3dSmrg   fn->gimple_df->default_defs = hash_table<ssa_name_hasher>::create_ggc (20);
12221debfc3dSmrg   pt_solution_reset (&fn->gimple_df->escaped);
12231debfc3dSmrg   init_ssanames (fn, 0);
12241debfc3dSmrg }
12251debfc3dSmrg 
12261debfc3dSmrg /* Deallocate memory associated with SSA data structures for FNDECL.  */
12271debfc3dSmrg 
12281debfc3dSmrg void
delete_tree_ssa(struct function * fn)12291debfc3dSmrg delete_tree_ssa (struct function *fn)
12301debfc3dSmrg {
12311debfc3dSmrg   fini_ssanames (fn);
12321debfc3dSmrg 
12331debfc3dSmrg   /* We no longer maintain the SSA operand cache at this point.  */
12341debfc3dSmrg   if (ssa_operands_active (fn))
12351debfc3dSmrg     fini_ssa_operands (fn);
12361debfc3dSmrg 
12371debfc3dSmrg   fn->gimple_df->default_defs->empty ();
12381debfc3dSmrg   fn->gimple_df->default_defs = NULL;
12391debfc3dSmrg   pt_solution_reset (&fn->gimple_df->escaped);
12401debfc3dSmrg   if (fn->gimple_df->decls_to_pointers != NULL)
12411debfc3dSmrg     delete fn->gimple_df->decls_to_pointers;
12421debfc3dSmrg   fn->gimple_df->decls_to_pointers = NULL;
12431debfc3dSmrg   fn->gimple_df = NULL;
12441debfc3dSmrg 
12451debfc3dSmrg   /* We no longer need the edge variable maps.  */
12461debfc3dSmrg   redirect_edge_var_map_empty ();
12471debfc3dSmrg }
12481debfc3dSmrg 
12491debfc3dSmrg /* Return true if EXPR is a useless type conversion, otherwise return
12501debfc3dSmrg    false.  */
12511debfc3dSmrg 
12521debfc3dSmrg bool
tree_ssa_useless_type_conversion(tree expr)12531debfc3dSmrg tree_ssa_useless_type_conversion (tree expr)
12541debfc3dSmrg {
12551debfc3dSmrg   /* If we have an assignment that merely uses a NOP_EXPR to change
12561debfc3dSmrg      the top of the RHS to the type of the LHS and the type conversion
12571debfc3dSmrg      is "safe", then strip away the type conversion so that we can
12581debfc3dSmrg      enter LHS = RHS into the const_and_copies table.  */
12591debfc3dSmrg   if (CONVERT_EXPR_P (expr)
12601debfc3dSmrg       || TREE_CODE (expr) == VIEW_CONVERT_EXPR
12611debfc3dSmrg       || TREE_CODE (expr) == NON_LVALUE_EXPR)
12621debfc3dSmrg     return useless_type_conversion_p
12631debfc3dSmrg       (TREE_TYPE (expr),
12641debfc3dSmrg        TREE_TYPE (TREE_OPERAND (expr, 0)));
12651debfc3dSmrg 
12661debfc3dSmrg   return false;
12671debfc3dSmrg }
12681debfc3dSmrg 
12691debfc3dSmrg /* Strip conversions from EXP according to
12701debfc3dSmrg    tree_ssa_useless_type_conversion and return the resulting
12711debfc3dSmrg    expression.  */
12721debfc3dSmrg 
12731debfc3dSmrg tree
tree_ssa_strip_useless_type_conversions(tree exp)12741debfc3dSmrg tree_ssa_strip_useless_type_conversions (tree exp)
12751debfc3dSmrg {
12761debfc3dSmrg   while (tree_ssa_useless_type_conversion (exp))
12771debfc3dSmrg     exp = TREE_OPERAND (exp, 0);
12781debfc3dSmrg   return exp;
12791debfc3dSmrg }
12801debfc3dSmrg 
12811debfc3dSmrg /* Return true if T, as SSA_NAME, has an implicit default defined value.  */
12821debfc3dSmrg 
12831debfc3dSmrg bool
ssa_defined_default_def_p(tree t)12841debfc3dSmrg ssa_defined_default_def_p (tree t)
12851debfc3dSmrg {
12861debfc3dSmrg   tree var = SSA_NAME_VAR (t);
12871debfc3dSmrg 
12881debfc3dSmrg   if (!var)
12891debfc3dSmrg     ;
12901debfc3dSmrg   /* Parameters get their initial value from the function entry.  */
12911debfc3dSmrg   else if (TREE_CODE (var) == PARM_DECL)
12921debfc3dSmrg     return true;
12931debfc3dSmrg   /* When returning by reference the return address is actually a hidden
12941debfc3dSmrg      parameter.  */
12951debfc3dSmrg   else if (TREE_CODE (var) == RESULT_DECL && DECL_BY_REFERENCE (var))
12961debfc3dSmrg     return true;
12971debfc3dSmrg   /* Hard register variables get their initial value from the ether.  */
12981debfc3dSmrg   else if (VAR_P (var) && DECL_HARD_REGISTER (var))
12991debfc3dSmrg     return true;
13001debfc3dSmrg 
13011debfc3dSmrg   return false;
13021debfc3dSmrg }
13031debfc3dSmrg 
13041debfc3dSmrg 
13051debfc3dSmrg /* Return true if T, an SSA_NAME, has an undefined value.  PARTIAL is what
13061debfc3dSmrg    should be returned if the value is only partially undefined.  */
13071debfc3dSmrg 
13081debfc3dSmrg bool
ssa_undefined_value_p(tree t,bool partial)13091debfc3dSmrg ssa_undefined_value_p (tree t, bool partial)
13101debfc3dSmrg {
13111debfc3dSmrg   gimple *def_stmt;
13121debfc3dSmrg 
13131debfc3dSmrg   if (ssa_defined_default_def_p (t))
13141debfc3dSmrg     return false;
13151debfc3dSmrg 
13161debfc3dSmrg   /* The value is undefined iff its definition statement is empty.  */
13171debfc3dSmrg   def_stmt = SSA_NAME_DEF_STMT (t);
13181debfc3dSmrg   if (gimple_nop_p (def_stmt))
13191debfc3dSmrg     return true;
13201debfc3dSmrg 
13211debfc3dSmrg   /* Check if the complex was not only partially defined.  */
13221debfc3dSmrg   if (partial && is_gimple_assign (def_stmt)
13231debfc3dSmrg       && gimple_assign_rhs_code (def_stmt) == COMPLEX_EXPR)
13241debfc3dSmrg     {
13251debfc3dSmrg       tree rhs1, rhs2;
13261debfc3dSmrg 
13271debfc3dSmrg       rhs1 = gimple_assign_rhs1 (def_stmt);
13281debfc3dSmrg       rhs2 = gimple_assign_rhs2 (def_stmt);
13291debfc3dSmrg       return (TREE_CODE (rhs1) == SSA_NAME && ssa_undefined_value_p (rhs1))
13301debfc3dSmrg 	     || (TREE_CODE (rhs2) == SSA_NAME && ssa_undefined_value_p (rhs2));
13311debfc3dSmrg     }
13321debfc3dSmrg   return false;
13331debfc3dSmrg }
13341debfc3dSmrg 
13351debfc3dSmrg 
13361debfc3dSmrg /* Return TRUE iff STMT, a gimple statement, references an undefined
13371debfc3dSmrg    SSA name.  */
13381debfc3dSmrg 
13391debfc3dSmrg bool
gimple_uses_undefined_value_p(gimple * stmt)13401debfc3dSmrg gimple_uses_undefined_value_p (gimple *stmt)
13411debfc3dSmrg {
13421debfc3dSmrg   ssa_op_iter iter;
13431debfc3dSmrg   tree op;
13441debfc3dSmrg 
13451debfc3dSmrg   FOR_EACH_SSA_TREE_OPERAND (op, stmt, iter, SSA_OP_USE)
13461debfc3dSmrg     if (ssa_undefined_value_p (op))
13471debfc3dSmrg       return true;
13481debfc3dSmrg 
13491debfc3dSmrg   return false;
13501debfc3dSmrg }
13511debfc3dSmrg 
13521debfc3dSmrg 
13531debfc3dSmrg 
13541debfc3dSmrg /* If necessary, rewrite the base of the reference tree *TP from
13551debfc3dSmrg    a MEM_REF to a plain or converted symbol.  */
13561debfc3dSmrg 
13571debfc3dSmrg static void
maybe_rewrite_mem_ref_base(tree * tp,bitmap suitable_for_renaming)13581debfc3dSmrg maybe_rewrite_mem_ref_base (tree *tp, bitmap suitable_for_renaming)
13591debfc3dSmrg {
13601debfc3dSmrg   tree sym;
13611debfc3dSmrg 
13621debfc3dSmrg   while (handled_component_p (*tp))
13631debfc3dSmrg     tp = &TREE_OPERAND (*tp, 0);
13641debfc3dSmrg   if (TREE_CODE (*tp) == MEM_REF
13651debfc3dSmrg       && TREE_CODE (TREE_OPERAND (*tp, 0)) == ADDR_EXPR
13661debfc3dSmrg       && (sym = TREE_OPERAND (TREE_OPERAND (*tp, 0), 0))
13671debfc3dSmrg       && DECL_P (sym)
13681debfc3dSmrg       && !TREE_ADDRESSABLE (sym)
13691debfc3dSmrg       && bitmap_bit_p (suitable_for_renaming, DECL_UID (sym))
13701debfc3dSmrg       && is_gimple_reg_type (TREE_TYPE (*tp))
13711debfc3dSmrg       && ! VOID_TYPE_P (TREE_TYPE (*tp)))
13721debfc3dSmrg     {
13731debfc3dSmrg       if (TREE_CODE (TREE_TYPE (sym)) == VECTOR_TYPE
13741debfc3dSmrg 	  && useless_type_conversion_p (TREE_TYPE (*tp),
13751debfc3dSmrg 					TREE_TYPE (TREE_TYPE (sym)))
13761debfc3dSmrg 	  && multiple_of_p (sizetype, TREE_OPERAND (*tp, 1),
13771debfc3dSmrg 			    TYPE_SIZE_UNIT (TREE_TYPE (*tp))))
13781debfc3dSmrg 	{
13791debfc3dSmrg 	  *tp = build3 (BIT_FIELD_REF, TREE_TYPE (*tp), sym,
13801debfc3dSmrg 			TYPE_SIZE (TREE_TYPE (*tp)),
13811debfc3dSmrg 			int_const_binop (MULT_EXPR,
13821debfc3dSmrg 					 bitsize_int (BITS_PER_UNIT),
13831debfc3dSmrg 					 TREE_OPERAND (*tp, 1)));
13841debfc3dSmrg 	}
13851debfc3dSmrg       else if (TREE_CODE (TREE_TYPE (sym)) == COMPLEX_TYPE
13861debfc3dSmrg 	       && useless_type_conversion_p (TREE_TYPE (*tp),
13871debfc3dSmrg 					     TREE_TYPE (TREE_TYPE (sym))))
13881debfc3dSmrg 	{
13891debfc3dSmrg 	  *tp = build1 (integer_zerop (TREE_OPERAND (*tp, 1))
13901debfc3dSmrg 			? REALPART_EXPR : IMAGPART_EXPR,
13911debfc3dSmrg 			TREE_TYPE (*tp), sym);
13921debfc3dSmrg 	}
13931debfc3dSmrg       else if (integer_zerop (TREE_OPERAND (*tp, 1))
13941debfc3dSmrg 	       && DECL_SIZE (sym) == TYPE_SIZE (TREE_TYPE (*tp)))
13951debfc3dSmrg 	{
13961debfc3dSmrg 	  if (!useless_type_conversion_p (TREE_TYPE (*tp),
13971debfc3dSmrg 					  TREE_TYPE (sym)))
13981debfc3dSmrg 	    *tp = build1 (VIEW_CONVERT_EXPR,
13991debfc3dSmrg 			  TREE_TYPE (*tp), sym);
14001debfc3dSmrg 	  else
14011debfc3dSmrg 	    *tp = sym;
14021debfc3dSmrg 	}
14031debfc3dSmrg       else if (DECL_SIZE (sym)
14041debfc3dSmrg 	       && TREE_CODE (DECL_SIZE (sym)) == INTEGER_CST
1405a2dc1f3fSmrg 	       && (known_subrange_p
1406a2dc1f3fSmrg 		   (mem_ref_offset (*tp),
1407a2dc1f3fSmrg 		    wi::to_offset (TYPE_SIZE_UNIT (TREE_TYPE (*tp))),
1408a2dc1f3fSmrg 		    0, wi::to_offset (DECL_SIZE_UNIT (sym))))
14091debfc3dSmrg 	       && (! INTEGRAL_TYPE_P (TREE_TYPE (*tp))
14101debfc3dSmrg 		   || (wi::to_offset (TYPE_SIZE (TREE_TYPE (*tp)))
14111debfc3dSmrg 		       == TYPE_PRECISION (TREE_TYPE (*tp))))
1412*23f5f463Smrg 	       && (! INTEGRAL_TYPE_P (TREE_TYPE (sym))
1413*23f5f463Smrg 		   || type_has_mode_precision_p (TREE_TYPE (sym)))
14141debfc3dSmrg 	       && wi::umod_trunc (wi::to_offset (TYPE_SIZE (TREE_TYPE (*tp))),
14151debfc3dSmrg 				  BITS_PER_UNIT) == 0)
14161debfc3dSmrg 	{
14171debfc3dSmrg 	  *tp = build3 (BIT_FIELD_REF, TREE_TYPE (*tp), sym,
14181debfc3dSmrg 			TYPE_SIZE (TREE_TYPE (*tp)),
14191debfc3dSmrg 			wide_int_to_tree (bitsizetype,
14201debfc3dSmrg 					  mem_ref_offset (*tp)
14211debfc3dSmrg 					  << LOG2_BITS_PER_UNIT));
14221debfc3dSmrg 	}
14231debfc3dSmrg     }
14241debfc3dSmrg }
14251debfc3dSmrg 
14261debfc3dSmrg /* For a tree REF return its base if it is the base of a MEM_REF
14271debfc3dSmrg    that cannot be rewritten into SSA form.  Otherwise return NULL_TREE.  */
14281debfc3dSmrg 
14291debfc3dSmrg static tree
non_rewritable_mem_ref_base(tree ref)14301debfc3dSmrg non_rewritable_mem_ref_base (tree ref)
14311debfc3dSmrg {
14321debfc3dSmrg   tree base;
14331debfc3dSmrg 
14341debfc3dSmrg   /* A plain decl does not need it set.  */
14351debfc3dSmrg   if (DECL_P (ref))
14361debfc3dSmrg     return NULL_TREE;
14371debfc3dSmrg 
14381debfc3dSmrg   if (! (base = CONST_CAST_TREE (strip_invariant_refs (ref))))
14391debfc3dSmrg     {
14401debfc3dSmrg       base = get_base_address (ref);
14411debfc3dSmrg       if (DECL_P (base))
14421debfc3dSmrg 	return base;
14431debfc3dSmrg       return NULL_TREE;
14441debfc3dSmrg     }
14451debfc3dSmrg 
14461debfc3dSmrg   /* But watch out for MEM_REFs we cannot lower to a
14471debfc3dSmrg      VIEW_CONVERT_EXPR or a BIT_FIELD_REF.  */
14481debfc3dSmrg   if (TREE_CODE (base) == MEM_REF
14491debfc3dSmrg       && TREE_CODE (TREE_OPERAND (base, 0)) == ADDR_EXPR)
14501debfc3dSmrg     {
14511debfc3dSmrg       tree decl = TREE_OPERAND (TREE_OPERAND (base, 0), 0);
14521debfc3dSmrg       if (! DECL_P (decl))
14531debfc3dSmrg 	return NULL_TREE;
14541debfc3dSmrg       if (! is_gimple_reg_type (TREE_TYPE (base))
14551debfc3dSmrg 	  || VOID_TYPE_P (TREE_TYPE (base))
14561debfc3dSmrg 	  || TREE_THIS_VOLATILE (decl) != TREE_THIS_VOLATILE (base))
14571debfc3dSmrg 	return decl;
14581debfc3dSmrg       if ((TREE_CODE (TREE_TYPE (decl)) == VECTOR_TYPE
14591debfc3dSmrg 	   || TREE_CODE (TREE_TYPE (decl)) == COMPLEX_TYPE)
14601debfc3dSmrg 	  && useless_type_conversion_p (TREE_TYPE (base),
14611debfc3dSmrg 					TREE_TYPE (TREE_TYPE (decl)))
1462a2dc1f3fSmrg 	  && known_ge (mem_ref_offset (base), 0)
1463a2dc1f3fSmrg 	  && known_gt (wi::to_poly_offset (TYPE_SIZE_UNIT (TREE_TYPE (decl))),
14641debfc3dSmrg 		       mem_ref_offset (base))
14651debfc3dSmrg 	  && multiple_of_p (sizetype, TREE_OPERAND (base, 1),
14661debfc3dSmrg 			    TYPE_SIZE_UNIT (TREE_TYPE (base))))
14671debfc3dSmrg 	return NULL_TREE;
14681debfc3dSmrg       /* For same sizes and zero offset we can use a VIEW_CONVERT_EXPR.  */
14691debfc3dSmrg       if (integer_zerop (TREE_OPERAND (base, 1))
14701debfc3dSmrg 	  && DECL_SIZE (decl) == TYPE_SIZE (TREE_TYPE (base)))
14711debfc3dSmrg 	return NULL_TREE;
14721debfc3dSmrg       /* For integral typed extracts we can use a BIT_FIELD_REF.  */
14731debfc3dSmrg       if (DECL_SIZE (decl)
1474a2dc1f3fSmrg 	  && TREE_CODE (DECL_SIZE_UNIT (decl)) == INTEGER_CST
1475a2dc1f3fSmrg 	  && (known_subrange_p
1476a2dc1f3fSmrg 	      (mem_ref_offset (base),
1477a2dc1f3fSmrg 	       wi::to_poly_offset (TYPE_SIZE_UNIT (TREE_TYPE (base))),
1478a2dc1f3fSmrg 	       0, wi::to_poly_offset (DECL_SIZE_UNIT (decl))))
14791debfc3dSmrg 	  /* ???  We can't handle bitfield precision extracts without
14801debfc3dSmrg 	     either using an alternate type for the BIT_FIELD_REF and
14811debfc3dSmrg 	     then doing a conversion or possibly adjusting the offset
14821debfc3dSmrg 	     according to endianness.  */
14831debfc3dSmrg 	  && (! INTEGRAL_TYPE_P (TREE_TYPE (base))
14841debfc3dSmrg 	      || (wi::to_offset (TYPE_SIZE (TREE_TYPE (base)))
14851debfc3dSmrg 		  == TYPE_PRECISION (TREE_TYPE (base))))
1486*23f5f463Smrg 	  /* ???  Likewise for extracts from bitfields, we'd have
1487*23f5f463Smrg 	     to pun the base object to a size precision mode first.  */
1488*23f5f463Smrg 	  && (! INTEGRAL_TYPE_P (TREE_TYPE (decl))
1489*23f5f463Smrg 	      || type_has_mode_precision_p (TREE_TYPE (decl)))
14901debfc3dSmrg 	  && wi::umod_trunc (wi::to_offset (TYPE_SIZE (TREE_TYPE (base))),
14911debfc3dSmrg 			     BITS_PER_UNIT) == 0)
14921debfc3dSmrg 	return NULL_TREE;
14931debfc3dSmrg       return decl;
14941debfc3dSmrg     }
14951debfc3dSmrg 
14961debfc3dSmrg   return NULL_TREE;
14971debfc3dSmrg }
14981debfc3dSmrg 
14991debfc3dSmrg /* For an lvalue tree LHS return true if it cannot be rewritten into SSA form.
15001debfc3dSmrg    Otherwise return true.  */
15011debfc3dSmrg 
15021debfc3dSmrg static bool
non_rewritable_lvalue_p(tree lhs)15031debfc3dSmrg non_rewritable_lvalue_p (tree lhs)
15041debfc3dSmrg {
15051debfc3dSmrg   /* A plain decl is always rewritable.  */
15061debfc3dSmrg   if (DECL_P (lhs))
15071debfc3dSmrg     return false;
15081debfc3dSmrg 
15091debfc3dSmrg   /* We can re-write REALPART_EXPR and IMAGPART_EXPR sets in
15101debfc3dSmrg      a reasonably efficient manner... */
15111debfc3dSmrg   if ((TREE_CODE (lhs) == REALPART_EXPR
15121debfc3dSmrg        || TREE_CODE (lhs) == IMAGPART_EXPR)
15131debfc3dSmrg       && DECL_P (TREE_OPERAND (lhs, 0)))
15141debfc3dSmrg     return false;
15151debfc3dSmrg 
15161debfc3dSmrg   /* ???  The following could be relaxed allowing component
15171debfc3dSmrg      references that do not change the access size.  */
15181debfc3dSmrg   if (TREE_CODE (lhs) == MEM_REF
15191debfc3dSmrg       && TREE_CODE (TREE_OPERAND (lhs, 0)) == ADDR_EXPR)
15201debfc3dSmrg     {
15211debfc3dSmrg       tree decl = TREE_OPERAND (TREE_OPERAND (lhs, 0), 0);
15221debfc3dSmrg 
15231debfc3dSmrg       /* A decl that is wrapped inside a MEM-REF that covers
15241debfc3dSmrg 	 it full is also rewritable.  */
15251debfc3dSmrg       if (integer_zerop (TREE_OPERAND (lhs, 1))
15261debfc3dSmrg 	  && DECL_P (decl)
15271debfc3dSmrg 	  && DECL_SIZE (decl) == TYPE_SIZE (TREE_TYPE (lhs))
15281debfc3dSmrg 	  /* If the dynamic type of the decl has larger precision than
15291debfc3dSmrg 	     the decl itself we can't use the decls type for SSA rewriting.  */
15301debfc3dSmrg 	  && ((! INTEGRAL_TYPE_P (TREE_TYPE (decl))
15311debfc3dSmrg 	       || compare_tree_int (DECL_SIZE (decl),
15321debfc3dSmrg 				    TYPE_PRECISION (TREE_TYPE (decl))) == 0)
15331debfc3dSmrg 	      || (INTEGRAL_TYPE_P (TREE_TYPE (lhs))
15341debfc3dSmrg 		  && (TYPE_PRECISION (TREE_TYPE (decl))
15351debfc3dSmrg 		      >= TYPE_PRECISION (TREE_TYPE (lhs)))))
15361debfc3dSmrg 	  /* Make sure we are not re-writing non-float copying into float
15371debfc3dSmrg 	     copying as that can incur normalization.  */
15381debfc3dSmrg 	  && (! FLOAT_TYPE_P (TREE_TYPE (decl))
15391debfc3dSmrg 	      || types_compatible_p (TREE_TYPE (lhs), TREE_TYPE (decl)))
15401debfc3dSmrg 	  && (TREE_THIS_VOLATILE (decl) == TREE_THIS_VOLATILE (lhs)))
15411debfc3dSmrg 	return false;
15421debfc3dSmrg 
15431debfc3dSmrg       /* A vector-insert using a MEM_REF or ARRAY_REF is rewritable
15441debfc3dSmrg 	 using a BIT_INSERT_EXPR.  */
15451debfc3dSmrg       if (DECL_P (decl)
15461debfc3dSmrg 	  && VECTOR_TYPE_P (TREE_TYPE (decl))
15471debfc3dSmrg 	  && TYPE_MODE (TREE_TYPE (decl)) != BLKmode
1548a2dc1f3fSmrg 	  && known_ge (mem_ref_offset (lhs), 0)
1549a2dc1f3fSmrg 	  && known_gt (wi::to_poly_offset (TYPE_SIZE_UNIT (TREE_TYPE (decl))),
1550a2dc1f3fSmrg 		       mem_ref_offset (lhs))
1551a2dc1f3fSmrg 	  && multiple_of_p (sizetype, TREE_OPERAND (lhs, 1),
15528feb0f0bSmrg 			    TYPE_SIZE_UNIT (TREE_TYPE (lhs)))
15538feb0f0bSmrg 	  && known_ge (wi::to_poly_offset (TYPE_SIZE (TREE_TYPE (decl))),
15548feb0f0bSmrg 		       wi::to_poly_offset (TYPE_SIZE (TREE_TYPE (lhs)))))
15558feb0f0bSmrg 	{
15568feb0f0bSmrg 	  poly_uint64 lhs_bits, nelts;
15578feb0f0bSmrg 	  if (poly_int_tree_p (TYPE_SIZE (TREE_TYPE (lhs)), &lhs_bits)
15588feb0f0bSmrg 	      && multiple_p (lhs_bits,
15598feb0f0bSmrg 			     tree_to_uhwi
15608feb0f0bSmrg 			       (TYPE_SIZE (TREE_TYPE (TREE_TYPE (decl)))),
15618feb0f0bSmrg 			     &nelts)
15628feb0f0bSmrg 	      && valid_vector_subparts_p (nelts))
15638feb0f0bSmrg 	    {
15648feb0f0bSmrg 	      if (known_eq (nelts, 1u))
15651debfc3dSmrg 		return false;
15668feb0f0bSmrg 	      /* For sub-vector inserts the insert vector mode has to be
15678feb0f0bSmrg 		 supported.  */
15688feb0f0bSmrg 	      tree vtype = build_vector_type (TREE_TYPE (TREE_TYPE (decl)),
15698feb0f0bSmrg 					      nelts);
15708feb0f0bSmrg 	      if (TYPE_MODE (vtype) != BLKmode)
15718feb0f0bSmrg 		return false;
15728feb0f0bSmrg 	    }
15738feb0f0bSmrg 	}
15741debfc3dSmrg     }
15751debfc3dSmrg 
15761debfc3dSmrg   /* A vector-insert using a BIT_FIELD_REF is rewritable using
15771debfc3dSmrg      BIT_INSERT_EXPR.  */
15781debfc3dSmrg   if (TREE_CODE (lhs) == BIT_FIELD_REF
15791debfc3dSmrg       && DECL_P (TREE_OPERAND (lhs, 0))
15801debfc3dSmrg       && VECTOR_TYPE_P (TREE_TYPE (TREE_OPERAND (lhs, 0)))
15811debfc3dSmrg       && TYPE_MODE (TREE_TYPE (TREE_OPERAND (lhs, 0))) != BLKmode
1582a2dc1f3fSmrg       && operand_equal_p (TYPE_SIZE_UNIT (TREE_TYPE (lhs)),
1583a2dc1f3fSmrg 			  TYPE_SIZE_UNIT
1584a2dc1f3fSmrg 			    (TREE_TYPE (TREE_TYPE (TREE_OPERAND (lhs, 0)))), 0)
15851debfc3dSmrg       && (tree_to_uhwi (TREE_OPERAND (lhs, 2))
15861debfc3dSmrg 	  % tree_to_uhwi (TYPE_SIZE (TREE_TYPE (lhs)))) == 0)
15871debfc3dSmrg     return false;
15881debfc3dSmrg 
15891debfc3dSmrg   return true;
15901debfc3dSmrg }
15911debfc3dSmrg 
15921debfc3dSmrg /* When possible, clear TREE_ADDRESSABLE bit or set DECL_GIMPLE_REG_P bit and
15931debfc3dSmrg    mark the variable VAR for conversion into SSA.  Return true when updating
15941debfc3dSmrg    stmts is required.  */
15951debfc3dSmrg 
15961debfc3dSmrg static void
maybe_optimize_var(tree var,bitmap addresses_taken,bitmap not_reg_needs,bitmap suitable_for_renaming)15971debfc3dSmrg maybe_optimize_var (tree var, bitmap addresses_taken, bitmap not_reg_needs,
15981debfc3dSmrg 		    bitmap suitable_for_renaming)
15991debfc3dSmrg {
16001debfc3dSmrg   /* Global Variables, result decls cannot be changed.  */
16011debfc3dSmrg   if (is_global_var (var)
16021debfc3dSmrg       || TREE_CODE (var) == RESULT_DECL
16031debfc3dSmrg       || bitmap_bit_p (addresses_taken, DECL_UID (var)))
16041debfc3dSmrg     return;
16051debfc3dSmrg 
16061debfc3dSmrg   if (TREE_ADDRESSABLE (var)
16071debfc3dSmrg       /* Do not change TREE_ADDRESSABLE if we need to preserve var as
16081debfc3dSmrg 	 a non-register.  Otherwise we are confused and forget to
16091debfc3dSmrg 	 add virtual operands for it.  */
16101debfc3dSmrg       && (!is_gimple_reg_type (TREE_TYPE (var))
16111debfc3dSmrg 	  || TREE_CODE (TREE_TYPE (var)) == VECTOR_TYPE
16121debfc3dSmrg 	  || TREE_CODE (TREE_TYPE (var)) == COMPLEX_TYPE
16131debfc3dSmrg 	  || !bitmap_bit_p (not_reg_needs, DECL_UID (var))))
16141debfc3dSmrg     {
16151debfc3dSmrg       TREE_ADDRESSABLE (var) = 0;
1616c0a68be4Smrg       /* If we cleared TREE_ADDRESSABLE make sure DECL_GIMPLE_REG_P
1617c0a68be4Smrg          is unset if we cannot rewrite the var into SSA.  */
1618c0a68be4Smrg       if ((TREE_CODE (TREE_TYPE (var)) == VECTOR_TYPE
1619c0a68be4Smrg 	   || TREE_CODE (TREE_TYPE (var)) == COMPLEX_TYPE)
1620c0a68be4Smrg 	  && bitmap_bit_p (not_reg_needs, DECL_UID (var)))
1621c0a68be4Smrg 	DECL_GIMPLE_REG_P (var) = 0;
16221debfc3dSmrg       if (is_gimple_reg (var))
16231debfc3dSmrg 	bitmap_set_bit (suitable_for_renaming, DECL_UID (var));
16241debfc3dSmrg       if (dump_file)
16251debfc3dSmrg 	{
16261debfc3dSmrg 	  fprintf (dump_file, "No longer having address taken: ");
1627a2dc1f3fSmrg 	  print_generic_expr (dump_file, var);
16281debfc3dSmrg 	  fprintf (dump_file, "\n");
16291debfc3dSmrg 	}
16301debfc3dSmrg     }
16311debfc3dSmrg 
16321debfc3dSmrg   if (!DECL_GIMPLE_REG_P (var)
16331debfc3dSmrg       && !bitmap_bit_p (not_reg_needs, DECL_UID (var))
16341debfc3dSmrg       && (TREE_CODE (TREE_TYPE (var)) == COMPLEX_TYPE
16351debfc3dSmrg 	  || TREE_CODE (TREE_TYPE (var)) == VECTOR_TYPE)
16361debfc3dSmrg       && !TREE_THIS_VOLATILE (var)
16371debfc3dSmrg       && (!VAR_P (var) || !DECL_HARD_REGISTER (var)))
16381debfc3dSmrg     {
16391debfc3dSmrg       DECL_GIMPLE_REG_P (var) = 1;
16401debfc3dSmrg       bitmap_set_bit (suitable_for_renaming, DECL_UID (var));
16411debfc3dSmrg       if (dump_file)
16421debfc3dSmrg 	{
16431debfc3dSmrg 	  fprintf (dump_file, "Now a gimple register: ");
1644a2dc1f3fSmrg 	  print_generic_expr (dump_file, var);
16451debfc3dSmrg 	  fprintf (dump_file, "\n");
16461debfc3dSmrg 	}
16471debfc3dSmrg     }
16481debfc3dSmrg }
16491debfc3dSmrg 
16501debfc3dSmrg /* Return true when STMT is ASAN mark where second argument is an address
16511debfc3dSmrg    of a local variable.  */
16521debfc3dSmrg 
16531debfc3dSmrg static bool
is_asan_mark_p(gimple * stmt)16541debfc3dSmrg is_asan_mark_p (gimple *stmt)
16551debfc3dSmrg {
16561debfc3dSmrg   if (!gimple_call_internal_p (stmt, IFN_ASAN_MARK))
16571debfc3dSmrg     return false;
16581debfc3dSmrg 
16591debfc3dSmrg   tree addr = get_base_address (gimple_call_arg (stmt, 1));
16601debfc3dSmrg   if (TREE_CODE (addr) == ADDR_EXPR
16611debfc3dSmrg       && VAR_P (TREE_OPERAND (addr, 0)))
16621debfc3dSmrg     {
16631debfc3dSmrg       tree var = TREE_OPERAND (addr, 0);
16641debfc3dSmrg       if (lookup_attribute (ASAN_USE_AFTER_SCOPE_ATTRIBUTE,
16651debfc3dSmrg 			    DECL_ATTRIBUTES (var)))
16661debfc3dSmrg 	return false;
16671debfc3dSmrg 
16681debfc3dSmrg       unsigned addressable = TREE_ADDRESSABLE (var);
16691debfc3dSmrg       TREE_ADDRESSABLE (var) = 0;
16701debfc3dSmrg       bool r = is_gimple_reg (var);
16711debfc3dSmrg       TREE_ADDRESSABLE (var) = addressable;
16721debfc3dSmrg       return r;
16731debfc3dSmrg     }
16741debfc3dSmrg 
16751debfc3dSmrg   return false;
16761debfc3dSmrg }
16771debfc3dSmrg 
16781debfc3dSmrg /* Compute TREE_ADDRESSABLE and DECL_GIMPLE_REG_P for local variables.  */
16791debfc3dSmrg 
16801debfc3dSmrg void
execute_update_addresses_taken(void)16811debfc3dSmrg execute_update_addresses_taken (void)
16821debfc3dSmrg {
16831debfc3dSmrg   basic_block bb;
1684a2dc1f3fSmrg   auto_bitmap addresses_taken;
1685a2dc1f3fSmrg   auto_bitmap not_reg_needs;
1686a2dc1f3fSmrg   auto_bitmap suitable_for_renaming;
16871debfc3dSmrg   tree var;
16881debfc3dSmrg   unsigned i;
16891debfc3dSmrg 
16901debfc3dSmrg   timevar_push (TV_ADDRESS_TAKEN);
16911debfc3dSmrg 
16921debfc3dSmrg   /* Collect into ADDRESSES_TAKEN all variables whose address is taken within
16931debfc3dSmrg      the function body.  */
16941debfc3dSmrg   FOR_EACH_BB_FN (bb, cfun)
16951debfc3dSmrg     {
16961debfc3dSmrg       for (gimple_stmt_iterator gsi = gsi_start_bb (bb); !gsi_end_p (gsi);
16971debfc3dSmrg 	   gsi_next (&gsi))
16981debfc3dSmrg 	{
16991debfc3dSmrg 	  gimple *stmt = gsi_stmt (gsi);
17001debfc3dSmrg 	  enum gimple_code code = gimple_code (stmt);
17011debfc3dSmrg 	  tree decl;
17021debfc3dSmrg 
17031debfc3dSmrg 	  if (code == GIMPLE_CALL)
17041debfc3dSmrg 	    {
17051debfc3dSmrg 	      if (optimize_atomic_compare_exchange_p (stmt))
17061debfc3dSmrg 		{
17071debfc3dSmrg 		  /* For __atomic_compare_exchange_N if the second argument
17081debfc3dSmrg 		     is &var, don't mark var addressable;
17091debfc3dSmrg 		     if it becomes non-addressable, we'll rewrite it into
17101debfc3dSmrg 		     ATOMIC_COMPARE_EXCHANGE call.  */
17111debfc3dSmrg 		  tree arg = gimple_call_arg (stmt, 1);
17121debfc3dSmrg 		  gimple_call_set_arg (stmt, 1, null_pointer_node);
17131debfc3dSmrg 		  gimple_ior_addresses_taken (addresses_taken, stmt);
17141debfc3dSmrg 		  gimple_call_set_arg (stmt, 1, arg);
17151debfc3dSmrg 		}
17161debfc3dSmrg 	      else if (is_asan_mark_p (stmt)
17171debfc3dSmrg 		       || gimple_call_internal_p (stmt, IFN_GOMP_SIMT_ENTER))
17181debfc3dSmrg 		;
17191debfc3dSmrg 	      else
17201debfc3dSmrg 		gimple_ior_addresses_taken (addresses_taken, stmt);
17211debfc3dSmrg 	    }
17221debfc3dSmrg 	  else
17231debfc3dSmrg 	    /* Note all addresses taken by the stmt.  */
17241debfc3dSmrg 	    gimple_ior_addresses_taken (addresses_taken, stmt);
17251debfc3dSmrg 
17261debfc3dSmrg 	  /* If we have a call or an assignment, see if the lhs contains
17271debfc3dSmrg 	     a local decl that requires not to be a gimple register.  */
17281debfc3dSmrg 	  if (code == GIMPLE_ASSIGN || code == GIMPLE_CALL)
17291debfc3dSmrg 	    {
17301debfc3dSmrg               tree lhs = gimple_get_lhs (stmt);
17311debfc3dSmrg               if (lhs
17321debfc3dSmrg 		  && TREE_CODE (lhs) != SSA_NAME
17331debfc3dSmrg 		  && ((code == GIMPLE_CALL && ! DECL_P (lhs))
17341debfc3dSmrg 		      || non_rewritable_lvalue_p (lhs)))
17351debfc3dSmrg 		{
17361debfc3dSmrg 		  decl = get_base_address (lhs);
17371debfc3dSmrg 		  if (DECL_P (decl))
17381debfc3dSmrg 		    bitmap_set_bit (not_reg_needs, DECL_UID (decl));
17391debfc3dSmrg                 }
17401debfc3dSmrg 	    }
17411debfc3dSmrg 
17421debfc3dSmrg 	  if (gimple_assign_single_p (stmt))
17431debfc3dSmrg 	    {
17441debfc3dSmrg 	      tree rhs = gimple_assign_rhs1 (stmt);
17451debfc3dSmrg 	      if ((decl = non_rewritable_mem_ref_base (rhs)))
17461debfc3dSmrg 		bitmap_set_bit (not_reg_needs, DECL_UID (decl));
17471debfc3dSmrg 	    }
17481debfc3dSmrg 
17491debfc3dSmrg 	  else if (code == GIMPLE_CALL)
17501debfc3dSmrg 	    {
17511debfc3dSmrg 	      for (i = 0; i < gimple_call_num_args (stmt); ++i)
17521debfc3dSmrg 		{
17531debfc3dSmrg 		  tree arg = gimple_call_arg (stmt, i);
17541debfc3dSmrg 		  if ((decl = non_rewritable_mem_ref_base (arg)))
17551debfc3dSmrg 		    bitmap_set_bit (not_reg_needs, DECL_UID (decl));
17561debfc3dSmrg 		}
17571debfc3dSmrg 	    }
17581debfc3dSmrg 
17591debfc3dSmrg 	  else if (code == GIMPLE_ASM)
17601debfc3dSmrg 	    {
17611debfc3dSmrg 	      gasm *asm_stmt = as_a <gasm *> (stmt);
17621debfc3dSmrg 	      for (i = 0; i < gimple_asm_noutputs (asm_stmt); ++i)
17631debfc3dSmrg 		{
17641debfc3dSmrg 		  tree link = gimple_asm_output_op (asm_stmt, i);
17651debfc3dSmrg 		  tree lhs = TREE_VALUE (link);
17661debfc3dSmrg 		  if (TREE_CODE (lhs) != SSA_NAME)
17671debfc3dSmrg 		    {
17681debfc3dSmrg 		      decl = get_base_address (lhs);
17691debfc3dSmrg 		      if (DECL_P (decl)
17701debfc3dSmrg 			  && (non_rewritable_lvalue_p (lhs)
17711debfc3dSmrg 			      /* We cannot move required conversions from
17721debfc3dSmrg 				 the lhs to the rhs in asm statements, so
17731debfc3dSmrg 				 require we do not need any.  */
17741debfc3dSmrg 			      || !useless_type_conversion_p
17751debfc3dSmrg 			            (TREE_TYPE (lhs), TREE_TYPE (decl))))
17761debfc3dSmrg 			bitmap_set_bit (not_reg_needs, DECL_UID (decl));
17771debfc3dSmrg 		    }
17781debfc3dSmrg 		}
17791debfc3dSmrg 	      for (i = 0; i < gimple_asm_ninputs (asm_stmt); ++i)
17801debfc3dSmrg 		{
17811debfc3dSmrg 		  tree link = gimple_asm_input_op (asm_stmt, i);
17821debfc3dSmrg 		  if ((decl = non_rewritable_mem_ref_base (TREE_VALUE (link))))
17831debfc3dSmrg 		    bitmap_set_bit (not_reg_needs, DECL_UID (decl));
17841debfc3dSmrg 		}
17851debfc3dSmrg 	    }
17861debfc3dSmrg 	}
17871debfc3dSmrg 
17881debfc3dSmrg       for (gphi_iterator gsi = gsi_start_phis (bb); !gsi_end_p (gsi);
17891debfc3dSmrg 	   gsi_next (&gsi))
17901debfc3dSmrg 	{
17911debfc3dSmrg 	  size_t i;
17921debfc3dSmrg 	  gphi *phi = gsi.phi ();
17931debfc3dSmrg 
17941debfc3dSmrg 	  for (i = 0; i < gimple_phi_num_args (phi); i++)
17951debfc3dSmrg 	    {
17961debfc3dSmrg 	      tree op = PHI_ARG_DEF (phi, i), var;
17971debfc3dSmrg 	      if (TREE_CODE (op) == ADDR_EXPR
17981debfc3dSmrg 		  && (var = get_base_address (TREE_OPERAND (op, 0))) != NULL
17991debfc3dSmrg 		  && DECL_P (var))
18001debfc3dSmrg 		bitmap_set_bit (addresses_taken, DECL_UID (var));
18011debfc3dSmrg 	    }
18021debfc3dSmrg 	}
18031debfc3dSmrg     }
18041debfc3dSmrg 
18051debfc3dSmrg   /* We cannot iterate over all referenced vars because that can contain
18061debfc3dSmrg      unused vars from BLOCK trees, which causes code generation differences
18071debfc3dSmrg      for -g vs. -g0.  */
18081debfc3dSmrg   for (var = DECL_ARGUMENTS (cfun->decl); var; var = DECL_CHAIN (var))
18091debfc3dSmrg     maybe_optimize_var (var, addresses_taken, not_reg_needs,
18101debfc3dSmrg 			suitable_for_renaming);
18111debfc3dSmrg 
18121debfc3dSmrg   FOR_EACH_VEC_SAFE_ELT (cfun->local_decls, i, var)
18131debfc3dSmrg     maybe_optimize_var (var, addresses_taken, not_reg_needs,
18141debfc3dSmrg 			suitable_for_renaming);
18151debfc3dSmrg 
18161debfc3dSmrg   /* Operand caches need to be recomputed for operands referencing the updated
18171debfc3dSmrg      variables and operands need to be rewritten to expose bare symbols.  */
18181debfc3dSmrg   if (!bitmap_empty_p (suitable_for_renaming))
18191debfc3dSmrg     {
18201debfc3dSmrg       FOR_EACH_BB_FN (bb, cfun)
18211debfc3dSmrg 	for (gimple_stmt_iterator gsi = gsi_start_bb (bb); !gsi_end_p (gsi);)
18221debfc3dSmrg 	  {
18231debfc3dSmrg 	    gimple *stmt = gsi_stmt (gsi);
18241debfc3dSmrg 
18251debfc3dSmrg 	    /* Re-write TARGET_MEM_REFs of symbols we want to
18261debfc3dSmrg 	       rewrite into SSA form.  */
18271debfc3dSmrg 	    if (gimple_assign_single_p (stmt))
18281debfc3dSmrg 	      {
18291debfc3dSmrg 		tree lhs = gimple_assign_lhs (stmt);
18301debfc3dSmrg 		tree rhs, *rhsp = gimple_assign_rhs1_ptr (stmt);
18311debfc3dSmrg 		tree sym;
18321debfc3dSmrg 
18331debfc3dSmrg 		/* Rewrite LHS IMAG/REALPART_EXPR similar to
18341debfc3dSmrg 		   gimplify_modify_expr_complex_part.  */
18351debfc3dSmrg 		if ((TREE_CODE (lhs) == IMAGPART_EXPR
18361debfc3dSmrg 		     || TREE_CODE (lhs) == REALPART_EXPR)
18371debfc3dSmrg 		    && DECL_P (TREE_OPERAND (lhs, 0))
18381debfc3dSmrg 		    && bitmap_bit_p (suitable_for_renaming,
18391debfc3dSmrg 				     DECL_UID (TREE_OPERAND (lhs, 0))))
18401debfc3dSmrg 		  {
18411debfc3dSmrg 		    tree other = make_ssa_name (TREE_TYPE (lhs));
18421debfc3dSmrg 		    tree lrhs = build1 (TREE_CODE (lhs) == IMAGPART_EXPR
18431debfc3dSmrg 					? REALPART_EXPR : IMAGPART_EXPR,
18441debfc3dSmrg 					TREE_TYPE (other),
18451debfc3dSmrg 					TREE_OPERAND (lhs, 0));
18461debfc3dSmrg 		    gimple *load = gimple_build_assign (other, lrhs);
18471debfc3dSmrg 		    location_t loc = gimple_location (stmt);
18481debfc3dSmrg 		    gimple_set_location (load, loc);
18491debfc3dSmrg 		    gimple_set_vuse (load, gimple_vuse (stmt));
18501debfc3dSmrg 		    gsi_insert_before (&gsi, load, GSI_SAME_STMT);
18511debfc3dSmrg 		    gimple_assign_set_lhs (stmt, TREE_OPERAND (lhs, 0));
18521debfc3dSmrg 		    gimple_assign_set_rhs_with_ops
18531debfc3dSmrg 		      (&gsi, COMPLEX_EXPR,
18541debfc3dSmrg 		       TREE_CODE (lhs) == IMAGPART_EXPR
18551debfc3dSmrg 		       ? other : gimple_assign_rhs1 (stmt),
18561debfc3dSmrg 		       TREE_CODE (lhs) == IMAGPART_EXPR
18571debfc3dSmrg 		       ? gimple_assign_rhs1 (stmt) : other, NULL_TREE);
18581debfc3dSmrg 		    stmt = gsi_stmt (gsi);
18591debfc3dSmrg 		    unlink_stmt_vdef (stmt);
18601debfc3dSmrg 		    update_stmt (stmt);
18611debfc3dSmrg 		    continue;
18621debfc3dSmrg 		  }
18631debfc3dSmrg 
18641debfc3dSmrg 		/* Rewrite a vector insert via a BIT_FIELD_REF on the LHS
18651debfc3dSmrg 		   into a BIT_INSERT_EXPR.  */
18661debfc3dSmrg 		if (TREE_CODE (lhs) == BIT_FIELD_REF
18671debfc3dSmrg 		    && DECL_P (TREE_OPERAND (lhs, 0))
18681debfc3dSmrg 		    && bitmap_bit_p (suitable_for_renaming,
18691debfc3dSmrg 				     DECL_UID (TREE_OPERAND (lhs, 0)))
18701debfc3dSmrg 		    && VECTOR_TYPE_P (TREE_TYPE (TREE_OPERAND (lhs, 0)))
18711debfc3dSmrg 		    && TYPE_MODE (TREE_TYPE (TREE_OPERAND (lhs, 0))) != BLKmode
1872a2dc1f3fSmrg 		    && operand_equal_p (TYPE_SIZE_UNIT (TREE_TYPE (lhs)),
1873a2dc1f3fSmrg 					TYPE_SIZE_UNIT (TREE_TYPE
1874a2dc1f3fSmrg 					  (TREE_TYPE (TREE_OPERAND (lhs, 0)))),
1875a2dc1f3fSmrg 					0)
18761debfc3dSmrg 		    && (tree_to_uhwi (TREE_OPERAND (lhs, 2))
18771debfc3dSmrg 			% tree_to_uhwi (TYPE_SIZE (TREE_TYPE (lhs))) == 0))
18781debfc3dSmrg 		  {
18791debfc3dSmrg 		    tree var = TREE_OPERAND (lhs, 0);
18801debfc3dSmrg 		    tree val = gimple_assign_rhs1 (stmt);
1881a2dc1f3fSmrg 		    if (! types_compatible_p (TREE_TYPE (TREE_TYPE (var)),
1882a2dc1f3fSmrg 					      TREE_TYPE (val)))
1883a2dc1f3fSmrg 		      {
1884a2dc1f3fSmrg 			tree tem = make_ssa_name (TREE_TYPE (TREE_TYPE (var)));
1885a2dc1f3fSmrg 			gimple *pun
1886a2dc1f3fSmrg 			  = gimple_build_assign (tem,
1887a2dc1f3fSmrg 						 build1 (VIEW_CONVERT_EXPR,
1888a2dc1f3fSmrg 							 TREE_TYPE (tem), val));
1889a2dc1f3fSmrg 			gsi_insert_before (&gsi, pun, GSI_SAME_STMT);
1890a2dc1f3fSmrg 			val = tem;
1891a2dc1f3fSmrg 		      }
18921debfc3dSmrg 		    tree bitpos = TREE_OPERAND (lhs, 2);
18931debfc3dSmrg 		    gimple_assign_set_lhs (stmt, var);
18941debfc3dSmrg 		    gimple_assign_set_rhs_with_ops
18951debfc3dSmrg 		      (&gsi, BIT_INSERT_EXPR, var, val, bitpos);
18961debfc3dSmrg 		    stmt = gsi_stmt (gsi);
18971debfc3dSmrg 		    unlink_stmt_vdef (stmt);
18981debfc3dSmrg 		    update_stmt (stmt);
18991debfc3dSmrg 		    continue;
19001debfc3dSmrg 		  }
19011debfc3dSmrg 
19021debfc3dSmrg 		/* Rewrite a vector insert using a MEM_REF on the LHS
19031debfc3dSmrg 		   into a BIT_INSERT_EXPR.  */
19041debfc3dSmrg 		if (TREE_CODE (lhs) == MEM_REF
19051debfc3dSmrg 		    && TREE_CODE (TREE_OPERAND (lhs, 0)) == ADDR_EXPR
19061debfc3dSmrg 		    && (sym = TREE_OPERAND (TREE_OPERAND (lhs, 0), 0))
19071debfc3dSmrg 		    && DECL_P (sym)
19081debfc3dSmrg 		    && bitmap_bit_p (suitable_for_renaming, DECL_UID (sym))
19091debfc3dSmrg 		    && VECTOR_TYPE_P (TREE_TYPE (sym))
19101debfc3dSmrg 		    && TYPE_MODE (TREE_TYPE (sym)) != BLKmode
19118feb0f0bSmrg 		    /* If it is a full replacement we can do better below.  */
19128feb0f0bSmrg 		    && maybe_ne (wi::to_poly_offset
19138feb0f0bSmrg 				   (TYPE_SIZE_UNIT (TREE_TYPE (lhs))),
19148feb0f0bSmrg 				 wi::to_poly_offset
19158feb0f0bSmrg                                    (TYPE_SIZE_UNIT (TREE_TYPE (sym))))
19168feb0f0bSmrg 		    && known_ge (mem_ref_offset (lhs), 0)
19178feb0f0bSmrg 		    && known_gt (wi::to_poly_offset
19188feb0f0bSmrg 				   (TYPE_SIZE_UNIT (TREE_TYPE (sym))),
19198feb0f0bSmrg 				 mem_ref_offset (lhs))
19208feb0f0bSmrg 		    && multiple_of_p (sizetype,
19218feb0f0bSmrg 				      TREE_OPERAND (lhs, 1),
19228feb0f0bSmrg 				      TYPE_SIZE_UNIT (TREE_TYPE (lhs))))
19231debfc3dSmrg 		  {
19241debfc3dSmrg 		    tree val = gimple_assign_rhs1 (stmt);
1925a2dc1f3fSmrg 		    if (! types_compatible_p (TREE_TYPE (val),
1926a2dc1f3fSmrg 					      TREE_TYPE (TREE_TYPE (sym))))
1927a2dc1f3fSmrg 		      {
19288feb0f0bSmrg 			poly_uint64 lhs_bits, nelts;
19298feb0f0bSmrg 			tree temtype = TREE_TYPE (TREE_TYPE (sym));
19308feb0f0bSmrg 			if (poly_int_tree_p (TYPE_SIZE (TREE_TYPE (lhs)),
19318feb0f0bSmrg 					     &lhs_bits)
19328feb0f0bSmrg 			    && multiple_p (lhs_bits,
19338feb0f0bSmrg 					   tree_to_uhwi
19348feb0f0bSmrg 					     (TYPE_SIZE (TREE_TYPE
19358feb0f0bSmrg 							   (TREE_TYPE (sym)))),
19368feb0f0bSmrg 					   &nelts)
19378feb0f0bSmrg 			    && maybe_ne (nelts, 1u)
19388feb0f0bSmrg 			    && valid_vector_subparts_p (nelts))
19398feb0f0bSmrg 			  temtype = build_vector_type (temtype, nelts);
19408feb0f0bSmrg 			tree tem = make_ssa_name (temtype);
1941a2dc1f3fSmrg 			gimple *pun
1942a2dc1f3fSmrg 			  = gimple_build_assign (tem,
1943a2dc1f3fSmrg 						 build1 (VIEW_CONVERT_EXPR,
1944a2dc1f3fSmrg 							 TREE_TYPE (tem), val));
1945a2dc1f3fSmrg 			gsi_insert_before (&gsi, pun, GSI_SAME_STMT);
1946a2dc1f3fSmrg 			val = tem;
1947a2dc1f3fSmrg 		      }
19481debfc3dSmrg 		    tree bitpos
19491debfc3dSmrg 		      = wide_int_to_tree (bitsizetype,
19501debfc3dSmrg 					  mem_ref_offset (lhs) * BITS_PER_UNIT);
19511debfc3dSmrg 		    gimple_assign_set_lhs (stmt, sym);
19521debfc3dSmrg 		    gimple_assign_set_rhs_with_ops
19531debfc3dSmrg 		      (&gsi, BIT_INSERT_EXPR, sym, val, bitpos);
19541debfc3dSmrg 		    stmt = gsi_stmt (gsi);
19551debfc3dSmrg 		    unlink_stmt_vdef (stmt);
19561debfc3dSmrg 		    update_stmt (stmt);
19571debfc3dSmrg 		    continue;
19581debfc3dSmrg 		  }
19591debfc3dSmrg 
19601debfc3dSmrg 		/* We shouldn't have any fancy wrapping of
19611debfc3dSmrg 		   component-refs on the LHS, but look through
19621debfc3dSmrg 		   VIEW_CONVERT_EXPRs as that is easy.  */
19631debfc3dSmrg 		while (TREE_CODE (lhs) == VIEW_CONVERT_EXPR)
19641debfc3dSmrg 		  lhs = TREE_OPERAND (lhs, 0);
19651debfc3dSmrg 		if (TREE_CODE (lhs) == MEM_REF
19661debfc3dSmrg 		    && TREE_CODE (TREE_OPERAND (lhs, 0)) == ADDR_EXPR
19671debfc3dSmrg 		    && integer_zerop (TREE_OPERAND (lhs, 1))
19681debfc3dSmrg 		    && (sym = TREE_OPERAND (TREE_OPERAND (lhs, 0), 0))
19691debfc3dSmrg 		    && DECL_P (sym)
19701debfc3dSmrg 		    && !TREE_ADDRESSABLE (sym)
19711debfc3dSmrg 		    && bitmap_bit_p (suitable_for_renaming, DECL_UID (sym)))
19721debfc3dSmrg 		  lhs = sym;
19731debfc3dSmrg 		else
19741debfc3dSmrg 		  lhs = gimple_assign_lhs (stmt);
19751debfc3dSmrg 
19761debfc3dSmrg 		/* Rewrite the RHS and make sure the resulting assignment
19771debfc3dSmrg 		   is validly typed.  */
19781debfc3dSmrg 		maybe_rewrite_mem_ref_base (rhsp, suitable_for_renaming);
19791debfc3dSmrg 		rhs = gimple_assign_rhs1 (stmt);
19801debfc3dSmrg 		if (gimple_assign_lhs (stmt) != lhs
19811debfc3dSmrg 		    && !useless_type_conversion_p (TREE_TYPE (lhs),
19821debfc3dSmrg 						   TREE_TYPE (rhs)))
19831debfc3dSmrg 		  {
19841debfc3dSmrg 		    if (gimple_clobber_p (stmt))
19851debfc3dSmrg 		      {
19861debfc3dSmrg 			rhs = build_constructor (TREE_TYPE (lhs), NULL);
19871debfc3dSmrg 			TREE_THIS_VOLATILE (rhs) = 1;
19881debfc3dSmrg 		      }
19891debfc3dSmrg 		    else
19901debfc3dSmrg 		      rhs = fold_build1 (VIEW_CONVERT_EXPR,
19911debfc3dSmrg 					 TREE_TYPE (lhs), rhs);
19921debfc3dSmrg 		  }
19931debfc3dSmrg 		if (gimple_assign_lhs (stmt) != lhs)
19941debfc3dSmrg 		  gimple_assign_set_lhs (stmt, lhs);
19951debfc3dSmrg 
19961debfc3dSmrg 		if (gimple_assign_rhs1 (stmt) != rhs)
19971debfc3dSmrg 		  {
19981debfc3dSmrg 		    gimple_stmt_iterator gsi = gsi_for_stmt (stmt);
19991debfc3dSmrg 		    gimple_assign_set_rhs_from_tree (&gsi, rhs);
20001debfc3dSmrg 		  }
20011debfc3dSmrg 	      }
20021debfc3dSmrg 
20031debfc3dSmrg 	    else if (gimple_code (stmt) == GIMPLE_CALL)
20041debfc3dSmrg 	      {
20051debfc3dSmrg 		unsigned i;
20061debfc3dSmrg 		if (optimize_atomic_compare_exchange_p (stmt))
20071debfc3dSmrg 		  {
20081debfc3dSmrg 		    tree expected = gimple_call_arg (stmt, 1);
20091debfc3dSmrg 		    if (bitmap_bit_p (suitable_for_renaming,
20101debfc3dSmrg 				      DECL_UID (TREE_OPERAND (expected, 0))))
20111debfc3dSmrg 		      {
20121debfc3dSmrg 			fold_builtin_atomic_compare_exchange (&gsi);
20131debfc3dSmrg 			continue;
20141debfc3dSmrg 		      }
20151debfc3dSmrg 		  }
20161debfc3dSmrg 		else if (is_asan_mark_p (stmt))
20171debfc3dSmrg 		  {
20181debfc3dSmrg 		    tree var = TREE_OPERAND (gimple_call_arg (stmt, 1), 0);
20191debfc3dSmrg 		    if (bitmap_bit_p (suitable_for_renaming, DECL_UID (var)))
20201debfc3dSmrg 		      {
20211debfc3dSmrg 			unlink_stmt_vdef (stmt);
20221debfc3dSmrg 			if (asan_mark_p (stmt, ASAN_MARK_POISON))
20231debfc3dSmrg 			  {
20241debfc3dSmrg 			    gcall *call
20251debfc3dSmrg 			      = gimple_build_call_internal (IFN_ASAN_POISON, 0);
20261debfc3dSmrg 			    gimple_call_set_lhs (call, var);
20271debfc3dSmrg 			    gsi_replace (&gsi, call, GSI_SAME_STMT);
20281debfc3dSmrg 			  }
20291debfc3dSmrg 			else
20301debfc3dSmrg 			  {
20311debfc3dSmrg 			    /* In ASAN_MARK (UNPOISON, &b, ...) the variable
20321debfc3dSmrg 			       is uninitialized.  Avoid dependencies on
20331debfc3dSmrg 			       previous out of scope value.  */
20348feb0f0bSmrg 			    tree clobber = build_clobber (TREE_TYPE (var));
20351debfc3dSmrg 			    gimple *g = gimple_build_assign (var, clobber);
20361debfc3dSmrg 			    gsi_replace (&gsi, g, GSI_SAME_STMT);
20371debfc3dSmrg 			  }
20381debfc3dSmrg 			continue;
20391debfc3dSmrg 		      }
20401debfc3dSmrg 		  }
20411debfc3dSmrg 		else if (gimple_call_internal_p (stmt, IFN_GOMP_SIMT_ENTER))
20421debfc3dSmrg 		  for (i = 1; i < gimple_call_num_args (stmt); i++)
20431debfc3dSmrg 		    {
20441debfc3dSmrg 		      tree *argp = gimple_call_arg_ptr (stmt, i);
20451debfc3dSmrg 		      if (*argp == null_pointer_node)
20461debfc3dSmrg 			continue;
20471debfc3dSmrg 		      gcc_assert (TREE_CODE (*argp) == ADDR_EXPR
20481debfc3dSmrg 				  && VAR_P (TREE_OPERAND (*argp, 0)));
20491debfc3dSmrg 		      tree var = TREE_OPERAND (*argp, 0);
20501debfc3dSmrg 		      if (bitmap_bit_p (suitable_for_renaming, DECL_UID (var)))
20511debfc3dSmrg 			*argp = null_pointer_node;
20521debfc3dSmrg 		    }
20531debfc3dSmrg 		for (i = 0; i < gimple_call_num_args (stmt); ++i)
20541debfc3dSmrg 		  {
20551debfc3dSmrg 		    tree *argp = gimple_call_arg_ptr (stmt, i);
20561debfc3dSmrg 		    maybe_rewrite_mem_ref_base (argp, suitable_for_renaming);
20571debfc3dSmrg 		  }
20581debfc3dSmrg 	      }
20591debfc3dSmrg 
20601debfc3dSmrg 	    else if (gimple_code (stmt) == GIMPLE_ASM)
20611debfc3dSmrg 	      {
20621debfc3dSmrg 		gasm *asm_stmt = as_a <gasm *> (stmt);
20631debfc3dSmrg 		unsigned i;
20641debfc3dSmrg 		for (i = 0; i < gimple_asm_noutputs (asm_stmt); ++i)
20651debfc3dSmrg 		  {
20661debfc3dSmrg 		    tree link = gimple_asm_output_op (asm_stmt, i);
20671debfc3dSmrg 		    maybe_rewrite_mem_ref_base (&TREE_VALUE (link),
20681debfc3dSmrg 						suitable_for_renaming);
20691debfc3dSmrg 		  }
20701debfc3dSmrg 		for (i = 0; i < gimple_asm_ninputs (asm_stmt); ++i)
20711debfc3dSmrg 		  {
20721debfc3dSmrg 		    tree link = gimple_asm_input_op (asm_stmt, i);
20731debfc3dSmrg 		    maybe_rewrite_mem_ref_base (&TREE_VALUE (link),
20741debfc3dSmrg 						suitable_for_renaming);
20751debfc3dSmrg 		  }
20761debfc3dSmrg 	      }
20771debfc3dSmrg 
20781debfc3dSmrg 	    else if (gimple_debug_bind_p (stmt)
20791debfc3dSmrg 		     && gimple_debug_bind_has_value_p (stmt))
20801debfc3dSmrg 	      {
20811debfc3dSmrg 		tree *valuep = gimple_debug_bind_get_value_ptr (stmt);
20821debfc3dSmrg 		tree decl;
20831debfc3dSmrg 		maybe_rewrite_mem_ref_base (valuep, suitable_for_renaming);
20841debfc3dSmrg 		decl = non_rewritable_mem_ref_base (*valuep);
20851debfc3dSmrg 		if (decl
20861debfc3dSmrg 		    && bitmap_bit_p (suitable_for_renaming, DECL_UID (decl)))
20871debfc3dSmrg 		  gimple_debug_bind_reset_value (stmt);
20881debfc3dSmrg 	      }
20891debfc3dSmrg 
20901debfc3dSmrg 	    if (gimple_references_memory_p (stmt)
20911debfc3dSmrg 		|| is_gimple_debug (stmt))
20921debfc3dSmrg 	      update_stmt (stmt);
20931debfc3dSmrg 
20941debfc3dSmrg 	    gsi_next (&gsi);
20951debfc3dSmrg 	  }
20961debfc3dSmrg 
20971debfc3dSmrg       /* Update SSA form here, we are called as non-pass as well.  */
20981debfc3dSmrg       if (number_of_loops (cfun) > 1
20991debfc3dSmrg 	  && loops_state_satisfies_p (LOOP_CLOSED_SSA))
21001debfc3dSmrg 	rewrite_into_loop_closed_ssa (NULL, TODO_update_ssa);
21011debfc3dSmrg       else
21021debfc3dSmrg 	update_ssa (TODO_update_ssa);
21031debfc3dSmrg     }
21041debfc3dSmrg 
21051debfc3dSmrg   timevar_pop (TV_ADDRESS_TAKEN);
21061debfc3dSmrg }
21071debfc3dSmrg 
21081debfc3dSmrg namespace {
21091debfc3dSmrg 
21101debfc3dSmrg const pass_data pass_data_update_address_taken =
21111debfc3dSmrg {
21121debfc3dSmrg   GIMPLE_PASS, /* type */
21131debfc3dSmrg   "addressables", /* name */
21141debfc3dSmrg   OPTGROUP_NONE, /* optinfo_flags */
21151debfc3dSmrg   TV_ADDRESS_TAKEN, /* tv_id */
21161debfc3dSmrg   PROP_ssa, /* properties_required */
21171debfc3dSmrg   0, /* properties_provided */
21181debfc3dSmrg   0, /* properties_destroyed */
21191debfc3dSmrg   0, /* todo_flags_start */
21201debfc3dSmrg   TODO_update_address_taken, /* todo_flags_finish */
21211debfc3dSmrg };
21221debfc3dSmrg 
21231debfc3dSmrg class pass_update_address_taken : public gimple_opt_pass
21241debfc3dSmrg {
21251debfc3dSmrg public:
pass_update_address_taken(gcc::context * ctxt)21261debfc3dSmrg   pass_update_address_taken (gcc::context *ctxt)
21271debfc3dSmrg     : gimple_opt_pass (pass_data_update_address_taken, ctxt)
21281debfc3dSmrg   {}
21291debfc3dSmrg 
21301debfc3dSmrg   /* opt_pass methods: */
21311debfc3dSmrg 
21321debfc3dSmrg }; // class pass_update_address_taken
21331debfc3dSmrg 
21341debfc3dSmrg } // anon namespace
21351debfc3dSmrg 
21361debfc3dSmrg gimple_opt_pass *
make_pass_update_address_taken(gcc::context * ctxt)21371debfc3dSmrg make_pass_update_address_taken (gcc::context *ctxt)
21381debfc3dSmrg {
21391debfc3dSmrg   return new pass_update_address_taken (ctxt);
21401debfc3dSmrg }
2141