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