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