#include "params.h"
#include "tm_p.h"
#include "target.h"
+#include "regs.h"
/* cleanup_cfg maintains following flags for each basic block. */
#define FORWARDER_BLOCK_P(BB) (BB_FLAGS (BB) & BB_FORWARDER_BLOCK)
+/* Set to true when we are running first pass of try_optimize_cfg loop. */
+static bool first_pass;
static bool try_crossjump_to_edge (int, edge, edge);
static bool try_crossjump_bb (int, basic_block);
static bool outgoing_edges_match (int, basic_block, basic_block);
}
}
/* Delete the block with the unconditional jump, and clean up the mess. */
- delete_block (jump_block);
- tidy_fallthru_edge (cbranch_jump_edge, cbranch_block, cbranch_dest_block);
+ delete_basic_block (jump_block);
+ tidy_fallthru_edge (cbranch_jump_edge);
return true;
}
CLEAR_REGNO_REG_SET (nonequal, regno);
if (regno < FIRST_PSEUDO_REGISTER)
{
- int n = HARD_REGNO_NREGS (regno, GET_MODE (dest));
+ int n = hard_regno_nregs[regno][GET_MODE (dest)];
while (--n > 0)
CLEAR_REGNO_REG_SET (nonequal, regno + n);
}
SET_REGNO_REG_SET (nonequal, regno);
if (regno < FIRST_PSEUDO_REGISTER)
{
- int n = HARD_REGNO_NREGS (regno, GET_MODE (dest));
+ int n = hard_regno_nregs[regno][GET_MODE (dest)];
while (--n > 0)
SET_REGNO_REG_SET (nonequal, regno + n);
}
return 1;
if (regno < FIRST_PSEUDO_REGISTER)
{
- int n = HARD_REGNO_NREGS (regno, GET_MODE (*x));
+ int n = hard_regno_nregs[regno][GET_MODE (*x)];
while (--n > 0)
if (REGNO_REG_SET_P (nonequal, regno + n))
return 1;
int counter;
bool threaded = false;
int nthreaded_edges = 0;
+ bool may_thread = first_pass | (b->flags & BB_DIRTY);
next = e->succ_next;
{
basic_block new_target = NULL;
bool new_target_threaded = false;
+ may_thread |= target->flags & BB_DIRTY;
if (FORWARDER_BLOCK_P (target)
&& target->succ->dest != EXIT_BLOCK_PTR)
/* Allow to thread only over one edge at time to simplify updating
of probabilities. */
- else if (mode & CLEANUP_THREADING)
+ else if ((mode & CLEANUP_THREADING) && may_thread)
{
edge t = thread_jump (mode, e, target);
if (t)
to_remove = redirect_from->succ->dest;
redirect_edge_and_branch_force (redirect_from->succ, redirect_to);
- delete_block (to_remove);
+ delete_basic_block (to_remove);
update_forwarder_flag (redirect_from);
If there is a match, we'll do it the other way around. */
if (e == fallthru)
continue;
+ /* If nothing changed since the last attempt, there is nothing
+ we can do. */
+ if (!first_pass
+ && (!(e->src->flags & BB_DIRTY)
+ && !(fallthru->src->flags & BB_DIRTY)))
+ continue;
if (try_crossjump_to_edge (mode, e, fallthru))
{
if (e->src->index > e2->src->index)
continue;
+ /* If nothing changed since the last attempt, there is nothing
+ we can do. */
+ if (!first_pass
+ && (!(e->src->flags & BB_DIRTY)
+ && !(e2->src->flags & BB_DIRTY)))
+ continue;
+
if (try_crossjump_to_edge (mode, e, e2))
{
changed = true;
FOR_EACH_BB (bb)
update_forwarder_flag (bb);
- if (mode & CLEANUP_UPDATE_LIFE)
+ if (mode & (CLEANUP_UPDATE_LIFE | CLEANUP_CROSSJUMP | CLEANUP_THREADING))
clear_bb_flags ();
if (! (* targetm.cannot_modify_jumps_p) ())
{
+ first_pass = true;
/* Attempt to merge blocks as made possible by edge removal. If
a block has only one successor, and the successor has only
one predecessor, they may be combined. */
fprintf (rtl_dump_file, "Deleting block %i.\n",
b->index);
- delete_block (b);
+ delete_basic_block (b);
if (!(mode & CLEANUP_CFGLAYOUT))
changed = true;
b = c;
c = b->prev_bb == ENTRY_BLOCK_PTR ? b->next_bb : b->prev_bb;
redirect_edge_succ_nodup (b->pred, b->succ->dest);
- delete_block (b);
+ delete_basic_block (b);
changed = true;
b = c;
}
&& b->succ->dest != EXIT_BLOCK_PTR
&& onlyjump_p (BB_END (b))
&& try_redirect_by_replacing_jump (b->succ, b->succ->dest,
- (mode & CLEANUP_CFGLAYOUT)))
+ (mode & CLEANUP_CFGLAYOUT) != 0))
{
update_forwarder_flag (b);
changed_here = true;
#endif
changed_overall |= changed;
+ first_pass = false;
}
while (changed);
}
if (!(b->flags & BB_REACHABLE))
{
- delete_block (b);
+ delete_basic_block (b);
changed = true;
}
}
PROP_DEATH_NOTES
| PROP_SCAN_DEAD_CODE
| PROP_KILL_DEAD_CODE
- | PROP_LOG_LINKS))
+ | ((mode & CLEANUP_LOG_LINKS)
+ ? PROP_LOG_LINKS : 0)))
break;
}
else if (!(mode & (CLEANUP_NO_INSN_DEL | CLEANUP_PRE_SIBCALL))