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. */
+Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301, USA. */
/* Dead code elimination.
#include "system.h"
#include "coretypes.h"
#include "tm.h"
-#include "errors.h"
#include "ggc.h"
/* These RTL headers are needed for basic-block.h. */
processed that it is control dependent on. */
static sbitmap visited_control_parents;
+/* TRUE if this pass alters the CFG (by removing control statements).
+ FALSE otherwise.
+
+ If this pass alters the CFG, then it will arrange for the dominators
+ to be recomputed. */
+static bool cfg_altered;
+
/* Execute CODE for each edge (given number EDGE_NUMBER within the CODE)
for which the block with index N is control dependent. */
#define EXECUTE_IF_CONTROL_DEPENDENT(N, EDGE_NUMBER, CODE) \
tree op, def;
ssa_op_iter iter;
+ /* With non-call exceptions, we have to assume that all statements could
+ throw. If a statement may throw, it is inherently necessary. */
+ if (flag_non_call_exceptions
+ && tree_could_throw_p (stmt))
+ {
+ mark_stmt_necessary (stmt, true);
+ return;
+ }
+
/* Statements that are implicitly live. Most function calls, asm and return
statements are required. Labels and BIND_EXPR nodes are kept because
they are control flow, and we have no way of knowing whether they can be
}
}
\f
-/* Remove dead statement pointed by iterator I. Receives the basic block BB
+/* Remove dead statement pointed to by iterator I. Receives the basic block BB
containing I so that we don't have to look it up. */
static void
nothing to the program, then we not only remove it, but we also change
the flow graph so that the current block will simply fall-thru to its
immediate post-dominator. The blocks we are circumventing will be
- removed by cleaup_cfg if this change in the flow graph makes them
+ removed by cleaup_tree_cfg if this change in the flow graph makes them
unreachable. */
if (is_ctrl_stmt (t))
{
/* Remove the remaining the outgoing edges. */
while (!single_succ_p (bb))
- remove_edge (EDGE_SUCC (bb, 1));
+ {
+ /* FIXME. When we remove the edge, we modify the CFG, which
+ in turn modifies the dominator and post-dominator tree.
+ Is it safe to postpone recomputing the dominator and
+ post-dominator tree until the end of this pass given that
+ the post-dominators are used above? */
+ cfg_altered = true;
+ remove_edge (EDGE_SUCC (bb, 1));
+ }
}
- FOR_EACH_SSA_DEF_OPERAND (def_p, t, iter,
- SSA_OP_VIRTUAL_DEFS | SSA_OP_VIRTUAL_KILLS)
+ FOR_EACH_SSA_DEF_OPERAND (def_p, t, iter, SSA_OP_VIRTUAL_DEFS)
{
tree def = DEF_FROM_PTR (def_p);
mark_sym_for_renaming (SSA_NAME_VAR (def));
sbitmap_zero (processed);
worklist = VEC_alloc (tree, heap, 64);
+ cfg_altered = false;
}
/* Cleanup after this pass. */
if (aggressive)
free_dominance_info (CDI_POST_DOMINATORS);
+ /* If we removed paths in the CFG, then we need to update
+ dominators as well. I haven't investigated the possibility
+ of incrementally updating dominators. */
+ if (cfg_altered)
+ free_dominance_info (CDI_DOMINATORS);
+
/* Debugging dumps. */
if (dump_file)
print_stats ();