This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
[tree-ssa] Cleanup documentation in tree-cfg.c. Removec-call-graph.c
- From: Diego Novillo <dnovillo at redhat dot com>
- To: "gcc-patches at gcc dot gnu dot org" <gcc-patches at gcc dot gnu dot org>
- Date: Thu, 25 Mar 2004 13:51:15 -0500
- Subject: [tree-ssa] Cleanup documentation in tree-cfg.c. Removec-call-graph.c
- Organization: Red Hat Canada
Another cleanup patch. This cleans up the documentation comments in
tree-cfg.c and marks some functions static.
The two outside changes are
1. Removal of c-call-graph.c. This should not be necessary
anymore. If needed, it's still in CVS history.
2. Renaming of bsi_insert_on_edge_immediate to pre_insert_on_edge.
This function is only used from PRE and it would seem that we
should be able to just replace it with bsi_insert_on_edge
followed by bsi_commit_edge_inserts, but I got a bootstrap error
in PRE when I tried that (uninitialized warnings on PRE
generated temps). Dan said he would look at that shortly.
Diego.
* Makefile.in (C_AND_OBJC_OBJS): Remove c-call-graph.o
(c-call-graph.o): Remove.
* c-call-graph.c: Remove.
* c-tree.h (print_call_graph): Remove.
(debug_call_graph): Remove.
* tree-cfg.c: Update/add comments everywhere.
(pre_insert_on_edge): Rename from bsi_insert_on_edge_immediate.
* tree-flow.h (build_tree_cfg): Make static.
(tree_cfg2dot): Likewise.
(verify_stmt): Likewise.
* tree-ssa-pre.c (insert_one_operand): Call pre_insert_on_edge.
Index: Makefile.in
===================================================================
RCS file: /cvs/gcc/gcc/gcc/Makefile.in,v
retrieving revision 1.903.2.195
diff -d -c -p -d -u -p -r1.903.2.195 Makefile.in
--- Makefile.in 19 Mar 2004 02:07:23 -0000 1.903.2.195
+++ Makefile.in 25 Mar 2004 15:46:32 -0000
@@ -858,7 +858,7 @@ C_AND_OBJC_OBJS = attribs.o c-errors.o c
c-convert.o c-aux-info.o c-common.o c-opts.o c-format.o c-semantics.o \
c-incpath.o cppdefault.o c-ppoutput.o c-cppbuiltin.o prefix.o \
c-objc-common.o c-dump.o c-pch.o $(C_TARGET_OBJS) \
- c-simplify.o c-call-graph.o tree-mudflap.o c-mudflap.o c-pretty-print.o
+ c-simplify.o tree-mudflap.o c-mudflap.o c-pretty-print.o
# Language-specific object files for C.
C_OBJS = c-parse.o c-lang.o stub-objc.o $(C_AND_OBJC_OBJS)
@@ -1659,9 +1659,6 @@ gimple-low.o : gimple-low.c $(CONFIG_H)
flags.h $(RTL_H) function.h tree-pass.h
tree-browser.o : tree-browser.c tree-browser.def $(CONFIG_H) $(SYSTEM_H) \
$(TREE_H) errors.h tree-inline.h diagnostic.h $(HASHTAB_H) \
- $(TM_H) coretypes.h
-c-call-graph.o : c-call-graph.c $(CONFIG_H) $(SYSTEM_H) $(C_TREE_H) \
- $(C_COMMON_H) diagnostic.h hard-reg-set.h $(BASIC_BLOCK_H) $(TREE_FLOW_H) \
$(TM_H) coretypes.h
tree-simple.o : tree-simple.c $(CONFIG_H) $(SYSTEM_H) $(TREE_H) $(EXPR_H) \
$(RTL_H) $(TREE_SIMPLE_H) $(TM_H) coretypes.h bitmap.h $(GGC_H)
Index: c-call-graph.c
===================================================================
RCS file: c-call-graph.c
diff -N c-call-graph.c
--- c-call-graph.c 5 Nov 2003 13:39:23 -0000 1.1.4.14
+++ /dev/null 1 Jan 1970 00:00:00 -0000
@@ -1,313 +0,0 @@
-/* Construction of the function call graph.
- Copyright (C) 2002, 2003 Free Software Foundation, Inc.
- Contributed by Sebastian Pop <s.pop@laposte.net>
-
-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. */
-
-#include "config.h"
-#include "system.h"
-#include "coretypes.h"
-#include "tm.h"
-#include "tree.h"
-#include "c-tree.h"
-#include "c-common.h"
-#include "hard-reg-set.h"
-#include "basic-block.h"
-#include "tree-flow.h"
-#include "diagnostic.h"
-
-
-/* Static declarations. */
-static void construct_call_graph (pretty_printer *, tree, HOST_WIDE_INT);
-static void print_callee (pretty_printer *, tree, int);
-
-#define INDENT(SPACE) do { \
- int i; for (i = 0; i<SPACE; i++) pp_space (buffer); } while (0)
-#define NIY do { \
- pp_flush (buffer); debug_tree (node); abort (); } while (0)
-
-
-/* Print the call graph associated to the tree T, in the file FILE. */
-
-void
-print_call_graph (FILE *file, tree t)
-{
- pretty_printer buffer_rec;
- pretty_printer *buffer = &buffer_rec;
-
- pp_construct (buffer, /* prefix */NULL, /* line-width */0);
- pp_clear_output_area (buffer);
- pp_printf (buffer, "<file>\n");
- construct_call_graph (buffer, t, 0);
- pp_printf (buffer, "</file>\n");
- fprintf (file, "%s", pp_base_formatted_text (buffer));
-}
-
-/* Print the call graph on stderr. */
-
-void
-debug_call_graph (tree t)
-{
- print_call_graph (stderr, t);
-}
-
-
-/* Scan the tree T searching for callee/caller functions, then output found
- function calls/callers in the pretty_printer BUFFER under the DTD format
- described above.
- Not Yet Implemented : the dump of global variables and their use. */
-
-static void
-construct_call_graph (pretty_printer *buffer, tree t, HOST_WIDE_INT spc)
-{
- static unsigned int decision_points;
- static unsigned int nb_statements;
- static unsigned int nb_calls;
- tree node = t;
-
- while (node && node != error_mark_node)
- {
- enum tree_code code = TREE_CODE (node);
-#if 0
- if (is_ctrl_stmt (node)) decision_points++;
- if (is_exec_stmt (node)) nb_statements++;
-#endif
-
- switch (code)
- {
- case TYPE_DECL:
- case FIELD_DECL:
- case VAR_DECL:
- case PARM_DECL:
- /* Some nodes on which we need to stop the recursion. */
- return;
-
- case FUNCTION_DECL:
- if (BUILT_IN_FRONTEND)
-
- INDENT (spc);
- pp_printf (buffer, "<caller id = \"");
- pp_printf (buffer, get_name (node), 0);
- pp_printf (buffer, "\">\n");
-
- /* What about definition of nested functions? That will reset the
- current value of decision_points and nb_statements... */
- decision_points = 0;
- nb_statements = 0;
- nb_calls = 0;
- construct_call_graph (buffer, DECL_SAVED_TREE (node), spc+1);
-
- /* Statements based statistics. */
- INDENT (spc+1);
- pp_printf (buffer, "<stats calls=\"%d\" decisions=\"%d\" stmts=\"%d\" Gilb=\"%f\"",
- nb_calls, decision_points, nb_statements,
- ((nb_statements == 0) ? 0.0 :
- ((float)decision_points / (float)nb_statements)));
-
- /* Control flow statistics. */
- init_flow ();
- build_tree_cfg (&DECL_SAVED_TREE (node));
- pp_printf (buffer, " CFG-edges=\"%d\" CFG-BB=\"%d\" McCabe=\"%d\">\n",
- n_edges, n_basic_blocks, n_edges - n_basic_blocks + 2);
- delete_tree_cfg ();
-
- /* End of the node. */
- INDENT (spc);
- pp_printf (buffer, "</caller>\n");
- return;
-
- case CALL_EXPR:
- {
- tree op0;
- op0 = TREE_OPERAND (node, 0);
-
- nb_calls++;
- if (TREE_CODE (op0) == NON_LVALUE_EXPR)
- op0 = TREE_OPERAND (op0, 0);
-
- switch (TREE_CODE (op0))
- {
- case VAR_DECL:
- case PARM_DECL:
- /* if (TREE_CODE (op0) == PARM_DECL)
- This function pointer was received in parameter.
- I think that this should not enter in the call graph.
- Or otherwise it enters but with a special mark
- saying that the name of this function is a parameter,
- and thus for this name we don't expect a declaration.
- Example:
- /gcc/libiberty/splay_tree.c:splay_tree_foreach_helper (). */
- print_callee (buffer, op0, spc);
- break;
-
- case ADDR_EXPR:
- case INDIRECT_REF:
- case NOP_EXPR:
- print_callee (buffer, TREE_OPERAND (op0, 0), spc);
- break;
-
- case COND_EXPR:
-#if 0
- /* XXX: Why is this disabled? */
- print_callee (buffer, TREE_OPERAND (TREE_OPERAND (op0, 0), 1), spc);
- print_callee (buffer, TREE_OPERAND (TREE_OPERAND (op0, 0), 2), spc);
-#endif
- break;
-
- case COMPONENT_REF:
- /* The function is a pointer contained in a structure. */
- if (TREE_CODE (TREE_OPERAND (op0, 0)) == INDIRECT_REF ||
- TREE_CODE (TREE_OPERAND (op0, 0)) == VAR_DECL)
- print_callee (buffer, TREE_OPERAND (op0, 1), spc);
-#if 0
- else
- /* We can have several levels of structures and a function
- pointer inside. This is not implemented yet... */
- NIY;
-#endif
- break;
-
- case ARRAY_REF:
- if (TREE_CODE (TREE_OPERAND (op0, 0)) == VAR_DECL)
- print_callee (buffer, TREE_OPERAND (op0, 0), spc);
- else
- print_callee (buffer, TREE_OPERAND (op0, 1), spc);
- break;
-
- default:
- NIY;
- }
- /* Walk through function's arguments. */
- construct_call_graph (buffer, TREE_OPERAND (node, 1), spc);
- node = TREE_CHAIN (node);
- break;
- }
-
- case ADDR_EXPR:
- /* May be a function pointer passed as a parameter to a function. */
- if (TREE_CODE (TREE_OPERAND (node, 0)) == FUNCTION_DECL)
- print_callee (buffer, TREE_OPERAND (node, 0), spc);
- else
- construct_call_graph (buffer, TREE_OPERAND (node, 0), spc);
- node = TREE_CHAIN (node);
- break;
-
- case ARRAY_REF:
- if (TREE_CODE (TREE_OPERAND (node, 0)) == ARRAY_REF)
- construct_call_graph (buffer, TREE_OPERAND (node, 0), spc);
-
- construct_call_graph (buffer, TREE_OPERAND (node, 1), spc);
- node = TREE_CHAIN (node);
- break;
-
- case TREE_LIST:
- construct_call_graph (buffer, TREE_VALUE (node), spc);
- node = TREE_CHAIN (node);
- break;
-
- case FIX_TRUNC_EXPR:
- case FIX_CEIL_EXPR:
- case FIX_FLOOR_EXPR:
- case FIX_ROUND_EXPR:
- case FLOAT_EXPR:
- case TRUTH_NOT_EXPR:
- case BIT_NOT_EXPR:
- case NE_EXPR:
- case INDIRECT_REF:
- case COMPOUND_STMT:
- case EXPR_STMT:
- case NOP_EXPR:
- case RETURN_STMT:
- /* Unary nodes. */
- construct_call_graph (buffer, TREE_OPERAND (node, 0), spc);
- node = TREE_CHAIN (node);
- break;
-
- case DO_STMT:
- case WHILE_STMT:
- case SWITCH_STMT:
- case LSHIFT_EXPR:
- case RSHIFT_EXPR:
- case LROTATE_EXPR:
- case RROTATE_EXPR:
- case BIT_IOR_EXPR:
- case BIT_XOR_EXPR:
- case BIT_AND_EXPR:
- case TRUTH_ANDIF_EXPR:
- case TRUTH_ORIF_EXPR:
- case TRUTH_AND_EXPR:
- case TRUTH_OR_EXPR:
- case TRUTH_XOR_EXPR:
- case LT_EXPR:
- case LE_EXPR:
- case GT_EXPR:
- case GE_EXPR:
- case EQ_EXPR:
- case PLUS_EXPR:
- case MINUS_EXPR:
- case MULT_EXPR:
- case TRUNC_DIV_EXPR:
- case MODIFY_EXPR:
- /* Binary nodes. */
- construct_call_graph (buffer, TREE_OPERAND (node, 0), spc);
- construct_call_graph (buffer, TREE_OPERAND (node, 1), spc);
- node = TREE_CHAIN (node);
- break;
-
- case COND_EXPR:
- case IF_STMT:
- /* Ternary nodes. */
- construct_call_graph (buffer, TREE_OPERAND (node, 0), spc);
- construct_call_graph (buffer, TREE_OPERAND (node, 1), spc);
- construct_call_graph (buffer, TREE_OPERAND (node, 2), spc);
- node = TREE_CHAIN (node);
- break;
-
- case FOR_STMT:
- /* Quaternary nodes. */
- construct_call_graph (buffer, TREE_OPERAND (node, 0), spc);
- construct_call_graph (buffer, TREE_OPERAND (node, 1), spc);
- construct_call_graph (buffer, TREE_OPERAND (node, 2), spc);
- construct_call_graph (buffer, TREE_OPERAND (node, 3), spc);
- node = TREE_CHAIN (node);
- break;
-
- default:
- node = TREE_CHAIN (node);
- break;
- }
- }
-}
-
-
-/* Print the callee function declaration. */
-
-static void
-print_callee (pretty_printer *buffer, tree node, int spc)
-{
- int i;
-
- /* Indent. */
- for (i = 0; i<spc; i++)
- pp_space (buffer);
-
- /* Print the node. */
- pp_printf (buffer, "<callee idref = \"");
- pp_printf (buffer, get_name (node), 0);
- pp_printf (buffer, "\"/>\n");
-}
Index: c-tree.h
===================================================================
RCS file: /cvs/gcc/gcc/gcc/c-tree.h,v
retrieving revision 1.99.2.34
diff -d -c -p -d -u -p -r1.99.2.34 c-tree.h
--- c-tree.h 24 Mar 2004 18:47:42 -0000 1.99.2.34
+++ c-tree.h 25 Mar 2004 15:46:32 -0000
@@ -312,10 +312,6 @@ extern void c_write_global_declarations
extern GTY(()) tree static_ctors;
extern GTY(()) tree static_dtors;
-/* In c-call-graph.c */
-extern void print_call_graph (FILE*, tree);
-extern void debug_call_graph (tree);
-
/* In order for the format checking to accept the C frontend
diagnostic framework extensions, you must include this file before
toplev.h, not after. */
Index: tree-cfg.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/Attic/tree-cfg.c,v
retrieving revision 1.1.4.278
diff -d -c -p -d -u -p -r1.1.4.278 tree-cfg.c
--- tree-cfg.c 16 Mar 2004 22:31:55 -0000 1.1.4.278
+++ tree-cfg.c 25 Mar 2004 15:46:32 -0000
@@ -96,7 +96,6 @@ static edge tree_redirect_edge_and_branc
static edge tree_try_redirect_by_replacing_jump (edge, basic_block);
static void split_critical_edges (void);
-
/* Various helpers. */
static inline bool stmt_starts_bb_p (tree, tree);
static int tree_verify_flow_info (void);
@@ -104,9 +103,9 @@ static void tree_make_forwarder_block (e
static bool thread_jumps (void);
static bool tree_forwarder_block_p (basic_block);
static void bsi_commit_edge_inserts_1 (edge e);
+static void tree_cfg2dot (FILE *);
/* Flowgraph optimization and cleanup. */
-
static void tree_merge_blocks (basic_block, basic_block);
static bool tree_can_merge_blocks_p (basic_block, basic_block);
static void remove_bb (basic_block);
@@ -116,17 +115,17 @@ static bool cleanup_control_expr_graph (
static edge find_taken_edge_cond_expr (basic_block, tree);
static edge find_taken_edge_switch_expr (basic_block, tree);
static tree find_case_label_for_value (tree, tree);
-static int phi_alternatives_equal (basic_block, edge, edge);
+static bool phi_alternatives_equal (basic_block, edge, edge);
/*---------------------------------------------------------------------------
Create basic blocks
---------------------------------------------------------------------------*/
-/* Entry point to the CFG builder for trees. FNBODY is the body of the
- function to process. */
+/* Entry point to the CFG builder for trees. TP points to the list of
+ statements to be added to the flowgraph. */
-void
+static void
build_tree_cfg (tree *tp)
{
/* Register specific tree functions. */
@@ -287,9 +286,11 @@ factor_computed_gotos (void)
}
}
+
/* Create annotations for a single basic block. */
-static void create_block_annotation (basic_block bb)
+static void
+create_block_annotation (basic_block bb)
{
/* Verify that the tree_annotations field is clear. */
if (bb->tree_annotations)
@@ -297,6 +298,7 @@ static void create_block_annotation (bas
bb->tree_annotations = ggc_alloc_cleared (sizeof (struct bb_ann_d));
}
+
/* Free the annotations for all the basic blocks. */
static void free_blocks_annotations (void)
@@ -304,6 +306,7 @@ static void free_blocks_annotations (voi
clear_blocks_annotations ();
}
+
/* Clear the annotations for all the basic blocks. */
static void
@@ -315,6 +318,7 @@ clear_blocks_annotations (void)
bb->tree_annotations = NULL;
}
+
/* Build a flowgraph for the statement_list STMT_LIST. */
static void
@@ -402,6 +406,7 @@ create_bb (void *h, void *e, basic_block
return bb;
}
+
/*---------------------------------------------------------------------------
Edge creation
---------------------------------------------------------------------------*/
@@ -446,6 +451,7 @@ make_edges (void)
for (e = EXIT_BLOCK_PTR->prev_bb->succ; e; e = e->succ_next)
if (e->flags & EDGE_FALLTHRU)
break;
+
if (e && e->dest == EXIT_BLOCK_PTR)
{
block_stmt_iterator bsi;
@@ -478,6 +484,7 @@ make_edges (void)
cleanup_tree_cfg ();
}
+
/* Create edges for control statement at basic block BB. */
static void
@@ -525,6 +532,7 @@ make_ctrl_stmt_edges (basic_block bb)
}
}
+
/* Create exit edges for statements in block BB that alter the flow of
control. Statements that alter the control flow are 'goto', 'return'
and calls to non-returning functions. */
@@ -586,6 +594,7 @@ make_exit_edges (basic_block bb)
}
}
+
/* Create the edges for a COND_EXPR starting at block BB.
At this point, both clauses must contain only simple gotos. */
@@ -611,6 +620,7 @@ make_cond_expr_edges (basic_block bb)
make_edge (bb, else_bb, EDGE_FALSE_VALUE);
}
+
/* Create the edges for a SWITCH_EXPR starting at block BB.
At this point, the switch body has been lowered and the
SWITCH_LABELS filled in, so this is in effect a multi-way branch. */
@@ -633,12 +643,16 @@ make_switch_expr_edges (basic_block bb)
}
}
+
+/* Return the basic block holding label DEST. */
+
basic_block
label_to_block (tree dest)
{
return VARRAY_BB (label_to_block_map, LABEL_DECL_UID (dest));
}
+
/* Create edges for a goto statement at block BB. */
static void
@@ -748,7 +762,9 @@ cleanup_tree_cfg (void)
timevar_pop (TV_TREE_CLEANUP_CFG);
}
+
/* Cleanup useless labels from the flow graph. */
+
static void
cleanup_dead_labels (void)
{
@@ -869,6 +885,7 @@ cleanup_dead_labels (void)
free (label_for_bb);
}
+
/* Checks whether we can merge block B into block A. */
static bool
@@ -922,7 +939,8 @@ tree_can_merge_blocks_p (basic_block a,
return true;
}
-/* Merges block B into block A. */
+
+/* Merge block B into block A. */
static void
tree_merge_blocks (basic_block a, basic_block b)
@@ -933,7 +951,7 @@ tree_merge_blocks (basic_block a, basic_
if (dump_file)
fprintf (dump_file, "Merging blocks %d and %d\n", a->index, b->index);
- /* Ensure that b follows a. */
+ /* Ensure that B follows A. */
move_block_after (b, a);
if (!(a->succ->flags & EDGE_FALLTHRU))
@@ -1143,6 +1161,7 @@ remove_useless_stmts_cond (tree *stmt_p,
data->last_goto = NULL;
}
+
static void
remove_useless_stmts_tf (tree *stmt_p, struct rus_data *data)
{
@@ -1193,6 +1212,7 @@ remove_useless_stmts_tf (tree *stmt_p, s
}
}
+
static void
remove_useless_stmts_tc (tree *stmt_p, struct rus_data *data)
{
@@ -1267,6 +1287,7 @@ remove_useless_stmts_tc (tree *stmt_p, s
data->may_throw |= this_may_throw;
}
+
static void
remove_useless_stmts_bind (tree *stmt_p, struct rus_data *data)
{
@@ -1294,6 +1315,7 @@ remove_useless_stmts_bind (tree *stmt_p,
}
}
+
static void
remove_useless_stmts_goto (tree *stmt_p, struct rus_data *data)
{
@@ -1307,6 +1329,7 @@ remove_useless_stmts_goto (tree *stmt_p,
data->last_goto = stmt_p;
}
+
static void
remove_useless_stmts_label (tree *stmt_p, struct rus_data *data)
{
@@ -1327,6 +1350,7 @@ remove_useless_stmts_label (tree *stmt_p
/* ??? Add something here to delete unused labels. */
}
+
/* If the function is "const" or "pure", then clear TREE_SIDE_EFFECTS on its
decl. This allows us to eliminate redundant or useless
calls to "const" functions.
@@ -1334,6 +1358,7 @@ remove_useless_stmts_label (tree *stmt_p
Gimplifier already does the same operation, but we may notice functions
being const and pure once their calls has been gimplified, so we need
to update the flag. */
+
static void
update_call_expr_flags (tree call)
{
@@ -1346,7 +1371,9 @@ update_call_expr_flags (tree call)
TREE_NOTHROW (call) = 1;
}
-/* t is CALL_EXPR. Set current_function_calls_* flags. */
+
+/* T is CALL_EXPR. Set current_function_calls_* flags. */
+
void
notice_special_calls (tree t)
{
@@ -1358,8 +1385,10 @@ notice_special_calls (tree t)
current_function_calls_setjmp = true;
}
+
/* Clear flags set by notice_special_calls. Used by dead code removal
to update the flags. */
+
void
clear_special_calls (void)
{
@@ -1367,6 +1396,7 @@ clear_special_calls (void)
current_function_calls_setjmp = false;
}
+
static void
remove_useless_stmts_1 (tree *tp, struct rus_data *data)
{
@@ -1476,6 +1506,7 @@ remove_useless_stmts (void)
while (data.repeat);
}
+
struct tree_opt_pass pass_remove_useless_stmts =
{
"useless", /* name */
@@ -1492,6 +1523,7 @@ struct tree_opt_pass pass_remove_useless
TODO_dump_func /* todo_flags_finish */
};
+
/* Remove obviously useless statements in basic block BB. */
static void
@@ -1592,7 +1624,8 @@ cfg_remove_useless_stmts_bb (basic_block
}
}
-/* A cfg-aware version of remove_useless_stmts_and_vars. */
+
+/* A CFG-aware version of remove_useless_stmts. */
void
cfg_remove_useless_stmts (void)
@@ -1609,6 +1642,7 @@ cfg_remove_useless_stmts (void)
}
}
+
/* Remove PHI nodes associated with basic block BB and all edges out of BB. */
static void
@@ -1627,12 +1661,12 @@ remove_phi_nodes_and_edges_for_unreachab
}
/* Remove edges to BB's successors. */
-
while (bb->succ != NULL)
ssa_remove_edge (bb->succ);
}
-/* Remove statements of the basic block BB. */
+
+/* Remove statements of basic block BB. */
static void
remove_bb (basic_block bb)
@@ -1658,9 +1692,9 @@ remove_bb (basic_block bb)
set_bb_for_stmt (stmt, NULL);
/* Don't warn for removed gotos. Gotos are often removed due to
- jump threading, thus resulting into bogus warnings. Not great,
- since this way we lose warnings for gotos in the original program
- that are indeed unreachable. */
+ jump threading, thus resulting in bogus warnings. Not great,
+ since this way we lose warnings for gotos in the original
+ program that are indeed unreachable. */
if (TREE_CODE (stmt) != GOTO_EXPR && EXPR_LOCUS (stmt) && !loc)
loc = EXPR_LOCUS (stmt);
}
@@ -1675,9 +1709,10 @@ remove_bb (basic_block bb)
remove_phi_nodes_and_edges_for_unreachable_block (bb);
}
+
/* Examine BB to determine if it is a forwarding block (a block which only
transfers control to a new destination). If BB is a forwarding block,
- then return edge leading to the ultimate destination. */
+ then return the edge leading to the ultimate destination. */
edge
tree_block_forwards_to (basic_block bb)
@@ -1737,6 +1772,7 @@ tree_block_forwards_to (basic_block bb)
return NULL;
}
+
/* Try to remove superfluous control structures. */
static bool
@@ -1762,6 +1798,7 @@ cleanup_control_flow (void)
return retval;
}
+
/* Disconnect an unreachable block in the control expression starting
at block BB. */
@@ -1824,6 +1861,7 @@ cleanup_control_expr_graph (basic_block
return retval;
}
+
/* Given a control block BB and a constant value VAL, return the edge that
will be taken out of the block. If VAL does not match a unique edge,
NULL is returned. */
@@ -1854,6 +1892,7 @@ find_taken_edge (basic_block bb, tree va
return bb->succ;
}
+
/* Given a constant value VAL and the entry block BB to a COND_EXPR
statement, determine which of the two edges will be taken out of the
block. Return NULL if either edge may be taken. */
@@ -1882,6 +1921,7 @@ find_taken_edge_cond_expr (basic_block b
return NULL;
}
+
/* Given a constant value VAL and the entry block BB to a SWITCH_EXPR
statement, determine which edge will be taken out of the block. Return
NULL if any edge may be taken. */
@@ -1906,6 +1946,7 @@ find_taken_edge_switch_expr (basic_block
return e;
}
+
/* Return the CASE_LABEL_EXPR that SWITCH_EXPR will take for VAL. */
static tree
@@ -1938,14 +1979,16 @@ find_case_label_for_value (tree switch_e
if (!default_case)
abort ();
+
return default_case;
}
-/* If all the phi nodes in DEST have alternatives for E1 and E2 and
+
+/* If all the PHI nodes in DEST have alternatives for E1 and E2 and
those alternatives are equal in each of the PHI nodes, then return
- nonzero, else return zero. */
+ true, else return false. */
-static int
+static bool
phi_alternatives_equal (basic_block dest, edge e1, edge e2)
{
tree phi, val1, val2;
@@ -1971,6 +2014,7 @@ phi_alternatives_equal (basic_block dest
return true;
}
+
/* Computing the Dominance Frontier:
As described in Morgan, section 3.5, this may be done simply by
@@ -1985,8 +2029,7 @@ phi_alternatives_equal (basic_block dest
(2) Consider a block X in the frontier of one of the children C
of B. If X is not equal to B and is not dominated by B, it
- is in the frontier of B.
-*/
+ is in the frontier of B. */
static void
compute_dominance_frontiers_1 (bitmap *frontiers, basic_block bb, sbitmap done)
@@ -2031,6 +2074,7 @@ compute_dominance_frontiers_1 (bitmap *f
}
}
+
void
compute_dominance_frontiers (bitmap *frontiers)
{
@@ -2047,11 +2091,13 @@ compute_dominance_frontiers (bitmap *fro
timevar_pop (TV_DOM_FRONTIERS);
}
+
+
/*---------------------------------------------------------------------------
Debugging functions
---------------------------------------------------------------------------*/
-/* Dump tree-specific information of BB to file OUTF. */
+/* Dump tree-specific information of block BB to file OUTF. */
void
tree_dump_bb (basic_block bb, FILE *outf, int indent)
@@ -2059,6 +2105,7 @@ tree_dump_bb (basic_block bb, FILE *outf
dump_generic_bb (outf, bb, indent, TDF_VOPS);
}
+
/* Dump a basic block on stderr. */
void
@@ -2067,7 +2114,8 @@ debug_tree_bb (basic_block bb)
dump_bb (bb, stderr, 0);
}
-/* Dump a basic block N on stderr. */
+
+/* Dump basic block with index N on stderr. */
basic_block
debug_tree_bb_n (int n)
@@ -2076,6 +2124,7 @@ debug_tree_bb_n (int n)
return BASIC_BLOCK (n);
}
+
/* Dump the CFG on stderr.
FLAGS are the same used by the tree dumping functions
@@ -2116,6 +2165,7 @@ dump_tree_cfg (FILE *file, int flags)
dump_function_to_file (current_function_decl, file, flags | TDF_BLOCKS);
}
+
/* Dump CFG statistics on FILE. */
void
@@ -2176,7 +2226,8 @@ dump_cfg_stats (FILE *file)
}
-/* Dump CFG statistics on stderr. */
+/* Dump CFG statistics on stderr. Keep extern so that it's always
+ linked in the final executable. */
void
debug_cfg_stats (void)
@@ -2187,7 +2238,7 @@ debug_cfg_stats (void)
/* Dump the flowgraph to a .dot FILE. */
-void
+static void
tree_cfg2dot (FILE *file)
{
edge e;
@@ -2279,8 +2330,9 @@ is_ctrl_stmt (tree t)
|| TREE_CODE (t) == RESX_EXPR);
}
-/* Return true if T is a stmt that may or may not alter the flow of control
- (i.e., a call to a non-returning function). */
+
+/* Return true if T is a statement that may alter the flow of control
+ (e.g., a call to a non-returning function). */
bool
is_ctrl_altering_stmt (tree t)
@@ -2303,13 +2355,13 @@ is_ctrl_altering_stmt (tree t)
/* FALLTHRU */
case CALL_EXPR:
- /* A non-pure/const CALL_EXPR alters flow control if the current function
- has nonlocal labels. */
+ /* A non-pure/const CALL_EXPR alters flow control if the current
+ function has nonlocal labels. */
if (TREE_SIDE_EFFECTS (t)
&& current_function_has_nonlocal_label)
return true;
- /* A CALL_EXPR also alters flow control if it does not return. */
+ /* A CALL_EXPR also alters control flow if it does not return. */
if (call_expr_flags (call) & (ECF_NORETURN | ECF_LONGJMP))
return true;
break;
@@ -2322,6 +2374,7 @@ is_ctrl_altering_stmt (tree t)
return tree_can_throw_internal (t);
}
+
/* Return true if T is a computed goto. */
bool
@@ -2331,6 +2384,7 @@ computed_goto_p (tree t)
&& TREE_CODE (GOTO_DESTINATION (t)) != LABEL_DECL);
}
+
/* Checks whether EXPR is a simple local goto. */
bool
@@ -2342,6 +2396,7 @@ simple_goto_p (tree expr)
== current_function_decl));
}
+
/* Return true if T should start a new basic block. PREV_T is the
statement preceding T. It is used when T is a label or a case label.
Labels should only start a new basic block if their previous statement
@@ -2356,9 +2411,10 @@ stmt_starts_bb_p (tree t, tree prev_t)
if (t == NULL_TREE)
return false;
- /* LABEL_EXPRs start a new basic block only if the preceding statement wasn't
- a label of the same type. This prevents the creation of consecutive
- blocks that have nothing but a single label. */
+ /* LABEL_EXPRs start a new basic block only if the preceding
+ statement wasn't a label of the same type. This prevents the
+ creation of consecutive blocks that have nothing but a single
+ label. */
code = TREE_CODE (t);
if (code == LABEL_EXPR)
{
@@ -2383,6 +2439,7 @@ stmt_starts_bb_p (tree t, tree prev_t)
return false;
}
+
/* Return true if T should end a basic block. */
bool
@@ -2391,7 +2448,8 @@ stmt_ends_bb_p (tree t)
return is_ctrl_stmt (t) || is_ctrl_altering_stmt (t);
}
-/* Add gotos that used to be represented implicitly in cfg. */
+
+/* Add gotos that used to be represented implicitly in the CFG. */
void
disband_implicit_edges (void)
@@ -2412,7 +2470,6 @@ disband_implicit_edges (void)
from cfg_remove_useless_stmts here since it violates the
invariants for tree--cfg correspondence and thus fits better
here where we do it anyway. */
-
for (e = bb->succ; e; e = e->succ_next)
{
if (e->dest != bb->next_bb)
@@ -2432,7 +2489,7 @@ disband_implicit_edges (void)
if (stmt && TREE_CODE (stmt) == RETURN_EXPR)
{
- /* Remove the RETURN_EXPR if we may fallthru to the exit
+ /* Remove the RETURN_EXPR if we may fall though to the exit
instead. */
if (!bb->succ
|| bb->succ->succ_next
@@ -2466,6 +2523,7 @@ disband_implicit_edges (void)
abort ();
label = tree_block_label (e->dest);
+
/* ??? Why bother putting this back together when rtl is just
about to take it apart again? */
if (factored_computed_goto_label
@@ -2482,6 +2540,7 @@ disband_implicit_edges (void)
factored_computed_goto_label = NULL;
}
+
/* Remove all the blocks and edges that make up the flowgraph. */
void
@@ -2496,8 +2555,8 @@ delete_tree_cfg (void)
free_rbi_pool ();
}
-/* Return the first statement in basic block BB, stripped of any NOP
- containers. */
+
+/* Return the first statement in basic block BB. */
tree
first_stmt (basic_block bb)
@@ -2506,8 +2565,8 @@ first_stmt (basic_block bb)
return !bsi_end_p (i) ? bsi_stmt (i) : NULL_TREE;
}
-/* Return the last statement in basic block BB, stripped of any NOP
- containers. */
+
+/* Return the last statement in basic block BB. */
tree
last_stmt (basic_block bb)
@@ -2516,6 +2575,7 @@ last_stmt (basic_block bb)
return !bsi_end_p (b) ? bsi_stmt (b) : NULL_TREE;
}
+
/* Return a pointer to the last statement in block BB. */
tree *
@@ -2525,8 +2585,10 @@ last_stmt_ptr (basic_block bb)
return !bsi_end_p (last) ? bsi_stmt_ptr (last) : NULL;
}
+
/* Return the last statement of an otherwise empty block. Return NULL
- if the block is totally empty, or if it contains more than one stmt. */
+ if the block is totally empty, or if it contains more than one
+ statement. */
tree
last_and_only_stmt (basic_block bb)
@@ -2549,7 +2611,6 @@ last_and_only_stmt (basic_block bb)
Thus the only thing that should appear here in a block containing
one executable statement is a label. */
-
prev = bsi_stmt (i);
if (TREE_CODE (prev) == LABEL_EXPR)
return last;
@@ -2557,7 +2618,8 @@ last_and_only_stmt (basic_block bb)
return NULL_TREE;
}
-/* Insert statement T into basic block BB. */
+
+/* Mark BB as the basic block holding statement T. */
void
set_bb_for_stmt (tree t, basic_block bb)
@@ -2601,7 +2663,10 @@ set_bb_for_stmt (tree t, basic_block bb)
}
}
-/* Insert a statement, or statement list, before the given pointer. */
+
+/* Insert statement (or statement list) T before the statement
+ pointed-to by iterator I. M specifies how to update iterator I
+ after insertion (see enum bsi_iterator_update). */
void
bsi_insert_before (block_stmt_iterator *i, tree t, enum bsi_iterator_update m)
@@ -2611,7 +2676,10 @@ bsi_insert_before (block_stmt_iterator *
tsi_link_before (&i->tsi, t, m);
}
-/* Insert a statement, or statement list, after the given pointer. */
+
+/* Insert statement (or statement list) T after the statement
+ pointed-to by iterator I. M specifies how to update iterator I
+ after insertion (see enum bsi_iterator_update). */
void
bsi_insert_after (block_stmt_iterator *i, tree t, enum bsi_iterator_update m)
@@ -2621,7 +2689,8 @@ bsi_insert_after (block_stmt_iterator *i
tsi_link_after (&i->tsi, t, m);
}
-/* Remove the statement at the given pointer. The pointer is updated
+
+/* Remove the statement pointed to by iterator I. The iterator is updated
to the next statement. */
void
@@ -2633,6 +2702,7 @@ bsi_remove (block_stmt_iterator *i)
tsi_delink (&i->tsi);
}
+
/* Move the statement at FROM so it comes right after the statement at TO. */
void
@@ -2643,6 +2713,7 @@ bsi_move_after (block_stmt_iterator *fro
bsi_insert_after (to, stmt, BSI_SAME_STMT);
}
+
/* Move the statement at FROM so it comes right before the statement at TO. */
void
@@ -2653,6 +2724,7 @@ bsi_move_before (block_stmt_iterator *fr
bsi_insert_before (to, stmt, BSI_SAME_STMT);
}
+
/* Move the statement at FROM to the end of basic block BB. */
void
@@ -2667,7 +2739,10 @@ bsi_move_to_bb_end (block_stmt_iterator
bsi_move_after (from, &last);
}
-/* Replace the contents of a stmt with another. */
+
+/* Replace the contents of the statement pointed to by iterator BSI
+ with STMT. If PRESERVE_EH_INFO is true, the exception handling
+ information of the original statement is preserved. */
void
bsi_replace (const block_stmt_iterator *bsi, tree stmt, bool preserve_eh_info)
@@ -2691,14 +2766,15 @@ bsi_replace (const block_stmt_iterator *
modify_stmt (stmt);
}
-/* This routine locates a place to insert a statement on an edge. Every
- attempt is made to place the stmt in an existing basic block, but
+
+/* Insert the statement pointed-to by BSI into edge E. Every attempt
+ is made to place the statement in an existing basic block, but
sometimes that isn't possible. When it isn't possible, the edge is
- split and the stmt is added to the new block.
+ split and the statement is added to the new block.
In all cases, the returned *BSI points to the correct location. The
return value is true if insertion should be done after the location,
- or false if before the location. */
+ or false if it should be done before the location. */
static bool
tree_find_edge_insert_loc (edge e, block_stmt_iterator *bsi)
@@ -2766,11 +2842,12 @@ tree_find_edge_insert_loc (edge e, block
goto restart;
}
+
/* This routine will commit all pending edge insertions, creating any new
basic blocks which are necessary.
- If specified, NEW_BLOCKS returns a count of the number of new basic blocks
- which were created. */
+ If specified, NEW_BLOCKS returns a count of the number of new basic
+ blocks which were created. */
void
bsi_commit_edge_inserts (int *new_blocks)
@@ -2812,8 +2889,8 @@ bsi_commit_edge_inserts_1 (edge e)
}
-/* This routine adds a stmt to the pending list on an edge. No actual
- insertion is made until a call to bsi_commit_edge_inserts () is made. */
+/* Add STMT to the pending list of edge E. No actual insertion is
+ made until a call to bsi_commit_edge_inserts () is made. */
void
bsi_insert_on_edge (edge e, tree stmt)
@@ -2821,11 +2898,15 @@ bsi_insert_on_edge (edge e, tree stmt)
append_to_statement_list (stmt, &PENDING_STMT (e));
}
-/* Similar to bsi_insert_on_edge+bsi_commit_edge_inserts. */
-/* ??? Why in the world do we need this? Only PRE uses it. */
+
+/* Specialized edge insertion for SSA-PRE. FIXME: This should
+ probably disappear. The only reason it's here is because PRE needs
+ the call to tree_find_edge_insert_loc(). */
+
+void pre_insert_on_edge (edge e, tree stmt);
void
-bsi_insert_on_edge_immediate (edge e, tree stmt)
+pre_insert_on_edge (edge e, tree stmt)
{
block_stmt_iterator bsi;
@@ -2838,11 +2919,12 @@ bsi_insert_on_edge_immediate (edge e, tr
bsi_insert_before (&bsi, stmt, BSI_NEW_STMT);
}
+
/*---------------------------------------------------------------------------
- Tree specific functions for the cfg loop optimizer
+ Tree specific functions for CFG manipulation
---------------------------------------------------------------------------*/
-/* Split a (typically critical) edge. Return the new block.
+/* Split a (typically critical) edge EDGE_IN. Return the new block.
Abort on abnormal edges. */
static basic_block
@@ -2863,7 +2945,6 @@ tree_split_edge (edge edge_in)
/* Place the new block in the block list. Try to keep the new block
near its "logical" location. This is of most help to humans looking
at debugging dumps. */
-
for (e = dest->pred; e; e = e->pred_next)
if (e->src->next_bb == dest)
break;
@@ -2898,7 +2979,9 @@ tree_split_edge (edge edge_in)
return new_bb;
}
+
/* Return true when BB has label LABEL in it. */
+
static bool
has_label_p (basic_block bb, tree label)
{
@@ -2916,6 +2999,7 @@ has_label_p (basic_block bb, tree label)
return false;
}
+
/* Callback for walk_tree, check that all elements with address taken are
properly noticed as such. */
@@ -3052,34 +3136,36 @@ verify_expr (tree *tp, int *walk_subtree
}
-/* Verify the STMT, return true if STMT is missformed.
- Always keep global so it can be called via GDB.
-
+/* Verify STMT, return true if STMT is not in GIMPLE form.
TODO: Implement type checking. */
-bool
+static bool
verify_stmt (tree stmt)
{
tree addr;
if (!is_gimple_stmt (stmt))
{
- error ("Is not valid gimple statement.");
+ error ("Is not a valid GIMPLE statement.");
debug_generic_stmt (stmt);
return true;
}
+
addr = walk_tree (&stmt, verify_expr, NULL, NULL);
if (addr)
{
debug_generic_stmt (addr);
return true;
}
+
return false;
}
+
/* Return true when the T can be shared. */
+
static bool
-tree_node_shared_p (tree t)
+tree_node_can_be_shared (tree t)
{
if (TYPE_P (t) || DECL_P (t)
/* We check for constants explicitly since they are not considered
@@ -3088,6 +3174,7 @@ tree_node_shared_p (tree t)
|| is_gimple_min_invariant (t)
|| TREE_CODE (t) == SSA_NAME)
return true;
+
while ((TREE_CODE (t) == ARRAY_REF
/* We check for constants explicitly since they are not considered
gimple invariants if they overflowed. */
@@ -3097,27 +3184,33 @@ tree_node_shared_p (tree t)
|| TREE_CODE (t) == REALPART_EXPR
|| TREE_CODE (t) == IMAGPART_EXPR))
t = TREE_OPERAND (t, 0);
+
if (DECL_P (t))
return true;
+
return false;
}
+
/* Called via walk_trees. Verify tree sharing. */
+
static tree
verify_node_sharing (tree * tp, int *walk_subtrees, void *data)
{
htab_t htab = (htab_t) data;
void **slot;
- if (tree_node_shared_p (*tp))
+ if (tree_node_can_be_shared (*tp))
{
*walk_subtrees = false;
return NULL;
}
+
slot = htab_find_slot (htab, *tp, INSERT);
if (*slot)
return *slot;
*slot = *tp;
+
return NULL;
}
@@ -3156,7 +3249,7 @@ verify_stmts (void)
&& TREE_CODE (t) != FUNCTION_DECL
&& !is_gimple_val (t))
{
- error ("PHI def is not GIMPLE value");
+ error ("PHI def is not a GIMPLE value");
debug_generic_stmt (phi);
debug_generic_stmt (t);
err |= true;
@@ -3172,7 +3265,7 @@ verify_stmts (void)
addr = walk_tree (&t, verify_node_sharing, htab, NULL);
if (addr)
{
- error ("Wrong sharing of tree nodes");
+ error ("Incorrect sharing of tree nodes");
debug_generic_stmt (phi);
debug_generic_stmt (addr);
err |= true;
@@ -3187,7 +3280,7 @@ verify_stmts (void)
addr = walk_tree (&stmt, verify_node_sharing, htab, NULL);
if (addr)
{
- error ("Wrong sharing of tree nodes");
+ error ("Incorrect sharing of tree nodes");
debug_generic_stmt (stmt);
debug_generic_stmt (addr);
err |= true;
@@ -3216,12 +3309,13 @@ tree_verify_flow_info (void)
if (ENTRY_BLOCK_PTR->stmt_list)
{
- error ("ENTRY_BLOCK has stmt list associated with it\n");
+ error ("ENTRY_BLOCK has a statement list associated with it\n");
err = 1;
}
+
if (EXIT_BLOCK_PTR->stmt_list)
{
- error ("EXIT_BLOCK has stmt list associated with it\n");
+ error ("EXIT_BLOCK has a statement list associated with it\n");
err = 1;
}
@@ -3241,6 +3335,7 @@ tree_verify_flow_info (void)
{
if (TREE_CODE (bsi_stmt (bsi)) != LABEL_EXPR)
break;
+
if (label_to_block (LABEL_EXPR_LABEL (bsi_stmt (bsi))) != bb)
{
error ("Label %s to block does not match in bb %d\n",
@@ -3248,6 +3343,7 @@ tree_verify_flow_info (void)
bb->index);
err = 1;
}
+
if (decl_function_context (LABEL_EXPR_LABEL (bsi_stmt (bsi)))
!= current_function_decl)
{
@@ -3257,7 +3353,8 @@ tree_verify_flow_info (void)
err = 1;
}
}
- /* Verify that body of basic block is free of control flow. */
+
+ /* Verify that body of basic block BB is free of control flow. */
for (; !bsi_end_p (bsi); bsi_next (&bsi))
{
tree stmt = bsi_stmt (bsi);
@@ -3268,8 +3365,10 @@ tree_verify_flow_info (void)
bb->index);
err = 1;
}
+
if (stmt_ends_bb_p (stmt))
found_ctrl_stmt = true;
+
if (TREE_CODE (stmt) == LABEL_EXPR)
{
error ("Label %s in the middle of basic block %d\n",
@@ -3304,7 +3403,7 @@ tree_verify_flow_info (void)
if (TREE_CODE (COND_EXPR_THEN (stmt)) != GOTO_EXPR
|| TREE_CODE (COND_EXPR_ELSE (stmt)) != GOTO_EXPR)
{
- error ("Structured COND_EXPR at end of bb %d\n", bb->index);
+ error ("Structured COND_EXPR at the end of bb %d\n", bb->index);
err = 1;
}
@@ -3321,6 +3420,7 @@ tree_verify_flow_info (void)
bb->index);
err = 1;
}
+
if (!has_label_p (true_edge->dest,
GOTO_DESTINATION (COND_EXPR_THEN (stmt))))
{
@@ -3328,6 +3428,7 @@ tree_verify_flow_info (void)
bb->index);
err = 1;
}
+
if (!has_label_p (false_edge->dest,
GOTO_DESTINATION (COND_EXPR_ELSE (stmt))))
{
@@ -3346,9 +3447,8 @@ tree_verify_flow_info (void)
}
else
{
- /* We shall double check that the labels in destination
- blocks have address taken. */
-
+ /* FIXME. We should double check that the labels in the
+ destination blocks have their address taken. */
for (e = bb->succ; e; e = e->succ_next)
if ((e->flags & (EDGE_FALLTHRU | EDGE_TRUE_VALUE
| EDGE_FALSE_VALUE))
@@ -3386,7 +3486,7 @@ tree_verify_flow_info (void)
vec = SWITCH_LABELS (stmt);
n = TREE_VEC_LENGTH (vec);
- /* Mark all destination basic block. */
+ /* Mark all the destination basic blocks. */
for (i = 0; i < n; ++i)
{
tree lab = CASE_LABEL (TREE_VEC_ELT (vec, i));
@@ -3414,7 +3514,8 @@ tree_verify_flow_info (void)
err = 1;
}
}
- /* Check we do have all of them. */
+
+ /* Check that we have all of them. */
for (i = 0; i < n; ++i)
{
tree lab = CASE_LABEL (TREE_VEC_ELT (vec, i));
@@ -3427,6 +3528,7 @@ tree_verify_flow_info (void)
err = 1;
}
}
+
for (e = bb->succ; e; e = e->succ_next)
e->dest->aux = (void *)0;
}
@@ -3441,6 +3543,7 @@ tree_verify_flow_info (void)
return err;
}
+
/* Updates phi nodes after creating forwarder block joined
by edge FALLTHRU. */
@@ -3457,8 +3560,8 @@ tree_make_forwarder_block (edge fallthru
if (!bb->pred->pred_next)
return;
- /* If we redirected a branch we must create new phi nodes on the start of
- bb. */
+ /* If we redirected a branch we must create new phi nodes at the
+ start of BB. */
for (phi = phi_nodes (dummy); phi; phi = TREE_CHAIN (phi))
{
var = PHI_RESULT (phi);
@@ -3468,7 +3571,7 @@ tree_make_forwarder_block (edge fallthru
add_phi_arg (&new_phi, PHI_RESULT (phi), fallthru);
}
- /* Ensure that the phi node chains are in the same order. */
+ /* Ensure that the PHI node chains are in the same order. */
set_phi_nodes (bb, nreverse (phi_nodes (bb)));
/* Add the arguments we have stored on edges. */
@@ -3481,10 +3584,12 @@ tree_make_forwarder_block (edge fallthru
phi;
phi = TREE_CHAIN (phi), var = TREE_CHAIN (var))
add_phi_arg (&phi, TREE_VALUE (var), e);
+
PENDING_STMT (e) = NULL;
}
}
+
/* Return true if basic block BB does nothing except pass control
flow to another block and that we can safely insert a label at
the start of the successor block. */
@@ -3495,8 +3600,8 @@ tree_forwarder_block_p (basic_block bb)
block_stmt_iterator bsi;
edge e;
- /* If we have already determined this block is not forwardable, then
- no further checks are necessary. */
+ /* If we have already determined that this block is not forwardable,
+ then no further checks are necessary. */
if (! bb_ann (bb)->forwardable)
return false;
@@ -3551,7 +3656,8 @@ tree_forwarder_block_p (basic_block bb)
return true;
}
-/* Threads jumps over empty statements.
+
+/* Thread jumps over empty statements.
This code should _not_ thread over obviously equivalent conditions
as that requires nontrivial updates to the SSA graph. */
@@ -3579,7 +3685,7 @@ thread_jumps (void)
continue;
/* This block is now part of a forwarding path, mark it as not
- forwardable so that we can detect loops. This bit will be
+ forwardable so that we can detect loops. This bit will be
reset below. */
bb_ann (bb)->forwardable = 0;
@@ -3595,8 +3701,9 @@ thread_jumps (void)
|| !tree_forwarder_block_p (e->dest))
continue;
- /* Now walk though as many forwarder block as possible to find
- the ultimate destination we want to thread our jump to. */
+ /* Now walk through as many forwarder block as possible to
+ find the ultimate destination we want to thread our jump
+ to. */
last = e->dest->succ;
bb_ann (e->dest)->forwardable = 0;
for (dest = e->dest->succ->dest;
@@ -3653,7 +3760,7 @@ thread_jumps (void)
if (!old)
{
- /* Update phi nodes. We know that the new argument should
+ /* Update PHI nodes. We know that the new argument should
have the same value as the argument associated with LAST.
Otherwise we would have changed our target block above. */
for (phi = phi_nodes (dest); phi; phi = TREE_CHAIN (phi))
@@ -3670,9 +3777,11 @@ thread_jumps (void)
a forwarding chain path. */
bb_ann (bb)->forwardable = 1;
}
+
return retval;
}
+
/* Return a non-special label in the head of basic block BLOCK.
Create one if it doesn't exist. */
@@ -3703,10 +3812,12 @@ tree_block_label (basic_block bb)
return label;
}
-/* Attempt to perform edge redirection by replacing possibly complex jump
- instruction by goto or removing jump completely. This can apply only
- if all edges now point to the same block. The parameters and
- return values are equivalent to redirect_edge_and_branch. */
+
+/* Attempt to perform edge redirection by replacing a possibly complex
+ jump instruction by a goto or by removing the jump completely.
+ This can apply only if all edges now point to the same block. The
+ parameters and return values are equivalent to
+ redirect_edge_and_branch. */
static edge
tree_try_redirect_by_replacing_jump (edge e, basic_block target)
@@ -3741,8 +3852,9 @@ tree_try_redirect_by_replacing_jump (edg
return NULL;
}
-/* Redirect E to DEST. Return NULL on failure, edge representing redirected
- branch otherwise. */
+
+/* Redirect E to DEST. Return NULL on failure. Otherwise, return the
+ edge representing the redirected branch. */
static edge
tree_redirect_edge_and_branch (edge e, basic_block dest)
@@ -3777,8 +3889,8 @@ tree_redirect_edge_and_branch (edge e, b
break;
case GOTO_EXPR:
- /* No nonabnormal edges should lead from a non-simple goto, and simple
- ones should be represented implicitly. */
+ /* No non-abnormal edges should lead from a non-simple goto, and
+ simple ones should be represented implicitly. */
abort ();
case SWITCH_EXPR:
@@ -3802,7 +3914,7 @@ tree_redirect_edge_and_branch (edge e, b
default:
/* Otherwise it must be a fallthru edge, and we don't need to
- do anything except for redirecting it. */
+ do anything besides redirecting it. */
if (!(e->flags & EDGE_FALLTHRU))
abort ();
break;
@@ -3816,7 +3928,8 @@ tree_redirect_edge_and_branch (edge e, b
return e;
}
-/* Simple wrapper as we always can redirect fallthru edges. */
+
+/* Simple wrapper, as we can always redirect fallthru edges. */
static basic_block
tree_redirect_edge_and_branch_force (edge e, basic_block dest)
@@ -3828,8 +3941,9 @@ tree_redirect_edge_and_branch_force (edg
return NULL;
}
+
/* Splits basic block BB after statement STMT (but at least after the
- labels). If STMT is NULL, the BB is split just after the labels. */
+ labels). If STMT is NULL, BB is split just after the labels. */
static basic_block
tree_split_block (basic_block bb, void *stmt)
@@ -3878,6 +3992,7 @@ tree_split_block (basic_block bb, void *
return new_bb;
}
+
/* Moves basic block BB after block AFTER. */
static bool
@@ -3892,14 +4007,18 @@ tree_move_block_after (basic_block bb, b
return true;
}
+
/* Return true if basic_block can be duplicated. */
+
static bool
tree_can_duplicate_bb_p (basic_block bb ATTRIBUTE_UNUSED)
{
return true;
}
-/* Create a duplicate of the basic block BB. Does not work over ssa. */
+
+/* Create a duplicate of the basic block BB. NOTE: This does not
+ preserve SSA form. */
static basic_block
tree_duplicate_bb (basic_block bb)
@@ -3922,6 +4041,7 @@ tree_duplicate_bb (basic_block bb)
return new_bb;
}
+
/* Dump FUNCTION_DECL FN to file FILE using FLAGS (see TDF_* in tree.h) */
void
@@ -3950,8 +4070,8 @@ dump_function_to_file (tree fn, FILE *fi
return;
}
- /* When gimple is lowered, the variables are no longer available in the
- bind_exprs, so display them separately. */
+ /* When GIMPLE is lowered, the variables are no longer available in
+ BIND_EXPRs, so display them separately. */
if (cfun && cfun->unexpanded_var_list)
{
ignore_topmost_bind = true;
@@ -3970,7 +4090,7 @@ dump_function_to_file (tree fn, FILE *fi
if (basic_block_info)
{
- /* Make a cfg based dump. */
+ /* Make a CFG based dump. */
if (!ignore_topmost_bind)
fprintf (file, "{\n");
@@ -3978,9 +4098,7 @@ dump_function_to_file (tree fn, FILE *fi
fprintf (file, "\n");
FOR_EACH_BB (bb)
- {
- dump_generic_bb (file, bb, 2, flags);
- }
+ dump_generic_bb (file, bb, 2, flags);
fprintf (file, "}\n");
}
@@ -4019,17 +4137,17 @@ dump_function_to_file (tree fn, FILE *fi
fprintf (file, "\n\n");
}
-/* Pretty print of the loops intermediate representation. */
+/* Pretty print of the loops intermediate representation. */
static void print_loop (FILE *, struct loop *, int);
static void print_pred_bbs (FILE *, edge);
static void print_succ_bbs (FILE *, edge);
-/* Print the predecessors indexes. */
+
+/* Print the predecessors indexes of edge E on FILE. */
static void
-print_pred_bbs (FILE *file,
- edge e)
+print_pred_bbs (FILE *file, edge e)
{
if (e == NULL)
return;
@@ -4044,18 +4162,16 @@ print_pred_bbs (FILE *file,
}
}
-/* Print the successors indexes. */
+
+/* Print the successors indexes of edge E on FILE. */
static void
-print_succ_bbs (FILE *file,
- edge e)
+print_succ_bbs (FILE *file, edge e)
{
if (e == NULL)
return;
-
else if (e->succ_next == NULL)
fprintf (file, "bb_%d", e->dest->index);
-
else
{
fprintf (file, "bb_%d, ", e->dest->index);
@@ -4063,12 +4179,11 @@ print_succ_bbs (FILE *file,
}
}
-/* Pretty print a loop on the given file. */
+
+/* Pretty print LOOP on FILE, indented INDENT spaces. */
static void
-print_loop (FILE *file,
- struct loop *loop,
- int indent)
+print_loop (FILE *file, struct loop *loop, int indent)
{
char *s_indent;
basic_block bb;
@@ -4080,7 +4195,6 @@ print_loop (FILE *file,
memset ((void *) s_indent, ' ', (size_t) indent);
s_indent[indent] = '\0';
-
/* Print the loop's header. */
fprintf (file, "%sloop_%d\n", s_indent, loop->num);
@@ -4107,8 +4221,9 @@ print_loop (FILE *file,
print_loop (file, loop->next, indent);
}
+
/* Follow a CFG edge from the entry point of the program, and on entry
- of a loop, pretty print the loop structure. */
+ of a loop, pretty print the loop structure on FILE. */
void
print_loop_ir (FILE *file)
@@ -4120,6 +4235,7 @@ print_loop_ir (FILE *file)
print_loop (file, bb->loop_father, 0);
}
+
/* Debugging loops structure at tree level. */
void
@@ -4128,22 +4244,29 @@ debug_loop_ir (void)
print_loop_ir (stderr);
}
-/* Return 1 if BB ends with a call, possibly followed by some
- instructions that must stay with the call, 0 otherwise. */
+
+/* Return true if BB ends with a call, possibly followed by some
+ instructions that must stay with the call. Return false,
+ otherwise. */
static bool
tree_block_ends_with_call_p (basic_block bb)
{
block_stmt_iterator bsi = bsi_last (bb);
tree t = tsi_stmt (bsi.tsi);
+
if (TREE_CODE (t) == RETURN_EXPR && TREE_OPERAND (t, 0))
t = TREE_OPERAND (t, 0);
+
if (TREE_CODE (t) == MODIFY_EXPR)
t = TREE_OPERAND (t, 1);
+
return TREE_CODE (t) == CALL_EXPR;
}
-/* Return 1 if BB ends with a conditional branch, 0 otherwise. */
+
+/* Return true if BB ends with a conditional branch. Return false,
+ otherwise. */
static bool
tree_block_ends_with_condjump_p (basic_block bb)
@@ -4152,7 +4275,8 @@ tree_block_ends_with_condjump_p (basic_b
return (TREE_CODE (stmt) == COND_EXPR);
}
-/* Return true if we need to add fake edge to exit.
+
+/* Return true if we need to add fake edge to exit at statement T.
Helper function for tree_flow_call_edges_add. */
static bool
@@ -4160,6 +4284,7 @@ need_fake_edge_p (tree t)
{
if (TREE_CODE (t) == RETURN_EXPR && TREE_OPERAND (t, 0))
t = TREE_OPERAND (t, 0);
+
if (TREE_CODE (t) == MODIFY_EXPR)
t = TREE_OPERAND (t, 1);
@@ -4182,13 +4307,14 @@ need_fake_edge_p (tree t)
return false;
}
-/* Add fake edges to the function exit for any non constant and non noreturn
- calls, volatile inline assembly in the bitmap of blocks specified by
- BLOCKS or to the whole CFG if BLOCKS is zero. Return the number of blocks
- that were split.
- The goal is to expose cases in which entering a basic block does not imply
- that all subsequent instructions must be executed. */
+/* Add fake edges to the function exit for any non constant and non
+ noreturn calls, volatile inline assembly in the bitmap of blocks
+ specified by BLOCKS or to the whole CFG if BLOCKS is zero. Return
+ the number of blocks that were split.
+
+ The goal is to expose cases in which entering a basic block does
+ not imply that all subsequent instructions must be executed. */
static int
tree_flow_call_edges_add (sbitmap blocks)
@@ -4243,7 +4369,6 @@ tree_flow_call_edges_add (sbitmap blocks
/* Now add fake edges to the function exit for any non constant
calls since there is no way that we can determine if they will
return or not... */
-
for (i = 0; i < last_bb; i++)
{
basic_block bb = BASIC_BLOCK (i);
@@ -4266,11 +4391,11 @@ tree_flow_call_edges_add (sbitmap blocks
if (need_fake_edge_p (stmt))
{
edge e;
- /* The handling above of the final block before the epilogue
- should be enough to verify that there is no edge to the exit
- block in CFG already. Calling make_edge in such case would
- cause us to mark that edge as fake and remove it later. */
-
+ /* The handling above of the final block before the
+ epilogue should be enough to verify that there is
+ no edge to the exit block in CFG already.
+ Calling make_edge in such case would cause us to
+ mark that edge as fake and remove it later. */
#ifdef ENABLE_CHECKING
if (stmt == last_stmt)
for (e = bb->succ; e; e = e->succ_next)
@@ -4300,8 +4425,7 @@ tree_flow_call_edges_add (sbitmap blocks
return blocks_split;
}
-/* FIXME These need to be filled in with appropriate pointers. But this
- implies an ABI change in some functions. */
+
struct cfg_hooks tree_cfg_hooks = {
"tree",
tree_verify_flow_info,
@@ -4343,7 +4467,6 @@ split_critical_edges (void)
split_edge (e);
}
}
-
}
struct tree_opt_pass pass_split_crit_edges =
@@ -4362,6 +4485,8 @@ struct tree_opt_pass pass_split_crit_edg
0, /* todo_flags_finish */
};
+/* Emit return warnings. */
+
static void
execute_warn_function_return (void)
{
@@ -4415,10 +4540,11 @@ execute_warn_function_return (void)
}
}
-/* Given a basic block which ends with a conditional and has precisely
- two successors, determine which of the edges is taken if the conditional
- is true and which is taken if the conditional is false. Set TRUE_EDGE
- and FALSE_EDGE appropriately. */
+
+/* Given a basic block B which ends with a conditional and has
+ precisely two successors, determine which of the edges is taken if
+ the conditional is true and which is taken if the conditional is
+ false. Set TRUE_EDGE and FALSE_EDGE appropriately. */
void
extract_true_false_edges_from_block (basic_block b,
Index: tree-flow.h
===================================================================
RCS file: /cvs/gcc/gcc/gcc/Attic/tree-flow.h,v
retrieving revision 1.1.4.198
diff -d -c -p -d -u -p -r1.1.4.198 tree-flow.h
--- tree-flow.h 23 Mar 2004 23:21:07 -0000 1.1.4.198
+++ tree-flow.h 25 Mar 2004 15:46:32 -0000
@@ -436,7 +436,6 @@ extern void bsi_replace (const block_stm
/* Location to track pending stmt for edge insertion. */
#define PENDING_STMT(e) ((e)->insns.t)
-extern void build_tree_cfg (tree *);
extern void delete_tree_cfg (void);
extern void disband_implicit_edges (void);
extern bool stmt_ends_bb_p (tree);
@@ -451,7 +450,6 @@ extern void dump_tree_cfg (FILE *, int);
extern void debug_tree_cfg (int);
extern void dump_cfg_stats (FILE *);
extern void debug_cfg_stats (void);
-extern void tree_cfg2dot (FILE *);
extern void debug_loop_ir (void);
extern void print_loop_ir (FILE *);
extern void cleanup_tree_cfg (void);
@@ -467,11 +465,9 @@ extern void tree_optimize_tail_calls (bo
extern edge tree_block_forwards_to (basic_block bb);
extern void bsi_insert_on_edge (edge, tree);
extern void bsi_commit_edge_inserts (int *);
-extern void bsi_insert_on_edge_immediate (edge, tree);
extern void notice_special_calls (tree);
extern void clear_special_calls (void);
extern void compute_dominance_frontiers (bitmap *);
-extern bool verify_stmt (tree);
extern void verify_stmts (void);
extern void extract_true_false_edges_from_block (basic_block, edge *, edge *);
Index: tree-ssa-pre.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/Attic/tree-ssa-pre.c,v
retrieving revision 1.1.4.134
diff -d -c -p -d -u -p -r1.1.4.134 tree-ssa-pre.c
--- tree-ssa-pre.c 16 Mar 2004 22:31:56 -0000 1.1.4.134
+++ tree-ssa-pre.c 25 Mar 2004 15:46:32 -0000
@@ -2084,6 +2084,8 @@ static void
insert_one_operand (struct expr_info *ei, tree ephi, int opnd_indx,
tree x, edge succ, tree **avdefsp)
{
+ /* FIXME. pre_insert_on_edge should probably disappear. */
+ extern void pre_insert_on_edge (edge, tree);
tree expr;
tree temp = ei->temp;
tree copy;
@@ -2112,11 +2114,11 @@ insert_one_operand (struct expr_info *ei
}
/* Do the insertion. */
- /* ??? Previously we did bizzare searching, presumably to get
+ /* ??? Previously we did bizarre searching, presumably to get
around bugs elsewhere in the infrastructure. I'm not sure
- if we really should be using bsi_insert_on_edge_immediate,
+ if we really should be using pre_insert_on_edge
or just bsi_insert_after at the end of BB. */
- bsi_insert_on_edge_immediate (succ, expr);
+ pre_insert_on_edge (succ, expr);
EPHI_ARG_DEF (ephi, opnd_indx)
= create_expr_ref (ei, ei->expr, EUSE_NODE, bb, 0);