OSDN Git Service
(root)
/
pf3gnuchains
/
gcc-fork.git
/ blobdiff
commit
grep
author
committer
pickaxe
?
search:
re
summary
|
shortlog
|
log
|
commit
|
commitdiff
|
tree
raw
|
inline
| side by side
Fix PR32824.
[pf3gnuchains/gcc-fork.git]
/
gcc
/
tree-cfgcleanup.c
diff --git
a/gcc/tree-cfgcleanup.c
b/gcc/tree-cfgcleanup.c
index
eae0c84
..
b8f5a54
100644
(file)
--- a/
gcc/tree-cfgcleanup.c
+++ b/
gcc/tree-cfgcleanup.c
@@
-1,5
+1,5
@@
/* CFG cleanup for trees.
/* CFG cleanup for trees.
- Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009
+ Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009
, 2010
Free Software Foundation, Inc.
This file is part of GCC.
Free Software Foundation, Inc.
This file is part of GCC.
@@
-23,9
+23,7
@@
along with GCC; see the file COPYING3. If not see
#include "coretypes.h"
#include "tm.h"
#include "tree.h"
#include "coretypes.h"
#include "tm.h"
#include "tree.h"
-#include "rtl.h"
#include "tm_p.h"
#include "tm_p.h"
-#include "hard-reg-set.h"
#include "basic-block.h"
#include "output.h"
#include "toplev.h"
#include "basic-block.h"
#include "output.h"
#include "toplev.h"
@@
-103,20
+101,28
@@
cleanup_control_expr_graph (basic_block bb, gimple_stmt_iterator gsi)
/* For conditions try harder and lookup single-argument
PHI nodes. Only do so from the same basic-block though
as other basic-blocks may be dead already. */
/* For conditions try harder and lookup single-argument
PHI nodes. Only do so from the same basic-block though
as other basic-blocks may be dead already. */
- if (TREE_CODE (lhs) == SSA_NAME)
+ if (TREE_CODE (lhs) == SSA_NAME
+ && !name_registered_for_update_p (lhs))
{
gimple def_stmt = SSA_NAME_DEF_STMT (lhs);
if (gimple_code (def_stmt) == GIMPLE_PHI
&& gimple_phi_num_args (def_stmt) == 1
{
gimple def_stmt = SSA_NAME_DEF_STMT (lhs);
if (gimple_code (def_stmt) == GIMPLE_PHI
&& gimple_phi_num_args (def_stmt) == 1
- && gimple_bb (def_stmt) == gimple_bb (stmt))
+ && gimple_bb (def_stmt) == gimple_bb (stmt)
+ && (TREE_CODE (PHI_ARG_DEF (def_stmt, 0)) != SSA_NAME
+ || !name_registered_for_update_p (PHI_ARG_DEF (def_stmt,
+ 0))))
lhs = PHI_ARG_DEF (def_stmt, 0);
}
lhs = PHI_ARG_DEF (def_stmt, 0);
}
- if (TREE_CODE (rhs) == SSA_NAME)
+ if (TREE_CODE (rhs) == SSA_NAME
+ && !name_registered_for_update_p (rhs))
{
gimple def_stmt = SSA_NAME_DEF_STMT (rhs);
if (gimple_code (def_stmt) == GIMPLE_PHI
&& gimple_phi_num_args (def_stmt) == 1
{
gimple def_stmt = SSA_NAME_DEF_STMT (rhs);
if (gimple_code (def_stmt) == GIMPLE_PHI
&& gimple_phi_num_args (def_stmt) == 1
- && gimple_bb (def_stmt) == gimple_bb (stmt))
+ && gimple_bb (def_stmt) == gimple_bb (stmt)
+ && (TREE_CODE (PHI_ARG_DEF (def_stmt, 0)) != SSA_NAME
+ || !name_registered_for_update_p (PHI_ARG_DEF (def_stmt,
+ 0))))
rhs = PHI_ARG_DEF (def_stmt, 0);
}
val = fold_binary_loc (loc, gimple_cond_code (stmt),
rhs = PHI_ARG_DEF (def_stmt, 0);
}
val = fold_binary_loc (loc, gimple_cond_code (stmt),
@@
-259,6
+265,7
@@
static bool
tree_forwarder_block_p (basic_block bb, bool phi_wanted)
{
gimple_stmt_iterator gsi;
tree_forwarder_block_p (basic_block bb, bool phi_wanted)
{
gimple_stmt_iterator gsi;
+ location_t locus;
/* BB must have a single outgoing edge. */
if (single_succ_p (bb) != 1
/* BB must have a single outgoing edge. */
if (single_succ_p (bb) != 1
@@
-277,6
+284,8
@@
tree_forwarder_block_p (basic_block bb, bool phi_wanted)
gcc_assert (bb != ENTRY_BLOCK_PTR);
#endif
gcc_assert (bb != ENTRY_BLOCK_PTR);
#endif
+ locus = single_succ_edge (bb)->goto_locus;
+
/* There should not be an edge coming from entry, or an EH edge. */
{
edge_iterator ei;
/* There should not be an edge coming from entry, or an EH edge. */
{
edge_iterator ei;
@@
-285,6
+294,10
@@
tree_forwarder_block_p (basic_block bb, bool phi_wanted)
FOR_EACH_EDGE (e, ei, bb->preds)
if (e->src == ENTRY_BLOCK_PTR || (e->flags & EDGE_EH))
return false;
FOR_EACH_EDGE (e, ei, bb->preds)
if (e->src == ENTRY_BLOCK_PTR || (e->flags & EDGE_EH))
return false;
+ /* If goto_locus of any of the edges differs, prevent removing
+ the forwarder block for -O0. */
+ else if (optimize == 0 && e->goto_locus != locus)
+ return false;
}
/* Now walk through the statements backward. We can ignore labels,
}
/* Now walk through the statements backward. We can ignore labels,
@@
-298,6
+311,8
@@
tree_forwarder_block_p (basic_block bb, bool phi_wanted)
case GIMPLE_LABEL:
if (DECL_NONLOCAL (gimple_label_label (stmt)))
return false;
case GIMPLE_LABEL:
if (DECL_NONLOCAL (gimple_label_label (stmt)))
return false;
+ if (optimize == 0 && gimple_location (stmt) != locus)
+ return false;
break;
/* ??? For now, hope there's a corresponding debug
break;
/* ??? For now, hope there's a corresponding debug
@@
-600,11
+615,7
@@
cleanup_tree_cfg_bb (basic_block bb)
retval = cleanup_control_flow_bb (bb);
retval = cleanup_control_flow_bb (bb);
- /* Forwarder blocks can carry line number information which is
- useful when debugging, so we only clean them up when
- optimizing. */
- if (optimize > 0
- && tree_forwarder_block_p (bb, false)
+ if (tree_forwarder_block_p (bb, false)
&& remove_forwarder_block (bb))
return true;
&& remove_forwarder_block (bb))
return true;