tree-ssa.c (verify_ssa): Verify SSA names in the loop over all SSA names.

2011-12-05  Richard Guenther  <rguenther@suse.de>

	* tree-ssa.c (verify_ssa): Verify SSA names in the loop
	over all SSA names.  Remove SSA operand checking, call
	verify_ssa_operands.
	* tree-ssa-operands.h (verify_ssa_operands): Declare.
	* tree-ssa-operands.c (verify_ssa_operands): New function.

From-SVN: r182007
This commit is contained in:
Richard Guenther 2011-12-05 11:05:24 +00:00 committed by Richard Biener
parent 76264f602a
commit bc590dfb1f
4 changed files with 130 additions and 83 deletions

View File

@ -1,3 +1,11 @@
2011-12-05 Richard Guenther <rguenther@suse.de>
* tree-ssa.c (verify_ssa): Verify SSA names in the loop
over all SSA names. Remove SSA operand checking, call
verify_ssa_operands.
* tree-ssa-operands.h (verify_ssa_operands): Declare.
* tree-ssa-operands.c (verify_ssa_operands): New function.
2011-12-05 Ramana Radhakrishnan <ramana.radhakrishnan@linaro.org>
* config/arm/arm.c (vfp3_const_double_for_fract_bits): Define.

View File

@ -33,7 +33,8 @@ along with GCC; see the file COPYING3. If not see
#include "ggc.h"
#include "timevar.h"
#include "langhooks.h"
#include "ipa-reference.h"
#include "diagnostic-core.h"
/* This file contains the code required to manage the operands cache of the
SSA optimizer. For every stmt, we maintain an operand cache in the stmt
@ -1081,6 +1082,118 @@ build_ssa_operands (gimple stmt)
finalize_ssa_stmt_operands (stmt);
}
/* Verifies SSA statement operands. */
DEBUG_FUNCTION bool
verify_ssa_operands (gimple stmt)
{
use_operand_p use_p;
def_operand_p def_p;
ssa_op_iter iter;
unsigned i;
tree use, def;
bool volatile_p = gimple_has_volatile_ops (stmt);
/* build_ssa_operands w/o finalizing them. */
gimple_set_has_volatile_ops (stmt, false);
start_ssa_stmt_operands ();
parse_ssa_operands (stmt);
/* Now verify the built operands are the same as present in STMT. */
def = gimple_vdef (stmt);
if (def
&& TREE_CODE (def) == SSA_NAME)
def = SSA_NAME_VAR (def);
if (build_vdef != def)
{
error ("virtual definition of statement not up-to-date");
return true;
}
if (gimple_vdef (stmt)
&& ((def_p = gimple_vdef_op (stmt)) == NULL_DEF_OPERAND_P
|| DEF_FROM_PTR (def_p) != gimple_vdef (stmt)))
{
error ("virtual def operand missing for stmt");
return true;
}
use = gimple_vuse (stmt);
if (use
&& TREE_CODE (use) == SSA_NAME)
use = SSA_NAME_VAR (use);
if (build_vuse != use)
{
error ("virtual use of statement not up-to-date");
return true;
}
if (gimple_vuse (stmt)
&& ((use_p = gimple_vuse_op (stmt)) == NULL_USE_OPERAND_P
|| USE_FROM_PTR (use_p) != gimple_vuse (stmt)))
{
error ("virtual use operand missing for stmt");
return true;
}
FOR_EACH_SSA_USE_OPERAND (use_p, stmt, iter, SSA_OP_USE)
{
FOR_EACH_VEC_ELT (tree, build_uses, i, use)
{
if (use_p->use == (tree *)use)
{
VEC_replace (tree, build_uses, i, NULL_TREE);
break;
}
}
if (i == VEC_length (tree, build_uses))
{
error ("excess use operand for stmt");
debug_generic_expr (USE_FROM_PTR (use_p));
return true;
}
}
FOR_EACH_VEC_ELT (tree, build_uses, i, use)
if (use != NULL_TREE)
{
error ("use operand missing for stmt");
debug_generic_expr (*(tree *)use);
return true;
}
FOR_EACH_SSA_DEF_OPERAND (def_p, stmt, iter, SSA_OP_DEF)
{
FOR_EACH_VEC_ELT (tree, build_defs, i, def)
{
if (def_p == (tree *)def)
{
VEC_replace (tree, build_defs, i, NULL_TREE);
break;
}
}
if (i == VEC_length (tree, build_defs))
{
error ("excess def operand for stmt");
debug_generic_expr (DEF_FROM_PTR (def_p));
return true;
}
}
FOR_EACH_VEC_ELT (tree, build_defs, i, def)
if (def != NULL_TREE)
{
error ("def operand missing for stmt");
debug_generic_expr (*(tree *)def);
return true;
}
if (gimple_has_volatile_ops (stmt) != volatile_p)
{
error ("stmt volatile flag not up-to-date");
return true;
}
cleanup_build_arrays ();
return false;
}
/* Releases the operands of STMT back to their freelists, and clears
the stmt operand lists. */

