/* Initial capacity for the basic block array. */
static const int initial_cfg_capacity = 20;
-/* Mapping of labels to their associated blocks. This can greatly speed up
- building of the CFG in code with lots of gotos. */
-static GTY(()) varray_type label_to_block_map;
-
/* This hash table allows us to efficiently lookup all CASE_LABEL_EXPRs
which use a particular edge. The CASE_LABEL_EXPRs are chained together
via their TREE_CHAIN field, which we clear after we're done with the
/* Register specific tree functions. */
tree_register_cfg_hooks ();
- /* Initialize rbi_pool. */
- alloc_rbi_pool ();
-
/* Initialize the basic block array. */
init_flow ();
profile_status = PROFILE_ABSENT;
/* Return the basic block holding label DEST. */
basic_block
-label_to_block (tree dest)
+label_to_block_fn (struct function *ifun, tree dest)
{
int uid = LABEL_DECL_UID (dest);
bsi_insert_before (&bsi, stmt, BSI_NEW_STMT);
uid = LABEL_DECL_UID (dest);
}
- return VARRAY_BB (label_to_block_map, uid);
+ return VARRAY_BB (ifun->cfg->x_label_to_block_map, uid);
}
-
/* Create edges for a goto statement at block BB. */
static void
&& DECL_NONLOCAL (LABEL_EXPR_LABEL (stmt)))
return false;
- /* There may be no phi nodes at the start of b. Most of these degenerate
- phi nodes should be cleaned up by kill_redundant_phi_nodes. */
+ /* There may be no PHI nodes at the start of B. */
if (phi_nodes (b))
return false;
0 /* letter */
};
-
-/* Remove obviously useless statements in basic block BB. */
-
-static void
-cfg_remove_useless_stmts_bb (basic_block bb)
-{
- block_stmt_iterator bsi;
- tree stmt = NULL_TREE;
- tree cond, var = NULL_TREE, val = NULL_TREE;
- struct var_ann_d *ann;
-
- /* Check whether we come here from a condition, and if so, get the
- condition. */
- if (!single_pred_p (bb)
- || !(single_pred_edge (bb)->flags
- & (EDGE_TRUE_VALUE | EDGE_FALSE_VALUE)))
- return;
-
- cond = COND_EXPR_COND (last_stmt (single_pred (bb)));
-
- if (TREE_CODE (cond) == VAR_DECL || TREE_CODE (cond) == PARM_DECL)
- {
- var = cond;
- val = (single_pred_edge (bb)->flags & EDGE_FALSE_VALUE
- ? boolean_false_node : boolean_true_node);
- }
- else if (TREE_CODE (cond) == TRUTH_NOT_EXPR
- && (TREE_CODE (TREE_OPERAND (cond, 0)) == VAR_DECL
- || TREE_CODE (TREE_OPERAND (cond, 0)) == PARM_DECL))
- {
- var = TREE_OPERAND (cond, 0);
- val = (single_pred_edge (bb)->flags & EDGE_FALSE_VALUE
- ? boolean_true_node : boolean_false_node);
- }
- else
- {
- if (single_pred_edge (bb)->flags & EDGE_FALSE_VALUE)
- cond = invert_truthvalue (cond);
- if (TREE_CODE (cond) == EQ_EXPR
- && (TREE_CODE (TREE_OPERAND (cond, 0)) == VAR_DECL
- || TREE_CODE (TREE_OPERAND (cond, 0)) == PARM_DECL)
- && (TREE_CODE (TREE_OPERAND (cond, 1)) == VAR_DECL
- || TREE_CODE (TREE_OPERAND (cond, 1)) == PARM_DECL
- || TREE_CONSTANT (TREE_OPERAND (cond, 1))))
- {
- var = TREE_OPERAND (cond, 0);
- val = TREE_OPERAND (cond, 1);
- }
- else
- return;
- }
-
- /* Only work for normal local variables. */
- ann = var_ann (var);
- if (!ann
- || ann->may_aliases
- || TREE_ADDRESSABLE (var))
- return;
-
- if (! TREE_CONSTANT (val))
- {
- ann = var_ann (val);
- if (!ann
- || ann->may_aliases
- || TREE_ADDRESSABLE (val))
- return;
- }
-
- /* Ignore floating point variables, since comparison behaves weird for
- them. */
- if (FLOAT_TYPE_P (TREE_TYPE (var)))
- return;
-
- for (bsi = bsi_start (bb); !bsi_end_p (bsi);)
- {
- stmt = bsi_stmt (bsi);
-
- /* If the THEN/ELSE clause merely assigns a value to a variable/parameter
- which is already known to contain that value, then remove the useless
- THEN/ELSE clause. */
- if (TREE_CODE (stmt) == MODIFY_EXPR
- && TREE_OPERAND (stmt, 0) == var
- && operand_equal_p (val, TREE_OPERAND (stmt, 1), 0))
- {
- bsi_remove (&bsi);
- continue;
- }
-
- /* Invalidate the var if we encounter something that could modify it.
- Likewise for the value it was previously set to. Note that we only
- consider values that are either a VAR_DECL or PARM_DECL so we
- can test for conflict very simply. */
- if (TREE_CODE (stmt) == ASM_EXPR
- || (TREE_CODE (stmt) == MODIFY_EXPR
- && (TREE_OPERAND (stmt, 0) == var
- || TREE_OPERAND (stmt, 0) == val)))
- return;
-
- bsi_next (&bsi);
- }
-}
-
-
-/* A CFG-aware version of remove_useless_stmts. */
-
-void
-cfg_remove_useless_stmts (void)
-{
- basic_block bb;
-
-#ifdef ENABLE_CHECKING
- verify_flow_info ();
-#endif
-
- FOR_EACH_BB (bb)
- {
- cfg_remove_useless_stmts_bb (bb);
- }
-}
-
-
/* Remove PHI nodes associated with basic block BB and all edges out of BB. */
static void
{
static long max_num_merged_labels = 0;
unsigned long size, total = 0;
- int n_edges;
+ long num_edges;
basic_block bb;
const char * const fmt_str = "%-30s%-13s%12s\n";
const char * const fmt_str_1 = "%-30s%13d%11lu%c\n";
fprintf (file, fmt_str_1, "Basic blocks", n_basic_blocks,
SCALE (size), LABEL (size));
- n_edges = 0;
+ num_edges = 0;
FOR_EACH_BB (bb)
- n_edges += EDGE_COUNT (bb->succs);
- size = n_edges * sizeof (struct edge_def);
+ num_edges += EDGE_COUNT (bb->succs);
+ size = num_edges * sizeof (struct edge_def);
total += size;
- fprintf (file, fmt_str_1, "Edges", n_edges, SCALE (size), LABEL (size));
+ fprintf (file, fmt_str_1, "Edges", num_edges, SCALE (size), LABEL (size));
size = n_basic_blocks * sizeof (struct bb_ann_d);
total += size;
free_blocks_annotations ();
label_to_block_map = NULL;
- free_rbi_pool ();
FOR_EACH_BB (bb)
bb->rbi = NULL;
}
}
break;
+ case ASSERT_EXPR:
+ x = fold (ASSERT_EXPR_COND (t));
+ if (x == boolean_false_node)
+ {
+ error ("ASSERT_EXPR with an always-false condition");
+ return *tp;
+ }
+ break;
+
case MODIFY_EXPR:
x = TREE_OPERAND (t, 0);
if (TREE_CODE (x) == BIT_FIELD_REF
if (TREE_CODE (stmt) == LABEL_EXPR)
{
error ("Label %s in the middle of basic block %d\n",
- IDENTIFIER_POINTER (DECL_NAME (stmt)),
+ IDENTIFIER_POINTER (DECL_NAME (LABEL_EXPR_LABEL (stmt))),
bb->index);
err = 1;
}
if (TREE_CODE (stmt) == LABEL_EXPR)
continue;
- /* Record the definitions. */
- get_stmt_operands (stmt);
-
FOR_EACH_SSA_TREE_OPERAND (val, stmt, op_iter, SSA_OP_ALL_DEFS)
mark_for_rewrite (val);
for (bsi = bsi_start (bb); !bsi_end_p (bsi); bsi_next (&bsi))
{
stmt = bsi_stmt (bsi);
- get_stmt_operands (stmt);
ann = stmt_ann (stmt);
uses = USE_OPS (ann);
/* When GIMPLE is lowered, the variables are no longer available in
BIND_EXPRs, so display them separately. */
- if (cfun && cfun->unexpanded_var_list)
+ if (cfun && cfun->decl == fn && cfun->unexpanded_var_list)
{
ignore_topmost_bind = true;
}
}
- if (basic_block_info)
+ if (cfun && cfun->decl == fn && cfun->cfg && basic_block_info)
{
/* Make a CFG based dump. */
check_bb_profile (ENTRY_BLOCK_PTR, file);
0, /* todo_flags_finish */
0 /* letter */
};
-
-#include "gt-tree-cfg.h"