xref: /dragonfly/contrib/gcc-8.0/gcc/tree-ssa.c (revision 58e805e6)
138fd1498Szrj /* Miscellaneous SSA utility functions.
238fd1498Szrj    Copyright (C) 2001-2018 Free Software Foundation, Inc.
338fd1498Szrj 
438fd1498Szrj This file is part of GCC.
538fd1498Szrj 
638fd1498Szrj GCC is free software; you can redistribute it and/or modify
738fd1498Szrj it under the terms of the GNU General Public License as published by
838fd1498Szrj the Free Software Foundation; either version 3, or (at your option)
938fd1498Szrj any later version.
1038fd1498Szrj 
1138fd1498Szrj GCC is distributed in the hope that it will be useful,
1238fd1498Szrj but WITHOUT ANY WARRANTY; without even the implied warranty of
1338fd1498Szrj MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
1438fd1498Szrj GNU General Public License for more details.
1538fd1498Szrj 
1638fd1498Szrj You should have received a copy of the GNU General Public License
1738fd1498Szrj along with GCC; see the file COPYING3.  If not see
1838fd1498Szrj <http://www.gnu.org/licenses/>.  */
1938fd1498Szrj 
2038fd1498Szrj #include "config.h"
2138fd1498Szrj #include "system.h"
2238fd1498Szrj #include "coretypes.h"
2338fd1498Szrj #include "backend.h"
2438fd1498Szrj #include "tree.h"
2538fd1498Szrj #include "gimple.h"
2638fd1498Szrj #include "cfghooks.h"
2738fd1498Szrj #include "tree-pass.h"
2838fd1498Szrj #include "ssa.h"
2938fd1498Szrj #include "gimple-pretty-print.h"
3038fd1498Szrj #include "diagnostic-core.h"
3138fd1498Szrj #include "fold-const.h"
3238fd1498Szrj #include "stor-layout.h"
3338fd1498Szrj #include "gimple-fold.h"
3438fd1498Szrj #include "gimplify.h"
3538fd1498Szrj #include "gimple-iterator.h"
3638fd1498Szrj #include "gimple-walk.h"
3738fd1498Szrj #include "tree-ssa-loop-manip.h"
3838fd1498Szrj #include "tree-into-ssa.h"
3938fd1498Szrj #include "tree-ssa.h"
4038fd1498Szrj #include "cfgloop.h"
4138fd1498Szrj #include "cfgexpand.h"
4238fd1498Szrj #include "tree-cfg.h"
4338fd1498Szrj #include "tree-dfa.h"
4438fd1498Szrj #include "stringpool.h"
4538fd1498Szrj #include "attribs.h"
4638fd1498Szrj #include "asan.h"
4738fd1498Szrj 
4838fd1498Szrj /* Pointer map of variable mappings, keyed by edge.  */
4938fd1498Szrj static hash_map<edge, auto_vec<edge_var_map> > *edge_var_maps;
5038fd1498Szrj 
5138fd1498Szrj 
5238fd1498Szrj /* Add a mapping with PHI RESULT and PHI DEF associated with edge E.  */
5338fd1498Szrj 
5438fd1498Szrj void
redirect_edge_var_map_add(edge e,tree result,tree def,source_location locus)5538fd1498Szrj redirect_edge_var_map_add (edge e, tree result, tree def, source_location locus)
5638fd1498Szrj {
5738fd1498Szrj   edge_var_map new_node;
5838fd1498Szrj 
5938fd1498Szrj   if (edge_var_maps == NULL)
6038fd1498Szrj     edge_var_maps = new hash_map<edge, auto_vec<edge_var_map> >;
6138fd1498Szrj 
6238fd1498Szrj   auto_vec<edge_var_map> &slot = edge_var_maps->get_or_insert (e);
6338fd1498Szrj   new_node.def = def;
6438fd1498Szrj   new_node.result = result;
6538fd1498Szrj   new_node.locus = locus;
6638fd1498Szrj 
6738fd1498Szrj   slot.safe_push (new_node);
6838fd1498Szrj }
6938fd1498Szrj 
7038fd1498Szrj 
7138fd1498Szrj /* Clear the var mappings in edge E.  */
7238fd1498Szrj 
7338fd1498Szrj void
redirect_edge_var_map_clear(edge e)7438fd1498Szrj redirect_edge_var_map_clear (edge e)
7538fd1498Szrj {
7638fd1498Szrj   if (!edge_var_maps)
7738fd1498Szrj     return;
7838fd1498Szrj 
7938fd1498Szrj   auto_vec<edge_var_map> *head = edge_var_maps->get (e);
8038fd1498Szrj 
8138fd1498Szrj   if (head)
8238fd1498Szrj     head->release ();
8338fd1498Szrj }
8438fd1498Szrj 
8538fd1498Szrj 
8638fd1498Szrj /* Duplicate the redirected var mappings in OLDE in NEWE.
8738fd1498Szrj 
8838fd1498Szrj    This assumes a hash_map can have multiple edges mapping to the same
8938fd1498Szrj    var_map (many to one mapping), since we don't remove the previous mappings.
9038fd1498Szrj    */
9138fd1498Szrj 
9238fd1498Szrj void
redirect_edge_var_map_dup(edge newe,edge olde)9338fd1498Szrj redirect_edge_var_map_dup (edge newe, edge olde)
9438fd1498Szrj {
9538fd1498Szrj   if (!edge_var_maps)
9638fd1498Szrj     return;
9738fd1498Szrj 
9838fd1498Szrj   auto_vec<edge_var_map> *new_head = &edge_var_maps->get_or_insert (newe);
9938fd1498Szrj   auto_vec<edge_var_map> *old_head = edge_var_maps->get (olde);
10038fd1498Szrj   if (!old_head)
10138fd1498Szrj     return;
10238fd1498Szrj 
10338fd1498Szrj   new_head->safe_splice (*old_head);
10438fd1498Szrj }
10538fd1498Szrj 
10638fd1498Szrj 
10738fd1498Szrj /* Return the variable mappings for a given edge.  If there is none, return
10838fd1498Szrj    NULL.  */
10938fd1498Szrj 
11038fd1498Szrj vec<edge_var_map> *
redirect_edge_var_map_vector(edge e)11138fd1498Szrj redirect_edge_var_map_vector (edge e)
11238fd1498Szrj {
11338fd1498Szrj   /* Hey, what kind of idiot would... you'd be surprised.  */
11438fd1498Szrj   if (!edge_var_maps)
11538fd1498Szrj     return NULL;
11638fd1498Szrj 
11738fd1498Szrj   auto_vec<edge_var_map> *slot = edge_var_maps->get (e);
11838fd1498Szrj   if (!slot)
11938fd1498Szrj     return NULL;
12038fd1498Szrj 
12138fd1498Szrj   return slot;
12238fd1498Szrj }
12338fd1498Szrj 
12438fd1498Szrj /* Clear the edge variable mappings.  */
12538fd1498Szrj 
12638fd1498Szrj void
redirect_edge_var_map_empty(void)12738fd1498Szrj redirect_edge_var_map_empty (void)
12838fd1498Szrj {
12938fd1498Szrj   if (edge_var_maps)
13038fd1498Szrj     edge_var_maps->empty ();
13138fd1498Szrj }
13238fd1498Szrj 
13338fd1498Szrj 
13438fd1498Szrj /* Remove the corresponding arguments from the PHI nodes in E's
13538fd1498Szrj    destination block and redirect it to DEST.  Return redirected edge.
13638fd1498Szrj    The list of removed arguments is stored in a vector accessed
13738fd1498Szrj    through edge_var_maps.  */
13838fd1498Szrj 
13938fd1498Szrj edge
ssa_redirect_edge(edge e,basic_block dest)14038fd1498Szrj ssa_redirect_edge (edge e, basic_block dest)
14138fd1498Szrj {
14238fd1498Szrj   gphi_iterator gsi;
14338fd1498Szrj   gphi *phi;
14438fd1498Szrj 
14538fd1498Szrj   redirect_edge_var_map_clear (e);
14638fd1498Szrj 
14738fd1498Szrj   /* Remove the appropriate PHI arguments in E's destination block.
14838fd1498Szrj      If we are redirecting a copied edge the destination has not
14938fd1498Szrj      got PHI argument space reserved nor an interesting argument.  */
15038fd1498Szrj   if (! (e->dest->flags & BB_DUPLICATED))
15138fd1498Szrj     for (gsi = gsi_start_phis (e->dest); !gsi_end_p (gsi); gsi_next (&gsi))
15238fd1498Szrj       {
15338fd1498Szrj 	tree def;
15438fd1498Szrj 	source_location locus ;
15538fd1498Szrj 
15638fd1498Szrj 	phi = gsi.phi ();
15738fd1498Szrj 	def = gimple_phi_arg_def (phi, e->dest_idx);
15838fd1498Szrj 	locus = gimple_phi_arg_location (phi, e->dest_idx);
15938fd1498Szrj 
16038fd1498Szrj 	if (def == NULL_TREE)
16138fd1498Szrj 	  continue;
16238fd1498Szrj 
16338fd1498Szrj 	redirect_edge_var_map_add (e, gimple_phi_result (phi), def, locus);
16438fd1498Szrj       }
16538fd1498Szrj 
16638fd1498Szrj   e = redirect_edge_succ_nodup (e, dest);
16738fd1498Szrj 
16838fd1498Szrj   return e;
16938fd1498Szrj }
17038fd1498Szrj 
17138fd1498Szrj 
17238fd1498Szrj /* Add PHI arguments queued in PENDING_STMT list on edge E to edge
17338fd1498Szrj    E->dest.  */
17438fd1498Szrj 
17538fd1498Szrj void
flush_pending_stmts(edge e)17638fd1498Szrj flush_pending_stmts (edge e)
17738fd1498Szrj {
17838fd1498Szrj   gphi *phi;
17938fd1498Szrj   edge_var_map *vm;
18038fd1498Szrj   int i;
18138fd1498Szrj   gphi_iterator gsi;
18238fd1498Szrj 
18338fd1498Szrj   vec<edge_var_map> *v = redirect_edge_var_map_vector (e);
18438fd1498Szrj   if (!v)
18538fd1498Szrj     return;
18638fd1498Szrj 
18738fd1498Szrj   for (gsi = gsi_start_phis (e->dest), i = 0;
18838fd1498Szrj        !gsi_end_p (gsi) && v->iterate (i, &vm);
18938fd1498Szrj        gsi_next (&gsi), i++)
19038fd1498Szrj     {
19138fd1498Szrj       tree def;
19238fd1498Szrj 
19338fd1498Szrj       phi = gsi.phi ();
19438fd1498Szrj       def = redirect_edge_var_map_def (vm);
19538fd1498Szrj       add_phi_arg (phi, def, e, redirect_edge_var_map_location (vm));
19638fd1498Szrj     }
19738fd1498Szrj 
19838fd1498Szrj   redirect_edge_var_map_clear (e);
19938fd1498Szrj }
20038fd1498Szrj 
20138fd1498Szrj /* Replace the LHS of STMT, an assignment, either a GIMPLE_ASSIGN or a
20238fd1498Szrj    GIMPLE_CALL, with NLHS, in preparation for modifying the RHS to an
20338fd1498Szrj    expression with a different value.
20438fd1498Szrj 
20538fd1498Szrj    This will update any annotations (say debug bind stmts) referring
20638fd1498Szrj    to the original LHS, so that they use the RHS instead.  This is
20738fd1498Szrj    done even if NLHS and LHS are the same, for it is understood that
20838fd1498Szrj    the RHS will be modified afterwards, and NLHS will not be assigned
20938fd1498Szrj    an equivalent value.
21038fd1498Szrj 
21138fd1498Szrj    Adjusting any non-annotation uses of the LHS, if needed, is a
21238fd1498Szrj    responsibility of the caller.
21338fd1498Szrj 
21438fd1498Szrj    The effect of this call should be pretty much the same as that of
21538fd1498Szrj    inserting a copy of STMT before STMT, and then removing the
21638fd1498Szrj    original stmt, at which time gsi_remove() would have update
21738fd1498Szrj    annotations, but using this function saves all the inserting,
21838fd1498Szrj    copying and removing.  */
21938fd1498Szrj 
22038fd1498Szrj void
gimple_replace_ssa_lhs(gimple * stmt,tree nlhs)22138fd1498Szrj gimple_replace_ssa_lhs (gimple *stmt, tree nlhs)
22238fd1498Szrj {
22338fd1498Szrj   if (MAY_HAVE_DEBUG_BIND_STMTS)
22438fd1498Szrj     {
22538fd1498Szrj       tree lhs = gimple_get_lhs (stmt);
22638fd1498Szrj 
22738fd1498Szrj       gcc_assert (SSA_NAME_DEF_STMT (lhs) == stmt);
22838fd1498Szrj 
22938fd1498Szrj       insert_debug_temp_for_var_def (NULL, lhs);
23038fd1498Szrj     }
23138fd1498Szrj 
23238fd1498Szrj   gimple_set_lhs (stmt, nlhs);
23338fd1498Szrj }
23438fd1498Szrj 
23538fd1498Szrj 
23638fd1498Szrj /* Given a tree for an expression for which we might want to emit
23738fd1498Szrj    locations or values in debug information (generally a variable, but
23838fd1498Szrj    we might deal with other kinds of trees in the future), return the
23938fd1498Szrj    tree that should be used as the variable of a DEBUG_BIND STMT or
24038fd1498Szrj    VAR_LOCATION INSN or NOTE.  Return NULL if VAR is not to be tracked.  */
24138fd1498Szrj 
24238fd1498Szrj tree
target_for_debug_bind(tree var)24338fd1498Szrj target_for_debug_bind (tree var)
24438fd1498Szrj {
24538fd1498Szrj   if (!MAY_HAVE_DEBUG_BIND_STMTS)
24638fd1498Szrj     return NULL_TREE;
24738fd1498Szrj 
24838fd1498Szrj   if (TREE_CODE (var) == SSA_NAME)
24938fd1498Szrj     {
25038fd1498Szrj       var = SSA_NAME_VAR (var);
25138fd1498Szrj       if (var == NULL_TREE)
25238fd1498Szrj 	return NULL_TREE;
25338fd1498Szrj     }
25438fd1498Szrj 
25538fd1498Szrj   if ((!VAR_P (var) || VAR_DECL_IS_VIRTUAL_OPERAND (var))
25638fd1498Szrj       && TREE_CODE (var) != PARM_DECL)
25738fd1498Szrj     return NULL_TREE;
25838fd1498Szrj 
25938fd1498Szrj   if (DECL_HAS_VALUE_EXPR_P (var))
26038fd1498Szrj     return target_for_debug_bind (DECL_VALUE_EXPR (var));
26138fd1498Szrj 
26238fd1498Szrj   if (DECL_IGNORED_P (var))
26338fd1498Szrj     return NULL_TREE;
26438fd1498Szrj 
26538fd1498Szrj   /* var-tracking only tracks registers.  */
26638fd1498Szrj   if (!is_gimple_reg_type (TREE_TYPE (var)))
26738fd1498Szrj     return NULL_TREE;
26838fd1498Szrj 
26938fd1498Szrj   return var;
27038fd1498Szrj }
27138fd1498Szrj 
27238fd1498Szrj /* Called via walk_tree, look for SSA_NAMEs that have already been
27338fd1498Szrj    released.  */
27438fd1498Szrj 
27538fd1498Szrj static tree
find_released_ssa_name(tree * tp,int * walk_subtrees,void * data_)27638fd1498Szrj find_released_ssa_name (tree *tp, int *walk_subtrees, void *data_)
27738fd1498Szrj {
27838fd1498Szrj   struct walk_stmt_info *wi = (struct walk_stmt_info *) data_;
27938fd1498Szrj 
28038fd1498Szrj   if (wi && wi->is_lhs)
28138fd1498Szrj     return NULL_TREE;
28238fd1498Szrj 
28338fd1498Szrj   if (TREE_CODE (*tp) == SSA_NAME)
28438fd1498Szrj     {
28538fd1498Szrj       if (SSA_NAME_IN_FREE_LIST (*tp))
28638fd1498Szrj 	return *tp;
28738fd1498Szrj 
28838fd1498Szrj       *walk_subtrees = 0;
28938fd1498Szrj     }
29038fd1498Szrj   else if (IS_TYPE_OR_DECL_P (*tp))
29138fd1498Szrj     *walk_subtrees = 0;
29238fd1498Szrj 
29338fd1498Szrj   return NULL_TREE;
29438fd1498Szrj }
29538fd1498Szrj 
29638fd1498Szrj /* Insert a DEBUG BIND stmt before the DEF of VAR if VAR is referenced
29738fd1498Szrj    by other DEBUG stmts, and replace uses of the DEF with the
29838fd1498Szrj    newly-created debug temp.  */
29938fd1498Szrj 
30038fd1498Szrj void
insert_debug_temp_for_var_def(gimple_stmt_iterator * gsi,tree var)30138fd1498Szrj insert_debug_temp_for_var_def (gimple_stmt_iterator *gsi, tree var)
30238fd1498Szrj {
30338fd1498Szrj   imm_use_iterator imm_iter;
30438fd1498Szrj   use_operand_p use_p;
30538fd1498Szrj   gimple *stmt;
30638fd1498Szrj   gimple *def_stmt = NULL;
30738fd1498Szrj   int usecount = 0;
30838fd1498Szrj   tree value = NULL;
30938fd1498Szrj 
31038fd1498Szrj   if (!MAY_HAVE_DEBUG_BIND_STMTS)
31138fd1498Szrj     return;
31238fd1498Szrj 
31338fd1498Szrj   /* If this name has already been registered for replacement, do nothing
31438fd1498Szrj      as anything that uses this name isn't in SSA form.  */
31538fd1498Szrj   if (name_registered_for_update_p (var))
31638fd1498Szrj     return;
31738fd1498Szrj 
31838fd1498Szrj   /* Check whether there are debug stmts that reference this variable and,
31938fd1498Szrj      if there are, decide whether we should use a debug temp.  */
32038fd1498Szrj   FOR_EACH_IMM_USE_FAST (use_p, imm_iter, var)
32138fd1498Szrj     {
32238fd1498Szrj       stmt = USE_STMT (use_p);
32338fd1498Szrj 
32438fd1498Szrj       if (!gimple_debug_bind_p (stmt))
32538fd1498Szrj 	continue;
32638fd1498Szrj 
32738fd1498Szrj       if (usecount++)
32838fd1498Szrj 	break;
32938fd1498Szrj 
33038fd1498Szrj       if (gimple_debug_bind_get_value (stmt) != var)
33138fd1498Szrj 	{
33238fd1498Szrj 	  /* Count this as an additional use, so as to make sure we
33338fd1498Szrj 	     use a temp unless VAR's definition has a SINGLE_RHS that
33438fd1498Szrj 	     can be shared.  */
33538fd1498Szrj 	  usecount++;
33638fd1498Szrj 	  break;
33738fd1498Szrj 	}
33838fd1498Szrj     }
33938fd1498Szrj 
34038fd1498Szrj   if (!usecount)
34138fd1498Szrj     return;
34238fd1498Szrj 
34338fd1498Szrj   if (gsi)
34438fd1498Szrj     def_stmt = gsi_stmt (*gsi);
34538fd1498Szrj   else
34638fd1498Szrj     def_stmt = SSA_NAME_DEF_STMT (var);
34738fd1498Szrj 
34838fd1498Szrj   /* If we didn't get an insertion point, and the stmt has already
34938fd1498Szrj      been removed, we won't be able to insert the debug bind stmt, so
35038fd1498Szrj      we'll have to drop debug information.  */
35138fd1498Szrj   if (gimple_code (def_stmt) == GIMPLE_PHI)
35238fd1498Szrj     {
35338fd1498Szrj       value = degenerate_phi_result (as_a <gphi *> (def_stmt));
35438fd1498Szrj       if (value && walk_tree (&value, find_released_ssa_name, NULL, NULL))
35538fd1498Szrj 	value = NULL;
35638fd1498Szrj       /* error_mark_node is what fixup_noreturn_call changes PHI arguments
35738fd1498Szrj 	 to.  */
35838fd1498Szrj       else if (value == error_mark_node)
35938fd1498Szrj 	value = NULL;
36038fd1498Szrj     }
36138fd1498Szrj   else if (is_gimple_assign (def_stmt))
36238fd1498Szrj     {
36338fd1498Szrj       bool no_value = false;
36438fd1498Szrj 
36538fd1498Szrj       if (!dom_info_available_p (CDI_DOMINATORS))
36638fd1498Szrj 	{
36738fd1498Szrj 	  struct walk_stmt_info wi;
36838fd1498Szrj 
36938fd1498Szrj 	  memset (&wi, 0, sizeof (wi));
37038fd1498Szrj 
37138fd1498Szrj 	  /* When removing blocks without following reverse dominance
37238fd1498Szrj 	     order, we may sometimes encounter SSA_NAMEs that have
37338fd1498Szrj 	     already been released, referenced in other SSA_DEFs that
37438fd1498Szrj 	     we're about to release.  Consider:
37538fd1498Szrj 
37638fd1498Szrj 	     <bb X>:
37738fd1498Szrj 	     v_1 = foo;
37838fd1498Szrj 
37938fd1498Szrj 	     <bb Y>:
38038fd1498Szrj 	     w_2 = v_1 + bar;
38138fd1498Szrj 	     # DEBUG w => w_2
38238fd1498Szrj 
38338fd1498Szrj 	     If we deleted BB X first, propagating the value of w_2
38438fd1498Szrj 	     won't do us any good.  It's too late to recover their
38538fd1498Szrj 	     original definition of v_1: when it was deleted, it was
38638fd1498Szrj 	     only referenced in other DEFs, it couldn't possibly know
38738fd1498Szrj 	     it should have been retained, and propagating every
38838fd1498Szrj 	     single DEF just in case it might have to be propagated
38938fd1498Szrj 	     into a DEBUG STMT would probably be too wasteful.
39038fd1498Szrj 
39138fd1498Szrj 	     When dominator information is not readily available, we
39238fd1498Szrj 	     check for and accept some loss of debug information.  But
39338fd1498Szrj 	     if it is available, there's no excuse for us to remove
39438fd1498Szrj 	     blocks in the wrong order, so we don't even check for
39538fd1498Szrj 	     dead SSA NAMEs.  SSA verification shall catch any
39638fd1498Szrj 	     errors.  */
39738fd1498Szrj 	  if ((!gsi && !gimple_bb (def_stmt))
39838fd1498Szrj 	      || walk_gimple_op (def_stmt, find_released_ssa_name, &wi))
39938fd1498Szrj 	    no_value = true;
40038fd1498Szrj 	}
40138fd1498Szrj 
40238fd1498Szrj       if (!no_value)
40338fd1498Szrj 	value = gimple_assign_rhs_to_tree (def_stmt);
40438fd1498Szrj     }
40538fd1498Szrj 
40638fd1498Szrj   if (value)
40738fd1498Szrj     {
40838fd1498Szrj       /* If there's a single use of VAR, and VAR is the entire debug
40938fd1498Szrj 	 expression (usecount would have been incremented again
41038fd1498Szrj 	 otherwise), and the definition involves only constants and
41138fd1498Szrj 	 SSA names, then we can propagate VALUE into this single use,
41238fd1498Szrj 	 avoiding the temp.
41338fd1498Szrj 
41438fd1498Szrj 	 We can also avoid using a temp if VALUE can be shared and
41538fd1498Szrj 	 propagated into all uses, without generating expressions that
41638fd1498Szrj 	 wouldn't be valid gimple RHSs.
41738fd1498Szrj 
41838fd1498Szrj 	 Other cases that would require unsharing or non-gimple RHSs
41938fd1498Szrj 	 are deferred to a debug temp, although we could avoid temps
42038fd1498Szrj 	 at the expense of duplication of expressions.  */
42138fd1498Szrj 
42238fd1498Szrj       if (CONSTANT_CLASS_P (value)
42338fd1498Szrj 	  || gimple_code (def_stmt) == GIMPLE_PHI
42438fd1498Szrj 	  || (usecount == 1
42538fd1498Szrj 	      && (!gimple_assign_single_p (def_stmt)
42638fd1498Szrj 		  || is_gimple_min_invariant (value)))
42738fd1498Szrj 	  || is_gimple_reg (value))
42838fd1498Szrj 	;
42938fd1498Szrj       else
43038fd1498Szrj 	{
43138fd1498Szrj 	  gdebug *def_temp;
43238fd1498Szrj 	  tree vexpr = make_node (DEBUG_EXPR_DECL);
43338fd1498Szrj 
43438fd1498Szrj 	  def_temp = gimple_build_debug_bind (vexpr,
43538fd1498Szrj 					      unshare_expr (value),
43638fd1498Szrj 					      def_stmt);
43738fd1498Szrj 
43838fd1498Szrj 	  DECL_ARTIFICIAL (vexpr) = 1;
43938fd1498Szrj 	  TREE_TYPE (vexpr) = TREE_TYPE (value);
44038fd1498Szrj 	  if (DECL_P (value))
44138fd1498Szrj 	    SET_DECL_MODE (vexpr, DECL_MODE (value));
44238fd1498Szrj 	  else
44338fd1498Szrj 	    SET_DECL_MODE (vexpr, TYPE_MODE (TREE_TYPE (value)));
44438fd1498Szrj 
44538fd1498Szrj 	  if (gsi)
44638fd1498Szrj 	    gsi_insert_before (gsi, def_temp, GSI_SAME_STMT);
44738fd1498Szrj 	  else
44838fd1498Szrj 	    {
44938fd1498Szrj 	      gimple_stmt_iterator ngsi = gsi_for_stmt (def_stmt);
45038fd1498Szrj 	      gsi_insert_before (&ngsi, def_temp, GSI_SAME_STMT);
45138fd1498Szrj 	    }
45238fd1498Szrj 
45338fd1498Szrj 	  value = vexpr;
45438fd1498Szrj 	}
45538fd1498Szrj     }
45638fd1498Szrj 
45738fd1498Szrj   FOR_EACH_IMM_USE_STMT (stmt, imm_iter, var)
45838fd1498Szrj     {
45938fd1498Szrj       if (!gimple_debug_bind_p (stmt))
46038fd1498Szrj 	continue;
46138fd1498Szrj 
46238fd1498Szrj       if (value)
46338fd1498Szrj 	{
46438fd1498Szrj 	  FOR_EACH_IMM_USE_ON_STMT (use_p, imm_iter)
46538fd1498Szrj 	    /* unshare_expr is not needed here.  vexpr is either a
46638fd1498Szrj 	       SINGLE_RHS, that can be safely shared, some other RHS
46738fd1498Szrj 	       that was unshared when we found it had a single debug
46838fd1498Szrj 	       use, or a DEBUG_EXPR_DECL, that can be safely
46938fd1498Szrj 	       shared.  */
47038fd1498Szrj 	    SET_USE (use_p, unshare_expr (value));
47138fd1498Szrj 	  /* If we didn't replace uses with a debug decl fold the
47238fd1498Szrj 	     resulting expression.  Otherwise we end up with invalid IL.  */
47338fd1498Szrj 	  if (TREE_CODE (value) != DEBUG_EXPR_DECL)
47438fd1498Szrj 	    {
47538fd1498Szrj 	      gimple_stmt_iterator gsi = gsi_for_stmt (stmt);
47638fd1498Szrj 	      fold_stmt_inplace (&gsi);
47738fd1498Szrj 	    }
47838fd1498Szrj 	}
47938fd1498Szrj       else
48038fd1498Szrj 	gimple_debug_bind_reset_value (stmt);
48138fd1498Szrj 
48238fd1498Szrj       update_stmt (stmt);
48338fd1498Szrj     }
48438fd1498Szrj }
48538fd1498Szrj 
48638fd1498Szrj 
48738fd1498Szrj /* Insert a DEBUG BIND stmt before STMT for each DEF referenced by
48838fd1498Szrj    other DEBUG stmts, and replace uses of the DEF with the
48938fd1498Szrj    newly-created debug temp.  */
49038fd1498Szrj 
49138fd1498Szrj void
insert_debug_temps_for_defs(gimple_stmt_iterator * gsi)49238fd1498Szrj insert_debug_temps_for_defs (gimple_stmt_iterator *gsi)
49338fd1498Szrj {
49438fd1498Szrj   gimple *stmt;
49538fd1498Szrj   ssa_op_iter op_iter;
49638fd1498Szrj   def_operand_p def_p;
49738fd1498Szrj 
49838fd1498Szrj   if (!MAY_HAVE_DEBUG_BIND_STMTS)
49938fd1498Szrj     return;
50038fd1498Szrj 
50138fd1498Szrj   stmt = gsi_stmt (*gsi);
50238fd1498Szrj 
50338fd1498Szrj   FOR_EACH_PHI_OR_STMT_DEF (def_p, stmt, op_iter, SSA_OP_DEF)
50438fd1498Szrj     {
50538fd1498Szrj       tree var = DEF_FROM_PTR (def_p);
50638fd1498Szrj 
50738fd1498Szrj       if (TREE_CODE (var) != SSA_NAME)
50838fd1498Szrj 	continue;
50938fd1498Szrj 
51038fd1498Szrj       insert_debug_temp_for_var_def (gsi, var);
51138fd1498Szrj     }
51238fd1498Szrj }
51338fd1498Szrj 
51438fd1498Szrj /* Reset all debug stmts that use SSA_NAME(s) defined in STMT.  */
51538fd1498Szrj 
51638fd1498Szrj void
reset_debug_uses(gimple * stmt)51738fd1498Szrj reset_debug_uses (gimple *stmt)
51838fd1498Szrj {
51938fd1498Szrj   ssa_op_iter op_iter;
52038fd1498Szrj   def_operand_p def_p;
52138fd1498Szrj   imm_use_iterator imm_iter;
52238fd1498Szrj   gimple *use_stmt;
52338fd1498Szrj 
52438fd1498Szrj   if (!MAY_HAVE_DEBUG_BIND_STMTS)
52538fd1498Szrj     return;
52638fd1498Szrj 
52738fd1498Szrj   FOR_EACH_PHI_OR_STMT_DEF (def_p, stmt, op_iter, SSA_OP_DEF)
52838fd1498Szrj     {
52938fd1498Szrj       tree var = DEF_FROM_PTR (def_p);
53038fd1498Szrj 
53138fd1498Szrj       if (TREE_CODE (var) != SSA_NAME)
53238fd1498Szrj 	continue;
53338fd1498Szrj 
53438fd1498Szrj       FOR_EACH_IMM_USE_STMT (use_stmt, imm_iter, var)
53538fd1498Szrj 	{
53638fd1498Szrj 	  if (!gimple_debug_bind_p (use_stmt))
53738fd1498Szrj 	    continue;
53838fd1498Szrj 
53938fd1498Szrj 	  gimple_debug_bind_reset_value (use_stmt);
54038fd1498Szrj 	  update_stmt (use_stmt);
54138fd1498Szrj 	}
54238fd1498Szrj     }
54338fd1498Szrj }
54438fd1498Szrj 
54538fd1498Szrj /* Delete SSA DEFs for SSA versions in the TOREMOVE bitmap, removing
54638fd1498Szrj    dominated stmts before their dominators, so that release_ssa_defs
54738fd1498Szrj    stands a chance of propagating DEFs into debug bind stmts.  */
54838fd1498Szrj 
54938fd1498Szrj void
release_defs_bitset(bitmap toremove)55038fd1498Szrj release_defs_bitset (bitmap toremove)
55138fd1498Szrj {
55238fd1498Szrj   unsigned j;
55338fd1498Szrj   bitmap_iterator bi;
55438fd1498Szrj 
55538fd1498Szrj   /* Performing a topological sort is probably overkill, this will
55638fd1498Szrj      most likely run in slightly superlinear time, rather than the
55738fd1498Szrj      pathological quadratic worst case.  */
55838fd1498Szrj   while (!bitmap_empty_p (toremove))
55938fd1498Szrj     {
56038fd1498Szrj       unsigned to_remove_bit = -1U;
56138fd1498Szrj       EXECUTE_IF_SET_IN_BITMAP (toremove, 0, j, bi)
56238fd1498Szrj 	{
56338fd1498Szrj 	  if (to_remove_bit != -1U)
56438fd1498Szrj 	    {
56538fd1498Szrj 	      bitmap_clear_bit (toremove, to_remove_bit);
56638fd1498Szrj 	      to_remove_bit = -1U;
56738fd1498Szrj 	    }
56838fd1498Szrj 
56938fd1498Szrj 	  bool remove_now = true;
57038fd1498Szrj 	  tree var = ssa_name (j);
57138fd1498Szrj 	  gimple *stmt;
57238fd1498Szrj 	  imm_use_iterator uit;
57338fd1498Szrj 
57438fd1498Szrj 	  FOR_EACH_IMM_USE_STMT (stmt, uit, var)
57538fd1498Szrj 	    {
57638fd1498Szrj 	      ssa_op_iter dit;
57738fd1498Szrj 	      def_operand_p def_p;
57838fd1498Szrj 
57938fd1498Szrj 	      /* We can't propagate PHI nodes into debug stmts.  */
58038fd1498Szrj 	      if (gimple_code (stmt) == GIMPLE_PHI
58138fd1498Szrj 		  || is_gimple_debug (stmt))
58238fd1498Szrj 		continue;
58338fd1498Szrj 
58438fd1498Szrj 	      /* If we find another definition to remove that uses
58538fd1498Szrj 		 the one we're looking at, defer the removal of this
58638fd1498Szrj 		 one, so that it can be propagated into debug stmts
58738fd1498Szrj 		 after the other is.  */
58838fd1498Szrj 	      FOR_EACH_SSA_DEF_OPERAND (def_p, stmt, dit, SSA_OP_DEF)
58938fd1498Szrj 		{
59038fd1498Szrj 		  tree odef = DEF_FROM_PTR (def_p);
59138fd1498Szrj 
59238fd1498Szrj 		  if (bitmap_bit_p (toremove, SSA_NAME_VERSION (odef)))
59338fd1498Szrj 		    {
59438fd1498Szrj 		      remove_now = false;
59538fd1498Szrj 		      break;
59638fd1498Szrj 		    }
59738fd1498Szrj 		}
59838fd1498Szrj 
59938fd1498Szrj 	      if (!remove_now)
60038fd1498Szrj 		BREAK_FROM_IMM_USE_STMT (uit);
60138fd1498Szrj 	    }
60238fd1498Szrj 
60338fd1498Szrj 	  if (remove_now)
60438fd1498Szrj 	    {
60538fd1498Szrj 	      gimple *def = SSA_NAME_DEF_STMT (var);
60638fd1498Szrj 	      gimple_stmt_iterator gsi = gsi_for_stmt (def);
60738fd1498Szrj 
60838fd1498Szrj 	      if (gimple_code (def) == GIMPLE_PHI)
60938fd1498Szrj 		remove_phi_node (&gsi, true);
61038fd1498Szrj 	      else
61138fd1498Szrj 		{
61238fd1498Szrj 		  gsi_remove (&gsi, true);
61338fd1498Szrj 		  release_defs (def);
61438fd1498Szrj 		}
61538fd1498Szrj 
61638fd1498Szrj 	      to_remove_bit = j;
61738fd1498Szrj 	    }
61838fd1498Szrj 	}
61938fd1498Szrj       if (to_remove_bit != -1U)
62038fd1498Szrj 	bitmap_clear_bit (toremove, to_remove_bit);
62138fd1498Szrj     }
62238fd1498Szrj 
62338fd1498Szrj }
62438fd1498Szrj 
62538fd1498Szrj /* Verify virtual SSA form.  */
62638fd1498Szrj 
62738fd1498Szrj bool
verify_vssa(basic_block bb,tree current_vdef,sbitmap visited)62838fd1498Szrj verify_vssa (basic_block bb, tree current_vdef, sbitmap visited)
62938fd1498Szrj {
63038fd1498Szrj   bool err = false;
63138fd1498Szrj 
63238fd1498Szrj   if (bitmap_bit_p (visited, bb->index))
63338fd1498Szrj     return false;
63438fd1498Szrj 
63538fd1498Szrj   bitmap_set_bit (visited, bb->index);
63638fd1498Szrj 
63738fd1498Szrj   /* Pick up the single virtual PHI def.  */
63838fd1498Szrj   gphi *phi = NULL;
63938fd1498Szrj   for (gphi_iterator si = gsi_start_phis (bb); !gsi_end_p (si);
64038fd1498Szrj        gsi_next (&si))
64138fd1498Szrj     {
64238fd1498Szrj       tree res = gimple_phi_result (si.phi ());
64338fd1498Szrj       if (virtual_operand_p (res))
64438fd1498Szrj 	{
64538fd1498Szrj 	  if (phi)
64638fd1498Szrj 	    {
64738fd1498Szrj 	      error ("multiple virtual PHI nodes in BB %d", bb->index);
64838fd1498Szrj 	      print_gimple_stmt (stderr, phi, 0);
64938fd1498Szrj 	      print_gimple_stmt (stderr, si.phi (), 0);
65038fd1498Szrj 	      err = true;
65138fd1498Szrj 	    }
65238fd1498Szrj 	  else
65338fd1498Szrj 	    phi = si.phi ();
65438fd1498Szrj 	}
65538fd1498Szrj     }
65638fd1498Szrj   if (phi)
65738fd1498Szrj     {
65838fd1498Szrj       current_vdef = gimple_phi_result (phi);
65938fd1498Szrj       if (TREE_CODE (current_vdef) != SSA_NAME)
66038fd1498Szrj 	{
66138fd1498Szrj 	  error ("virtual definition is not an SSA name");
66238fd1498Szrj 	  print_gimple_stmt (stderr, phi, 0);
66338fd1498Szrj 	  err = true;
66438fd1498Szrj 	}
66538fd1498Szrj     }
66638fd1498Szrj 
66738fd1498Szrj   /* Verify stmts.  */
66838fd1498Szrj   for (gimple_stmt_iterator gsi = gsi_start_bb (bb); !gsi_end_p (gsi);
66938fd1498Szrj        gsi_next (&gsi))
67038fd1498Szrj     {
67138fd1498Szrj       gimple *stmt = gsi_stmt (gsi);
67238fd1498Szrj       tree vuse = gimple_vuse (stmt);
67338fd1498Szrj       if (vuse)
67438fd1498Szrj 	{
67538fd1498Szrj 	  if (vuse != current_vdef)
67638fd1498Szrj 	    {
67738fd1498Szrj 	      error ("stmt with wrong VUSE");
67838fd1498Szrj 	      print_gimple_stmt (stderr, stmt, 0, TDF_VOPS);
67938fd1498Szrj 	      fprintf (stderr, "expected ");
68038fd1498Szrj 	      print_generic_expr (stderr, current_vdef);
68138fd1498Szrj 	      fprintf (stderr, "\n");
68238fd1498Szrj 	      err = true;
68338fd1498Szrj 	    }
68438fd1498Szrj 	  tree vdef = gimple_vdef (stmt);
68538fd1498Szrj 	  if (vdef)
68638fd1498Szrj 	    {
68738fd1498Szrj 	      current_vdef = vdef;
68838fd1498Szrj 	      if (TREE_CODE (current_vdef) != SSA_NAME)
68938fd1498Szrj 		{
69038fd1498Szrj 		  error ("virtual definition is not an SSA name");
69138fd1498Szrj 		  print_gimple_stmt (stderr, phi, 0);
69238fd1498Szrj 		  err = true;
69338fd1498Szrj 		}
69438fd1498Szrj 	    }
69538fd1498Szrj 	}
69638fd1498Szrj     }
69738fd1498Szrj 
69838fd1498Szrj   /* Verify destination PHI uses and recurse.  */
69938fd1498Szrj   edge_iterator ei;
70038fd1498Szrj   edge e;
70138fd1498Szrj   FOR_EACH_EDGE (e, ei, bb->succs)
70238fd1498Szrj     {
70338fd1498Szrj       gphi *phi = get_virtual_phi (e->dest);
70438fd1498Szrj       if (phi
70538fd1498Szrj 	  && PHI_ARG_DEF_FROM_EDGE (phi, e) != current_vdef)
70638fd1498Szrj 	{
70738fd1498Szrj 	  error ("PHI node with wrong VUSE on edge from BB %d",
70838fd1498Szrj 		 e->src->index);
70938fd1498Szrj 	  print_gimple_stmt (stderr, phi, 0, TDF_VOPS);
71038fd1498Szrj 	  fprintf (stderr, "expected ");
71138fd1498Szrj 	  print_generic_expr (stderr, current_vdef);
71238fd1498Szrj 	  fprintf (stderr, "\n");
71338fd1498Szrj 	  err = true;
71438fd1498Szrj 	}
71538fd1498Szrj 
71638fd1498Szrj       /* Recurse.  */
71738fd1498Szrj       err |= verify_vssa (e->dest, current_vdef, visited);
71838fd1498Szrj     }
71938fd1498Szrj 
72038fd1498Szrj   return err;
72138fd1498Szrj }
72238fd1498Szrj 
72338fd1498Szrj /* Return true if SSA_NAME is malformed and mark it visited.
72438fd1498Szrj 
72538fd1498Szrj    IS_VIRTUAL is true if this SSA_NAME was found inside a virtual
72638fd1498Szrj       operand.  */
72738fd1498Szrj 
72838fd1498Szrj static bool
verify_ssa_name(tree ssa_name,bool is_virtual)72938fd1498Szrj verify_ssa_name (tree ssa_name, bool is_virtual)
73038fd1498Szrj {
73138fd1498Szrj   if (TREE_CODE (ssa_name) != SSA_NAME)
73238fd1498Szrj     {
73338fd1498Szrj       error ("expected an SSA_NAME object");
73438fd1498Szrj       return true;
73538fd1498Szrj     }
73638fd1498Szrj 
73738fd1498Szrj   if (SSA_NAME_IN_FREE_LIST (ssa_name))
73838fd1498Szrj     {
73938fd1498Szrj       error ("found an SSA_NAME that had been released into the free pool");
74038fd1498Szrj       return true;
74138fd1498Szrj     }
74238fd1498Szrj 
74338fd1498Szrj   if (SSA_NAME_VAR (ssa_name) != NULL_TREE
74438fd1498Szrj       && TREE_TYPE (ssa_name) != TREE_TYPE (SSA_NAME_VAR (ssa_name)))
74538fd1498Szrj     {
74638fd1498Szrj       error ("type mismatch between an SSA_NAME and its symbol");
74738fd1498Szrj       return true;
74838fd1498Szrj     }
74938fd1498Szrj 
75038fd1498Szrj   if (is_virtual && !virtual_operand_p (ssa_name))
75138fd1498Szrj     {
75238fd1498Szrj       error ("found a virtual definition for a GIMPLE register");
75338fd1498Szrj       return true;
75438fd1498Szrj     }
75538fd1498Szrj 
75638fd1498Szrj   if (is_virtual && SSA_NAME_VAR (ssa_name) != gimple_vop (cfun))
75738fd1498Szrj     {
75838fd1498Szrj       error ("virtual SSA name for non-VOP decl");
75938fd1498Szrj       return true;
76038fd1498Szrj     }
76138fd1498Szrj 
76238fd1498Szrj   if (!is_virtual && virtual_operand_p (ssa_name))
76338fd1498Szrj     {
76438fd1498Szrj       error ("found a real definition for a non-register");
76538fd1498Szrj       return true;
76638fd1498Szrj     }
76738fd1498Szrj 
76838fd1498Szrj   if (SSA_NAME_IS_DEFAULT_DEF (ssa_name)
76938fd1498Szrj       && !gimple_nop_p (SSA_NAME_DEF_STMT (ssa_name)))
77038fd1498Szrj     {
77138fd1498Szrj       error ("found a default name with a non-empty defining statement");
77238fd1498Szrj       return true;
77338fd1498Szrj     }
77438fd1498Szrj 
77538fd1498Szrj   return false;
77638fd1498Szrj }
77738fd1498Szrj 
77838fd1498Szrj 
77938fd1498Szrj /* Return true if the definition of SSA_NAME at block BB is malformed.
78038fd1498Szrj 
78138fd1498Szrj    STMT is the statement where SSA_NAME is created.
78238fd1498Szrj 
78338fd1498Szrj    DEFINITION_BLOCK is an array of basic blocks indexed by SSA_NAME
78438fd1498Szrj       version numbers.  If DEFINITION_BLOCK[SSA_NAME_VERSION] is set,
78538fd1498Szrj       it means that the block in that array slot contains the
78638fd1498Szrj       definition of SSA_NAME.
78738fd1498Szrj 
78838fd1498Szrj    IS_VIRTUAL is true if SSA_NAME is created by a VDEF.  */
78938fd1498Szrj 
79038fd1498Szrj static bool
verify_def(basic_block bb,basic_block * definition_block,tree ssa_name,gimple * stmt,bool is_virtual)79138fd1498Szrj verify_def (basic_block bb, basic_block *definition_block, tree ssa_name,
79238fd1498Szrj 	    gimple *stmt, bool is_virtual)
79338fd1498Szrj {
79438fd1498Szrj   if (verify_ssa_name (ssa_name, is_virtual))
79538fd1498Szrj     goto err;
79638fd1498Szrj 
79738fd1498Szrj   if (SSA_NAME_VAR (ssa_name)
79838fd1498Szrj       && TREE_CODE (SSA_NAME_VAR (ssa_name)) == RESULT_DECL
79938fd1498Szrj       && DECL_BY_REFERENCE (SSA_NAME_VAR (ssa_name)))
80038fd1498Szrj     {
80138fd1498Szrj       error ("RESULT_DECL should be read only when DECL_BY_REFERENCE is set");
80238fd1498Szrj       goto err;
80338fd1498Szrj     }
80438fd1498Szrj 
80538fd1498Szrj   if (definition_block[SSA_NAME_VERSION (ssa_name)])
80638fd1498Szrj     {
80738fd1498Szrj       error ("SSA_NAME created in two different blocks %i and %i",
80838fd1498Szrj 	     definition_block[SSA_NAME_VERSION (ssa_name)]->index, bb->index);
80938fd1498Szrj       goto err;
81038fd1498Szrj     }
81138fd1498Szrj 
81238fd1498Szrj   definition_block[SSA_NAME_VERSION (ssa_name)] = bb;
81338fd1498Szrj 
81438fd1498Szrj   if (SSA_NAME_DEF_STMT (ssa_name) != stmt)
81538fd1498Szrj     {
81638fd1498Szrj       error ("SSA_NAME_DEF_STMT is wrong");
81738fd1498Szrj       fprintf (stderr, "Expected definition statement:\n");
81838fd1498Szrj       print_gimple_stmt (stderr, SSA_NAME_DEF_STMT (ssa_name), 4, TDF_VOPS);
81938fd1498Szrj       fprintf (stderr, "\nActual definition statement:\n");
82038fd1498Szrj       print_gimple_stmt (stderr, stmt, 4, TDF_VOPS);
82138fd1498Szrj       goto err;
82238fd1498Szrj     }
82338fd1498Szrj 
82438fd1498Szrj   return false;
82538fd1498Szrj 
82638fd1498Szrj err:
82738fd1498Szrj   fprintf (stderr, "while verifying SSA_NAME ");
82838fd1498Szrj   print_generic_expr (stderr, ssa_name);
82938fd1498Szrj   fprintf (stderr, " in statement\n");
83038fd1498Szrj   print_gimple_stmt (stderr, stmt, 4, TDF_VOPS);
83138fd1498Szrj 
83238fd1498Szrj   return true;
83338fd1498Szrj }
83438fd1498Szrj 
83538fd1498Szrj 
83638fd1498Szrj /* Return true if the use of SSA_NAME at statement STMT in block BB is
83738fd1498Szrj    malformed.
83838fd1498Szrj 
83938fd1498Szrj    DEF_BB is the block where SSA_NAME was found to be created.
84038fd1498Szrj 
84138fd1498Szrj    IDOM contains immediate dominator information for the flowgraph.
84238fd1498Szrj 
84338fd1498Szrj    CHECK_ABNORMAL is true if the caller wants to check whether this use
84438fd1498Szrj       is flowing through an abnormal edge (only used when checking PHI
84538fd1498Szrj       arguments).
84638fd1498Szrj 
84738fd1498Szrj    If NAMES_DEFINED_IN_BB is not NULL, it contains a bitmap of ssa names
84838fd1498Szrj      that are defined before STMT in basic block BB.  */
84938fd1498Szrj 
85038fd1498Szrj 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)85138fd1498Szrj verify_use (basic_block bb, basic_block def_bb, use_operand_p use_p,
85238fd1498Szrj 	    gimple *stmt, bool check_abnormal, bitmap names_defined_in_bb)
85338fd1498Szrj {
85438fd1498Szrj   bool err = false;
85538fd1498Szrj   tree ssa_name = USE_FROM_PTR (use_p);
85638fd1498Szrj 
85738fd1498Szrj   if (!TREE_VISITED (ssa_name))
85838fd1498Szrj     if (verify_imm_links (stderr, ssa_name))
85938fd1498Szrj       err = true;
86038fd1498Szrj 
86138fd1498Szrj   TREE_VISITED (ssa_name) = 1;
86238fd1498Szrj 
86338fd1498Szrj   if (gimple_nop_p (SSA_NAME_DEF_STMT (ssa_name))
86438fd1498Szrj       && SSA_NAME_IS_DEFAULT_DEF (ssa_name))
86538fd1498Szrj     ; /* Default definitions have empty statements.  Nothing to do.  */
86638fd1498Szrj   else if (!def_bb)
86738fd1498Szrj     {
86838fd1498Szrj       error ("missing definition");
86938fd1498Szrj       err = true;
87038fd1498Szrj     }
87138fd1498Szrj   else if (bb != def_bb
87238fd1498Szrj 	   && !dominated_by_p (CDI_DOMINATORS, bb, def_bb))
87338fd1498Szrj     {
87438fd1498Szrj       error ("definition in block %i does not dominate use in block %i",
87538fd1498Szrj 	     def_bb->index, bb->index);
87638fd1498Szrj       err = true;
87738fd1498Szrj     }
87838fd1498Szrj   else if (bb == def_bb
87938fd1498Szrj 	   && names_defined_in_bb != NULL
88038fd1498Szrj 	   && !bitmap_bit_p (names_defined_in_bb, SSA_NAME_VERSION (ssa_name)))
88138fd1498Szrj     {
88238fd1498Szrj       error ("definition in block %i follows the use", def_bb->index);
88338fd1498Szrj       err = true;
88438fd1498Szrj     }
88538fd1498Szrj 
88638fd1498Szrj   if (check_abnormal
88738fd1498Szrj       && !SSA_NAME_OCCURS_IN_ABNORMAL_PHI (ssa_name))
88838fd1498Szrj     {
88938fd1498Szrj       error ("SSA_NAME_OCCURS_IN_ABNORMAL_PHI should be set");
89038fd1498Szrj       err = true;
89138fd1498Szrj     }
89238fd1498Szrj 
89338fd1498Szrj   /* Make sure the use is in an appropriate list by checking the previous
89438fd1498Szrj      element to make sure it's the same.  */
89538fd1498Szrj   if (use_p->prev == NULL)
89638fd1498Szrj     {
89738fd1498Szrj       error ("no immediate_use list");
89838fd1498Szrj       err = true;
89938fd1498Szrj     }
90038fd1498Szrj   else
90138fd1498Szrj     {
90238fd1498Szrj       tree listvar;
90338fd1498Szrj       if (use_p->prev->use == NULL)
90438fd1498Szrj 	listvar = use_p->prev->loc.ssa_name;
90538fd1498Szrj       else
90638fd1498Szrj 	listvar = USE_FROM_PTR (use_p->prev);
90738fd1498Szrj       if (listvar != ssa_name)
90838fd1498Szrj         {
90938fd1498Szrj 	  error ("wrong immediate use list");
91038fd1498Szrj 	  err = true;
91138fd1498Szrj 	}
91238fd1498Szrj     }
91338fd1498Szrj 
91438fd1498Szrj   if (err)
91538fd1498Szrj     {
91638fd1498Szrj       fprintf (stderr, "for SSA_NAME: ");
91738fd1498Szrj       print_generic_expr (stderr, ssa_name, TDF_VOPS);
91838fd1498Szrj       fprintf (stderr, " in statement:\n");
91938fd1498Szrj       print_gimple_stmt (stderr, stmt, 0, TDF_VOPS);
92038fd1498Szrj     }
92138fd1498Szrj 
92238fd1498Szrj   return err;
92338fd1498Szrj }
92438fd1498Szrj 
92538fd1498Szrj 
92638fd1498Szrj /* Return true if any of the arguments for PHI node PHI at block BB is
92738fd1498Szrj    malformed.
92838fd1498Szrj 
92938fd1498Szrj    DEFINITION_BLOCK is an array of basic blocks indexed by SSA_NAME
93038fd1498Szrj       version numbers.  If DEFINITION_BLOCK[SSA_NAME_VERSION] is set,
93138fd1498Szrj       it means that the block in that array slot contains the
93238fd1498Szrj       definition of SSA_NAME.  */
93338fd1498Szrj 
93438fd1498Szrj static bool
verify_phi_args(gphi * phi,basic_block bb,basic_block * definition_block)93538fd1498Szrj verify_phi_args (gphi *phi, basic_block bb, basic_block *definition_block)
93638fd1498Szrj {
93738fd1498Szrj   edge e;
93838fd1498Szrj   bool err = false;
93938fd1498Szrj   size_t i, phi_num_args = gimple_phi_num_args (phi);
94038fd1498Szrj 
94138fd1498Szrj   if (EDGE_COUNT (bb->preds) != phi_num_args)
94238fd1498Szrj     {
94338fd1498Szrj       error ("incoming edge count does not match number of PHI arguments");
94438fd1498Szrj       err = true;
94538fd1498Szrj       goto error;
94638fd1498Szrj     }
94738fd1498Szrj 
94838fd1498Szrj   for (i = 0; i < phi_num_args; i++)
94938fd1498Szrj     {
95038fd1498Szrj       use_operand_p op_p = gimple_phi_arg_imm_use_ptr (phi, i);
95138fd1498Szrj       tree op = USE_FROM_PTR (op_p);
95238fd1498Szrj 
95338fd1498Szrj       e = EDGE_PRED (bb, i);
95438fd1498Szrj 
95538fd1498Szrj       if (op == NULL_TREE)
95638fd1498Szrj 	{
95738fd1498Szrj 	  error ("PHI argument is missing for edge %d->%d",
95838fd1498Szrj 	         e->src->index,
95938fd1498Szrj 		 e->dest->index);
96038fd1498Szrj 	  err = true;
96138fd1498Szrj 	  goto error;
96238fd1498Szrj 	}
96338fd1498Szrj 
96438fd1498Szrj       if (TREE_CODE (op) != SSA_NAME && !is_gimple_min_invariant (op))
96538fd1498Szrj 	{
96638fd1498Szrj 	  error ("PHI argument is not SSA_NAME, or invariant");
96738fd1498Szrj 	  err = true;
96838fd1498Szrj 	}
96938fd1498Szrj 
97038fd1498Szrj       if (TREE_CODE (op) == SSA_NAME)
97138fd1498Szrj 	{
97238fd1498Szrj 	  err = verify_ssa_name (op, virtual_operand_p (gimple_phi_result (phi)));
97338fd1498Szrj 	  err |= verify_use (e->src, definition_block[SSA_NAME_VERSION (op)],
97438fd1498Szrj 			     op_p, phi, e->flags & EDGE_ABNORMAL, NULL);
97538fd1498Szrj 	}
97638fd1498Szrj 
97738fd1498Szrj       if (TREE_CODE (op) == ADDR_EXPR)
97838fd1498Szrj 	{
97938fd1498Szrj 	  tree base = TREE_OPERAND (op, 0);
98038fd1498Szrj 	  while (handled_component_p (base))
98138fd1498Szrj 	    base = TREE_OPERAND (base, 0);
98238fd1498Szrj 	  if ((VAR_P (base)
98338fd1498Szrj 	       || TREE_CODE (base) == PARM_DECL
98438fd1498Szrj 	       || TREE_CODE (base) == RESULT_DECL)
98538fd1498Szrj 	      && !TREE_ADDRESSABLE (base))
98638fd1498Szrj 	    {
98738fd1498Szrj 	      error ("address taken, but ADDRESSABLE bit not set");
98838fd1498Szrj 	      err = true;
98938fd1498Szrj 	    }
99038fd1498Szrj 	}
99138fd1498Szrj 
99238fd1498Szrj       if (e->dest != bb)
99338fd1498Szrj 	{
99438fd1498Szrj 	  error ("wrong edge %d->%d for PHI argument",
99538fd1498Szrj 	         e->src->index, e->dest->index);
99638fd1498Szrj 	  err = true;
99738fd1498Szrj 	}
99838fd1498Szrj 
99938fd1498Szrj       if (err)
100038fd1498Szrj 	{
100138fd1498Szrj 	  fprintf (stderr, "PHI argument\n");
100238fd1498Szrj 	  print_generic_stmt (stderr, op, TDF_VOPS);
100338fd1498Szrj 	  goto error;
100438fd1498Szrj 	}
100538fd1498Szrj     }
100638fd1498Szrj 
100738fd1498Szrj error:
100838fd1498Szrj   if (err)
100938fd1498Szrj     {
101038fd1498Szrj       fprintf (stderr, "for PHI node\n");
101138fd1498Szrj       print_gimple_stmt (stderr, phi, 0, TDF_VOPS|TDF_MEMSYMS);
101238fd1498Szrj     }
101338fd1498Szrj 
101438fd1498Szrj 
101538fd1498Szrj   return err;
101638fd1498Szrj }
101738fd1498Szrj 
101838fd1498Szrj 
101938fd1498Szrj /* Verify common invariants in the SSA web.
102038fd1498Szrj    TODO: verify the variable annotations.  */
102138fd1498Szrj 
102238fd1498Szrj DEBUG_FUNCTION void
verify_ssa(bool check_modified_stmt,bool check_ssa_operands)102338fd1498Szrj verify_ssa (bool check_modified_stmt, bool check_ssa_operands)
102438fd1498Szrj {
102538fd1498Szrj   basic_block bb;
102638fd1498Szrj   basic_block *definition_block = XCNEWVEC (basic_block, num_ssa_names);
102738fd1498Szrj   ssa_op_iter iter;
102838fd1498Szrj   tree op;
102938fd1498Szrj   enum dom_state orig_dom_state = dom_info_state (CDI_DOMINATORS);
103038fd1498Szrj   auto_bitmap names_defined_in_bb;
103138fd1498Szrj 
103238fd1498Szrj   gcc_assert (!need_ssa_update_p (cfun));
103338fd1498Szrj 
103438fd1498Szrj   timevar_push (TV_TREE_SSA_VERIFY);
103538fd1498Szrj 
103638fd1498Szrj     {
103738fd1498Szrj       /* Keep track of SSA names present in the IL.  */
103838fd1498Szrj       size_t i;
103938fd1498Szrj       tree name;
104038fd1498Szrj       hash_map <void *, tree> ssa_info;
104138fd1498Szrj 
104238fd1498Szrj       FOR_EACH_SSA_NAME (i, name, cfun)
104338fd1498Szrj 	{
104438fd1498Szrj 	  gimple *stmt;
104538fd1498Szrj 	  TREE_VISITED (name) = 0;
104638fd1498Szrj 
104738fd1498Szrj 	  verify_ssa_name (name, virtual_operand_p (name));
104838fd1498Szrj 
104938fd1498Szrj 	  stmt = SSA_NAME_DEF_STMT (name);
105038fd1498Szrj 	  if (!gimple_nop_p (stmt))
105138fd1498Szrj 	    {
105238fd1498Szrj 	      basic_block bb = gimple_bb (stmt);
105338fd1498Szrj 	      if (verify_def (bb, definition_block,
105438fd1498Szrj 			      name, stmt, virtual_operand_p (name)))
105538fd1498Szrj 		goto err;
105638fd1498Szrj 	    }
105738fd1498Szrj 
105838fd1498Szrj 	  void *info = NULL;
105938fd1498Szrj 	  if (POINTER_TYPE_P (TREE_TYPE (name)))
106038fd1498Szrj 	    info = SSA_NAME_PTR_INFO (name);
106138fd1498Szrj 	  else if (INTEGRAL_TYPE_P (TREE_TYPE (name)))
106238fd1498Szrj 	    info = SSA_NAME_RANGE_INFO (name);
106338fd1498Szrj 	  if (info)
106438fd1498Szrj 	    {
106538fd1498Szrj 	      bool existed;
106638fd1498Szrj 	      tree &val = ssa_info.get_or_insert (info, &existed);
106738fd1498Szrj 	      if (existed)
106838fd1498Szrj 		{
106938fd1498Szrj 		  error ("shared SSA name info");
107038fd1498Szrj 		  print_generic_expr (stderr, val);
107138fd1498Szrj 		  fprintf (stderr, " and ");
107238fd1498Szrj 		  print_generic_expr (stderr, name);
107338fd1498Szrj 		  fprintf (stderr, "\n");
107438fd1498Szrj 		  goto err;
107538fd1498Szrj 		}
107638fd1498Szrj 	      else
107738fd1498Szrj 		val = name;
107838fd1498Szrj 	    }
107938fd1498Szrj 	}
108038fd1498Szrj     }
108138fd1498Szrj 
108238fd1498Szrj   calculate_dominance_info (CDI_DOMINATORS);
108338fd1498Szrj 
108438fd1498Szrj   /* Now verify all the uses and make sure they agree with the definitions
108538fd1498Szrj      found in the previous pass.  */
108638fd1498Szrj   FOR_EACH_BB_FN (bb, cfun)
108738fd1498Szrj     {
108838fd1498Szrj       edge e;
108938fd1498Szrj       edge_iterator ei;
109038fd1498Szrj 
109138fd1498Szrj       /* Make sure that all edges have a clear 'aux' field.  */
109238fd1498Szrj       FOR_EACH_EDGE (e, ei, bb->preds)
109338fd1498Szrj 	{
109438fd1498Szrj 	  if (e->aux)
109538fd1498Szrj 	    {
109638fd1498Szrj 	      error ("AUX pointer initialized for edge %d->%d", e->src->index,
109738fd1498Szrj 		      e->dest->index);
109838fd1498Szrj 	      goto err;
109938fd1498Szrj 	    }
110038fd1498Szrj 	}
110138fd1498Szrj 
110238fd1498Szrj       /* Verify the arguments for every PHI node in the block.  */
110338fd1498Szrj       for (gphi_iterator gsi = gsi_start_phis (bb); !gsi_end_p (gsi); gsi_next (&gsi))
110438fd1498Szrj 	{
110538fd1498Szrj 	  gphi *phi = gsi.phi ();
110638fd1498Szrj 	  if (verify_phi_args (phi, bb, definition_block))
110738fd1498Szrj 	    goto err;
110838fd1498Szrj 
110938fd1498Szrj 	  bitmap_set_bit (names_defined_in_bb,
111038fd1498Szrj 			  SSA_NAME_VERSION (gimple_phi_result (phi)));
111138fd1498Szrj 	}
111238fd1498Szrj 
111338fd1498Szrj       /* Now verify all the uses and vuses in every statement of the block.  */
111438fd1498Szrj       for (gimple_stmt_iterator gsi = gsi_start_bb (bb); !gsi_end_p (gsi);
111538fd1498Szrj 	   gsi_next (&gsi))
111638fd1498Szrj 	{
111738fd1498Szrj 	  gimple *stmt = gsi_stmt (gsi);
111838fd1498Szrj 	  use_operand_p use_p;
111938fd1498Szrj 
112038fd1498Szrj 	  if (check_modified_stmt && gimple_modified_p (stmt))
112138fd1498Szrj 	    {
112238fd1498Szrj 	      error ("stmt (%p) marked modified after optimization pass: ",
112338fd1498Szrj 		     (void *)stmt);
112438fd1498Szrj 	      print_gimple_stmt (stderr, stmt, 0, TDF_VOPS);
112538fd1498Szrj 	      goto err;
112638fd1498Szrj 	    }
112738fd1498Szrj 
112838fd1498Szrj 	  if (check_ssa_operands && verify_ssa_operands (cfun, stmt))
112938fd1498Szrj 	    {
113038fd1498Szrj 	      print_gimple_stmt (stderr, stmt, 0, TDF_VOPS);
113138fd1498Szrj 	      goto err;
113238fd1498Szrj 	    }
113338fd1498Szrj 
113438fd1498Szrj 	  if (gimple_debug_bind_p (stmt)
113538fd1498Szrj 	      && !gimple_debug_bind_has_value_p (stmt))
113638fd1498Szrj 	    continue;
113738fd1498Szrj 
113838fd1498Szrj 	  FOR_EACH_SSA_USE_OPERAND (use_p, stmt, iter, SSA_OP_USE|SSA_OP_VUSE)
113938fd1498Szrj 	    {
114038fd1498Szrj 	      op = USE_FROM_PTR (use_p);
114138fd1498Szrj 	      if (verify_use (bb, definition_block[SSA_NAME_VERSION (op)],
114238fd1498Szrj 			      use_p, stmt, false, names_defined_in_bb))
114338fd1498Szrj 		goto err;
114438fd1498Szrj 	    }
114538fd1498Szrj 
114638fd1498Szrj 	  FOR_EACH_SSA_TREE_OPERAND (op, stmt, iter, SSA_OP_ALL_DEFS)
114738fd1498Szrj 	    {
114838fd1498Szrj 	      if (SSA_NAME_DEF_STMT (op) != stmt)
114938fd1498Szrj 		{
115038fd1498Szrj 		  error ("SSA_NAME_DEF_STMT is wrong");
115138fd1498Szrj 		  fprintf (stderr, "Expected definition statement:\n");
115238fd1498Szrj 		  print_gimple_stmt (stderr, stmt, 4, TDF_VOPS);
115338fd1498Szrj 		  fprintf (stderr, "\nActual definition statement:\n");
115438fd1498Szrj 		  print_gimple_stmt (stderr, SSA_NAME_DEF_STMT (op),
115538fd1498Szrj 				     4, TDF_VOPS);
115638fd1498Szrj 		  goto err;
115738fd1498Szrj 		}
115838fd1498Szrj 	      bitmap_set_bit (names_defined_in_bb, SSA_NAME_VERSION (op));
115938fd1498Szrj 	    }
116038fd1498Szrj 	}
116138fd1498Szrj 
116238fd1498Szrj       bitmap_clear (names_defined_in_bb);
116338fd1498Szrj     }
116438fd1498Szrj 
116538fd1498Szrj   free (definition_block);
116638fd1498Szrj 
116738fd1498Szrj   if (gimple_vop (cfun)
116838fd1498Szrj       && ssa_default_def (cfun, gimple_vop (cfun)))
116938fd1498Szrj     {
117038fd1498Szrj       auto_sbitmap visited (last_basic_block_for_fn (cfun) + 1);
117138fd1498Szrj       bitmap_clear (visited);
117238fd1498Szrj       if (verify_vssa (ENTRY_BLOCK_PTR_FOR_FN (cfun),
117338fd1498Szrj 		       ssa_default_def (cfun, gimple_vop (cfun)), visited))
117438fd1498Szrj 	goto err;
117538fd1498Szrj     }
117638fd1498Szrj 
117738fd1498Szrj   /* Restore the dominance information to its prior known state, so
117838fd1498Szrj      that we do not perturb the compiler's subsequent behavior.  */
117938fd1498Szrj   if (orig_dom_state == DOM_NONE)
118038fd1498Szrj     free_dominance_info (CDI_DOMINATORS);
118138fd1498Szrj   else
118238fd1498Szrj     set_dom_info_availability (CDI_DOMINATORS, orig_dom_state);
118338fd1498Szrj 
118438fd1498Szrj   timevar_pop (TV_TREE_SSA_VERIFY);
118538fd1498Szrj   return;
118638fd1498Szrj 
118738fd1498Szrj err:
118838fd1498Szrj   internal_error ("verify_ssa failed");
118938fd1498Szrj }
119038fd1498Szrj 
119138fd1498Szrj 
119238fd1498Szrj /* Initialize global DFA and SSA structures.  */
119338fd1498Szrj 
119438fd1498Szrj void
init_tree_ssa(struct function * fn)119538fd1498Szrj init_tree_ssa (struct function *fn)
119638fd1498Szrj {
119738fd1498Szrj   fn->gimple_df = ggc_cleared_alloc<gimple_df> ();
119838fd1498Szrj   fn->gimple_df->default_defs = hash_table<ssa_name_hasher>::create_ggc (20);
119938fd1498Szrj   pt_solution_reset (&fn->gimple_df->escaped);
120038fd1498Szrj   init_ssanames (fn, 0);
120138fd1498Szrj }
120238fd1498Szrj 
120338fd1498Szrj /* Deallocate memory associated with SSA data structures for FNDECL.  */
120438fd1498Szrj 
120538fd1498Szrj void
delete_tree_ssa(struct function * fn)120638fd1498Szrj delete_tree_ssa (struct function *fn)
120738fd1498Szrj {
120838fd1498Szrj   fini_ssanames (fn);
120938fd1498Szrj 
121038fd1498Szrj   /* We no longer maintain the SSA operand cache at this point.  */
121138fd1498Szrj   if (ssa_operands_active (fn))
121238fd1498Szrj     fini_ssa_operands (fn);
121338fd1498Szrj 
121438fd1498Szrj   fn->gimple_df->default_defs->empty ();
121538fd1498Szrj   fn->gimple_df->default_defs = NULL;
121638fd1498Szrj   pt_solution_reset (&fn->gimple_df->escaped);
121738fd1498Szrj   if (fn->gimple_df->decls_to_pointers != NULL)
121838fd1498Szrj     delete fn->gimple_df->decls_to_pointers;
121938fd1498Szrj   fn->gimple_df->decls_to_pointers = NULL;
122038fd1498Szrj   fn->gimple_df = NULL;
122138fd1498Szrj 
122238fd1498Szrj   /* We no longer need the edge variable maps.  */
122338fd1498Szrj   redirect_edge_var_map_empty ();
122438fd1498Szrj }
122538fd1498Szrj 
122638fd1498Szrj /* Return true if EXPR is a useless type conversion, otherwise return
122738fd1498Szrj    false.  */
122838fd1498Szrj 
122938fd1498Szrj bool
tree_ssa_useless_type_conversion(tree expr)123038fd1498Szrj tree_ssa_useless_type_conversion (tree expr)
123138fd1498Szrj {
123238fd1498Szrj   /* If we have an assignment that merely uses a NOP_EXPR to change
123338fd1498Szrj      the top of the RHS to the type of the LHS and the type conversion
123438fd1498Szrj      is "safe", then strip away the type conversion so that we can
123538fd1498Szrj      enter LHS = RHS into the const_and_copies table.  */
123638fd1498Szrj   if (CONVERT_EXPR_P (expr)
123738fd1498Szrj       || TREE_CODE (expr) == VIEW_CONVERT_EXPR
123838fd1498Szrj       || TREE_CODE (expr) == NON_LVALUE_EXPR)
123938fd1498Szrj     return useless_type_conversion_p
124038fd1498Szrj       (TREE_TYPE (expr),
124138fd1498Szrj        TREE_TYPE (TREE_OPERAND (expr, 0)));
124238fd1498Szrj 
124338fd1498Szrj   return false;
124438fd1498Szrj }
124538fd1498Szrj 
124638fd1498Szrj /* Strip conversions from EXP according to
124738fd1498Szrj    tree_ssa_useless_type_conversion and return the resulting
124838fd1498Szrj    expression.  */
124938fd1498Szrj 
125038fd1498Szrj tree
tree_ssa_strip_useless_type_conversions(tree exp)125138fd1498Szrj tree_ssa_strip_useless_type_conversions (tree exp)
125238fd1498Szrj {
125338fd1498Szrj   while (tree_ssa_useless_type_conversion (exp))
125438fd1498Szrj     exp = TREE_OPERAND (exp, 0);
125538fd1498Szrj   return exp;
125638fd1498Szrj }
125738fd1498Szrj 
125838fd1498Szrj /* Return true if T, as SSA_NAME, has an implicit default defined value.  */
125938fd1498Szrj 
126038fd1498Szrj bool
ssa_defined_default_def_p(tree t)126138fd1498Szrj ssa_defined_default_def_p (tree t)
126238fd1498Szrj {
126338fd1498Szrj   tree var = SSA_NAME_VAR (t);
126438fd1498Szrj 
126538fd1498Szrj   if (!var)
126638fd1498Szrj     ;
126738fd1498Szrj   /* Parameters get their initial value from the function entry.  */
126838fd1498Szrj   else if (TREE_CODE (var) == PARM_DECL)
126938fd1498Szrj     return true;
127038fd1498Szrj   /* When returning by reference the return address is actually a hidden
127138fd1498Szrj      parameter.  */
127238fd1498Szrj   else if (TREE_CODE (var) == RESULT_DECL && DECL_BY_REFERENCE (var))
127338fd1498Szrj     return true;
127438fd1498Szrj   /* Hard register variables get their initial value from the ether.  */
127538fd1498Szrj   else if (VAR_P (var) && DECL_HARD_REGISTER (var))
127638fd1498Szrj     return true;
127738fd1498Szrj 
127838fd1498Szrj   return false;
127938fd1498Szrj }
128038fd1498Szrj 
128138fd1498Szrj 
128238fd1498Szrj /* Return true if T, an SSA_NAME, has an undefined value.  PARTIAL is what
128338fd1498Szrj    should be returned if the value is only partially undefined.  */
128438fd1498Szrj 
128538fd1498Szrj bool
ssa_undefined_value_p(tree t,bool partial)128638fd1498Szrj ssa_undefined_value_p (tree t, bool partial)
128738fd1498Szrj {
128838fd1498Szrj   gimple *def_stmt;
128938fd1498Szrj 
129038fd1498Szrj   if (ssa_defined_default_def_p (t))
129138fd1498Szrj     return false;
129238fd1498Szrj 
129338fd1498Szrj   /* The value is undefined iff its definition statement is empty.  */
129438fd1498Szrj   def_stmt = SSA_NAME_DEF_STMT (t);
129538fd1498Szrj   if (gimple_nop_p (def_stmt))
129638fd1498Szrj     return true;
129738fd1498Szrj 
129838fd1498Szrj   /* Check if the complex was not only partially defined.  */
129938fd1498Szrj   if (partial && is_gimple_assign (def_stmt)
130038fd1498Szrj       && gimple_assign_rhs_code (def_stmt) == COMPLEX_EXPR)
130138fd1498Szrj     {
130238fd1498Szrj       tree rhs1, rhs2;
130338fd1498Szrj 
130438fd1498Szrj       rhs1 = gimple_assign_rhs1 (def_stmt);
130538fd1498Szrj       rhs2 = gimple_assign_rhs2 (def_stmt);
130638fd1498Szrj       return (TREE_CODE (rhs1) == SSA_NAME && ssa_undefined_value_p (rhs1))
130738fd1498Szrj 	     || (TREE_CODE (rhs2) == SSA_NAME && ssa_undefined_value_p (rhs2));
130838fd1498Szrj     }
130938fd1498Szrj   return false;
131038fd1498Szrj }
131138fd1498Szrj 
131238fd1498Szrj 
131338fd1498Szrj /* Return TRUE iff STMT, a gimple statement, references an undefined
131438fd1498Szrj    SSA name.  */
131538fd1498Szrj 
131638fd1498Szrj bool
gimple_uses_undefined_value_p(gimple * stmt)131738fd1498Szrj gimple_uses_undefined_value_p (gimple *stmt)
131838fd1498Szrj {
131938fd1498Szrj   ssa_op_iter iter;
132038fd1498Szrj   tree op;
132138fd1498Szrj 
132238fd1498Szrj   FOR_EACH_SSA_TREE_OPERAND (op, stmt, iter, SSA_OP_USE)
132338fd1498Szrj     if (ssa_undefined_value_p (op))
132438fd1498Szrj       return true;
132538fd1498Szrj 
132638fd1498Szrj   return false;
132738fd1498Szrj }
132838fd1498Szrj 
132938fd1498Szrj 
133038fd1498Szrj 
133138fd1498Szrj /* If necessary, rewrite the base of the reference tree *TP from
133238fd1498Szrj    a MEM_REF to a plain or converted symbol.  */
133338fd1498Szrj 
133438fd1498Szrj static void
maybe_rewrite_mem_ref_base(tree * tp,bitmap suitable_for_renaming)133538fd1498Szrj maybe_rewrite_mem_ref_base (tree *tp, bitmap suitable_for_renaming)
133638fd1498Szrj {
133738fd1498Szrj   tree sym;
133838fd1498Szrj 
133938fd1498Szrj   while (handled_component_p (*tp))
134038fd1498Szrj     tp = &TREE_OPERAND (*tp, 0);
134138fd1498Szrj   if (TREE_CODE (*tp) == MEM_REF
134238fd1498Szrj       && TREE_CODE (TREE_OPERAND (*tp, 0)) == ADDR_EXPR
134338fd1498Szrj       && (sym = TREE_OPERAND (TREE_OPERAND (*tp, 0), 0))
134438fd1498Szrj       && DECL_P (sym)
134538fd1498Szrj       && !TREE_ADDRESSABLE (sym)
134638fd1498Szrj       && bitmap_bit_p (suitable_for_renaming, DECL_UID (sym))
134738fd1498Szrj       && is_gimple_reg_type (TREE_TYPE (*tp))
134838fd1498Szrj       && ! VOID_TYPE_P (TREE_TYPE (*tp)))
134938fd1498Szrj     {
135038fd1498Szrj       if (TREE_CODE (TREE_TYPE (sym)) == VECTOR_TYPE
135138fd1498Szrj 	  && useless_type_conversion_p (TREE_TYPE (*tp),
135238fd1498Szrj 					TREE_TYPE (TREE_TYPE (sym)))
135338fd1498Szrj 	  && multiple_of_p (sizetype, TREE_OPERAND (*tp, 1),
135438fd1498Szrj 			    TYPE_SIZE_UNIT (TREE_TYPE (*tp))))
135538fd1498Szrj 	{
135638fd1498Szrj 	  *tp = build3 (BIT_FIELD_REF, TREE_TYPE (*tp), sym,
135738fd1498Szrj 			TYPE_SIZE (TREE_TYPE (*tp)),
135838fd1498Szrj 			int_const_binop (MULT_EXPR,
135938fd1498Szrj 					 bitsize_int (BITS_PER_UNIT),
136038fd1498Szrj 					 TREE_OPERAND (*tp, 1)));
136138fd1498Szrj 	}
136238fd1498Szrj       else if (TREE_CODE (TREE_TYPE (sym)) == COMPLEX_TYPE
136338fd1498Szrj 	       && useless_type_conversion_p (TREE_TYPE (*tp),
136438fd1498Szrj 					     TREE_TYPE (TREE_TYPE (sym))))
136538fd1498Szrj 	{
136638fd1498Szrj 	  *tp = build1 (integer_zerop (TREE_OPERAND (*tp, 1))
136738fd1498Szrj 			? REALPART_EXPR : IMAGPART_EXPR,
136838fd1498Szrj 			TREE_TYPE (*tp), sym);
136938fd1498Szrj 	}
137038fd1498Szrj       else if (integer_zerop (TREE_OPERAND (*tp, 1))
137138fd1498Szrj 	       && DECL_SIZE (sym) == TYPE_SIZE (TREE_TYPE (*tp)))
137238fd1498Szrj 	{
137338fd1498Szrj 	  if (!useless_type_conversion_p (TREE_TYPE (*tp),
137438fd1498Szrj 					  TREE_TYPE (sym)))
137538fd1498Szrj 	    *tp = build1 (VIEW_CONVERT_EXPR,
137638fd1498Szrj 			  TREE_TYPE (*tp), sym);
137738fd1498Szrj 	  else
137838fd1498Szrj 	    *tp = sym;
137938fd1498Szrj 	}
138038fd1498Szrj       else if (DECL_SIZE (sym)
138138fd1498Szrj 	       && TREE_CODE (DECL_SIZE (sym)) == INTEGER_CST
138238fd1498Szrj 	       && (known_subrange_p
138338fd1498Szrj 		   (mem_ref_offset (*tp),
138438fd1498Szrj 		    wi::to_offset (TYPE_SIZE_UNIT (TREE_TYPE (*tp))),
138538fd1498Szrj 		    0, wi::to_offset (DECL_SIZE_UNIT (sym))))
138638fd1498Szrj 	       && (! INTEGRAL_TYPE_P (TREE_TYPE (*tp))
138738fd1498Szrj 		   || (wi::to_offset (TYPE_SIZE (TREE_TYPE (*tp)))
138838fd1498Szrj 		       == TYPE_PRECISION (TREE_TYPE (*tp))))
138938fd1498Szrj 	       && wi::umod_trunc (wi::to_offset (TYPE_SIZE (TREE_TYPE (*tp))),
139038fd1498Szrj 				  BITS_PER_UNIT) == 0)
139138fd1498Szrj 	{
139238fd1498Szrj 	  *tp = build3 (BIT_FIELD_REF, TREE_TYPE (*tp), sym,
139338fd1498Szrj 			TYPE_SIZE (TREE_TYPE (*tp)),
139438fd1498Szrj 			wide_int_to_tree (bitsizetype,
139538fd1498Szrj 					  mem_ref_offset (*tp)
139638fd1498Szrj 					  << LOG2_BITS_PER_UNIT));
139738fd1498Szrj 	}
139838fd1498Szrj     }
139938fd1498Szrj }
140038fd1498Szrj 
140138fd1498Szrj /* For a tree REF return its base if it is the base of a MEM_REF
140238fd1498Szrj    that cannot be rewritten into SSA form.  Otherwise return NULL_TREE.  */
140338fd1498Szrj 
140438fd1498Szrj static tree
non_rewritable_mem_ref_base(tree ref)140538fd1498Szrj non_rewritable_mem_ref_base (tree ref)
140638fd1498Szrj {
140738fd1498Szrj   tree base;
140838fd1498Szrj 
140938fd1498Szrj   /* A plain decl does not need it set.  */
141038fd1498Szrj   if (DECL_P (ref))
141138fd1498Szrj     return NULL_TREE;
141238fd1498Szrj 
141338fd1498Szrj   if (! (base = CONST_CAST_TREE (strip_invariant_refs (ref))))
141438fd1498Szrj     {
141538fd1498Szrj       base = get_base_address (ref);
141638fd1498Szrj       if (DECL_P (base))
141738fd1498Szrj 	return base;
141838fd1498Szrj       return NULL_TREE;
141938fd1498Szrj     }
142038fd1498Szrj 
142138fd1498Szrj   /* But watch out for MEM_REFs we cannot lower to a
142238fd1498Szrj      VIEW_CONVERT_EXPR or a BIT_FIELD_REF.  */
142338fd1498Szrj   if (TREE_CODE (base) == MEM_REF
142438fd1498Szrj       && TREE_CODE (TREE_OPERAND (base, 0)) == ADDR_EXPR)
142538fd1498Szrj     {
142638fd1498Szrj       tree decl = TREE_OPERAND (TREE_OPERAND (base, 0), 0);
142738fd1498Szrj       if (! DECL_P (decl))
142838fd1498Szrj 	return NULL_TREE;
142938fd1498Szrj       if (! is_gimple_reg_type (TREE_TYPE (base))
143038fd1498Szrj 	  || VOID_TYPE_P (TREE_TYPE (base))
143138fd1498Szrj 	  || TREE_THIS_VOLATILE (decl) != TREE_THIS_VOLATILE (base))
143238fd1498Szrj 	return decl;
143338fd1498Szrj       if ((TREE_CODE (TREE_TYPE (decl)) == VECTOR_TYPE
143438fd1498Szrj 	   || TREE_CODE (TREE_TYPE (decl)) == COMPLEX_TYPE)
143538fd1498Szrj 	  && useless_type_conversion_p (TREE_TYPE (base),
143638fd1498Szrj 					TREE_TYPE (TREE_TYPE (decl)))
143738fd1498Szrj 	  && known_ge (mem_ref_offset (base), 0)
143838fd1498Szrj 	  && known_gt (wi::to_poly_offset (TYPE_SIZE_UNIT (TREE_TYPE (decl))),
143938fd1498Szrj 		       mem_ref_offset (base))
144038fd1498Szrj 	  && multiple_of_p (sizetype, TREE_OPERAND (base, 1),
144138fd1498Szrj 			    TYPE_SIZE_UNIT (TREE_TYPE (base))))
144238fd1498Szrj 	return NULL_TREE;
144338fd1498Szrj       /* For same sizes and zero offset we can use a VIEW_CONVERT_EXPR.  */
144438fd1498Szrj       if (integer_zerop (TREE_OPERAND (base, 1))
144538fd1498Szrj 	  && DECL_SIZE (decl) == TYPE_SIZE (TREE_TYPE (base)))
144638fd1498Szrj 	return NULL_TREE;
144738fd1498Szrj       /* For integral typed extracts we can use a BIT_FIELD_REF.  */
144838fd1498Szrj       if (DECL_SIZE (decl)
1449*58e805e6Szrj 	  && TREE_CODE (DECL_SIZE_UNIT (decl)) == INTEGER_CST
145038fd1498Szrj 	  && (known_subrange_p
145138fd1498Szrj 	      (mem_ref_offset (base),
145238fd1498Szrj 	       wi::to_poly_offset (TYPE_SIZE_UNIT (TREE_TYPE (base))),
145338fd1498Szrj 	       0, wi::to_poly_offset (DECL_SIZE_UNIT (decl))))
145438fd1498Szrj 	  /* ???  We can't handle bitfield precision extracts without
145538fd1498Szrj 	     either using an alternate type for the BIT_FIELD_REF and
145638fd1498Szrj 	     then doing a conversion or possibly adjusting the offset
145738fd1498Szrj 	     according to endianness.  */
145838fd1498Szrj 	  && (! INTEGRAL_TYPE_P (TREE_TYPE (base))
145938fd1498Szrj 	      || (wi::to_offset (TYPE_SIZE (TREE_TYPE (base)))
146038fd1498Szrj 		  == TYPE_PRECISION (TREE_TYPE (base))))
146138fd1498Szrj 	  && wi::umod_trunc (wi::to_offset (TYPE_SIZE (TREE_TYPE (base))),
146238fd1498Szrj 			     BITS_PER_UNIT) == 0)
146338fd1498Szrj 	return NULL_TREE;
146438fd1498Szrj       return decl;
146538fd1498Szrj     }
146638fd1498Szrj 
146738fd1498Szrj   return NULL_TREE;
146838fd1498Szrj }
146938fd1498Szrj 
147038fd1498Szrj /* For an lvalue tree LHS return true if it cannot be rewritten into SSA form.
147138fd1498Szrj    Otherwise return true.  */
147238fd1498Szrj 
147338fd1498Szrj static bool
non_rewritable_lvalue_p(tree lhs)147438fd1498Szrj non_rewritable_lvalue_p (tree lhs)
147538fd1498Szrj {
147638fd1498Szrj   /* A plain decl is always rewritable.  */
147738fd1498Szrj   if (DECL_P (lhs))
147838fd1498Szrj     return false;
147938fd1498Szrj 
148038fd1498Szrj   /* We can re-write REALPART_EXPR and IMAGPART_EXPR sets in
148138fd1498Szrj      a reasonably efficient manner... */
148238fd1498Szrj   if ((TREE_CODE (lhs) == REALPART_EXPR
148338fd1498Szrj        || TREE_CODE (lhs) == IMAGPART_EXPR)
148438fd1498Szrj       && DECL_P (TREE_OPERAND (lhs, 0)))
148538fd1498Szrj     return false;
148638fd1498Szrj 
148738fd1498Szrj   /* ???  The following could be relaxed allowing component
148838fd1498Szrj      references that do not change the access size.  */
148938fd1498Szrj   if (TREE_CODE (lhs) == MEM_REF
149038fd1498Szrj       && TREE_CODE (TREE_OPERAND (lhs, 0)) == ADDR_EXPR)
149138fd1498Szrj     {
149238fd1498Szrj       tree decl = TREE_OPERAND (TREE_OPERAND (lhs, 0), 0);
149338fd1498Szrj 
149438fd1498Szrj       /* A decl that is wrapped inside a MEM-REF that covers
149538fd1498Szrj 	 it full is also rewritable.  */
149638fd1498Szrj       if (integer_zerop (TREE_OPERAND (lhs, 1))
149738fd1498Szrj 	  && DECL_P (decl)
149838fd1498Szrj 	  && DECL_SIZE (decl) == TYPE_SIZE (TREE_TYPE (lhs))
149938fd1498Szrj 	  /* If the dynamic type of the decl has larger precision than
150038fd1498Szrj 	     the decl itself we can't use the decls type for SSA rewriting.  */
150138fd1498Szrj 	  && ((! INTEGRAL_TYPE_P (TREE_TYPE (decl))
150238fd1498Szrj 	       || compare_tree_int (DECL_SIZE (decl),
150338fd1498Szrj 				    TYPE_PRECISION (TREE_TYPE (decl))) == 0)
150438fd1498Szrj 	      || (INTEGRAL_TYPE_P (TREE_TYPE (lhs))
150538fd1498Szrj 		  && (TYPE_PRECISION (TREE_TYPE (decl))
150638fd1498Szrj 		      >= TYPE_PRECISION (TREE_TYPE (lhs)))))
150738fd1498Szrj 	  /* Make sure we are not re-writing non-float copying into float
150838fd1498Szrj 	     copying as that can incur normalization.  */
150938fd1498Szrj 	  && (! FLOAT_TYPE_P (TREE_TYPE (decl))
151038fd1498Szrj 	      || types_compatible_p (TREE_TYPE (lhs), TREE_TYPE (decl)))
151138fd1498Szrj 	  && (TREE_THIS_VOLATILE (decl) == TREE_THIS_VOLATILE (lhs)))
151238fd1498Szrj 	return false;
151338fd1498Szrj 
151438fd1498Szrj       /* A vector-insert using a MEM_REF or ARRAY_REF is rewritable
151538fd1498Szrj 	 using a BIT_INSERT_EXPR.  */
151638fd1498Szrj       if (DECL_P (decl)
151738fd1498Szrj 	  && VECTOR_TYPE_P (TREE_TYPE (decl))
151838fd1498Szrj 	  && TYPE_MODE (TREE_TYPE (decl)) != BLKmode
151938fd1498Szrj 	  && operand_equal_p (TYPE_SIZE_UNIT (TREE_TYPE (lhs)),
152038fd1498Szrj 			      TYPE_SIZE_UNIT (TREE_TYPE (TREE_TYPE (decl))), 0)
152138fd1498Szrj 	  && known_ge (mem_ref_offset (lhs), 0)
152238fd1498Szrj 	  && known_gt (wi::to_poly_offset (TYPE_SIZE_UNIT (TREE_TYPE (decl))),
152338fd1498Szrj 		       mem_ref_offset (lhs))
152438fd1498Szrj 	  && multiple_of_p (sizetype, TREE_OPERAND (lhs, 1),
152538fd1498Szrj 			    TYPE_SIZE_UNIT (TREE_TYPE (lhs))))
152638fd1498Szrj 	return false;
152738fd1498Szrj     }
152838fd1498Szrj 
152938fd1498Szrj   /* A vector-insert using a BIT_FIELD_REF is rewritable using
153038fd1498Szrj      BIT_INSERT_EXPR.  */
153138fd1498Szrj   if (TREE_CODE (lhs) == BIT_FIELD_REF
153238fd1498Szrj       && DECL_P (TREE_OPERAND (lhs, 0))
153338fd1498Szrj       && VECTOR_TYPE_P (TREE_TYPE (TREE_OPERAND (lhs, 0)))
153438fd1498Szrj       && TYPE_MODE (TREE_TYPE (TREE_OPERAND (lhs, 0))) != BLKmode
153538fd1498Szrj       && operand_equal_p (TYPE_SIZE_UNIT (TREE_TYPE (lhs)),
153638fd1498Szrj 			  TYPE_SIZE_UNIT
153738fd1498Szrj 			    (TREE_TYPE (TREE_TYPE (TREE_OPERAND (lhs, 0)))), 0)
153838fd1498Szrj       && (tree_to_uhwi (TREE_OPERAND (lhs, 2))
153938fd1498Szrj 	  % tree_to_uhwi (TYPE_SIZE (TREE_TYPE (lhs)))) == 0)
154038fd1498Szrj     return false;
154138fd1498Szrj 
154238fd1498Szrj   return true;
154338fd1498Szrj }
154438fd1498Szrj 
154538fd1498Szrj /* When possible, clear TREE_ADDRESSABLE bit or set DECL_GIMPLE_REG_P bit and
154638fd1498Szrj    mark the variable VAR for conversion into SSA.  Return true when updating
154738fd1498Szrj    stmts is required.  */
154838fd1498Szrj 
154938fd1498Szrj static void
maybe_optimize_var(tree var,bitmap addresses_taken,bitmap not_reg_needs,bitmap suitable_for_renaming)155038fd1498Szrj maybe_optimize_var (tree var, bitmap addresses_taken, bitmap not_reg_needs,
155138fd1498Szrj 		    bitmap suitable_for_renaming)
155238fd1498Szrj {
155338fd1498Szrj   /* Global Variables, result decls cannot be changed.  */
155438fd1498Szrj   if (is_global_var (var)
155538fd1498Szrj       || TREE_CODE (var) == RESULT_DECL
155638fd1498Szrj       || bitmap_bit_p (addresses_taken, DECL_UID (var)))
155738fd1498Szrj     return;
155838fd1498Szrj 
155938fd1498Szrj   if (TREE_ADDRESSABLE (var)
156038fd1498Szrj       /* Do not change TREE_ADDRESSABLE if we need to preserve var as
156138fd1498Szrj 	 a non-register.  Otherwise we are confused and forget to
156238fd1498Szrj 	 add virtual operands for it.  */
156338fd1498Szrj       && (!is_gimple_reg_type (TREE_TYPE (var))
156438fd1498Szrj 	  || TREE_CODE (TREE_TYPE (var)) == VECTOR_TYPE
156538fd1498Szrj 	  || TREE_CODE (TREE_TYPE (var)) == COMPLEX_TYPE
156638fd1498Szrj 	  || !bitmap_bit_p (not_reg_needs, DECL_UID (var))))
156738fd1498Szrj     {
156838fd1498Szrj       TREE_ADDRESSABLE (var) = 0;
156938fd1498Szrj       if (is_gimple_reg (var))
157038fd1498Szrj 	bitmap_set_bit (suitable_for_renaming, DECL_UID (var));
157138fd1498Szrj       if (dump_file)
157238fd1498Szrj 	{
157338fd1498Szrj 	  fprintf (dump_file, "No longer having address taken: ");
157438fd1498Szrj 	  print_generic_expr (dump_file, var);
157538fd1498Szrj 	  fprintf (dump_file, "\n");
157638fd1498Szrj 	}
157738fd1498Szrj     }
157838fd1498Szrj 
157938fd1498Szrj   if (!DECL_GIMPLE_REG_P (var)
158038fd1498Szrj       && !bitmap_bit_p (not_reg_needs, DECL_UID (var))
158138fd1498Szrj       && (TREE_CODE (TREE_TYPE (var)) == COMPLEX_TYPE
158238fd1498Szrj 	  || TREE_CODE (TREE_TYPE (var)) == VECTOR_TYPE)
158338fd1498Szrj       && !TREE_THIS_VOLATILE (var)
158438fd1498Szrj       && (!VAR_P (var) || !DECL_HARD_REGISTER (var)))
158538fd1498Szrj     {
158638fd1498Szrj       DECL_GIMPLE_REG_P (var) = 1;
158738fd1498Szrj       bitmap_set_bit (suitable_for_renaming, DECL_UID (var));
158838fd1498Szrj       if (dump_file)
158938fd1498Szrj 	{
159038fd1498Szrj 	  fprintf (dump_file, "Now a gimple register: ");
159138fd1498Szrj 	  print_generic_expr (dump_file, var);
159238fd1498Szrj 	  fprintf (dump_file, "\n");
159338fd1498Szrj 	}
159438fd1498Szrj     }
159538fd1498Szrj }
159638fd1498Szrj 
159738fd1498Szrj /* Return true when STMT is ASAN mark where second argument is an address
159838fd1498Szrj    of a local variable.  */
159938fd1498Szrj 
160038fd1498Szrj static bool
is_asan_mark_p(gimple * stmt)160138fd1498Szrj is_asan_mark_p (gimple *stmt)
160238fd1498Szrj {
160338fd1498Szrj   if (!gimple_call_internal_p (stmt, IFN_ASAN_MARK))
160438fd1498Szrj     return false;
160538fd1498Szrj 
160638fd1498Szrj   tree addr = get_base_address (gimple_call_arg (stmt, 1));
160738fd1498Szrj   if (TREE_CODE (addr) == ADDR_EXPR
160838fd1498Szrj       && VAR_P (TREE_OPERAND (addr, 0)))
160938fd1498Szrj     {
161038fd1498Szrj       tree var = TREE_OPERAND (addr, 0);
161138fd1498Szrj       if (lookup_attribute (ASAN_USE_AFTER_SCOPE_ATTRIBUTE,
161238fd1498Szrj 			    DECL_ATTRIBUTES (var)))
161338fd1498Szrj 	return false;
161438fd1498Szrj 
161538fd1498Szrj       unsigned addressable = TREE_ADDRESSABLE (var);
161638fd1498Szrj       TREE_ADDRESSABLE (var) = 0;
161738fd1498Szrj       bool r = is_gimple_reg (var);
161838fd1498Szrj       TREE_ADDRESSABLE (var) = addressable;
161938fd1498Szrj       return r;
162038fd1498Szrj     }
162138fd1498Szrj 
162238fd1498Szrj   return false;
162338fd1498Szrj }
162438fd1498Szrj 
162538fd1498Szrj /* Compute TREE_ADDRESSABLE and DECL_GIMPLE_REG_P for local variables.  */
162638fd1498Szrj 
162738fd1498Szrj void
execute_update_addresses_taken(void)162838fd1498Szrj execute_update_addresses_taken (void)
162938fd1498Szrj {
163038fd1498Szrj   basic_block bb;
163138fd1498Szrj   auto_bitmap addresses_taken;
163238fd1498Szrj   auto_bitmap not_reg_needs;
163338fd1498Szrj   auto_bitmap suitable_for_renaming;
163438fd1498Szrj   tree var;
163538fd1498Szrj   unsigned i;
163638fd1498Szrj 
163738fd1498Szrj   timevar_push (TV_ADDRESS_TAKEN);
163838fd1498Szrj 
163938fd1498Szrj   /* Collect into ADDRESSES_TAKEN all variables whose address is taken within
164038fd1498Szrj      the function body.  */
164138fd1498Szrj   FOR_EACH_BB_FN (bb, cfun)
164238fd1498Szrj     {
164338fd1498Szrj       for (gimple_stmt_iterator gsi = gsi_start_bb (bb); !gsi_end_p (gsi);
164438fd1498Szrj 	   gsi_next (&gsi))
164538fd1498Szrj 	{
164638fd1498Szrj 	  gimple *stmt = gsi_stmt (gsi);
164738fd1498Szrj 	  enum gimple_code code = gimple_code (stmt);
164838fd1498Szrj 	  tree decl;
164938fd1498Szrj 
165038fd1498Szrj 	  if (code == GIMPLE_CALL)
165138fd1498Szrj 	    {
165238fd1498Szrj 	      if (optimize_atomic_compare_exchange_p (stmt))
165338fd1498Szrj 		{
165438fd1498Szrj 		  /* For __atomic_compare_exchange_N if the second argument
165538fd1498Szrj 		     is &var, don't mark var addressable;
165638fd1498Szrj 		     if it becomes non-addressable, we'll rewrite it into
165738fd1498Szrj 		     ATOMIC_COMPARE_EXCHANGE call.  */
165838fd1498Szrj 		  tree arg = gimple_call_arg (stmt, 1);
165938fd1498Szrj 		  gimple_call_set_arg (stmt, 1, null_pointer_node);
166038fd1498Szrj 		  gimple_ior_addresses_taken (addresses_taken, stmt);
166138fd1498Szrj 		  gimple_call_set_arg (stmt, 1, arg);
166238fd1498Szrj 		}
166338fd1498Szrj 	      else if (is_asan_mark_p (stmt)
166438fd1498Szrj 		       || gimple_call_internal_p (stmt, IFN_GOMP_SIMT_ENTER))
166538fd1498Szrj 		;
166638fd1498Szrj 	      else
166738fd1498Szrj 		gimple_ior_addresses_taken (addresses_taken, stmt);
166838fd1498Szrj 	    }
166938fd1498Szrj 	  else
167038fd1498Szrj 	    /* Note all addresses taken by the stmt.  */
167138fd1498Szrj 	    gimple_ior_addresses_taken (addresses_taken, stmt);
167238fd1498Szrj 
167338fd1498Szrj 	  /* If we have a call or an assignment, see if the lhs contains
167438fd1498Szrj 	     a local decl that requires not to be a gimple register.  */
167538fd1498Szrj 	  if (code == GIMPLE_ASSIGN || code == GIMPLE_CALL)
167638fd1498Szrj 	    {
167738fd1498Szrj               tree lhs = gimple_get_lhs (stmt);
167838fd1498Szrj               if (lhs
167938fd1498Szrj 		  && TREE_CODE (lhs) != SSA_NAME
168038fd1498Szrj 		  && ((code == GIMPLE_CALL && ! DECL_P (lhs))
168138fd1498Szrj 		      || non_rewritable_lvalue_p (lhs)))
168238fd1498Szrj 		{
168338fd1498Szrj 		  decl = get_base_address (lhs);
168438fd1498Szrj 		  if (DECL_P (decl))
168538fd1498Szrj 		    bitmap_set_bit (not_reg_needs, DECL_UID (decl));
168638fd1498Szrj                 }
168738fd1498Szrj 	    }
168838fd1498Szrj 
168938fd1498Szrj 	  if (gimple_assign_single_p (stmt))
169038fd1498Szrj 	    {
169138fd1498Szrj 	      tree rhs = gimple_assign_rhs1 (stmt);
169238fd1498Szrj 	      if ((decl = non_rewritable_mem_ref_base (rhs)))
169338fd1498Szrj 		bitmap_set_bit (not_reg_needs, DECL_UID (decl));
169438fd1498Szrj 	    }
169538fd1498Szrj 
169638fd1498Szrj 	  else if (code == GIMPLE_CALL)
169738fd1498Szrj 	    {
169838fd1498Szrj 	      for (i = 0; i < gimple_call_num_args (stmt); ++i)
169938fd1498Szrj 		{
170038fd1498Szrj 		  tree arg = gimple_call_arg (stmt, i);
170138fd1498Szrj 		  if ((decl = non_rewritable_mem_ref_base (arg)))
170238fd1498Szrj 		    bitmap_set_bit (not_reg_needs, DECL_UID (decl));
170338fd1498Szrj 		}
170438fd1498Szrj 	    }
170538fd1498Szrj 
170638fd1498Szrj 	  else if (code == GIMPLE_ASM)
170738fd1498Szrj 	    {
170838fd1498Szrj 	      gasm *asm_stmt = as_a <gasm *> (stmt);
170938fd1498Szrj 	      for (i = 0; i < gimple_asm_noutputs (asm_stmt); ++i)
171038fd1498Szrj 		{
171138fd1498Szrj 		  tree link = gimple_asm_output_op (asm_stmt, i);
171238fd1498Szrj 		  tree lhs = TREE_VALUE (link);
171338fd1498Szrj 		  if (TREE_CODE (lhs) != SSA_NAME)
171438fd1498Szrj 		    {
171538fd1498Szrj 		      decl = get_base_address (lhs);
171638fd1498Szrj 		      if (DECL_P (decl)
171738fd1498Szrj 			  && (non_rewritable_lvalue_p (lhs)
171838fd1498Szrj 			      /* We cannot move required conversions from
171938fd1498Szrj 				 the lhs to the rhs in asm statements, so
172038fd1498Szrj 				 require we do not need any.  */
172138fd1498Szrj 			      || !useless_type_conversion_p
172238fd1498Szrj 			            (TREE_TYPE (lhs), TREE_TYPE (decl))))
172338fd1498Szrj 			bitmap_set_bit (not_reg_needs, DECL_UID (decl));
172438fd1498Szrj 		    }
172538fd1498Szrj 		}
172638fd1498Szrj 	      for (i = 0; i < gimple_asm_ninputs (asm_stmt); ++i)
172738fd1498Szrj 		{
172838fd1498Szrj 		  tree link = gimple_asm_input_op (asm_stmt, i);
172938fd1498Szrj 		  if ((decl = non_rewritable_mem_ref_base (TREE_VALUE (link))))
173038fd1498Szrj 		    bitmap_set_bit (not_reg_needs, DECL_UID (decl));
173138fd1498Szrj 		}
173238fd1498Szrj 	    }
173338fd1498Szrj 	}
173438fd1498Szrj 
173538fd1498Szrj       for (gphi_iterator gsi = gsi_start_phis (bb); !gsi_end_p (gsi);
173638fd1498Szrj 	   gsi_next (&gsi))
173738fd1498Szrj 	{
173838fd1498Szrj 	  size_t i;
173938fd1498Szrj 	  gphi *phi = gsi.phi ();
174038fd1498Szrj 
174138fd1498Szrj 	  for (i = 0; i < gimple_phi_num_args (phi); i++)
174238fd1498Szrj 	    {
174338fd1498Szrj 	      tree op = PHI_ARG_DEF (phi, i), var;
174438fd1498Szrj 	      if (TREE_CODE (op) == ADDR_EXPR
174538fd1498Szrj 		  && (var = get_base_address (TREE_OPERAND (op, 0))) != NULL
174638fd1498Szrj 		  && DECL_P (var))
174738fd1498Szrj 		bitmap_set_bit (addresses_taken, DECL_UID (var));
174838fd1498Szrj 	    }
174938fd1498Szrj 	}
175038fd1498Szrj     }
175138fd1498Szrj 
175238fd1498Szrj   /* We cannot iterate over all referenced vars because that can contain
175338fd1498Szrj      unused vars from BLOCK trees, which causes code generation differences
175438fd1498Szrj      for -g vs. -g0.  */
175538fd1498Szrj   for (var = DECL_ARGUMENTS (cfun->decl); var; var = DECL_CHAIN (var))
175638fd1498Szrj     maybe_optimize_var (var, addresses_taken, not_reg_needs,
175738fd1498Szrj 			suitable_for_renaming);
175838fd1498Szrj 
175938fd1498Szrj   FOR_EACH_VEC_SAFE_ELT (cfun->local_decls, i, var)
176038fd1498Szrj     maybe_optimize_var (var, addresses_taken, not_reg_needs,
176138fd1498Szrj 			suitable_for_renaming);
176238fd1498Szrj 
176338fd1498Szrj   /* Operand caches need to be recomputed for operands referencing the updated
176438fd1498Szrj      variables and operands need to be rewritten to expose bare symbols.  */
176538fd1498Szrj   if (!bitmap_empty_p (suitable_for_renaming))
176638fd1498Szrj     {
176738fd1498Szrj       FOR_EACH_BB_FN (bb, cfun)
176838fd1498Szrj 	for (gimple_stmt_iterator gsi = gsi_start_bb (bb); !gsi_end_p (gsi);)
176938fd1498Szrj 	  {
177038fd1498Szrj 	    gimple *stmt = gsi_stmt (gsi);
177138fd1498Szrj 
177238fd1498Szrj 	    /* Re-write TARGET_MEM_REFs of symbols we want to
177338fd1498Szrj 	       rewrite into SSA form.  */
177438fd1498Szrj 	    if (gimple_assign_single_p (stmt))
177538fd1498Szrj 	      {
177638fd1498Szrj 		tree lhs = gimple_assign_lhs (stmt);
177738fd1498Szrj 		tree rhs, *rhsp = gimple_assign_rhs1_ptr (stmt);
177838fd1498Szrj 		tree sym;
177938fd1498Szrj 
178038fd1498Szrj 		/* Rewrite LHS IMAG/REALPART_EXPR similar to
178138fd1498Szrj 		   gimplify_modify_expr_complex_part.  */
178238fd1498Szrj 		if ((TREE_CODE (lhs) == IMAGPART_EXPR
178338fd1498Szrj 		     || TREE_CODE (lhs) == REALPART_EXPR)
178438fd1498Szrj 		    && DECL_P (TREE_OPERAND (lhs, 0))
178538fd1498Szrj 		    && bitmap_bit_p (suitable_for_renaming,
178638fd1498Szrj 				     DECL_UID (TREE_OPERAND (lhs, 0))))
178738fd1498Szrj 		  {
178838fd1498Szrj 		    tree other = make_ssa_name (TREE_TYPE (lhs));
178938fd1498Szrj 		    tree lrhs = build1 (TREE_CODE (lhs) == IMAGPART_EXPR
179038fd1498Szrj 					? REALPART_EXPR : IMAGPART_EXPR,
179138fd1498Szrj 					TREE_TYPE (other),
179238fd1498Szrj 					TREE_OPERAND (lhs, 0));
179338fd1498Szrj 		    gimple *load = gimple_build_assign (other, lrhs);
179438fd1498Szrj 		    location_t loc = gimple_location (stmt);
179538fd1498Szrj 		    gimple_set_location (load, loc);
179638fd1498Szrj 		    gimple_set_vuse (load, gimple_vuse (stmt));
179738fd1498Szrj 		    gsi_insert_before (&gsi, load, GSI_SAME_STMT);
179838fd1498Szrj 		    gimple_assign_set_lhs (stmt, TREE_OPERAND (lhs, 0));
179938fd1498Szrj 		    gimple_assign_set_rhs_with_ops
180038fd1498Szrj 		      (&gsi, COMPLEX_EXPR,
180138fd1498Szrj 		       TREE_CODE (lhs) == IMAGPART_EXPR
180238fd1498Szrj 		       ? other : gimple_assign_rhs1 (stmt),
180338fd1498Szrj 		       TREE_CODE (lhs) == IMAGPART_EXPR
180438fd1498Szrj 		       ? gimple_assign_rhs1 (stmt) : other, NULL_TREE);
180538fd1498Szrj 		    stmt = gsi_stmt (gsi);
180638fd1498Szrj 		    unlink_stmt_vdef (stmt);
180738fd1498Szrj 		    update_stmt (stmt);
180838fd1498Szrj 		    continue;
180938fd1498Szrj 		  }
181038fd1498Szrj 
181138fd1498Szrj 		/* Rewrite a vector insert via a BIT_FIELD_REF on the LHS
181238fd1498Szrj 		   into a BIT_INSERT_EXPR.  */
181338fd1498Szrj 		if (TREE_CODE (lhs) == BIT_FIELD_REF
181438fd1498Szrj 		    && DECL_P (TREE_OPERAND (lhs, 0))
181538fd1498Szrj 		    && bitmap_bit_p (suitable_for_renaming,
181638fd1498Szrj 				     DECL_UID (TREE_OPERAND (lhs, 0)))
181738fd1498Szrj 		    && VECTOR_TYPE_P (TREE_TYPE (TREE_OPERAND (lhs, 0)))
181838fd1498Szrj 		    && TYPE_MODE (TREE_TYPE (TREE_OPERAND (lhs, 0))) != BLKmode
181938fd1498Szrj 		    && operand_equal_p (TYPE_SIZE_UNIT (TREE_TYPE (lhs)),
182038fd1498Szrj 					TYPE_SIZE_UNIT (TREE_TYPE
182138fd1498Szrj 					  (TREE_TYPE (TREE_OPERAND (lhs, 0)))),
182238fd1498Szrj 					0)
182338fd1498Szrj 		    && (tree_to_uhwi (TREE_OPERAND (lhs, 2))
182438fd1498Szrj 			% tree_to_uhwi (TYPE_SIZE (TREE_TYPE (lhs))) == 0))
182538fd1498Szrj 		  {
182638fd1498Szrj 		    tree var = TREE_OPERAND (lhs, 0);
182738fd1498Szrj 		    tree val = gimple_assign_rhs1 (stmt);
182838fd1498Szrj 		    if (! types_compatible_p (TREE_TYPE (TREE_TYPE (var)),
182938fd1498Szrj 					      TREE_TYPE (val)))
183038fd1498Szrj 		      {
183138fd1498Szrj 			tree tem = make_ssa_name (TREE_TYPE (TREE_TYPE (var)));
183238fd1498Szrj 			gimple *pun
183338fd1498Szrj 			  = gimple_build_assign (tem,
183438fd1498Szrj 						 build1 (VIEW_CONVERT_EXPR,
183538fd1498Szrj 							 TREE_TYPE (tem), val));
183638fd1498Szrj 			gsi_insert_before (&gsi, pun, GSI_SAME_STMT);
183738fd1498Szrj 			val = tem;
183838fd1498Szrj 		      }
183938fd1498Szrj 		    tree bitpos = TREE_OPERAND (lhs, 2);
184038fd1498Szrj 		    gimple_assign_set_lhs (stmt, var);
184138fd1498Szrj 		    gimple_assign_set_rhs_with_ops
184238fd1498Szrj 		      (&gsi, BIT_INSERT_EXPR, var, val, bitpos);
184338fd1498Szrj 		    stmt = gsi_stmt (gsi);
184438fd1498Szrj 		    unlink_stmt_vdef (stmt);
184538fd1498Szrj 		    update_stmt (stmt);
184638fd1498Szrj 		    continue;
184738fd1498Szrj 		  }
184838fd1498Szrj 
184938fd1498Szrj 		/* Rewrite a vector insert using a MEM_REF on the LHS
185038fd1498Szrj 		   into a BIT_INSERT_EXPR.  */
185138fd1498Szrj 		if (TREE_CODE (lhs) == MEM_REF
185238fd1498Szrj 		    && TREE_CODE (TREE_OPERAND (lhs, 0)) == ADDR_EXPR
185338fd1498Szrj 		    && (sym = TREE_OPERAND (TREE_OPERAND (lhs, 0), 0))
185438fd1498Szrj 		    && DECL_P (sym)
185538fd1498Szrj 		    && bitmap_bit_p (suitable_for_renaming, DECL_UID (sym))
185638fd1498Szrj 		    && VECTOR_TYPE_P (TREE_TYPE (sym))
185738fd1498Szrj 		    && TYPE_MODE (TREE_TYPE (sym)) != BLKmode
185838fd1498Szrj 		    && operand_equal_p (TYPE_SIZE_UNIT (TREE_TYPE (lhs)),
185938fd1498Szrj 					TYPE_SIZE_UNIT
186038fd1498Szrj 					  (TREE_TYPE (TREE_TYPE (sym))), 0)
186138fd1498Szrj 		    && tree_fits_uhwi_p (TREE_OPERAND (lhs, 1))
186238fd1498Szrj 		    && tree_int_cst_lt (TREE_OPERAND (lhs, 1),
186338fd1498Szrj 					TYPE_SIZE_UNIT (TREE_TYPE (sym)))
186438fd1498Szrj 		    && (tree_to_uhwi (TREE_OPERAND (lhs, 1))
186538fd1498Szrj 			% tree_to_uhwi (TYPE_SIZE_UNIT (TREE_TYPE (lhs)))) == 0)
186638fd1498Szrj 		  {
186738fd1498Szrj 		    tree val = gimple_assign_rhs1 (stmt);
186838fd1498Szrj 		    if (! types_compatible_p (TREE_TYPE (val),
186938fd1498Szrj 					      TREE_TYPE (TREE_TYPE (sym))))
187038fd1498Szrj 		      {
187138fd1498Szrj 			tree tem = make_ssa_name (TREE_TYPE (TREE_TYPE (sym)));
187238fd1498Szrj 			gimple *pun
187338fd1498Szrj 			  = gimple_build_assign (tem,
187438fd1498Szrj 						 build1 (VIEW_CONVERT_EXPR,
187538fd1498Szrj 							 TREE_TYPE (tem), val));
187638fd1498Szrj 			gsi_insert_before (&gsi, pun, GSI_SAME_STMT);
187738fd1498Szrj 			val = tem;
187838fd1498Szrj 		      }
187938fd1498Szrj 		    tree bitpos
188038fd1498Szrj 		      = wide_int_to_tree (bitsizetype,
188138fd1498Szrj 					  mem_ref_offset (lhs) * BITS_PER_UNIT);
188238fd1498Szrj 		    gimple_assign_set_lhs (stmt, sym);
188338fd1498Szrj 		    gimple_assign_set_rhs_with_ops
188438fd1498Szrj 		      (&gsi, BIT_INSERT_EXPR, sym, val, bitpos);
188538fd1498Szrj 		    stmt = gsi_stmt (gsi);
188638fd1498Szrj 		    unlink_stmt_vdef (stmt);
188738fd1498Szrj 		    update_stmt (stmt);
188838fd1498Szrj 		    continue;
188938fd1498Szrj 		  }
189038fd1498Szrj 
189138fd1498Szrj 		/* We shouldn't have any fancy wrapping of
189238fd1498Szrj 		   component-refs on the LHS, but look through
189338fd1498Szrj 		   VIEW_CONVERT_EXPRs as that is easy.  */
189438fd1498Szrj 		while (TREE_CODE (lhs) == VIEW_CONVERT_EXPR)
189538fd1498Szrj 		  lhs = TREE_OPERAND (lhs, 0);
189638fd1498Szrj 		if (TREE_CODE (lhs) == MEM_REF
189738fd1498Szrj 		    && TREE_CODE (TREE_OPERAND (lhs, 0)) == ADDR_EXPR
189838fd1498Szrj 		    && integer_zerop (TREE_OPERAND (lhs, 1))
189938fd1498Szrj 		    && (sym = TREE_OPERAND (TREE_OPERAND (lhs, 0), 0))
190038fd1498Szrj 		    && DECL_P (sym)
190138fd1498Szrj 		    && !TREE_ADDRESSABLE (sym)
190238fd1498Szrj 		    && bitmap_bit_p (suitable_for_renaming, DECL_UID (sym)))
190338fd1498Szrj 		  lhs = sym;
190438fd1498Szrj 		else
190538fd1498Szrj 		  lhs = gimple_assign_lhs (stmt);
190638fd1498Szrj 
190738fd1498Szrj 		/* Rewrite the RHS and make sure the resulting assignment
190838fd1498Szrj 		   is validly typed.  */
190938fd1498Szrj 		maybe_rewrite_mem_ref_base (rhsp, suitable_for_renaming);
191038fd1498Szrj 		rhs = gimple_assign_rhs1 (stmt);
191138fd1498Szrj 		if (gimple_assign_lhs (stmt) != lhs
191238fd1498Szrj 		    && !useless_type_conversion_p (TREE_TYPE (lhs),
191338fd1498Szrj 						   TREE_TYPE (rhs)))
191438fd1498Szrj 		  {
191538fd1498Szrj 		    if (gimple_clobber_p (stmt))
191638fd1498Szrj 		      {
191738fd1498Szrj 			rhs = build_constructor (TREE_TYPE (lhs), NULL);
191838fd1498Szrj 			TREE_THIS_VOLATILE (rhs) = 1;
191938fd1498Szrj 		      }
192038fd1498Szrj 		    else
192138fd1498Szrj 		      rhs = fold_build1 (VIEW_CONVERT_EXPR,
192238fd1498Szrj 					 TREE_TYPE (lhs), rhs);
192338fd1498Szrj 		  }
192438fd1498Szrj 		if (gimple_assign_lhs (stmt) != lhs)
192538fd1498Szrj 		  gimple_assign_set_lhs (stmt, lhs);
192638fd1498Szrj 
192738fd1498Szrj 		if (gimple_assign_rhs1 (stmt) != rhs)
192838fd1498Szrj 		  {
192938fd1498Szrj 		    gimple_stmt_iterator gsi = gsi_for_stmt (stmt);
193038fd1498Szrj 		    gimple_assign_set_rhs_from_tree (&gsi, rhs);
193138fd1498Szrj 		  }
193238fd1498Szrj 	      }
193338fd1498Szrj 
193438fd1498Szrj 	    else if (gimple_code (stmt) == GIMPLE_CALL)
193538fd1498Szrj 	      {
193638fd1498Szrj 		unsigned i;
193738fd1498Szrj 		if (optimize_atomic_compare_exchange_p (stmt))
193838fd1498Szrj 		  {
193938fd1498Szrj 		    tree expected = gimple_call_arg (stmt, 1);
194038fd1498Szrj 		    if (bitmap_bit_p (suitable_for_renaming,
194138fd1498Szrj 				      DECL_UID (TREE_OPERAND (expected, 0))))
194238fd1498Szrj 		      {
194338fd1498Szrj 			fold_builtin_atomic_compare_exchange (&gsi);
194438fd1498Szrj 			continue;
194538fd1498Szrj 		      }
194638fd1498Szrj 		  }
194738fd1498Szrj 		else if (is_asan_mark_p (stmt))
194838fd1498Szrj 		  {
194938fd1498Szrj 		    tree var = TREE_OPERAND (gimple_call_arg (stmt, 1), 0);
195038fd1498Szrj 		    if (bitmap_bit_p (suitable_for_renaming, DECL_UID (var)))
195138fd1498Szrj 		      {
195238fd1498Szrj 			unlink_stmt_vdef (stmt);
195338fd1498Szrj 			if (asan_mark_p (stmt, ASAN_MARK_POISON))
195438fd1498Szrj 			  {
195538fd1498Szrj 			    gcall *call
195638fd1498Szrj 			      = gimple_build_call_internal (IFN_ASAN_POISON, 0);
195738fd1498Szrj 			    gimple_call_set_lhs (call, var);
195838fd1498Szrj 			    gsi_replace (&gsi, call, GSI_SAME_STMT);
195938fd1498Szrj 			  }
196038fd1498Szrj 			else
196138fd1498Szrj 			  {
196238fd1498Szrj 			    /* In ASAN_MARK (UNPOISON, &b, ...) the variable
196338fd1498Szrj 			       is uninitialized.  Avoid dependencies on
196438fd1498Szrj 			       previous out of scope value.  */
196538fd1498Szrj 			    tree clobber
196638fd1498Szrj 			      = build_constructor (TREE_TYPE (var), NULL);
196738fd1498Szrj 			    TREE_THIS_VOLATILE (clobber) = 1;
196838fd1498Szrj 			    gimple *g = gimple_build_assign (var, clobber);
196938fd1498Szrj 			    gsi_replace (&gsi, g, GSI_SAME_STMT);
197038fd1498Szrj 			  }
197138fd1498Szrj 			continue;
197238fd1498Szrj 		      }
197338fd1498Szrj 		  }
197438fd1498Szrj 		else if (gimple_call_internal_p (stmt, IFN_GOMP_SIMT_ENTER))
197538fd1498Szrj 		  for (i = 1; i < gimple_call_num_args (stmt); i++)
197638fd1498Szrj 		    {
197738fd1498Szrj 		      tree *argp = gimple_call_arg_ptr (stmt, i);
197838fd1498Szrj 		      if (*argp == null_pointer_node)
197938fd1498Szrj 			continue;
198038fd1498Szrj 		      gcc_assert (TREE_CODE (*argp) == ADDR_EXPR
198138fd1498Szrj 				  && VAR_P (TREE_OPERAND (*argp, 0)));
198238fd1498Szrj 		      tree var = TREE_OPERAND (*argp, 0);
198338fd1498Szrj 		      if (bitmap_bit_p (suitable_for_renaming, DECL_UID (var)))
198438fd1498Szrj 			*argp = null_pointer_node;
198538fd1498Szrj 		    }
198638fd1498Szrj 		for (i = 0; i < gimple_call_num_args (stmt); ++i)
198738fd1498Szrj 		  {
198838fd1498Szrj 		    tree *argp = gimple_call_arg_ptr (stmt, i);
198938fd1498Szrj 		    maybe_rewrite_mem_ref_base (argp, suitable_for_renaming);
199038fd1498Szrj 		  }
199138fd1498Szrj 	      }
199238fd1498Szrj 
199338fd1498Szrj 	    else if (gimple_code (stmt) == GIMPLE_ASM)
199438fd1498Szrj 	      {
199538fd1498Szrj 		gasm *asm_stmt = as_a <gasm *> (stmt);
199638fd1498Szrj 		unsigned i;
199738fd1498Szrj 		for (i = 0; i < gimple_asm_noutputs (asm_stmt); ++i)
199838fd1498Szrj 		  {
199938fd1498Szrj 		    tree link = gimple_asm_output_op (asm_stmt, i);
200038fd1498Szrj 		    maybe_rewrite_mem_ref_base (&TREE_VALUE (link),
200138fd1498Szrj 						suitable_for_renaming);
200238fd1498Szrj 		  }
200338fd1498Szrj 		for (i = 0; i < gimple_asm_ninputs (asm_stmt); ++i)
200438fd1498Szrj 		  {
200538fd1498Szrj 		    tree link = gimple_asm_input_op (asm_stmt, i);
200638fd1498Szrj 		    maybe_rewrite_mem_ref_base (&TREE_VALUE (link),
200738fd1498Szrj 						suitable_for_renaming);
200838fd1498Szrj 		  }
200938fd1498Szrj 	      }
201038fd1498Szrj 
201138fd1498Szrj 	    else if (gimple_debug_bind_p (stmt)
201238fd1498Szrj 		     && gimple_debug_bind_has_value_p (stmt))
201338fd1498Szrj 	      {
201438fd1498Szrj 		tree *valuep = gimple_debug_bind_get_value_ptr (stmt);
201538fd1498Szrj 		tree decl;
201638fd1498Szrj 		maybe_rewrite_mem_ref_base (valuep, suitable_for_renaming);
201738fd1498Szrj 		decl = non_rewritable_mem_ref_base (*valuep);
201838fd1498Szrj 		if (decl
201938fd1498Szrj 		    && bitmap_bit_p (suitable_for_renaming, DECL_UID (decl)))
202038fd1498Szrj 		  gimple_debug_bind_reset_value (stmt);
202138fd1498Szrj 	      }
202238fd1498Szrj 
202338fd1498Szrj 	    if (gimple_references_memory_p (stmt)
202438fd1498Szrj 		|| is_gimple_debug (stmt))
202538fd1498Szrj 	      update_stmt (stmt);
202638fd1498Szrj 
202738fd1498Szrj 	    gsi_next (&gsi);
202838fd1498Szrj 	  }
202938fd1498Szrj 
203038fd1498Szrj       /* Update SSA form here, we are called as non-pass as well.  */
203138fd1498Szrj       if (number_of_loops (cfun) > 1
203238fd1498Szrj 	  && loops_state_satisfies_p (LOOP_CLOSED_SSA))
203338fd1498Szrj 	rewrite_into_loop_closed_ssa (NULL, TODO_update_ssa);
203438fd1498Szrj       else
203538fd1498Szrj 	update_ssa (TODO_update_ssa);
203638fd1498Szrj     }
203738fd1498Szrj 
203838fd1498Szrj   timevar_pop (TV_ADDRESS_TAKEN);
203938fd1498Szrj }
204038fd1498Szrj 
204138fd1498Szrj namespace {
204238fd1498Szrj 
204338fd1498Szrj const pass_data pass_data_update_address_taken =
204438fd1498Szrj {
204538fd1498Szrj   GIMPLE_PASS, /* type */
204638fd1498Szrj   "addressables", /* name */
204738fd1498Szrj   OPTGROUP_NONE, /* optinfo_flags */
204838fd1498Szrj   TV_ADDRESS_TAKEN, /* tv_id */
204938fd1498Szrj   PROP_ssa, /* properties_required */
205038fd1498Szrj   0, /* properties_provided */
205138fd1498Szrj   0, /* properties_destroyed */
205238fd1498Szrj   0, /* todo_flags_start */
205338fd1498Szrj   TODO_update_address_taken, /* todo_flags_finish */
205438fd1498Szrj };
205538fd1498Szrj 
205638fd1498Szrj class pass_update_address_taken : public gimple_opt_pass
205738fd1498Szrj {
205838fd1498Szrj public:
pass_update_address_taken(gcc::context * ctxt)205938fd1498Szrj   pass_update_address_taken (gcc::context *ctxt)
206038fd1498Szrj     : gimple_opt_pass (pass_data_update_address_taken, ctxt)
206138fd1498Szrj   {}
206238fd1498Szrj 
206338fd1498Szrj   /* opt_pass methods: */
206438fd1498Szrj 
206538fd1498Szrj }; // class pass_update_address_taken
206638fd1498Szrj 
206738fd1498Szrj } // anon namespace
206838fd1498Szrj 
206938fd1498Szrj gimple_opt_pass *
make_pass_update_address_taken(gcc::context * ctxt)207038fd1498Szrj make_pass_update_address_taken (gcc::context *ctxt)
207138fd1498Szrj {
207238fd1498Szrj   return new pass_update_address_taken (ctxt);
207338fd1498Szrj }
2074