View File

@ -105,6 +105,7 @@ extern void fini_ssa_operands (void);
extern void update_stmt_operands (gimple);
extern void free_stmt_operands (gimple);
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);

View File

@ -938,6 +938,8 @@ verify_ssa (bool check_modified_stmt)
gimple stmt;
TREE_VISITED (name) = 0;
verify_ssa_name (name, !is_gimple_reg (name));
stmt = SSA_NAME_DEF_STMT (name);
if (!gimple_nop_p (stmt))
{
@ -987,9 +989,6 @@ verify_ssa (bool check_modified_stmt)
{
gimple stmt = gsi_stmt (gsi);
use_operand_p use_p;
bool has_err;
int count;
unsigned i;
if (check_modified_stmt && gimple_modified_p (stmt))
{
@ -999,89 +998,15 @@ verify_ssa (bool check_modified_stmt)
goto err;
}
if (is_gimple_assign (stmt)
&& TREE_CODE (gimple_assign_lhs (stmt)) != SSA_NAME)
if (verify_ssa_operands (stmt))
{
tree lhs, base_address;
lhs = gimple_assign_lhs (stmt);
base_address = get_base_address (lhs);
if (base_address
&& SSA_VAR_P (base_address)
&& !gimple_vdef (stmt)
&& optimize > 0)
{
error ("statement makes a memory store, but has no VDEFS");
print_gimple_stmt (stderr, stmt, 0, TDF_VOPS);
goto err;
}
}
else if (gimple_debug_bind_p (stmt)
&& !gimple_debug_bind_has_value_p (stmt))
continue;
/* Verify the single virtual operand and its constraints. */
has_err = false;
if (gimple_vdef (stmt))
{
if (gimple_vdef_op (stmt) == NULL_DEF_OPERAND_P)
{
error ("statement has VDEF operand not in defs list");
has_err = true;
}
if (!gimple_vuse (stmt))
{
error ("statement has VDEF but no VUSE operand");
has_err = true;
}
else if (SSA_NAME_VAR (gimple_vdef (stmt))
!= SSA_NAME_VAR (gimple_vuse (stmt)))
{
error ("VDEF and VUSE do not use the same symbol");
has_err = true;
}
has_err |= verify_ssa_name (gimple_vdef (stmt), true);
}
if (gimple_vuse (stmt))
{
if (gimple_vuse_op (stmt) == NULL_USE_OPERAND_P)
{
error ("statement has VUSE operand not in uses list");
has_err = true;
}
has_err |= verify_ssa_name (gimple_vuse (stmt), true);
}
if (has_err)
{
error ("in statement");
print_gimple_stmt (stderr, stmt, 0, TDF_VOPS|TDF_MEMSYMS);
print_gimple_stmt (stderr, stmt, 0, TDF_VOPS);
goto err;
}
count = 0;
FOR_EACH_SSA_TREE_OPERAND (op, stmt, iter, SSA_OP_USE|SSA_OP_DEF)
{
if (verify_ssa_name (op, false))
{
error ("in statement");
print_gimple_stmt (stderr, stmt, 0, TDF_VOPS|TDF_MEMSYMS);
goto err;
}
count++;
}
for (i = 0; i < gimple_num_ops (stmt); i++)
{
op = gimple_op (stmt, i);
if (op && TREE_CODE (op) == SSA_NAME && --count < 0)
{
error ("number of operands and imm-links don%'t agree"
" in statement");
print_gimple_stmt (stderr, stmt, 0, TDF_VOPS|TDF_MEMSYMS);
goto err;
}
}
if (gimple_debug_bind_p (stmt)
&& !gimple_debug_bind_has_value_p (stmt))
continue;
FOR_EACH_SSA_USE_OPERAND (use_p, stmt, iter, SSA_OP_USE|SSA_OP_VUSE)
{