}
}
-/* Checks that EXPR is invariant provided that INVARIANT_REGS are invariant. */
+/* Checks that EXPR is invariant provided that INVARIANT_REGS are invariant. */
static bool
invariant_rtx_wrto_regs_p (expr, invariant_regs)
rtx expr;
return true;
}
- /* Check the other operand. */
+ /* Check the other operand. */
if (!invariant_rtx_wrto_regs_p (op1, invariant_regs))
return false;
if (!REG_P (op0))
These cases needs to be either cared by copying the loop test in the front
of loop or keeping the test in first iteration of loop.
- When INIT/LIM are set, they are used instead of var/lim of DESC. */
+ When INIT/LIM are set, they are used instead of var/lim of DESC. */
rtx
count_loop_iterations (desc, init, lim)
struct loop_desc *desc;
if (stride != const1_rtx)
{
/* Number of iterations is now (EXP + STRIDE - 1 / STRIDE),
- but we need to take care for overflows. */
+ but we need to take care for overflows. */
mod = simplify_gen_binary (UMOD, GET_MODE (desc->var), exp, stride);
desc->var_alts = variable_initial_values (e, desc->var);
desc->lim_alts = variable_initial_values (e, desc->lim);
- /* Number of iterations. */
+ /* Number of iterations. */
if (!count_loop_iterations (desc, NULL, NULL))
return false;
desc->const_iter =
return any;
}
-/* Marks blocks that are part of non-recognized loops; i.e. we throw away
- all latch edges and mark blocks inside any remaining cycle. Everything
- is a bit complicated due to fact we do not want to do this for parts of
- cycles that only "pass" through some loop -- i.e. for each cycle, we want
- to mark blocks that belong directly to innermost loop containing the whole
- cycle. */
+/* Marks blocks and edges that are part of non-recognized loops; i.e. we
+ throw away all latch edges and mark blocks inside any remaining cycle.
+ Everything is a bit complicated due to fact we do not want to do this
+ for parts of cycles that only "pass" through some loop -- i.e. for
+ each cycle, we want to mark blocks that belong directly to innermost
+ loop containing the whole cycle. */
void
mark_irreducible_loops (loops)
struct loops *loops;
int *dfs_in, *closed, *mr, *mri, *n_edges, *stack;
unsigned i;
edge **edges, e;
+ edge *estack;
basic_block act;
int stack_top, tick, depth;
struct loop *cloop;
+ /* Reset the flags. */
+ FOR_BB_BETWEEN (act, ENTRY_BLOCK_PTR, EXIT_BLOCK_PTR, next_bb)
+ {
+ act->flags &= ~BB_IRREDUCIBLE_LOOP;
+ for (e = act->succ; e; e = e->succ_next)
+ e->flags &= ~EDGE_IRREDUCIBLE_LOOP;
+ }
+
/* The first last_basic_block + 1 entries are for real blocks (including
entry); then we have loops->num - 1 fake blocks for loops to that we
assign edges leading from loops (fake loop 0 is not interesting). */
n_edges = xmalloc ((last_basic_block + loops->num) * sizeof (int));
edges = xmalloc ((last_basic_block + loops->num) * sizeof (edge *));
stack = xmalloc ((n_basic_blocks + loops->num) * sizeof (int));
+ estack = xmalloc ((n_basic_blocks + loops->num) * sizeof (edge));
/* Create the edge lists. */
for (i = 0; i < last_basic_block + loops->num; i++)
stack_top = 0;
for (i = 0; i < loops->num; i++)
if (loops->parray[i])
- stack[stack_top++] = loops->parray[i]->header->index + 1;
+ {
+ stack[stack_top] = loops->parray[i]->header->index + 1;
+ estack[stack_top] = NULL;
+ stack_top++;
+ }
while (stack_top)
{
: e->dest->index + 1;
if (closed[sidx])
{
- if (mr[sidx] < mr[idx] && !closed[mri[sidx]])
+ if (!closed[mri[sidx]])
{
- mr[idx] = mr[sidx];
- mri[idx] = mri[sidx];
+ if (mr[sidx] < mr[idx])
+ {
+ mr[idx] = mr[sidx];
+ mri[idx] = mri[sidx];
+ }
+
+ if (mr[sidx] <= dfs_in[idx])
+ e->flags |= EDGE_IRREDUCIBLE_LOOP;
}
continue;
}
if (dfs_in[sidx] < 0)
{
- stack[stack_top++] = sidx;
+ stack[stack_top] = sidx;
+ estack[stack_top] = e;
+ stack_top++;
goto next;
}
if (dfs_in[sidx] < mr[idx])
mr[idx] = dfs_in[sidx];
mri[idx] = sidx;
}
+ e->flags |= EDGE_IRREDUCIBLE_LOOP;
}
/* Return back. */
closed[idx] = 1;
+ e = estack[stack_top - 1];
stack_top--;
- if (stack_top && dfs_in[stack[stack_top - 1]] >= 0)
+ if (e)
{
/* Propagate information back. */
sidx = stack[stack_top - 1];
mr[sidx] = mr[idx];
mri[sidx] = mri[idx];
}
+ if (mr[idx] <= dfs_in[sidx])
+ e->flags |= EDGE_IRREDUCIBLE_LOOP;
}
/* Mark the block if relevant. */
if (idx && idx <= last_basic_block && mr[idx] <= dfs_in[idx])
}
free (stack);
+ free (estack);
free (dfs_in);
free (closed);
free (mr);