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> 2011-12-05 Ramana Radhakrishnan <ramana.radhakrishnan@linaro.org>
* config/arm/arm.c (vfp3_const_double_for_fract_bits): Define. * 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 "ggc.h"
#include "timevar.h" #include "timevar.h"
#include "langhooks.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 /* 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 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); 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 /* Releases the operands of STMT back to their freelists, and clears
the stmt operand lists. */ the stmt operand lists. */

View File

@ -105,6 +105,7 @@ extern void fini_ssa_operands (void);
extern void update_stmt_operands (gimple); extern void update_stmt_operands (gimple);
extern void free_stmt_operands (gimple); extern void free_stmt_operands (gimple);
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 (FILE *file);
extern void dump_immediate_uses_for (FILE *file, tree var); extern void dump_immediate_uses_for (FILE *file, tree var);

View File

@ -938,6 +938,8 @@ verify_ssa (bool check_modified_stmt)
gimple stmt; gimple stmt;
TREE_VISITED (name) = 0; TREE_VISITED (name) = 0;
verify_ssa_name (name, !is_gimple_reg (name));
stmt = SSA_NAME_DEF_STMT (name); stmt = SSA_NAME_DEF_STMT (name);
if (!gimple_nop_p (stmt)) if (!gimple_nop_p (stmt))
{ {
@ -987,9 +989,6 @@ verify_ssa (bool check_modified_stmt)
{ {
gimple stmt = gsi_stmt (gsi); gimple stmt = gsi_stmt (gsi);
use_operand_p use_p; use_operand_p use_p;
bool has_err;
int count;
unsigned i;
if (check_modified_stmt && gimple_modified_p (stmt)) if (check_modified_stmt && gimple_modified_p (stmt))
{ {
@ -999,89 +998,15 @@ verify_ssa (bool check_modified_stmt)
goto err; goto err;
} }
if (is_gimple_assign (stmt) if (verify_ssa_operands (stmt))
&& TREE_CODE (gimple_assign_lhs (stmt)) != SSA_NAME)
{ {
tree lhs, base_address; print_gimple_stmt (stderr, stmt, 0, TDF_VOPS);
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);
goto err; goto err;
} }
count = 0; if (gimple_debug_bind_p (stmt)
FOR_EACH_SSA_TREE_OPERAND (op, stmt, iter, SSA_OP_USE|SSA_OP_DEF) && !gimple_debug_bind_has_value_p (stmt))
{ continue;
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;
}
}
FOR_EACH_SSA_USE_OPERAND (use_p, stmt, iter, SSA_OP_USE|SSA_OP_VUSE) FOR_EACH_SSA_USE_OPERAND (use_p, stmt, iter, SSA_OP_USE|SSA_OP_VUSE)
{ {