/* Rtl-level loop invariant motion.
- Copyright (C) 2004 Free Software Foundation, Inc.
+ Copyright (C) 2004, 2005 Free Software Foundation, Inc.
This file is part of GCC.
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. */
/* This implements the loop invariant motion pass. It is very simple
(no calls, libcalls, etc.). This should be sufficient to cleanup things like
#include "tm.h"
#include "rtl.h"
#include "hard-reg-set.h"
+#include "obstack.h"
#include "basic-block.h"
#include "cfgloop.h"
#include "expr.h"
static unsigned actual_stamp;
+typedef struct invariant *invariant_p;
+
+DEF_VEC_P(invariant_p);
+DEF_VEC_ALLOC_P(invariant_p, heap);
+
/* The invariants. */
-static varray_type invariants;
+static VEC(invariant_p,heap) *invariants;
/* Test for possibility of invariantness of X. */
bitmap may_exit, bitmap has_exit)
{
unsigned i;
+ edge_iterator ei;
edge e;
struct loop *outermost_exit = loop, *aexit;
bool has_call = false;
}
}
- for (e = body[i]->succ; e; e = e->succ_next)
+ FOR_EACH_EDGE (e, ei, body[i]->succs)
{
if (flow_bb_inside_loop_p (loop, e->dest))
continue;
find_defs (struct loop *loop, basic_block *body, struct df *df)
{
unsigned i;
- bitmap blocks = BITMAP_XMALLOC ();
+ bitmap blocks = BITMAP_ALLOC (NULL);
for (i = 0; i < loop->num_nodes; i++)
bitmap_set_bit (blocks, body[i]->index);
df_analyze_subcfg (df, blocks, DF_UD_CHAIN | DF_HARD_REGS | DF_EQUIV_NOTES);
- BITMAP_XFREE (blocks);
+ BITMAP_FREE (blocks);
}
/* Creates a new invariant for definition DEF in INSN, depending on invariants
inv->stamp = 0;
inv->insn = insn;
- inv->invno = VARRAY_ACTIVE_SIZE (invariants);
+ inv->invno = VEC_length (invariant_p, invariants);
if (def)
def->invno = inv->invno;
- VARRAY_PUSH_GENERIC_PTR_NOGC (invariants, inv);
+ VEC_safe_push (invariant_p, heap, invariants, inv);
if (dump_file)
{
if (GET_CODE (*use) == SUBREG)
use = &SUBREG_REG (*use);
- if (!REG_P (*use))
- abort ();
+ gcc_assert (REG_P (*use));
u->pos = use;
u->insn = insn;
return;
dest = SET_DEST (set);
- if (GET_CODE (dest) != REG
+ if (!REG_P (dest)
|| HARD_REGISTER_P (dest))
simple = false;
return;
}
- depends_on = BITMAP_XMALLOC ();
+ depends_on = BITMAP_ALLOC (NULL);
if (!check_dependencies (insn, df, depends_on))
{
- BITMAP_XFREE (depends_on);
+ BITMAP_FREE (depends_on);
return;
}
static void
find_invariants (struct loop *loop, struct df *df)
{
- bitmap may_exit = BITMAP_XMALLOC ();
- bitmap always_reached = BITMAP_XMALLOC ();
- bitmap has_exit = BITMAP_XMALLOC ();
- bitmap always_executed = BITMAP_XMALLOC ();
+ bitmap may_exit = BITMAP_ALLOC (NULL);
+ bitmap always_reached = BITMAP_ALLOC (NULL);
+ bitmap has_exit = BITMAP_ALLOC (NULL);
+ bitmap always_executed = BITMAP_ALLOC (NULL);
basic_block *body = get_loop_body_in_dom_order (loop);
find_exits (loop, body, may_exit, has_exit);
find_defs (loop, body, df);
find_invariants_body (loop, body, always_reached, always_executed, df);
- BITMAP_XFREE (always_reached);
- BITMAP_XFREE (always_executed);
- BITMAP_XFREE (may_exit);
- BITMAP_XFREE (has_exit);
+ BITMAP_FREE (always_reached);
+ BITMAP_FREE (always_executed);
+ BITMAP_FREE (may_exit);
+ BITMAP_FREE (has_exit);
free (body);
}
unsigned aregs_needed;
unsigned depno;
struct invariant *dep;
+ bitmap_iterator bi;
*comp_cost = 0;
*regs_needed = 0;
(*regs_needed)++;
(*comp_cost) += inv->cost;
- EXECUTE_IF_SET_IN_BITMAP (inv->depends_on, 0, depno,
+ EXECUTE_IF_SET_IN_BITMAP (inv->depends_on, 0, depno, bi)
{
- dep = VARRAY_GENERIC_PTR_NOGC (invariants, depno);
+ dep = VEC_index (invariant_p, invariants, depno);
get_inv_cost (dep, &acomp_cost, &aregs_needed);
(*regs_needed) += aregs_needed;
(*comp_cost) += acomp_cost;
- });
+ }
}
/* Calculates gain for eliminating invariant INV. REGS_USED is the number
int gain = 0, again;
unsigned aregs_needed, invno;
- for (invno = 0; invno < VARRAY_ACTIVE_SIZE (invariants); invno++)
+ for (invno = 0; VEC_iterate (invariant_p, invariants, invno, inv); invno++)
{
- inv = VARRAY_GENERIC_PTR_NOGC (invariants, invno);
if (inv->move)
continue;
static void
set_move_mark (unsigned invno)
{
- struct invariant *inv = VARRAY_GENERIC_PTR_NOGC (invariants, invno);
+ struct invariant *inv = VEC_index (invariant_p, invariants, invno);
+ bitmap_iterator bi;
if (inv->move)
return;
if (dump_file)
fprintf (dump_file, "Decided to move invariant %d\n", invno);
- EXECUTE_IF_SET_IN_BITMAP (inv->depends_on, 0, invno, set_move_mark (invno));
+ EXECUTE_IF_SET_IN_BITMAP (inv->depends_on, 0, invno, bi)
+ {
+ set_move_mark (invno);
+ }
}
/* Determines which invariants to move. DF is the dataflow object. */
unsigned i, regs_used, n_inv_uses, regs_needed = 0, new_regs;
struct invariant *inv = NULL;
- if (flag_move_all_movables)
- {
- /* This is easy & stupid. */
- for (i = 0; i < VARRAY_ACTIVE_SIZE (invariants); i++)
- {
- inv = VARRAY_GENERIC_PTR_NOGC (invariants, i);
- inv->move = true;
- }
- return;
- }
-
- if (!VARRAY_ACTIVE_SIZE (invariants))
+ if (!VEC_length (invariant_p, invariants))
return;
/* Now something slightly more involved. First estimate the number of used
}
}
- for (i = 0; i < VARRAY_ACTIVE_SIZE (invariants); i++)
+ for (i = 0; VEC_iterate (invariant_p, invariants, i, inv); i++)
{
- inv = VARRAY_GENERIC_PTR_NOGC (invariants, i);
if (inv->def)
n_inv_uses += inv->def->n_uses;
}
static void
move_invariant_reg (struct loop *loop, unsigned invno, struct df *df)
{
- struct invariant *inv = VARRAY_GENERIC_PTR_NOGC (invariants, invno);
+ struct invariant *inv = VEC_index (invariant_p, invariants, invno);
unsigned i;
basic_block preheader = loop_preheader_edge (loop)->src;
rtx reg, set;
struct use *use;
+ bitmap_iterator bi;
if (inv->processed)
return;
if (inv->depends_on)
{
- EXECUTE_IF_SET_IN_BITMAP (inv->depends_on, 0, i,
+ EXECUTE_IF_SET_IN_BITMAP (inv->depends_on, 0, i, bi)
{
move_invariant_reg (loop, i, df);
- });
+ }
}
/* Move the set out of the loop. If the set is always executed (we could
struct invariant *inv;
unsigned i;
- for (i = 0; i < VARRAY_ACTIVE_SIZE (invariants); i++)
+ for (i = 0; VEC_iterate (invariant_p, invariants, i, inv); i++)
{
- inv = VARRAY_GENERIC_PTR_NOGC (invariants, i);
if (inv->move)
move_invariant_reg (loop, i, df);
}
{
actual_stamp = 1;
- if (!invariants)
- VARRAY_GENERIC_PTR_NOGC_INIT (invariants, 100, "invariants");
+ invariants = VEC_alloc (invariant_p, heap, 100);
}
/* Frees the data allocated by invariant motion. DF is the dataflow
DF_REF_DATA (df->defs[i]) = NULL;
}
- for (i = 0; i < VARRAY_ACTIVE_SIZE (invariants); i++)
+ for (i = 0; VEC_iterate (invariant_p, invariants, i, inv); i++)
{
- inv = VARRAY_GENERIC_PTR_NOGC (invariants, i);
- BITMAP_XFREE (inv->depends_on);
+ BITMAP_FREE (inv->depends_on);
free (inv);
}
- VARRAY_POP_ALL (invariants);
+ VEC_free (invariant_p, heap, invariants);
}
/* Move the invariants out of the LOOP. DF is the dataflow object. */