Commit 80560f95 by Andrew MacLeod Committed by Andrew Macleod

tree-into-ssa.c (enum need_phi_state): Relocate from tree-flow.h.



	* tree-into-ssa.c (enum need_phi_state): Relocate from tree-flow.h.
	(dump_decl_set): Move to gimple.c.
	* gimple.h: Don't include tree-ssa-operands.h.
	(dump_decl_set): Add prototype.
	(gimple_vuse_op, gimple_vdef_op, update_stmt, update_stmt_if_modified):
	Move to gimple-ssa.h.
	(phi_ssa_name_p, phi_nodes, phi_nodes_ptr, gimple_phi_arg_def,
	gimple_phi_arg_def_ptr, gimple_phi_arg_edge, gimple_phi_arg_location,
	gimple_phi_arg_location_from_edge, gimple_phi_arg_set_location,
	gimple_phi_arg_has_location): Relocate from tree-flow-inline.h
	* gimple.c (walk_stmt_load_store_ops): Use gimple_phi_arg_def rather
	than PHI_ARG_DEF.
	(dump_decl_set): Relocate here.
	* gimple-ssa.h: New file.
	(gimple_vuse_op, gimple_vdef_op, update_stmt, update_stmt_if_modified):
	Relocate from gimple.h.
	* tree-cfg.c (has_zero_uses_1, single_imm_use_1): Move to...
	* tree-ssa-operands.c (swap_ssa_operands): Rename from
	swap_tree_operands and remove non-ssa path.
	(has_zero_uses_1, single_imm_use_1): Relocate from tree-cfg.c.
	* tree-ssa-reassoc.c (linearize_expr_tree, repropagate_negates): Use
	swap_ssa_operands.
	* tree-vect-loop.c (destroy_loop_vec_info, vect_is_slp_reduction,
	vect_is_simple_reduction_1): Use swap_ssa_operands.
	* tree-flow.h: Move various prototypes to tree-phinodes.h.
	(enum need_phi_state): Move to tree-into-ssa.c.
	(struct immediate_use_iterator_d, FOR_EACH_IMM_*,
	BREAK_FROM_IMM_USE_STMT): Move to ssa-iterators.h.
	(swap_tree_operands): Rename and move prototype to tree-ssa-operands.h.
	* tree-flow-inline.h (delink_imm_use, link_imm_use_to_list,
	link_imm_use, set_ssa_use_from_ptr, link_imm_use_stmt, relink_imm_use,
	relink_imm_use_stmt, end_readonly_imm_use_p, first_readonly_imm_use,
	next_readonly_imm_use, has_zero_uses, has_single_use, single_imm_use,
	num_imm_uses): Move to ssa-iterators.h.
	(get_use_from_ptr, get_def_from_ptr): Move to tree-ssa-operands.h
	(gimple_phi_arg_imm_use_ptr, phi_arg_index_from_use): Move to 
	tree-phinodes.h.
	(op_iter_done, op_iter_next_def, op_iter_next_tree,
	clear_and_done_ssa_iter, op_iter_init, op_iter_init_use,
	op_iter_init_def, op_iter_init_tree, single_ssa_tree_operand,
	single_ssa_use_operand, single_ssa_def_operand, zero_ssa_operands,
	num_ssa_operands, delink_stmt_imm_use, single_phi_def,
	op_iter_init_phiuse, op_iter_init_phidef, end_imm_use_stmt_p,
	end_imm_use_stmt_traverse, move_use_after_head, link_use_stmts_after,
	first_imm_use_stmt, next_imm_use_stmt, first_imm_use_on_stmt,
	end_imm_use_on_stmt_p, next_imm_use_on_stmt): Move to ssa-iterators.h.
	(gimple_phi_arg_def, gimple_phi_arg_def_ptr, gimple_phi_arg_edge,
	gimple_phi_arg_location, gimple_phi_arg_location_from_edge,
	gimple_phi_arg_set_location, gimple_phi_arg_has_location, phi_nodes,
	phi_nodes_ptr, phi_ssa_name_p): Move to gimple.h.
	(set_phi_nodes): Move to tree-phinodes.h.
	* tree-ssa-operands.h (enum ssa_op_iter_type,
	struct ssa_operand_iterator_d, SSA_OP*, FOR_EACH_SSA*, SINGLE_SSA*,
	ZERO_SSA_OPERANDS, NUM_SSA_OPERANDS): Move to ssa-iterators.h.
	(dump_decl_set): Remove prototype.
	(get_use_from_ptr, get_def_from_ptr): Relocate from tree-flow.h.
	* tree-phinodes.h: New file.  Move some prototypes from tree-flow.h.
	(set_phi_nodes): Relocate from tree-flow-inline.h.
	(gimple_phi_arg_imm_use_ptr, phi_arg_index_from_use): Relocate from
	tree-flow-inline.h
	* tree-ssa.h: Add tree-phinodes.h, gimple-ssa.h, ssa-iterators.h to
	include list.  Temporarily add gimple.h to include list.
	* ssa-iterators.h: New file.
	(struct immediate_use_iterator_d, FOR_EACH_IMM_*,
	BREAK_FROM_IMM_USE_STMT): Relocate from tree-flow.h.
	(enum ssa_op_iter_type, struct ssa_operand_iterator_d, SSA_OP*,
	FOR_EACH_SSA*, SINGLE_SSA*, ZERO_SSA_OPERANDS, NUM_SSA_OPERANDS):
	Relocate from tree-ssa-operands.h.
	(delink_imm_use, link_imm_use_to_list, link_imm_use,
	set_ssa_use_from_ptr, link_imm_use_stmt, relink_imm_use,
	relink_imm_use_stmt, end_readonly_imm_use_p, first_readonly_imm_use,
	next_readonly_imm_use, has_zero_uses, has_single_use, single_imm_use,
	num_imm_uses, get_use_from_ptr, get_def_from_ptr,
	phi_arg_index_from_use, op_iter_done, op_iter_next_def,
	op_iter_next_tree, clear_and_done_ssa_iter, op_iter_init,
	op_iter_init_use, op_iter_init_def, op_iter_init_tree,
	single_ssa_tree_operand, single_ssa_use_operand, single_ssa_def_operand,
	zero_ssa_operands, num_ssa_operands, delink_stmt_imm_use,
	single_phi_def, op_iter_init_phiuse, op_iter_init_phidef,
	end_imm_use_stmt_p, end_imm_use_stmt_traverse, move_use_after_head,
	link_use_stmts_after, first_imm_use_stmt, next_imm_use_stmt,
	first_imm_use_on_stmt, end_imm_use_on_stmt_p, next_imm_use_on_stmt):
	Relocate from tree-flow-inline.h.
	* tree-outof-ssa.h: Change _SSAEXPAND_H macro to GCC_TREE_OUTOF_SSA_H.

