aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--gcc/cfg.c45
-rw-r--r--gcc/cfg.h2
-rw-r--r--gcc/cgraph.c2
3 files changed, 32 insertions, 17 deletions
diff --git a/gcc/cfg.c b/gcc/cfg.c
index de0e71d..529b6ed 100644
--- a/gcc/cfg.c
+++ b/gcc/cfg.c
@@ -25,7 +25,7 @@ along with GCC; see the file COPYING3. If not see
Available functionality:
- Initialization/deallocation
- init_flow, clear_edges
+ init_flow, free_cfg
- Low level basic block manipulation
alloc_block, expunge_block
- Edge manipulation
@@ -83,7 +83,7 @@ init_flow (struct function *the_fun)
the_fun->cfg->bb_flags_allocated = BB_ALL_FLAGS;
}
-/* Helper function for remove_edge and clear_edges. Frees edge structure
+/* Helper function for remove_edge and free_cffg. Frees edge structure
without actually removing it from the pred/succ arrays. */
static void
@@ -93,29 +93,44 @@ free_edge (function *fn, edge e)
ggc_free (e);
}
-/* Free the memory associated with the edge structures. */
+/* Free basic block BB. */
+
+static void
+free_block (basic_block bb)
+{
+ vec_free (bb->succs);
+ bb->succs = NULL;
+ vec_free (bb->preds);
+ bb->preds = NULL;
+ /* Do not free BB itself yet since we leak pointers to dead statements
+ that points to dead basic blocks. */
+}
+
+/* Free the memory associated with the CFG in FN. */
void
-clear_edges (struct function *fn)
+free_cfg (struct function *fn)
{
- basic_block bb;
edge e;
edge_iterator ei;
+ basic_block next;
- FOR_EACH_BB_FN (bb, fn)
+ for (basic_block bb = ENTRY_BLOCK_PTR_FOR_FN (fn); bb; bb = next)
{
+ next = bb->next_bb;
FOR_EACH_EDGE (e, ei, bb->succs)
free_edge (fn, e);
- vec_safe_truncate (bb->succs, 0);
- vec_safe_truncate (bb->preds, 0);
+ free_block (bb);
}
- FOR_EACH_EDGE (e, ei, ENTRY_BLOCK_PTR_FOR_FN (fn)->succs)
- free_edge (fn, e);
- vec_safe_truncate (EXIT_BLOCK_PTR_FOR_FN (fn)->preds, 0);
- vec_safe_truncate (ENTRY_BLOCK_PTR_FOR_FN (fn)->succs, 0);
-
gcc_assert (!n_edges_for_fn (fn));
+ /* Sanity check that dominance tree is freed. */
+ gcc_assert (!fn->cfg->x_dom_computed[0] && !fn->cfg->x_dom_computed[1]);
+
+ vec_free (fn->cfg->x_label_to_block_map);
+ vec_free (basic_block_info_for_fn (fn));
+ ggc_free (fn->cfg);
+ fn->cfg = NULL;
}
/* Allocate memory for basic_block. */
@@ -190,8 +205,8 @@ expunge_block (basic_block b)
/* We should be able to ggc_free here, but we are not.
The dead SSA_NAMES are left pointing to dead statements that are pointing
to dead basic blocks making garbage collector to die.
- We should be able to release all dead SSA_NAMES and at the same time we should
- clear out BB pointer of dead statements consistently. */
+ We should be able to release all dead SSA_NAMES and at the same time we
+ should clear out BB pointer of dead statements consistently. */
}
/* Connect E to E->src. */
diff --git a/gcc/cfg.h b/gcc/cfg.h
index 93fde6d..a9c8300 100644
--- a/gcc/cfg.h
+++ b/gcc/cfg.h
@@ -82,7 +82,7 @@ struct GTY(()) control_flow_graph {
extern void init_flow (function *);
-extern void clear_edges (function *);
+extern void free_cfg (function *);
extern basic_block alloc_block (void);
extern void link_block (basic_block, basic_block);
extern void unlink_block (basic_block);
diff --git a/gcc/cgraph.c b/gcc/cgraph.c
index 19dfe2b..dbde8aa 100644
--- a/gcc/cgraph.c
+++ b/gcc/cgraph.c
@@ -1811,7 +1811,7 @@ release_function_body (tree decl)
gcc_assert (!dom_info_available_p (fn, CDI_DOMINATORS));
gcc_assert (!dom_info_available_p (fn, CDI_POST_DOMINATORS));
delete_tree_cfg_annotations (fn);
- clear_edges (fn);
+ free_cfg (fn);
fn->cfg = NULL;
}
if (fn->value_histograms)