* doc/tree-ssa.texi: Remove references to VDEF and add descriptions of V_MAY_DEF and V_MUST_DEF. * tree-dfa.c (dfa_stats_d): Add num_v_must_defs and rename num_vdefs to num_v_may_defs. (compute_immediate_uses_for_stmt): Rename occurences of vdef to v_may_def. (redirect_immediate_uses): Ditto. (dump_dfa_stats): Ditto. Also added code to dump num_v_must_defs. (collect_dfa_stats_r): Rename occurences of vdef to v_may_def. Also add code to sum up the number of v_must_defs. (vdefs_disappeared_p): Replace with... (v_may_defs_disappeared_p): This. (v_must_defs_disappeared_p): New function. (mark_new_vars_to_rename): Rename occurences of vdef to v_may_def. Also add code to mark new variables found in V_MUST_DEFs for renameing. * tree-flow.h (stmt_ann_d): Add v_must_def_ops and replace vdef_ops to v_may_def_ops. (get_vdef_ops): Replace with... (get_v_may_def_ops): This. * tree-flow-inline.h (get_vdef_ops): Replace with... (get_v_may_def_ops): This. (get_v_must_def_ops): New function. (get_vdef_result_ptr): Replace with... (get_v_may_def_result_ptr): This. (get_vdef_op_ptr): Ditto with... (get_v_may_def_op_ptr); This. (get_v_must_def_op_ptr): New function. * tree-into-ssa.c (mark_def_sites): Rename occurences of vdef to v_may_def. Also add code to mark statements with V_MUST_DEFs as definition sites. (rewrite_stmt): Rename occurences of vdef to v_may_def. Also add code to register new V_MUST_DEFs made by the statement. * tree-outof-ssa.c (VIRTUAL_PARTITION): Update comments. (check_replaceable): Rename occurences of vdef to v_may_def. Also add check for V_MUST_DEFs. (find_replaceable_in_bb): Ditto. * tree-pretty-print.c (dump_vops): Rename occurences of vdef to v_may_def. Also add code to dump V_MUST_DEFs. * tree-sra.c (mark_all_vdefs): Replace with... (mark_all_v_may_defs): This. (mark_all_v_must_defs): New function. (create_scalar_copies): Replace call to mark_all_vdefs with calls to mark_all_v_may_defs and mark_all_v_must_defs. (scalarize_structures): Rename occurences of vdef to v_may_def. Also add a check for V_MUST_DEFs. (scalarize_modify_expr): Rename occurences of vdef to v_may_def. * tree-ssa-alias.c (global_var): Update comment. (compute_may_aliases): Ditto. (compute_points_to_and_addr_escape): Rename occurences of vdef to v_may_def. Also add code to mark variables in V_MUST_DEF operands as being written to. (group_aliases): Update comment. (maybe_create_global_var): Ditto. * tree-ssa.c (verify_ssa): Rename occurences of vdef to v_may_def. Also add a check for V_MUST_DEFs on GIMPLE registers. (replace_immediate_uses): Rename occurences of vdef to v_may_def. * tree-ssa-ccp.c (visit_stmt): Rename occurences of vdef to v_may_def. Also add code to mark all V_MUST_DEF operands VARYING. (initialize): Ditto. (set_rhs): Rename occurences of vdef to v_may_def. Also add code to update SSA_NAMEs in V_MUST_DEFs. * tree-ssa-copy.c (cprop_into_stmt): Rename occurences of vdef to v_may_def. * tree-ssa-dce.c (mark_stmt_if_obviously_necessary): Rename occurences of vdef to v_may_def. Also add code to mark statements with V_MUST_DEFs as necessary. (propagate_necessity): Rename occurences of vdef to v_may_def. * tree-ssa-dom.c (redirect_edges_and_update_ssa_graph): Rename occurences of vdef to v_may_def. Also add code to mark operands in V_MUST_DEFs for renaming. (eliminate_redundant_computations): Rename occurences of vdef to v_may_def. (record_equivalences_from_stmt): Rename occurences of vdef to v_may_def. Also add code to record VUSEs for V_MUST_DEFs. (optimize_stmt): Remove unnesessary variable vdefs. Update comment. (register_definitions_for_stmt): Rename occurences of vdef to v_may_def. Also add code to register definitions made with V_MUST_DEFs. * tree-ssa-dse.c (fix_stmt_vdefs): Replace with... (fix_stmt_v_may_defs): This. (fix_phi_uses): Rename occurences of vdef to v_may_def. (dse_optimize_stmt): Ditto. * tree-ssa-live.c (create_ssa_var_map): Rename occurences of vdef to v_may_def. Also add code to mark V_MUST_DEF operands as being used in virtual operators. * tree-ssa-loop.c (mark_defs_for_rewrite): Rename occurences of vdef to v_may_def. Also add code to mark V_MUST_DEF operands for renaming. * tree-ssa-operands.c (opf_kill_def): New flag for killing definitions. (build_vdefs): Renamed to... (build_v_may_defs): This. (build_v_must_defs): New variable. (voperands_d): Add v_must_def_ops and replace vdef_ops with v_may_def_ops. (append_vdef): Replace with... (append_v_may_def): This. (append_v_must_def): New function. (NUM_FREE): Increment for V_MUST_DEF (optype_freelist): Increment its size for V_MUST_DEF (allocate_vdef_optype): Replace with... (allocate_v_may_def_optype): This. (allocate_v_must_def_optype): New function. (free_vdefs): Replace with... (free_v_may_defs): This. (free_v_must_defs): New function. (remove_vdefs): Replace with... (remove_v_may_defs): This. (remove_v_must_defs): New function. (init_ssa_operands): Rename occurences of vdef to v_may_def. Also add code to initialize build_v_must_defs. (finalize_ssa_vdefs): Replace with... (finalize_ssa_v_may_defs): This. (finalize_ssa_vuses): Rename occurences of vdef to v_may_def. (finalize_ssa_v_must_defs): New function. (finalize_ssa_stmt_operands): Replace call to finalize_ssa_vdefs with calls to finalize_ssa_v_may_defs and finalize_ssa_v_must_defs. (verify_start_operands): Rename occurences of vdef to v_may_def. Also add check for build_v_must_defs. (get_stmt_operands): Rename occurences of vdef to v_may_def. Also add code to handle V_MUST_DEFs and to use opf_kill_def for killing definitions. (get_expr_operands): Update comment and use opf_kill_def for killing definitions. (add_stmt_operand): Replace code that appends VDEFs with code that appends V_MUST_DEFs when opf_kill_def is set and V_MAY_DEFs otherwise. (add_call_clobber_ops): Update comments. * tree-ssa-operands.h (vdef_optype_d): Replace with... (v_may_def_optype_d): This. (v_must_def_optype_d): New structure. (VDEF_OPS): Replace with... (V_MAY_DEF_OPS): This. (STMT_VDEF_OPS): Same with... (STMT_V_MAY_DEF_OPS): This. (NUM_VDEFS): And... (NUM_V_MAY_DEFS): This. (VDEF_RESULT_PTR): As well as... (V_MAY_DEF_RESULT_PTR): This. (VDEF_RESULT): Same goes for... (V_MAY_DEF_RESULT): This. (VDEF_OP_PTR): And... (V_MAY_DEF_OP_PTR): This. (VDEF_OP): And... (V_MAY_DEF_OP): This. (V_MUST_DEF_OPS): New macro. (STMT_V_MUST_DEF_OPS): Ditto. (NUM_V_MUST_DEFS): Ditto. (V_MUST_DEF_OP_PTR): Ditto. (V_MUST_DEF_OP): Ditto. (remove_vdefs): Replace signature with... (remove_v_may_defs): This. (remove_v_must_defs): New function signature. * tree-ssa-pre.c (subst_phis): Replace call to remove_vdefs with calls to remove_v_may_defs and remove_v_must_defs. (process_left_occs_and_kills): Rename occurences of vdef to v_may_def. Also add code that marks left occurences of operands in V_MUST_DEFs. * tree-tailcall.c (find_tail_calls): Rename occurences of vdef to v_may_def. Also add check for V_MUST_DEFs. (eliminate_tail_call):Rename occurences of vdef to v_may_def. testsuite: * gcc.dg/tree-ssa/20031015-1.c: Scan for V_MAY_DEF instead of VDEF. * gcc.dg/tree-ssa/20040517-1.c: Ditto. From-SVN: r82947
603 lines
12 KiB
C
603 lines
12 KiB
C
/* Inline functions for tree-flow.h
|
|
Copyright (C) 2001, 2003 Free Software Foundation, Inc.
|
|
Contributed by Diego Novillo <dnovillo@redhat.com>
|
|
|
|
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 2, 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 COPYING. If not, write to
|
|
the Free Software Foundation, 59 Temple Place - Suite 330,
|
|
Boston, MA 02111-1307, USA. */
|
|
|
|
#ifndef _TREE_FLOW_INLINE_H
|
|
#define _TREE_FLOW_INLINE_H 1
|
|
|
|
/* Inline functions for manipulating various data structures defined in
|
|
tree-flow.h. See tree-flow.h for documentation. */
|
|
|
|
static inline var_ann_t
|
|
var_ann (tree t)
|
|
{
|
|
#if defined ENABLE_CHECKING
|
|
if (t == NULL_TREE
|
|
|| !DECL_P (t)
|
|
|| (t->common.ann
|
|
&& t->common.ann->common.type != VAR_ANN))
|
|
abort ();
|
|
#endif
|
|
|
|
return (var_ann_t) t->common.ann;
|
|
}
|
|
|
|
static inline var_ann_t
|
|
get_var_ann (tree var)
|
|
{
|
|
var_ann_t ann = var_ann (var);
|
|
return (ann) ? ann : create_var_ann (var);
|
|
}
|
|
|
|
static inline stmt_ann_t
|
|
stmt_ann (tree t)
|
|
{
|
|
#if defined ENABLE_CHECKING
|
|
if (!is_gimple_stmt (t) && !is_essa_node (t))
|
|
abort ();
|
|
#endif
|
|
|
|
return (stmt_ann_t) t->common.ann;
|
|
}
|
|
|
|
static inline stmt_ann_t
|
|
get_stmt_ann (tree stmt)
|
|
{
|
|
stmt_ann_t ann = stmt_ann (stmt);
|
|
return (ann) ? ann : create_stmt_ann (stmt);
|
|
}
|
|
|
|
|
|
static inline enum tree_ann_type
|
|
ann_type (tree_ann ann)
|
|
{
|
|
return ann->common.type;
|
|
}
|
|
|
|
static inline basic_block
|
|
bb_for_stmt (tree t)
|
|
{
|
|
stmt_ann_t ann = stmt_ann (t);
|
|
return ann ? ann->bb : NULL;
|
|
}
|
|
|
|
static inline varray_type
|
|
may_aliases (tree var)
|
|
{
|
|
var_ann_t ann = var_ann (var);
|
|
return ann ? ann->may_aliases : NULL;
|
|
}
|
|
|
|
static inline bool
|
|
has_hidden_use (tree var)
|
|
{
|
|
var_ann_t ann = var_ann (var);
|
|
return ann ? ann->has_hidden_use : false;
|
|
}
|
|
|
|
static inline void
|
|
set_has_hidden_use (tree var)
|
|
{
|
|
var_ann_t ann = var_ann (var);
|
|
if (ann == NULL)
|
|
ann = create_var_ann (var);
|
|
ann->has_hidden_use = 1;
|
|
}
|
|
|
|
static inline int
|
|
get_lineno (tree expr)
|
|
{
|
|
if (expr == NULL_TREE)
|
|
return -1;
|
|
|
|
if (TREE_CODE (expr) == COMPOUND_EXPR)
|
|
expr = TREE_OPERAND (expr, 0);
|
|
|
|
if (! EXPR_LOCUS (expr))
|
|
return -1;
|
|
|
|
return EXPR_LINENO (expr);
|
|
}
|
|
|
|
static inline const char *
|
|
get_filename (tree expr)
|
|
{
|
|
if (expr == NULL_TREE)
|
|
return "???";
|
|
|
|
if (TREE_CODE (expr) == COMPOUND_EXPR)
|
|
expr = TREE_OPERAND (expr, 0);
|
|
|
|
if (EXPR_LOCUS (expr) && EXPR_FILENAME (expr))
|
|
return EXPR_FILENAME (expr);
|
|
else
|
|
return "???";
|
|
}
|
|
|
|
static inline void
|
|
modify_stmt (tree t)
|
|
{
|
|
stmt_ann_t ann = stmt_ann (t);
|
|
if (ann == NULL)
|
|
ann = create_stmt_ann (t);
|
|
ann->modified = 1;
|
|
}
|
|
|
|
static inline void
|
|
unmodify_stmt (tree t)
|
|
{
|
|
stmt_ann_t ann = stmt_ann (t);
|
|
if (ann == NULL)
|
|
ann = create_stmt_ann (t);
|
|
ann->modified = 0;
|
|
}
|
|
|
|
static inline bool
|
|
stmt_modified_p (tree t)
|
|
{
|
|
stmt_ann_t ann = stmt_ann (t);
|
|
|
|
/* Note that if the statement doesn't yet have an annotation, we consider it
|
|
modified. This will force the next call to get_stmt_operands to scan the
|
|
statement. */
|
|
return ann ? ann->modified : true;
|
|
}
|
|
|
|
static inline def_optype
|
|
get_def_ops (stmt_ann_t ann)
|
|
{
|
|
return ann ? ann->def_ops : NULL;
|
|
}
|
|
|
|
static inline use_optype
|
|
get_use_ops (stmt_ann_t ann)
|
|
{
|
|
return ann ? ann->use_ops : NULL;
|
|
}
|
|
|
|
static inline v_may_def_optype
|
|
get_v_may_def_ops (stmt_ann_t ann)
|
|
{
|
|
return ann ? ann->v_may_def_ops : NULL;
|
|
}
|
|
|
|
static inline vuse_optype
|
|
get_vuse_ops (stmt_ann_t ann)
|
|
{
|
|
return ann ? ann->vuse_ops : NULL;
|
|
}
|
|
|
|
static inline v_must_def_optype
|
|
get_v_must_def_ops (stmt_ann_t ann)
|
|
{
|
|
return ann ? ann->v_must_def_ops : NULL;
|
|
}
|
|
|
|
static inline tree *
|
|
get_use_op_ptr (use_optype uses, unsigned int index)
|
|
{
|
|
#ifdef ENABLE_CHECKING
|
|
if (index >= uses->num_uses)
|
|
abort();
|
|
#endif
|
|
return uses->uses[index];
|
|
}
|
|
|
|
static inline tree *
|
|
get_def_op_ptr (def_optype defs, unsigned int index)
|
|
{
|
|
#ifdef ENABLE_CHECKING
|
|
if (index >= defs->num_defs)
|
|
abort();
|
|
#endif
|
|
return defs->defs[index];
|
|
}
|
|
|
|
static inline tree *
|
|
get_v_may_def_result_ptr(v_may_def_optype v_may_defs, unsigned int index)
|
|
{
|
|
#ifdef ENABLE_CHECKING
|
|
if (index >= v_may_defs->num_v_may_defs)
|
|
abort();
|
|
#endif
|
|
return &(v_may_defs->v_may_defs[index * 2]);
|
|
}
|
|
|
|
static inline tree *
|
|
get_v_may_def_op_ptr(v_may_def_optype v_may_defs, unsigned int index)
|
|
{
|
|
#ifdef ENABLE_CHECKING
|
|
if (index >= v_may_defs->num_v_may_defs)
|
|
abort();
|
|
#endif
|
|
return &(v_may_defs->v_may_defs[index * 2 + 1]);
|
|
}
|
|
|
|
static inline tree *
|
|
get_vuse_op_ptr(vuse_optype vuses, unsigned int index)
|
|
{
|
|
#ifdef ENABLE_CHECKING
|
|
if (index >= vuses->num_vuses)
|
|
abort();
|
|
#endif
|
|
return &(vuses->vuses[index]);
|
|
}
|
|
|
|
static inline tree *
|
|
get_v_must_def_op_ptr (v_must_def_optype v_must_defs, unsigned int index)
|
|
{
|
|
#ifdef ENABLE_CHECKING
|
|
if (index >= v_must_defs->num_v_must_defs)
|
|
abort();
|
|
#endif
|
|
return &(v_must_defs->v_must_defs[index]);
|
|
}
|
|
|
|
static inline void
|
|
start_ssa_stmt_operands (tree stmt ATTRIBUTE_UNUSED)
|
|
{
|
|
#ifdef ENABLE_CHECKING
|
|
verify_start_operands (stmt);
|
|
#endif
|
|
}
|
|
|
|
static inline bitmap
|
|
addresses_taken (tree stmt)
|
|
{
|
|
stmt_ann_t ann = stmt_ann (stmt);
|
|
return ann ? ann->addresses_taken : NULL;
|
|
}
|
|
|
|
static dataflow_t
|
|
get_immediate_uses (tree stmt)
|
|
{
|
|
stmt_ann_t ann = stmt_ann (stmt);
|
|
return ann ? ann->df : NULL;
|
|
}
|
|
|
|
static inline int
|
|
num_immediate_uses (dataflow_t df)
|
|
{
|
|
varray_type imm;
|
|
|
|
if (!df)
|
|
return 0;
|
|
|
|
imm = df->immediate_uses;
|
|
if (!imm)
|
|
return df->uses[1] ? 2 : 1;
|
|
|
|
return VARRAY_ACTIVE_SIZE (imm) + 2;
|
|
}
|
|
|
|
static inline tree
|
|
immediate_use (dataflow_t df, int num)
|
|
{
|
|
if (!df)
|
|
return NULL_TREE;
|
|
|
|
#ifdef ENABLE_CHECKING
|
|
if (num >= num_immediate_uses (df))
|
|
abort ();
|
|
#endif
|
|
if (num < 2)
|
|
return df->uses[num];
|
|
return VARRAY_TREE (df->immediate_uses, num - 2);
|
|
}
|
|
|
|
static inline bb_ann_t
|
|
bb_ann (basic_block bb)
|
|
{
|
|
return (bb_ann_t)bb->tree_annotations;
|
|
}
|
|
|
|
static inline tree
|
|
phi_nodes (basic_block bb)
|
|
{
|
|
if (bb->index < 0)
|
|
return NULL;
|
|
return bb_ann (bb)->phi_nodes;
|
|
}
|
|
|
|
/* Set list of phi nodes of a basic block BB to L. */
|
|
|
|
static inline void
|
|
set_phi_nodes (basic_block bb, tree l)
|
|
{
|
|
tree phi;
|
|
|
|
bb_ann (bb)->phi_nodes = l;
|
|
for (phi = l; phi; phi = TREE_CHAIN (phi))
|
|
set_bb_for_stmt (phi, bb);
|
|
}
|
|
|
|
/* Return the phi index number for an edge. */
|
|
static inline int
|
|
phi_arg_from_edge (tree phi, edge e)
|
|
{
|
|
int i;
|
|
#if defined ENABLE_CHECKING
|
|
if (!phi || TREE_CODE (phi) != PHI_NODE)
|
|
abort();
|
|
#endif
|
|
|
|
for (i = 0; i < PHI_NUM_ARGS (phi); i++)
|
|
if (PHI_ARG_EDGE (phi, i) == e)
|
|
return i;
|
|
|
|
return -1;
|
|
}
|
|
|
|
|
|
/* Return the phi argument number for an edge. */
|
|
static inline struct phi_arg_d *
|
|
phi_element_for_edge (tree phi, edge e)
|
|
{
|
|
int i;
|
|
|
|
i = phi_arg_from_edge (phi, e);
|
|
if (i != -1)
|
|
return &(PHI_ARG_ELT (phi, i));
|
|
else
|
|
return (struct phi_arg_d *)NULL;
|
|
}
|
|
|
|
/* ----------------------------------------------------------------------- */
|
|
|
|
static inline bool
|
|
is_exec_stmt (tree t)
|
|
{
|
|
return (t && !IS_EMPTY_STMT (t) && t != error_mark_node);
|
|
}
|
|
|
|
|
|
/* Return true if this stmt can be the target of a control transfer stmt such
|
|
as a goto. */
|
|
static inline bool
|
|
is_label_stmt (tree t)
|
|
{
|
|
if (t)
|
|
switch (TREE_CODE (t))
|
|
{
|
|
case LABEL_DECL:
|
|
case LABEL_EXPR:
|
|
case CASE_LABEL_EXPR:
|
|
return true;
|
|
default:
|
|
return false;
|
|
}
|
|
return false;
|
|
}
|
|
|
|
static inline bool
|
|
may_propagate_copy (tree dest, tree orig)
|
|
{
|
|
/* FIXME. GIMPLE is allowing pointer assignments and comparisons of
|
|
pointers that have different alias sets. This means that these
|
|
pointers will have different memory tags associated to them.
|
|
|
|
If we allow copy propagation in these cases, statements de-referencing
|
|
the new pointer will now have a reference to a different memory tag
|
|
with potentially incorrect SSA information.
|
|
|
|
This was showing up in libjava/java/util/zip/ZipFile.java with code
|
|
like:
|
|
|
|
struct java.io.BufferedInputStream *T.660;
|
|
struct java.io.BufferedInputStream *T.647;
|
|
struct java.io.InputStream *is;
|
|
struct java.io.InputStream *is.662;
|
|
[ ... ]
|
|
T.660 = T.647;
|
|
is = T.660; <-- This ought to be type-casted
|
|
is.662 = is;
|
|
|
|
Also, f/name.c exposed a similar problem with a COND_EXPR predicate
|
|
that was causing DOM to generate and equivalence with two pointers of
|
|
alias-incompatible types:
|
|
|
|
struct _ffename_space *n;
|
|
struct _ffename *ns;
|
|
[ ... ]
|
|
if (n == ns)
|
|
goto lab;
|
|
...
|
|
lab:
|
|
return n;
|
|
|
|
I think that GIMPLE should emit the appropriate type-casts. For the
|
|
time being, blocking copy-propagation in these cases is the safe thing
|
|
to do. */
|
|
if (TREE_CODE (dest) == SSA_NAME
|
|
&& TREE_CODE (orig) == SSA_NAME
|
|
&& POINTER_TYPE_P (TREE_TYPE (dest))
|
|
&& POINTER_TYPE_P (TREE_TYPE (orig)))
|
|
{
|
|
tree mt_dest = var_ann (SSA_NAME_VAR (dest))->type_mem_tag;
|
|
tree mt_orig = var_ann (SSA_NAME_VAR (orig))->type_mem_tag;
|
|
if (mt_dest && mt_orig && mt_dest != mt_orig)
|
|
return false;
|
|
}
|
|
|
|
/* If the destination is a SSA_NAME for a virtual operand, then we have
|
|
some special cases to handle. */
|
|
if (TREE_CODE (dest) == SSA_NAME && !is_gimple_reg (dest))
|
|
{
|
|
/* If both operands are SSA_NAMEs referring to virtual operands, then
|
|
we can always propagate. */
|
|
if (TREE_CODE (orig) == SSA_NAME)
|
|
{
|
|
if (!is_gimple_reg (orig))
|
|
return true;
|
|
|
|
#ifdef ENABLE_CHECKING
|
|
/* If we have one real and one virtual operand, then something has
|
|
gone terribly wrong. */
|
|
if (is_gimple_reg (orig))
|
|
abort ();
|
|
#endif
|
|
}
|
|
|
|
/* We have a "copy" from something like a constant into a virtual
|
|
operand. Reject these. */
|
|
return false;
|
|
}
|
|
|
|
return (!SSA_NAME_OCCURS_IN_ABNORMAL_PHI (dest)
|
|
&& (TREE_CODE (orig) != SSA_NAME
|
|
|| !SSA_NAME_OCCURS_IN_ABNORMAL_PHI (orig))
|
|
&& !DECL_HARD_REGISTER (SSA_NAME_VAR (dest)));
|
|
}
|
|
|
|
static inline void
|
|
set_default_def (tree var, tree def)
|
|
{
|
|
var_ann_t ann = var_ann (var);
|
|
if (ann == NULL)
|
|
ann = create_var_ann (var);
|
|
ann->default_def = def;
|
|
}
|
|
|
|
static inline tree
|
|
default_def (tree var)
|
|
{
|
|
var_ann_t ann = var_ann (var);
|
|
return ann ? ann->default_def : NULL_TREE;
|
|
}
|
|
|
|
/* 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 (tree t)
|
|
{
|
|
if (TREE_CODE (t) == SSA_NAME)
|
|
return true;
|
|
#ifdef ENABLE_CHECKING
|
|
if (!is_gimple_min_invariant (t))
|
|
abort ();
|
|
#endif
|
|
return false;
|
|
}
|
|
|
|
/* ----------------------------------------------------------------------- */
|
|
|
|
static inline block_stmt_iterator
|
|
bsi_start (basic_block bb)
|
|
{
|
|
block_stmt_iterator bsi;
|
|
if (bb->stmt_list)
|
|
bsi.tsi = tsi_start (bb->stmt_list);
|
|
else
|
|
{
|
|
#ifdef ENABLE_CHECKING
|
|
if (bb->index >= 0)
|
|
abort ();
|
|
#endif
|
|
bsi.tsi.ptr = NULL;
|
|
bsi.tsi.container = NULL;
|
|
}
|
|
bsi.bb = bb;
|
|
return bsi;
|
|
}
|
|
|
|
static inline block_stmt_iterator
|
|
bsi_last (basic_block bb)
|
|
{
|
|
block_stmt_iterator bsi;
|
|
if (bb->stmt_list)
|
|
bsi.tsi = tsi_last (bb->stmt_list);
|
|
else
|
|
{
|
|
#ifdef ENABLE_CHECKING
|
|
if (bb->index >= 0)
|
|
abort ();
|
|
#endif
|
|
bsi.tsi.ptr = NULL;
|
|
bsi.tsi.container = NULL;
|
|
}
|
|
bsi.bb = bb;
|
|
return bsi;
|
|
}
|
|
|
|
static inline bool
|
|
bsi_end_p (block_stmt_iterator i)
|
|
{
|
|
return tsi_end_p (i.tsi);
|
|
}
|
|
|
|
static inline void
|
|
bsi_next (block_stmt_iterator *i)
|
|
{
|
|
tsi_next (&i->tsi);
|
|
}
|
|
|
|
static inline void
|
|
bsi_prev (block_stmt_iterator *i)
|
|
{
|
|
tsi_prev (&i->tsi);
|
|
}
|
|
|
|
static inline tree
|
|
bsi_stmt (block_stmt_iterator i)
|
|
{
|
|
return tsi_stmt (i.tsi);
|
|
}
|
|
|
|
static inline tree *
|
|
bsi_stmt_ptr (block_stmt_iterator i)
|
|
{
|
|
return tsi_stmt_ptr (i.tsi);
|
|
}
|
|
|
|
static inline bool
|
|
may_be_aliased (tree var)
|
|
{
|
|
return (TREE_ADDRESSABLE (var)
|
|
|| decl_function_context (var) != current_function_decl);
|
|
}
|
|
|
|
static inline bool
|
|
is_call_clobbered (tree var)
|
|
{
|
|
return needs_to_live_in_memory (var)
|
|
|| bitmap_bit_p (call_clobbered_vars, var_ann (var)->uid);
|
|
}
|
|
|
|
static inline void
|
|
mark_call_clobbered (tree var)
|
|
{
|
|
var_ann_t ann = var_ann (var);
|
|
/* Call-clobbered variables need to live in memory. */
|
|
DECL_NEEDS_TO_LIVE_IN_MEMORY_INTERNAL (var) = 1;
|
|
bitmap_set_bit (call_clobbered_vars, ann->uid);
|
|
}
|
|
|
|
static inline void
|
|
mark_non_addressable (tree var)
|
|
{
|
|
bitmap_clear_bit (call_clobbered_vars, var_ann (var)->uid);
|
|
DECL_NEEDS_TO_LIVE_IN_MEMORY_INTERNAL (var) = 0;
|
|
TREE_ADDRESSABLE (var) = 0;
|
|
}
|
|
|
|
#endif /* _TREE_FLOW_INLINE_H */
|