From-SVN: r203068
parent 70b50ed7
2013-10-01 Andrew MacLeod <amacleod@redhat.com>
* tree-into-ssa.c (enum need_phi_state): Relocate from tree-flow.h.
(dump_decl_set): Move to gimple.c.
* gimple.h: Don't include tree-ssa-operands.h.
(dump_decl_set): Add prototype.
(gimple_vuse_op, gimple_vdef_op, update_stmt, update_stmt_if_modified):
Move to gimple-ssa.h.
(phi_ssa_name_p, phi_nodes, phi_nodes_ptr, gimple_phi_arg_def,
gimple_phi_arg_def_ptr, gimple_phi_arg_edge, gimple_phi_arg_location,
gimple_phi_arg_location_from_edge, gimple_phi_arg_set_location,
gimple_phi_arg_has_location): Relocate from tree-flow-inline.h
* gimple.c (walk_stmt_load_store_ops): Use gimple_phi_arg_def rather
than PHI_ARG_DEF.
(dump_decl_set): Relocate here.
* gimple-ssa.h: New file.
(gimple_vuse_op, gimple_vdef_op, update_stmt, update_stmt_if_modified):
Relocate from gimple.h.
* tree-cfg.c (has_zero_uses_1, single_imm_use_1): Move to...
* tree-ssa-operands.c (swap_ssa_operands): Rename from
swap_tree_operands and remove non-ssa path.
(has_zero_uses_1, single_imm_use_1): Relocate from tree-cfg.c.
* tree-ssa-reassoc.c (linearize_expr_tree, repropagate_negates): Use
swap_ssa_operands.
* tree-vect-loop.c (destroy_loop_vec_info, vect_is_slp_reduction,
vect_is_simple_reduction_1): Use swap_ssa_operands.
* tree-flow.h: Move various prototypes to tree-phinodes.h.
(enum need_phi_state): Move to tree-into-ssa.c.
(struct immediate_use_iterator_d, FOR_EACH_IMM_*,
BREAK_FROM_IMM_USE_STMT): Move to ssa-iterators.h.
(swap_tree_operands): Rename and move prototype to tree-ssa-operands.h.
* tree-flow-inline.h (delink_imm_use, link_imm_use_to_list,
link_imm_use, set_ssa_use_from_ptr, link_imm_use_stmt, relink_imm_use,
relink_imm_use_stmt, end_readonly_imm_use_p, first_readonly_imm_use,
next_readonly_imm_use, has_zero_uses, has_single_use, single_imm_use,
num_imm_uses): Move to ssa-iterators.h.
(get_use_from_ptr, get_def_from_ptr): Move to tree-ssa-operands.h
(gimple_phi_arg_imm_use_ptr, phi_arg_index_from_use): Move to
tree-phinodes.h.
(op_iter_done, op_iter_next_def, op_iter_next_tree,
clear_and_done_ssa_iter, op_iter_init, op_iter_init_use,
op_iter_init_def, op_iter_init_tree, single_ssa_tree_operand,
single_ssa_use_operand, single_ssa_def_operand, zero_ssa_operands,
num_ssa_operands, delink_stmt_imm_use, single_phi_def,
op_iter_init_phiuse, op_iter_init_phidef, end_imm_use_stmt_p,
end_imm_use_stmt_traverse, move_use_after_head, link_use_stmts_after,
first_imm_use_stmt, next_imm_use_stmt, first_imm_use_on_stmt,
end_imm_use_on_stmt_p, next_imm_use_on_stmt): Move to ssa-iterators.h.
(gimple_phi_arg_def, gimple_phi_arg_def_ptr, gimple_phi_arg_edge,
gimple_phi_arg_location, gimple_phi_arg_location_from_edge,
gimple_phi_arg_set_location, gimple_phi_arg_has_location, phi_nodes,
phi_nodes_ptr, phi_ssa_name_p): Move to gimple.h.
(set_phi_nodes): Move to tree-phinodes.h.
* tree-ssa-operands.h (enum ssa_op_iter_type,
struct ssa_operand_iterator_d, SSA_OP*, FOR_EACH_SSA*, SINGLE_SSA*,
ZERO_SSA_OPERANDS, NUM_SSA_OPERANDS): Move to ssa-iterators.h.
(dump_decl_set): Remove prototype.
(get_use_from_ptr, get_def_from_ptr): Relocate from tree-flow.h.
* tree-phinodes.h: New file. Move some prototypes from tree-flow.h.
(set_phi_nodes): Relocate from tree-flow-inline.h.
(gimple_phi_arg_imm_use_ptr, phi_arg_index_from_use): Relocate from
tree-flow-inline.h
* tree-ssa.h: Add tree-phinodes.h, gimple-ssa.h, ssa-iterators.h to
include list. Temporarily add gimple.h to include list.
* ssa-iterators.h: New file.
(struct immediate_use_iterator_d, FOR_EACH_IMM_*,
BREAK_FROM_IMM_USE_STMT): Relocate from tree-flow.h.
(enum ssa_op_iter_type, struct ssa_operand_iterator_d, SSA_OP*,
FOR_EACH_SSA*, SINGLE_SSA*, ZERO_SSA_OPERANDS, NUM_SSA_OPERANDS):
Relocate from tree-ssa-operands.h.
(delink_imm_use, link_imm_use_to_list, link_imm_use,
set_ssa_use_from_ptr, link_imm_use_stmt, relink_imm_use,
relink_imm_use_stmt, end_readonly_imm_use_p, first_readonly_imm_use,
next_readonly_imm_use, has_zero_uses, has_single_use, single_imm_use,
num_imm_uses, get_use_from_ptr, get_def_from_ptr,
phi_arg_index_from_use, op_iter_done, op_iter_next_def,
op_iter_next_tree, clear_and_done_ssa_iter, op_iter_init,
op_iter_init_use, op_iter_init_def, op_iter_init_tree,
single_ssa_tree_operand, single_ssa_use_operand, single_ssa_def_operand,
zero_ssa_operands, num_ssa_operands, delink_stmt_imm_use,
single_phi_def, op_iter_init_phiuse, op_iter_init_phidef,
end_imm_use_stmt_p, end_imm_use_stmt_traverse, move_use_after_head,
link_use_stmts_after, first_imm_use_stmt, next_imm_use_stmt,
first_imm_use_on_stmt, end_imm_use_on_stmt_p, next_imm_use_on_stmt):
Relocate from tree-flow-inline.h.
* tree-outof-ssa.h: Change _SSAEXPAND_H macro to GCC_TREE_OUTOF_SSA_H.
2013-10-01 Vidya Praveen <vidyapraveen@arm.com> 2013-10-01 Vidya Praveen <vidyapraveen@arm.com>
* aarch64-simd.md * aarch64-simd.md
......
/* Header file for routines that straddle the border between GIMPLE and
SSA in gimple.
Copyright (C) 2009-2013 Free Software Foundation, Inc.
This file is part of GCC.
GCC is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 3, or (at your option)
any later version.
GCC is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with GCC; see the file COPYING3. If not see
<http://www.gnu.org/licenses/>. */
#ifndef GCC_GIMPLE_SSA_H
#define GCC_GIMPLE_SSA_H
/* Return the set of VUSE operand for statement G. */
static inline use_operand_p
gimple_vuse_op (const_gimple g)
{
struct use_optype_d *ops;
if (!gimple_has_mem_ops (g))
return NULL_USE_OPERAND_P;
ops = g->gsops.opbase.use_ops;
if (ops
&& USE_OP_PTR (ops)->use == &g->gsmembase.vuse)
return USE_OP_PTR (ops);
return NULL_USE_OPERAND_P;
}
/* Return the set of VDEF operand for statement G. */
static inline def_operand_p
gimple_vdef_op (gimple g)
{
if (!gimple_has_mem_ops (g))
return NULL_DEF_OPERAND_P;
if (g->gsmembase.vdef)
return &g->gsmembase.vdef;
return NULL_DEF_OPERAND_P;
}
/* Mark statement S as modified, and update it. */
static inline void
update_stmt (gimple s)
{
if (gimple_has_ops (s))
{
gimple_set_modified (s, true);
update_stmt_operands (s);
}
}
/* Update statement S if it has been optimized. */
static inline void
update_stmt_if_modified (gimple s)
{
if (gimple_modified_p (s))
update_stmt_operands (s);
}
#endif /* GCC_GIMPLE_SSA_H */
...@@ -3923,7 +3923,7 @@ walk_stmt_load_store_addr_ops (gimple stmt, void *data, ...@@ -3923,7 +3923,7 @@ walk_stmt_load_store_addr_ops (gimple stmt, void *data,
{ {
for (i = 0; i < gimple_phi_num_args (stmt); ++i) for (i = 0; i < gimple_phi_num_args (stmt); ++i)
{ {
tree op = PHI_ARG_DEF (stmt, i); tree op = gimple_phi_arg_def (stmt, i);
if (TREE_CODE (op) == ADDR_EXPR) if (TREE_CODE (op) == ADDR_EXPR)
ret |= visit_addr (stmt, TREE_OPERAND (op, 0), data); ret |= visit_addr (stmt, TREE_OPERAND (op, 0), data);
} }
...@@ -4356,5 +4356,28 @@ types_compatible_p (tree type1, tree type2) ...@@ -4356,5 +4356,28 @@ types_compatible_p (tree type1, tree type2)
&& useless_type_conversion_p (type2, type1))); && useless_type_conversion_p (type2, type1)));
} }
/* Dump bitmap SET (assumed to contain VAR_DECLs) to FILE. */
void
dump_decl_set (FILE *file, bitmap set)
{
if (set)
{
bitmap_iterator bi;
unsigned i;
fprintf (file, "{ ");
EXECUTE_IF_SET_IN_BITMAP (set, 0, i, bi)
{
fprintf (file, "D.%u", i);
fprintf (file, " ");
}
fprintf (file, "}");
}
else
fprintf (file, "NIL");
}
#include "gt-gimple.h" #include "gt-gimple.h"
...@@ -28,7 +28,6 @@ along with GCC; see the file COPYING3. If not see ...@@ -28,7 +28,6 @@ along with GCC; see the file COPYING3. If not see
#include "ggc.h" #include "ggc.h"
#include "basic-block.h" #include "basic-block.h"
#include "tree.h" #include "tree.h"
#include "tree-ssa-operands.h"
#include "tree-ssa-alias.h" #include "tree-ssa-alias.h"
#include "internal-fn.h" #include "internal-fn.h"
...@@ -1055,6 +1054,7 @@ extern void omp_firstprivatize_variable (struct gimplify_omp_ctx *, tree); ...@@ -1055,6 +1054,7 @@ extern void omp_firstprivatize_variable (struct gimplify_omp_ctx *, tree);
extern tree gimple_boolify (tree); extern tree gimple_boolify (tree);
extern gimple_predicate rhs_predicate_for (tree); extern gimple_predicate rhs_predicate_for (tree);
extern tree canonicalize_cond_expr_cond (tree); extern tree canonicalize_cond_expr_cond (tree);
extern void dump_decl_set (FILE *, bitmap);
/* In omp-low.c. */ /* In omp-low.c. */
extern tree omp_reduction_init (tree, tree); extern tree omp_reduction_init (tree, tree);
...@@ -1462,34 +1462,6 @@ gimple_set_use_ops (gimple g, struct use_optype_d *use) ...@@ -1462,34 +1462,6 @@ gimple_set_use_ops (gimple g, struct use_optype_d *use)
} }
/* Return the set of VUSE operand for statement G. */
static inline use_operand_p
gimple_vuse_op (const_gimple g)
{
struct use_optype_d *ops;
if (!gimple_has_mem_ops (g))
return NULL_USE_OPERAND_P;
ops = g->gsops.opbase.use_ops;
if (ops
&& USE_OP_PTR (ops)->use == &g->gsmembase.vuse)
return USE_OP_PTR (ops);
return NULL_USE_OPERAND_P;
}
/* Return the set of VDEF operand for statement G. */
static inline def_operand_p
gimple_vdef_op (gimple g)
{
if (!gimple_has_mem_ops (g))
return NULL_DEF_OPERAND_P;
if (g->gsmembase.vdef)
return &g->gsmembase.vdef;
return NULL_DEF_OPERAND_P;
}
/* Return the single VUSE operand of the statement G. */ /* Return the single VUSE operand of the statement G. */
static inline tree static inline tree
...@@ -1590,27 +1562,6 @@ gimple_expr_code (const_gimple stmt) ...@@ -1590,27 +1562,6 @@ gimple_expr_code (const_gimple stmt)
} }
/* Mark statement S as modified, and update it. */
static inline void
update_stmt (gimple s)
{
if (gimple_has_ops (s))
{
gimple_set_modified (s, true);
update_stmt_operands (s);
}
}
/* Update statement S if it has been optimized. */
static inline void
update_stmt_if_modified (gimple s)
{
if (gimple_modified_p (s))
update_stmt_operands (s);
}
/* Return true if statement STMT contains volatile operands. */ /* Return true if statement STMT contains volatile operands. */
static inline bool static inline bool
...@@ -3572,6 +3523,96 @@ gimple_phi_set_arg (gimple gs, unsigned index, struct phi_arg_d * phiarg) ...@@ -3572,6 +3523,96 @@ gimple_phi_set_arg (gimple gs, unsigned index, struct phi_arg_d * phiarg)
gs->gimple_phi.args[index] = *phiarg; gs->gimple_phi.args[index] = *phiarg;
} }
/* PHI nodes should contain only ssa_names and invariants. A test
for ssa_name is definitely simpler; don't let invalid contents
slip in in the meantime. */
static inline bool
phi_ssa_name_p (const_tree t)
{
if (TREE_CODE (t) == SSA_NAME)
return true;
gcc_checking_assert (is_gimple_min_invariant (t));
return false;
}
/* Return the PHI nodes for basic block BB, or NULL if there are no
PHI nodes. */
static inline gimple_seq
phi_nodes (const_basic_block bb)
{
gcc_checking_assert (!(bb->flags & BB_RTL));
return bb->il.gimple.phi_nodes;
}
/* Return a pointer to the PHI nodes for basic block BB. */
static inline gimple_seq *
phi_nodes_ptr (basic_block bb)
{
gcc_checking_assert (!(bb->flags & BB_RTL));
return &bb->il.gimple.phi_nodes;
}
/* Return the tree operand for argument I of PHI node GS. */
static inline tree
gimple_phi_arg_def (gimple gs, size_t index)
{
return gimple_phi_arg (gs, index)->def;
}
/* Return a pointer to the tree operand for argument I of PHI node GS. */
static inline tree *
gimple_phi_arg_def_ptr (gimple gs, size_t index)
{
return &gimple_phi_arg (gs, index)->def;
}
/* Return the edge associated with argument I of phi node GS. */
static inline edge
gimple_phi_arg_edge (gimple gs, size_t i)
{
return EDGE_PRED (gimple_bb (gs), i);
}
/* Return the source location of gimple argument I of phi node GS. */
static inline source_location
gimple_phi_arg_location (gimple gs, size_t i)
{
return gimple_phi_arg (gs, i)->locus;
}
/* Return the source location of the argument on edge E of phi node GS. */
static inline source_location
gimple_phi_arg_location_from_edge (gimple gs, edge e)
{
return gimple_phi_arg (gs, e->dest_idx)->locus;
}
/* Set the source location of gimple argument I of phi node GS to LOC. */
static inline void
gimple_phi_arg_set_location (gimple gs, size_t i, source_location loc)
{
gimple_phi_arg (gs, i)->locus = loc;
}
/* Return TRUE if argument I of phi node GS has a location record. */
static inline bool
gimple_phi_arg_has_location (gimple gs, size_t i)
{
return gimple_phi_arg_location (gs, i) != UNKNOWN_LOCATION;
}
/* Return the region number for GIMPLE_RESX GS. */ /* Return the region number for GIMPLE_RESX GS. */
static inline int static inline int
......
...@@ -1516,49 +1516,6 @@ gimple_can_merge_blocks_p (basic_block a, basic_block b) ...@@ -1516,49 +1516,6 @@ gimple_can_merge_blocks_p (basic_block a, basic_block b)
return true; return true;
} }
/* Return true if the var whose chain of uses starts at PTR has no
nondebug uses. */
bool
has_zero_uses_1 (const ssa_use_operand_t *head)
{
const ssa_use_operand_t *ptr;
for (ptr = head->next; ptr != head; ptr = ptr->next)
if (!is_gimple_debug (USE_STMT (ptr)))
return false;
return true;
}
/* Return true if the var whose chain of uses starts at PTR has a
single nondebug use. Set USE_P and STMT to that single nondebug
use, if so, or to NULL otherwise. */
bool
single_imm_use_1 (const ssa_use_operand_t *head,
use_operand_p *use_p, gimple *stmt)
{
ssa_use_operand_t *ptr, *single_use = 0;
for (ptr = head->next; ptr != head; ptr = ptr->next)
if (!is_gimple_debug (USE_STMT (ptr)))
{
if (single_use)
{
single_use = NULL;
break;
}
single_use = ptr;
}
if (use_p)
*use_p = single_use;
if (stmt)
*stmt = single_use ? single_use->loc.stmt : NULL;
return !!single_use;
}
/* Replaces all uses of NAME by VAL. */ /* Replaces all uses of NAME by VAL. */
void void
......
...@@ -107,132 +107,8 @@ typedef struct ...@@ -107,132 +107,8 @@ typedef struct
!end_htab_p (&(ITER)); \ !end_htab_p (&(ITER)); \
RESULT = (TYPE) next_htab_element (&(ITER))) RESULT = (TYPE) next_htab_element (&(ITER)))
/* It is advantageous to avoid things like life analysis for variables which
do not need PHI nodes. This enum describes whether or not a particular
variable may need a PHI node. */
enum need_phi_state {
/* This is the default. If we are still in this state after finding
all the definition and use sites, then we will assume the variable
needs PHI nodes. This is probably an overly conservative assumption. */
NEED_PHI_STATE_UNKNOWN,
/* This state indicates that we have seen one or more sets of the
variable in a single basic block and that the sets dominate all
uses seen so far. If after finding all definition and use sites
we are still in this state, then the variable does not need any
PHI nodes. */
NEED_PHI_STATE_NO,
/* This state indicates that we have either seen multiple definitions of
the variable in multiple blocks, or that we encountered a use in a
block that was not dominated by the block containing the set(s) of
this variable. This variable is assumed to need PHI nodes. */
NEED_PHI_STATE_MAYBE
};
/* Immediate use lists are used to directly access all uses for an SSA
name and get pointers to the statement for each use.
The structure ssa_use_operand_d consists of PREV and NEXT pointers
to maintain the list. A USE pointer, which points to address where
the use is located and a LOC pointer which can point to the
statement where the use is located, or, in the case of the root
node, it points to the SSA name itself.
The list is anchored by an occurrence of ssa_operand_d *in* the
ssa_name node itself (named 'imm_uses'). This node is uniquely
identified by having a NULL USE pointer. and the LOC pointer
pointing back to the ssa_name node itself. This node forms the
base for a circular list, and initially this is the only node in
the list.
Fast iteration allows each use to be examined, but does not allow
any modifications to the uses or stmts.
Normal iteration allows insertion, deletion, and modification. the
iterator manages this by inserting a marker node into the list
immediately before the node currently being examined in the list.
this marker node is uniquely identified by having null stmt *and* a
null use pointer.
When iterating to the next use, the iteration routines check to see
if the node after the marker has changed. if it has, then the node
following the marker is now the next one to be visited. if not, the
marker node is moved past that node in the list (visualize it as
bumping the marker node through the list). this continues until
the marker node is moved to the original anchor position. the
marker node is then removed from the list.
If iteration is halted early, the marker node must be removed from
the list before continuing. */
typedef struct immediate_use_iterator_d
{
/* This is the current use the iterator is processing. */
ssa_use_operand_t *imm_use;
/* This marks the last use in the list (use node from SSA_NAME) */
ssa_use_operand_t *end_p;
/* This node is inserted and used to mark the end of the uses for a stmt. */
ssa_use_operand_t iter_node;
/* This is the next ssa_name to visit. IMM_USE may get removed before
the next one is traversed to, so it must be cached early. */
ssa_use_operand_t *next_imm_name;
} imm_use_iterator;
/* Use this iterator when simply looking at stmts. Adding, deleting or
modifying stmts will cause this iterator to malfunction. */
#define FOR_EACH_IMM_USE_FAST(DEST, ITER, SSAVAR) \
for ((DEST) = first_readonly_imm_use (&(ITER), (SSAVAR)); \
!end_readonly_imm_use_p (&(ITER)); \
(void) ((DEST) = next_readonly_imm_use (&(ITER))))
/* Use this iterator to visit each stmt which has a use of SSAVAR. */
#define FOR_EACH_IMM_USE_STMT(STMT, ITER, SSAVAR) \
for ((STMT) = first_imm_use_stmt (&(ITER), (SSAVAR)); \
!end_imm_use_stmt_p (&(ITER)); \
(void) ((STMT) = next_imm_use_stmt (&(ITER))))
/* Use this to terminate the FOR_EACH_IMM_USE_STMT loop early. Failure to
do so will result in leaving a iterator marker node in the immediate
use list, and nothing good will come from that. */
#define BREAK_FROM_IMM_USE_STMT(ITER) \
{ \
end_imm_use_stmt_traverse (&(ITER)); \
break; \
}
/* Use this iterator in combination with FOR_EACH_IMM_USE_STMT to
get access to each occurrence of ssavar on the stmt returned by
that iterator.. for instance:
FOR_EACH_IMM_USE_STMT (stmt, iter, var)
{
FOR_EACH_IMM_USE_ON_STMT (use_p, iter)
{
SET_USE (use_p, blah);
}
update_stmt (stmt);
} */
#define FOR_EACH_IMM_USE_ON_STMT(DEST, ITER) \
for ((DEST) = first_imm_use_on_stmt (&(ITER)); \
!end_imm_use_on_stmt_p (&(ITER)); \
(void) ((DEST) = next_imm_use_on_stmt (&(ITER))))
static inline void update_stmt (gimple);
static inline int get_lineno (const_gimple); static inline int get_lineno (const_gimple);
/* Accessors for basic block annotations. */
static inline gimple_seq phi_nodes (const_basic_block);
static inline void set_phi_nodes (basic_block, gimple_seq);
/*--------------------------------------------------------------------------- /*---------------------------------------------------------------------------
Global declarations Global declarations
---------------------------------------------------------------------------*/ ---------------------------------------------------------------------------*/
...@@ -403,17 +279,6 @@ extern bool stmt_references_abnormal_ssa_name (gimple); ...@@ -403,17 +279,6 @@ extern bool stmt_references_abnormal_ssa_name (gimple);
extern tree get_addr_base_and_unit_offset (tree, HOST_WIDE_INT *); extern tree get_addr_base_and_unit_offset (tree, HOST_WIDE_INT *);
extern void dump_enumerated_decls (FILE *, int); extern void dump_enumerated_decls (FILE *, int);
/* In tree-phinodes.c */
extern void reserve_phi_args_for_new_edge (basic_block);
extern void add_phi_node_to_bb (gimple phi, basic_block bb);
extern gimple create_phi_node (tree, basic_block);
extern void add_phi_arg (gimple, tree, edge, source_location);
extern void remove_phi_args (edge);
extern void remove_phi_node (gimple_stmt_iterator *, bool);
extern void remove_phi_nodes (basic_block);
extern void release_phi_node (gimple);
extern void phinodes_print_statistics (void);
/* In gimple-low.c */ /* In gimple-low.c */
extern void record_vars_into (tree, tree); extern void record_vars_into (tree, tree);
extern void record_vars (tree); extern void record_vars (tree);
...@@ -684,6 +549,4 @@ bool parallelized_function_p (tree); ...@@ -684,6 +549,4 @@ bool parallelized_function_p (tree);
#include "tree-flow-inline.h" #include "tree-flow-inline.h"
void swap_tree_operands (gimple, tree *, tree *);
#endif /* _TREE_FLOW_H */ #endif /* _TREE_FLOW_H */
...@@ -128,6 +128,30 @@ struct mark_def_sites_global_data ...@@ -128,6 +128,30 @@ struct mark_def_sites_global_data
bitmap kills; bitmap kills;
}; };
/* It is advantageous to avoid things like life analysis for variables which
do not need PHI nodes. This enum describes whether or not a particular
variable may need a PHI node. */
enum need_phi_state {
/* This is the default. If we are still in this state after finding
all the definition and use sites, then we will assume the variable
needs PHI nodes. This is probably an overly conservative assumption. */
NEED_PHI_STATE_UNKNOWN,
/* This state indicates that we have seen one or more sets of the
variable in a single basic block and that the sets dominate all
uses seen so far. If after finding all definition and use sites
we are still in this state, then the variable does not need any
PHI nodes. */
NEED_PHI_STATE_NO,
/* This state indicates that we have either seen multiple definitions of
the variable in multiple blocks, or that we encountered a use in a
block that was not dominated by the block containing the set(s) of
this variable. This variable is assumed to need PHI nodes. */
NEED_PHI_STATE_MAYBE
};
/* Information stored for both SSA names and decls. */ /* Information stored for both SSA names and decls. */
struct common_info_d struct common_info_d
{ {
...@@ -1494,31 +1518,6 @@ rewrite_dom_walker::after_dom_children (basic_block bb ATTRIBUTE_UNUSED) ...@@ -1494,31 +1518,6 @@ rewrite_dom_walker::after_dom_children (basic_block bb ATTRIBUTE_UNUSED)
/* Dump bitmap SET (assumed to contain VAR_DECLs) to FILE. */ /* Dump bitmap SET (assumed to contain VAR_DECLs) to FILE. */
void
dump_decl_set (FILE *file, bitmap set)
{
if (set)
{
bitmap_iterator bi;
unsigned i;
fprintf (file, "{ ");
EXECUTE_IF_SET_IN_BITMAP (set, 0, i, bi)
{
fprintf (file, "D.%u", i);
fprintf (file, " ");
}
fprintf (file, "}");
}
else
fprintf (file, "NIL");
}
/* Dump bitmap SET (assumed to contain VAR_DECLs) to FILE. */
DEBUG_FUNCTION void DEBUG_FUNCTION void
debug_decl_set (bitmap set) debug_decl_set (bitmap set)
{ {
......
...@@ -18,8 +18,8 @@ along with GCC; see the file COPYING3. If not see ...@@ -18,8 +18,8 @@ along with GCC; see the file COPYING3. If not see
<http://www.gnu.org/licenses/>. */ <http://www.gnu.org/licenses/>. */
#ifndef _SSAEXPAND_H #ifndef GCC_TREE_OUTOF_SSA_H
#define _SSAEXPAND_H 1 #define GCC_TREE_OUTOF_SSA_H
#include "tree-ssa-live.h" #include "tree-ssa-live.h"
#include "tree-ssa-ter.h" #include "tree-ssa-ter.h"
...@@ -77,4 +77,4 @@ extern void finish_out_of_ssa (struct ssaexpand *sa); ...@@ -77,4 +77,4 @@ extern void finish_out_of_ssa (struct ssaexpand *sa);
extern unsigned int rewrite_out_of_ssa (struct ssaexpand *sa); extern unsigned int rewrite_out_of_ssa (struct ssaexpand *sa);
extern void expand_phi_nodes (struct ssaexpand *sa); extern void expand_phi_nodes (struct ssaexpand *sa);
#endif #endif /* GCC_TREE_OUTOF_SSA_H */
/* Header file for PHI node routines
Copyright (C) 2013 Free Software Foundation, Inc.
This file is part of GCC.
GCC is free software; you can redistribute it and/or modify it under
the terms of the GNU General Public License as published by the Free
Software Foundation; either version 3, or (at your option) any later
version.
GCC is distributed in the hope that it will be useful, but WITHOUT ANY
WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
for more details.
You should have received a copy of the GNU General Public License
along with GCC; see the file COPYING3. If not see
<http://www.gnu.org/licenses/>. */
#ifndef GCC_TREE_PHINODES_H
#define GCC_TREE_PHINODES_H
extern void phinodes_print_statistics (void);
extern void release_phi_node (gimple);
extern void reserve_phi_args_for_new_edge (basic_block);
extern void add_phi_node_to_bb (gimple phi, basic_block bb);
extern gimple create_phi_node (tree, basic_block);
extern void add_phi_arg (gimple, tree, edge, source_location);
extern void remove_phi_args (edge);
extern void remove_phi_node (gimple_stmt_iterator *, bool);
extern void remove_phi_nodes (basic_block);
/* Return a use_operand_p pointer for argument I of PHI node GS. */
/* Set PHI nodes of a basic block BB to SEQ. */
static inline void
set_phi_nodes (basic_block bb, gimple_seq seq)
{
gimple_stmt_iterator i;
gcc_checking_assert (!(bb->flags & BB_RTL));
bb->il.gimple.phi_nodes = seq;
if (seq)
for (i = gsi_start (seq); !gsi_end_p (i); gsi_next (&i))
gimple_set_bb (gsi_stmt (i), bb);
}
static inline use_operand_p
gimple_phi_arg_imm_use_ptr (gimple gs, int i)
{
return &gimple_phi_arg (gs, i)->imm_use;
}
/* Return the phi argument which contains the specified use. */
static inline int
phi_arg_index_from_use (use_operand_p use)
{
struct phi_arg_d *element, *root;
size_t index;
gimple phi;
/* Since the use is the first thing in a PHI argument element, we can
calculate its index based on casting it to an argument, and performing
pointer arithmetic. */
phi = USE_STMT (use);
element = (struct phi_arg_d *)use;
root = gimple_phi_arg (phi, 0);
index = element - root;
/* Make sure the calculation doesn't have any leftover bytes. If it does,
then imm_use is likely not the first element in phi_arg_d. */
gcc_checking_assert ((((char *)element - (char *)root)
% sizeof (struct phi_arg_d)) == 0
&& index < gimple_phi_capacity (phi));
return index;
}
#endif /* GCC_TREE_PHINODES_H */
...@@ -1092,18 +1092,19 @@ update_stmt_operands (gimple stmt) ...@@ -1092,18 +1092,19 @@ update_stmt_operands (gimple stmt)
to test the validity of the swap operation. */ to test the validity of the swap operation. */
void void
swap_tree_operands (gimple stmt, tree *exp0, tree *exp1) swap_ssa_operands (gimple stmt, tree *exp0, tree *exp1)
{ {
tree op0, op1; tree op0, op1;
op0 = *exp0; op0 = *exp0;
op1 = *exp1; op1 = *exp1;
/* If the operand cache is active, attempt to preserve the relative gcc_checking_assert (ssa_operands_active (cfun));
positions of these two operands in their respective immediate use
lists by adjusting their use pointer to point to the new if (op0 != op1)
operand position. */
if (ssa_operands_active (cfun) && op0 != op1)
{ {
/* Attempt to preserve the relative positions of these two operands in
their * respective immediate use lists by adjusting their use pointer
to point to the new operand position. */
use_optype_p use0, use1, ptr; use_optype_p use0, use1, ptr;
use0 = use1 = NULL; use0 = use1 = NULL;
...@@ -1128,11 +1129,11 @@ swap_tree_operands (gimple stmt, tree *exp0, tree *exp1) ...@@ -1128,11 +1129,11 @@ swap_tree_operands (gimple stmt, tree *exp0, tree *exp1)
USE_OP_PTR (use0)->use = exp1; USE_OP_PTR (use0)->use = exp1;
if (use1) if (use1)
USE_OP_PTR (use1)->use = exp0; USE_OP_PTR (use1)->use = exp0;
}
/* Now swap the data. */ /* Now swap the data. */
*exp0 = op1; *exp0 = op1;
*exp1 = op0; *exp1 = op0;
}
} }
...@@ -1322,3 +1323,47 @@ unlink_stmt_vdef (gimple stmt) ...@@ -1322,3 +1323,47 @@ unlink_stmt_vdef (gimple stmt)
SSA_NAME_OCCURS_IN_ABNORMAL_PHI (vuse) = 1; SSA_NAME_OCCURS_IN_ABNORMAL_PHI (vuse) = 1;
} }
/* Return true if the var whose chain of uses starts at PTR has no
nondebug uses. */
bool
has_zero_uses_1 (const ssa_use_operand_t *head)
{
const ssa_use_operand_t *ptr;
for (ptr = head->next; ptr != head; ptr = ptr->next)
if (!is_gimple_debug (USE_STMT (ptr)))
return false;
return true;
}
/* Return true if the var whose chain of uses starts at PTR has a
single nondebug use. Set USE_P and STMT to that single nondebug
use, if so, or to NULL otherwise. */
bool
single_imm_use_1 (const ssa_use_operand_t *head,
use_operand_p *use_p, gimple *stmt)
{
ssa_use_operand_t *ptr, *single_use = 0;
for (ptr = head->next; ptr != head; ptr = ptr->next)
if (!is_gimple_debug (USE_STMT (ptr)))
{
if (single_use)
{
single_use = NULL;
break;
}
single_use = ptr;
}
if (use_p)
*use_p = single_use;
if (stmt)
*stmt = single_use ? single_use->loc.stmt : NULL;
return single_use;
}
...@@ -75,9 +75,11 @@ struct GTY(()) ssa_operands { ...@@ -75,9 +75,11 @@ struct GTY(()) ssa_operands {
#define PHI_RESULT_PTR(PHI) gimple_phi_result_ptr (PHI) #define PHI_RESULT_PTR(PHI) gimple_phi_result_ptr (PHI)
#define PHI_RESULT(PHI) DEF_FROM_PTR (PHI_RESULT_PTR (PHI)) #define PHI_RESULT(PHI) DEF_FROM_PTR (PHI_RESULT_PTR (PHI))
#define SET_PHI_RESULT(PHI, V) SET_DEF (PHI_RESULT_PTR (PHI), (V)) #define SET_PHI_RESULT(PHI, V) SET_DEF (PHI_RESULT_PTR (PHI), (V))
/*
#define PHI_ARG_DEF_PTR(PHI, I) gimple_phi_arg_imm_use_ptr ((PHI), (I))
#define PHI_ARG_DEF(PHI, I) USE_FROM_PTR (PHI_ARG_DEF_PTR ((PHI), (I))) #define PHI_ARG_DEF(PHI, I) USE_FROM_PTR (PHI_ARG_DEF_PTR ((PHI), (I)))
*/
#define PHI_ARG_DEF_PTR(PHI, I) gimple_phi_arg_imm_use_ptr ((PHI), (I))
#define PHI_ARG_DEF(PHI, I) gimple_phi_arg_def ((PHI), (I))
#define SET_PHI_ARG_DEF(PHI, I, V) \ #define SET_PHI_ARG_DEF(PHI, I, V) \
SET_USE (PHI_ARG_DEF_PTR ((PHI), (I)), (V)) SET_USE (PHI_ARG_DEF_PTR ((PHI), (I)), (V))
#define PHI_ARG_DEF_FROM_EDGE(PHI, E) \ #define PHI_ARG_DEF_FROM_EDGE(PHI, E) \
...@@ -87,136 +89,35 @@ struct GTY(()) ssa_operands { ...@@ -87,136 +89,35 @@ struct GTY(()) ssa_operands {
#define PHI_ARG_INDEX_FROM_USE(USE) phi_arg_index_from_use (USE) #define PHI_ARG_INDEX_FROM_USE(USE) phi_arg_index_from_use (USE)
extern bool ssa_operands_active (struct function *);
extern void init_ssa_operands (struct function *fn); extern void init_ssa_operands (struct function *fn);
extern void fini_ssa_operands (void); extern void fini_ssa_operands (void);
extern void update_stmt_operands (gimple); extern bool verify_ssa_operands (gimple stmt);
extern void free_stmt_operands (gimple); extern void free_stmt_operands (gimple);
extern void update_stmt_operands (gimple);
extern void swap_ssa_operands (gimple, tree *, tree *);
extern bool verify_imm_links (FILE *f, tree var); extern bool verify_imm_links (FILE *f, tree var);
extern bool verify_ssa_operands (gimple stmt);
extern void dump_immediate_uses (FILE *file);
extern void dump_immediate_uses_for (FILE *file, tree var); extern void dump_immediate_uses_for (FILE *file, tree var);
extern void dump_immediate_uses (FILE *file);
extern void debug_immediate_uses (void); extern void debug_immediate_uses (void);
extern void debug_immediate_uses_for (tree var); extern void debug_immediate_uses_for (tree var);
extern void dump_decl_set (FILE *, bitmap);
extern void debug_decl_set (bitmap);
extern bool ssa_operands_active (struct function *);
extern bool virtual_operand_p (tree); extern bool virtual_operand_p (tree);
extern void unlink_stmt_vdef (gimple); extern void unlink_stmt_vdef (gimple);
enum ssa_op_iter_type { /* Return the tree pointed-to by USE. */
ssa_op_iter_none = 0, static inline tree
ssa_op_iter_tree, get_use_from_ptr (use_operand_p use)
ssa_op_iter_use, {
ssa_op_iter_def return *(use->use);
}; }
/* This structure is used in the operand iterator loops. It contains the
items required to determine which operand is retrieved next. During
optimization, this structure is scalarized, and any unused fields are
optimized away, resulting in little overhead. */
typedef struct ssa_operand_iterator_d /* Return the tree pointed-to by DEF. */
static inline tree
get_def_from_ptr (def_operand_p def)
{ {
enum ssa_op_iter_type iter_type; return *def;
bool done; }
int flags;
unsigned i;
unsigned numops;
use_optype_p uses;
gimple stmt;
} ssa_op_iter;
/* These flags are used to determine which operands are returned during
execution of the loop. */
#define SSA_OP_USE 0x01 /* Real USE operands. */
#define SSA_OP_DEF 0x02 /* Real DEF operands. */
#define SSA_OP_VUSE 0x04 /* VUSE operands. */
#define SSA_OP_VDEF 0x08 /* VDEF operands. */
/* These are commonly grouped operand flags. */
#define SSA_OP_VIRTUAL_USES (SSA_OP_VUSE)
#define SSA_OP_VIRTUAL_DEFS (SSA_OP_VDEF)
#define SSA_OP_ALL_VIRTUALS (SSA_OP_VIRTUAL_USES | SSA_OP_VIRTUAL_DEFS)
#define SSA_OP_ALL_USES (SSA_OP_VIRTUAL_USES | SSA_OP_USE)
#define SSA_OP_ALL_DEFS (SSA_OP_VIRTUAL_DEFS | SSA_OP_DEF)
#define SSA_OP_ALL_OPERANDS (SSA_OP_ALL_USES | SSA_OP_ALL_DEFS)
/* This macro executes a loop over the operands of STMT specified in FLAG,
returning each operand as a 'tree' in the variable TREEVAR. ITER is an
ssa_op_iter structure used to control the loop. */
#define FOR_EACH_SSA_TREE_OPERAND(TREEVAR, STMT, ITER, FLAGS) \
for (TREEVAR = op_iter_init_tree (&(ITER), STMT, FLAGS); \
!op_iter_done (&(ITER)); \
(void) (TREEVAR = op_iter_next_tree (&(ITER))))
/* This macro executes a loop over the operands of STMT specified in FLAG,
returning each operand as a 'use_operand_p' in the variable USEVAR.
ITER is an ssa_op_iter structure used to control the loop. */
#define FOR_EACH_SSA_USE_OPERAND(USEVAR, STMT, ITER, FLAGS) \
for (USEVAR = op_iter_init_use (&(ITER), STMT, FLAGS); \
!op_iter_done (&(ITER)); \
USEVAR = op_iter_next_use (&(ITER)))
/* This macro executes a loop over the operands of STMT specified in FLAG,
returning each operand as a 'def_operand_p' in the variable DEFVAR.
ITER is an ssa_op_iter structure used to control the loop. */
#define FOR_EACH_SSA_DEF_OPERAND(DEFVAR, STMT, ITER, FLAGS) \
for (DEFVAR = op_iter_init_def (&(ITER), STMT, FLAGS); \
!op_iter_done (&(ITER)); \
DEFVAR = op_iter_next_def (&(ITER)))
/* This macro will execute a loop over all the arguments of a PHI which
match FLAGS. A use_operand_p is always returned via USEVAR. FLAGS
can be either SSA_OP_USE or SSA_OP_VIRTUAL_USES or SSA_OP_ALL_USES. */
#define FOR_EACH_PHI_ARG(USEVAR, STMT, ITER, FLAGS) \
for ((USEVAR) = op_iter_init_phiuse (&(ITER), STMT, FLAGS); \
!op_iter_done (&(ITER)); \
(USEVAR) = op_iter_next_use (&(ITER)))
/* This macro will execute a loop over a stmt, regardless of whether it is
a real stmt or a PHI node, looking at the USE nodes matching FLAGS. */
#define FOR_EACH_PHI_OR_STMT_USE(USEVAR, STMT, ITER, FLAGS) \
for ((USEVAR) = (gimple_code (STMT) == GIMPLE_PHI \
? op_iter_init_phiuse (&(ITER), STMT, FLAGS) \
: op_iter_init_use (&(ITER), STMT, FLAGS)); \
!op_iter_done (&(ITER)); \
(USEVAR) = op_iter_next_use (&(ITER)))
/* This macro will execute a loop over a stmt, regardless of whether it is
a real stmt or a PHI node, looking at the DEF nodes matching FLAGS. */
#define FOR_EACH_PHI_OR_STMT_DEF(DEFVAR, STMT, ITER, FLAGS) \
for ((DEFVAR) = (gimple_code (STMT) == GIMPLE_PHI \
? op_iter_init_phidef (&(ITER), STMT, FLAGS) \
: op_iter_init_def (&(ITER), STMT, FLAGS)); \
!op_iter_done (&(ITER)); \
(DEFVAR) = op_iter_next_def (&(ITER)))
/* This macro returns an operand in STMT as a tree if it is the ONLY
operand matching FLAGS. If there are 0 or more than 1 operand matching
FLAGS, then NULL_TREE is returned. */
#define SINGLE_SSA_TREE_OPERAND(STMT, FLAGS) \
single_ssa_tree_operand (STMT, FLAGS)
/* This macro returns an operand in STMT as a use_operand_p if it is the ONLY
operand matching FLAGS. If there are 0 or more than 1 operand matching
FLAGS, then NULL_USE_OPERAND_P is returned. */
#define SINGLE_SSA_USE_OPERAND(STMT, FLAGS) \
single_ssa_use_operand (STMT, FLAGS)
/* This macro returns an operand in STMT as a def_operand_p if it is the ONLY
operand matching FLAGS. If there are 0 or more than 1 operand matching
FLAGS, then NULL_DEF_OPERAND_P is returned. */
#define SINGLE_SSA_DEF_OPERAND(STMT, FLAGS) \
single_ssa_def_operand (STMT, FLAGS)
/* This macro returns TRUE if there are no operands matching FLAGS in STMT. */
#define ZERO_SSA_OPERANDS(STMT, FLAGS) zero_ssa_operands (STMT, FLAGS)
/* This macro counts the number of operands in STMT matching FLAGS. */
#define NUM_SSA_OPERANDS(STMT, FLAGS) num_ssa_operands (STMT, FLAGS)
#endif /* GCC_TREE_SSA_OPERANDS_H */ #endif /* GCC_TREE_SSA_OPERANDS_H */
...@@ -3580,9 +3580,9 @@ linearize_expr_tree (vec<operand_entry_t> *ops, gimple stmt, ...@@ -3580,9 +3580,9 @@ linearize_expr_tree (vec<operand_entry_t> *ops, gimple stmt,
print_gimple_stmt (dump_file, stmt, 0, 0); print_gimple_stmt (dump_file, stmt, 0, 0);
} }
swap_tree_operands (stmt, swap_ssa_operands (stmt,
gimple_assign_rhs1_ptr (stmt), gimple_assign_rhs1_ptr (stmt),
gimple_assign_rhs2_ptr (stmt)); gimple_assign_rhs2_ptr (stmt));
update_stmt (stmt); update_stmt (stmt);
if (dump_file && (dump_flags & TDF_DETAILS)) if (dump_file && (dump_flags & TDF_DETAILS))
...@@ -3649,9 +3649,9 @@ repropagate_negates (void) ...@@ -3649,9 +3649,9 @@ repropagate_negates (void)
to force the negated operand to the RHS of the PLUS_EXPR. */ to force the negated operand to the RHS of the PLUS_EXPR. */
if (gimple_assign_rhs1 (user) == negate) if (gimple_assign_rhs1 (user) == negate)
{ {
swap_tree_operands (user, swap_ssa_operands (user,
gimple_assign_rhs1_ptr (user), gimple_assign_rhs1_ptr (user),
gimple_assign_rhs2_ptr (user)); gimple_assign_rhs2_ptr (user));
} }
/* Now transform the PLUS_EXPR into a MINUS_EXPR and replace /* Now transform the PLUS_EXPR into a MINUS_EXPR and replace
......
...@@ -20,8 +20,13 @@ along with GCC; see the file COPYING3. If not see ...@@ -20,8 +20,13 @@ along with GCC; see the file COPYING3. If not see
#ifndef GCC_TREE_SSA_H #ifndef GCC_TREE_SSA_H
#define GCC_TREE_SSA_H #define GCC_TREE_SSA_H
#include "tree-flow.h" #include "gimple.h"
#include "tree-ssa-operands.h"
#include "tree-phinodes.h"
#include "gimple-ssa.h"
#include "ssa-iterators.h"
#include "tree-ssanames.h" #include "tree-ssanames.h"
#include "tree-flow.h"
/* Mapping for redirected edges. */ /* Mapping for redirected edges. */
struct _edge_var_map { struct _edge_var_map {
......
...@@ -967,9 +967,9 @@ destroy_loop_vec_info (loop_vec_info loop_vinfo, bool clean_stmts) ...@@ -967,9 +967,9 @@ destroy_loop_vec_info (loop_vec_info loop_vinfo, bool clean_stmts)
|| code == POINTER_PLUS_EXPR || code == POINTER_PLUS_EXPR
|| code == MULT_EXPR) || code == MULT_EXPR)
&& CONSTANT_CLASS_P (gimple_assign_rhs1 (stmt))) && CONSTANT_CLASS_P (gimple_assign_rhs1 (stmt)))
swap_tree_operands (stmt, swap_ssa_operands (stmt,
gimple_assign_rhs1_ptr (stmt), gimple_assign_rhs1_ptr (stmt),
gimple_assign_rhs2_ptr (stmt)); gimple_assign_rhs2_ptr (stmt));
} }
/* Free stmt_vec_info. */ /* Free stmt_vec_info. */
...@@ -2056,9 +2056,9 @@ vect_is_slp_reduction (loop_vec_info loop_info, gimple phi, gimple first_stmt) ...@@ -2056,9 +2056,9 @@ vect_is_slp_reduction (loop_vec_info loop_info, gimple phi, gimple first_stmt)
dump_printf (MSG_NOTE, "\n"); dump_printf (MSG_NOTE, "\n");
} }
swap_tree_operands (next_stmt, swap_ssa_operands (next_stmt,
gimple_assign_rhs1_ptr (next_stmt), gimple_assign_rhs1_ptr (next_stmt),
gimple_assign_rhs2_ptr (next_stmt)); gimple_assign_rhs2_ptr (next_stmt));
update_stmt (next_stmt); update_stmt (next_stmt);
if (CONSTANT_CLASS_P (gimple_assign_rhs1 (next_stmt))) if (CONSTANT_CLASS_P (gimple_assign_rhs1 (next_stmt)))
...@@ -2488,8 +2488,8 @@ vect_is_simple_reduction_1 (loop_vec_info loop_info, gimple phi, ...@@ -2488,8 +2488,8 @@ vect_is_simple_reduction_1 (loop_vec_info loop_info, gimple phi,
report_vect_op (MSG_NOTE, def_stmt, report_vect_op (MSG_NOTE, def_stmt,
"detected reduction: need to swap operands: "); "detected reduction: need to swap operands: ");
swap_tree_operands (def_stmt, gimple_assign_rhs1_ptr (def_stmt), swap_ssa_operands (def_stmt, gimple_assign_rhs1_ptr (def_stmt),
gimple_assign_rhs2_ptr (def_stmt)); gimple_assign_rhs2_ptr (def_stmt));
if (CONSTANT_CLASS_P (gimple_assign_rhs1 (def_stmt))) if (CONSTANT_CLASS_P (gimple_assign_rhs1 (def_stmt)))
LOOP_VINFO_OPERANDS_SWAPPED (loop_info) = true; LOOP_VINFO_OPERANDS_SWAPPED (loop_info) = true;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment