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 is the loop optimization pass of the compiler.
It finds invariant computations within loops and moves them
#include "optabs.h"
#include "cfgloop.h"
#include "ggc.h"
+#include "timevar.h"
+#include "tree-pass.h"
/* Get the loop info pointer of a loop. */
#define LOOP_INFO(LOOP) ((struct loop_info *) (LOOP)->aux)
if (! in_libcall
&& (set = single_set (p))
&& REG_P (SET_DEST (set))
+ && SET_DEST (set) != frame_pointer_rtx
#ifdef PIC_OFFSET_TABLE_REG_CALL_CLOBBERED
&& SET_DEST (set) != pic_offset_table_rtx
#endif
/* HACK: Must also search the loop fall through exit, create a label_ref
here which points to the loop->end, and append the loop_number_exit_labels
list to it. */
- label = gen_rtx_LABEL_REF (VOIDmode, loop->end);
+ label = gen_rtx_LABEL_REF (Pmode, loop->end);
LABEL_NEXTREF (label) = loop->exit_labels;
for (; label; label = LABEL_NEXTREF (label))
v->new_reg));
else if (GET_CODE (*v->location) == PLUS
&& REG_P (XEXP (*v->location, 0))
+ && REG_P (v->new_reg)
&& CONSTANT_P (XEXP (*v->location, 1)))
loop_insn_emit_before (loop, 0, v->insn,
gen_move_insn (XEXP (*v->location, 0),
some machines, don't use any hard registers at all. */
if (REGNO (x) < FIRST_PSEUDO_REGISTER
&& (SMALL_REGISTER_CLASSES
- || (call_used_regs[REGNO (x)] && call_seen)))
+ || (call_seen && call_used_regs[REGNO (x)])))
return 0;
/* Don't use registers that have been clobbered before the start of the
{
flow_loops_dump (loops, stderr, loop_dump_aux, 1);
}
+\f
+static bool
+gate_handle_loop_optimize (void)
+{
+ return (optimize > 0 && flag_loop_optimize);
+}
+
+/* Move constant computations out of loops. */
+static void
+rest_of_handle_loop_optimize (void)
+{
+ int do_prefetch;
+
+ /* CFG is no longer maintained up-to-date. */
+ free_bb_for_insn ();
+ profile_status = PROFILE_ABSENT;
+
+ do_prefetch = flag_prefetch_loop_arrays ? LOOP_PREFETCH : 0;
+
+ if (flag_rerun_loop_opt)
+ {
+ cleanup_barriers ();
+
+ /* We only want to perform unrolling once. */
+ loop_optimize (get_insns (), dump_file, 0);
+
+ /* The first call to loop_optimize makes some instructions
+ trivially dead. We delete those instructions now in the
+ hope that doing so will make the heuristics in loop work
+ better and possibly speed up compilation. */
+ delete_trivially_dead_insns (get_insns (), max_reg_num ());
+
+ /* The regscan pass is currently necessary as the alias
+ analysis code depends on this information. */
+ reg_scan (get_insns (), max_reg_num ());
+ }
+ cleanup_barriers ();
+ loop_optimize (get_insns (), dump_file, do_prefetch);
+
+ /* Loop can create trivially dead instructions. */
+ delete_trivially_dead_insns (get_insns (), max_reg_num ());
+ find_basic_blocks (get_insns ());
+}
+
+struct tree_opt_pass pass_loop_optimize =
+{
+ "old-loop", /* name */
+ gate_handle_loop_optimize, /* gate */
+ rest_of_handle_loop_optimize, /* execute */
+ NULL, /* sub */
+ NULL, /* next */
+ 0, /* static_pass_number */
+ TV_LOOP, /* tv_id */
+ 0, /* properties_required */
+ 0, /* properties_provided */
+ 0, /* properties_destroyed */
+ 0, /* todo_flags_start */
+ TODO_dump_func |
+ TODO_ggc_collect, /* todo_flags_finish */
+ 'L' /* letter */
+};
+
+