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. */
+the Free Software Foundation, 51 Franklin Street, Fifth Floor,
+Boston, MA 02110-1301, USA. */
#include "config.h"
#include "system.h"
#include "ggc.h"
#include "basic-block.h"
#include "output.h"
-#include "errors.h"
#include "expr.h"
#include "function.h"
#include "diagnostic.h"
bool jumps_threaded;
};
+/* Jump threading statistics. */
+
+struct thread_stats_d
+{
+ unsigned long num_threaded_edges;
+};
+
+struct thread_stats_d thread_stats;
+
+
/* Remove the last statement in block BB if it is a control statement
Also remove all outgoing edges except the edge which reaches DEST_BB.
If DEST_BB is NULL, then remove all outgoing edges. */
if (!bsi_end_p (bsi)
&& bsi_stmt (bsi)
&& (TREE_CODE (bsi_stmt (bsi)) == COND_EXPR
+ || TREE_CODE (bsi_stmt (bsi)) == GOTO_EXPR
|| TREE_CODE (bsi_stmt (bsi)) == SWITCH_EXPR))
bsi_remove (&bsi);
edges associated with E in the hash table. */
static struct redirection_data *
-lookup_redirection_data (edge e, edge incoming_edge, bool insert)
+lookup_redirection_data (edge e, edge incoming_edge, enum insert_option insert)
{
void **slot;
struct redirection_data *elt;
edge e = make_edge (rd->dup_block, rd->outgoing_edge->dest, EDGE_FALLTHRU);
tree phi;
+ e->probability = REG_BR_PROB_BASE;
+ e->count = rd->dup_block->count;
+
/* If there are any PHI nodes at the destination of the outgoing edge
from the duplicate block, then we will need to add a new argument
to them. The argument should have the same value as the argument
for (phi = phi_nodes (e->dest); phi; phi = PHI_CHAIN (phi))
{
int indx = rd->outgoing_edge->dest_idx;
- add_phi_arg (phi, PHI_ARG_DEF_TREE (phi, indx), e);
+ add_phi_arg (phi, PHI_ARG_DEF (phi, indx), e);
}
}
to clear it will cause all kinds of unpleasant problems later. */
e->aux = NULL;
+ thread_stats.num_threaded_edges++;
+
if (rd->dup_block)
{
edge e2;
rd->outgoing_edge->dest);
/* And fixup the flags on the single remaining edge. */
- EDGE_SUCC (local_info->bb, 0)->flags
+ single_succ_edge (local_info->bb)->flags
&= ~(EDGE_TRUE_VALUE | EDGE_FALSE_VALUE | EDGE_ABNORMAL);
- EDGE_SUCC (local_info->bb, 0)->flags |= EDGE_FALLTHRU;
+ single_succ_edge (local_info->bb)->flags |= EDGE_FALLTHRU;
}
}
the appropriate duplicate of BB.
BB and its duplicates will have assignments to the same set of
- SSA_NAMEs. Right now, we just call into rewrite_ssa_into_ssa
- to update the SSA graph for those names.
+ SSA_NAMEs. Right now, we just call into update_ssa to update the
+ SSA graph for those names.
We are also going to experiment with a true incremental update
scheme for the duplicated resources. One of the interesting
/* Insert the outgoing edge into the hash table if it is not
already in the hash table. */
- lookup_redirection_data (e2, e, true);
+ lookup_redirection_data (e2, e, INSERT);
}
}
if (all)
{
edge e = EDGE_PRED (bb, 0)->aux;
- lookup_redirection_data (e, NULL, false)->do_not_duplicate = true;
+ lookup_redirection_data (e, NULL, NO_INSERT)->do_not_duplicate = true;
}
/* Now create duplicates of BB.
Returns true if one or more edges were threaded, false otherwise. */
bool
-thread_through_all_blocks (void)
+thread_through_all_blocks (bitmap threaded_blocks)
{
- basic_block bb;
bool retval = false;
+ unsigned int i;
+ bitmap_iterator bi;
rediscover_loops_after_threading = false;
+ memset (&thread_stats, 0, sizeof (thread_stats));
- FOR_EACH_BB (bb)
+ EXECUTE_IF_SET_IN_BITMAP (threaded_blocks, 0, i, bi)
{
- if (bb_ann (bb)->incoming_edge_threaded)
- {
- retval |= thread_block (bb);
- bb_ann (bb)->incoming_edge_threaded = false;
-
- }
+ basic_block bb = BASIC_BLOCK (i);
+
+ if (EDGE_COUNT (bb->preds) > 0)
+ retval |= thread_block (bb);
}
+ if (dump_file && (dump_flags & TDF_STATS))
+ fprintf (dump_file, "\nJumps threaded: %lu\n",
+ thread_stats.num_threaded_edges);
+
return retval;
}