Commit 617b465c by Zdenek Dvorak Committed by Zdenek Dvorak

cfgloop.h (fix_loop_placement, [...]): Declare.

	* cfgloop.h (fix_loop_placement, can_duplicate_loop_p,
	duplicate_loop_to_header_edge, loopify, remove_path, split_loop_bb):
	Declare.
	(DLTHE_FLAG_UPDATE_FREQ): New.
	* cfgloopmanip.c (duplicate_loop, duplicate_subloops, copy_loops_to,
	loop_redirect_edge, loop_delete_branch_edge, copy_bbs, remove_bbs,
	rpe_enum_p, find_branch, alp_enum_p, add_loop, fix_loop_placements,
	fix_bb_placement, fix_bb_placements, place_new_loop,
	scale_loop_frequencies, scale_bbs_frequencies, record_exit_edges):
	New static functions.
	(fix_loop_placement, can_duplicate_loop_p,
	duplicate_loop_to_header_edge, loopify, remove_path, split_loop_bb):
	New functions.

	* cfgloop.h (loop_optimizer_init, loop_optimizer_finalize,
	unswitch_loops): Declare.
	* loop-init.c: New file.
	* loop-unswitch.c: New file.
	* Makefile.in (loop-init.o, loop-unswitch.o): New.
	* params.def (PARAM_MAX_UNSWITCH_INSNS, PARAM_MAX_UNSWITCH_LEVEL): New.
	* toplev.c (DFI_loop2): New dump.
	(flag_unswitch_loops): New.
	(lang_independent_options): Add it.
	(rest_of_compilation): Call new loop optimizer.
	(parse_options_and_default_flags): Turn flag_unswitch_loops on with -O3.

From-SVN: r62578
parent 3bd03194
2003-02-08 Zdenek Dvorak <rakdver@atrey.karlin.mff.cuni.cz>
* cfgloop.h (fix_loop_placement, can_duplicate_loop_p,
duplicate_loop_to_header_edge, loopify, remove_path, split_loop_bb):
Declare.
(DLTHE_FLAG_UPDATE_FREQ): New.
* cfgloopmanip.c (duplicate_loop, duplicate_subloops, copy_loops_to,
loop_redirect_edge, loop_delete_branch_edge, copy_bbs, remove_bbs,
rpe_enum_p, find_branch, alp_enum_p, add_loop, fix_loop_placements,
fix_bb_placement, fix_bb_placements, place_new_loop,
scale_loop_frequencies, scale_bbs_frequencies, record_exit_edges):
New static functions.
(fix_loop_placement, can_duplicate_loop_p,
duplicate_loop_to_header_edge, loopify, remove_path, split_loop_bb):
New functions.
* cfgloop.h (loop_optimizer_init, loop_optimizer_finalize,
unswitch_loops): Declare.
* loop-init.c: New file.
* loop-unswitch.c: New file.
* Makefile.in (loop-init.o, loop-unswitch.o): New.
* params.def (PARAM_MAX_UNSWITCH_INSNS, PARAM_MAX_UNSWITCH_LEVEL): New.
* toplev.c (DFI_loop2): New dump.
(flag_unswitch_loops): New.
(lang_independent_options): Add it.
(rest_of_compilation): Call new loop optimizer.
(parse_options_and_default_flags): Turn flag_unswitch_loops on with -O3.
2003-02-08 Kazu Hirata <kazu@cs.umass.edu> 2003-02-08 Kazu Hirata <kazu@cs.umass.edu>
* config/h8300/clzsi2.c: New. * config/h8300/clzsi2.c: New.
......
...@@ -768,7 +768,7 @@ C_OBJS = c-parse.o c-lang.o c-pretty-print.o $(C_AND_OBJC_OBJS) ...@@ -768,7 +768,7 @@ C_OBJS = c-parse.o c-lang.o c-pretty-print.o $(C_AND_OBJC_OBJS)
OBJS = alias.o bb-reorder.o bitmap.o builtins.o caller-save.o calls.o \ OBJS = alias.o bb-reorder.o bitmap.o builtins.o caller-save.o calls.o \
cfg.o cfganal.o cfgbuild.o cfgcleanup.o cfglayout.o cfgloop.o \ cfg.o cfganal.o cfgbuild.o cfgcleanup.o cfglayout.o cfgloop.o \
cfgloopanal.o cfgloopmanip.o \ cfgloopanal.o cfgloopmanip.o loop-init.o loop-unswitch.o \
cfgrtl.o combine.o conflict.o convert.o cse.o cselib.o dbxout.o \ cfgrtl.o combine.o conflict.o convert.o cse.o cselib.o dbxout.o \
debug.o df.o diagnostic.o doloop.o dominance.o \ debug.o df.o diagnostic.o doloop.o dominance.o \
dwarf2asm.o dwarf2out.o dwarfout.o emit-rtl.o except.o explow.o \ dwarf2asm.o dwarf2out.o dwarfout.o emit-rtl.o except.o explow.o \
...@@ -1600,6 +1600,12 @@ cfgloopanal.o : cfgloopanal.c $(CONFIG_H) $(SYSTEM_H) $(RTL_H) \ ...@@ -1600,6 +1600,12 @@ cfgloopanal.o : cfgloopanal.c $(CONFIG_H) $(SYSTEM_H) $(RTL_H) \
$(BASIC_BLOCK_H) hard-reg-set.h cfgloop.h $(EXPR_H) coretypes.h $(TM_H) $(BASIC_BLOCK_H) hard-reg-set.h cfgloop.h $(EXPR_H) coretypes.h $(TM_H)
cfgloopmanip.o : cfgloopmanip.c $(CONFIG_H) $(SYSTEM_H) $(RTL_H) \ cfgloopmanip.o : cfgloopmanip.c $(CONFIG_H) $(SYSTEM_H) $(RTL_H) \
$(BASIC_BLOCK_H) hard-reg-set.h cfgloop.h cfglayout.h output.h coretypes.h $(TM_H) $(BASIC_BLOCK_H) hard-reg-set.h cfgloop.h cfglayout.h output.h coretypes.h $(TM_H)
loop-init.o : loop-init.c $(CONFIG_H) $(SYSTEM_H) $(RTL_H) gcov-io.h \
gcov-iov.h $(BASIC_BLOCK_H) hard-reg-set.h cfgloop.h cfglayout.h profile.h \
coretypes.h $(TM_H)
loop-unswitch.o : loop-unswitch.c $(CONFIG_H) $(SYSTEM_H) $(RTL_H) $(TM_H) \
$(BASIC_BLOCK_H) hard-reg-set.h cfgloop.h cfglayout.h params.h \
output.h $(EXPR_H) coretypes.h $(TM_H)
dominance.o : dominance.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(RTL_H) \ dominance.o : dominance.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(RTL_H) \
hard-reg-set.h $(BASIC_BLOCK_H) et-forest.h hard-reg-set.h $(BASIC_BLOCK_H) et-forest.h
et-forest.o : et-forest.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) et-forest.h alloc-pool.h et-forest.o : et-forest.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) et-forest.h alloc-pool.h
......
...@@ -293,6 +293,7 @@ extern void cancel_loop PARAMS ((struct loops *, struct loop *)); ...@@ -293,6 +293,7 @@ extern void cancel_loop PARAMS ((struct loops *, struct loop *));
extern void cancel_loop_tree PARAMS ((struct loops *, struct loop *)); extern void cancel_loop_tree PARAMS ((struct loops *, struct loop *));
extern basic_block loop_split_edge_with PARAMS ((edge, rtx, struct loops *)); extern basic_block loop_split_edge_with PARAMS ((edge, rtx, struct loops *));
extern int fix_loop_placement PARAMS ((struct loop *));
enum enum
{ {
...@@ -312,3 +313,27 @@ extern rtx count_loop_iterations PARAMS ((struct loop_desc *, rtx, rtx)); ...@@ -312,3 +313,27 @@ extern rtx count_loop_iterations PARAMS ((struct loop_desc *, rtx, rtx));
extern bool just_once_each_iteration_p PARAMS ((struct loops *,struct loop *, extern bool just_once_each_iteration_p PARAMS ((struct loops *,struct loop *,
basic_block)); basic_block));
extern unsigned expected_loop_iterations PARAMS ((const struct loop *)); extern unsigned expected_loop_iterations PARAMS ((const struct loop *));
/* Loop manipulation. */
extern bool can_duplicate_loop_p PARAMS ((struct loop *loop));
#define DLTHE_FLAG_UPDATE_FREQ 1 /* Update frequencies in
duplicate_loop_to_header_edge. */
extern int duplicate_loop_to_header_edge PARAMS ((struct loop *, edge,
struct loops *, unsigned,
sbitmap, edge, edge *,
unsigned *, int));
extern struct loop *loopify PARAMS ((struct loops *, edge,
edge, basic_block));
extern bool remove_path PARAMS ((struct loops *, edge));
extern edge split_loop_bb PARAMS ((struct loops *, basic_block,
rtx));
/* Loop optimizer initialization. */
extern struct loops *loop_optimizer_init PARAMS ((FILE *));
extern void loop_optimizer_finalize PARAMS ((struct loops *, FILE *));
/* Optimization passes. */
extern void unswitch_loops PARAMS ((struct loops *));
/* Loop optimizer initialization routines.
Copyright (C) 2002, 2003 Free Software Foundation, Inc.
This file is part of GCC.
GCC is free software; you can redistribute it and/or modify it under
the terms of the GNU General Public License as published by the Free
Software Foundation; either version 2, or (at your option) any later
version.
GCC is distributed in the hope that it will be useful, but WITHOUT ANY
WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
for more details.
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. */
#include "config.h"
#include "system.h"
#include "coretypes.h"
#include "tm.h"
#include "rtl.h"
#include "hard-reg-set.h"
#include "basic-block.h"
#include "cfgloop.h"
#include "cfglayout.h"
#include "gcov-io.h"
#include "profile.h"
/* Initialize loop optimizer. */
struct loops *
loop_optimizer_init (dumpfile)
FILE *dumpfile;
{
struct loops *loops = xcalloc (1, sizeof (struct loops));
edge e;
/* Avoid annoying special cases of edges going to exit
block. */
for (e = EXIT_BLOCK_PTR->pred; e; e = e->pred_next)
if ((e->flags & EDGE_FALLTHRU) && e->src->succ->succ_next)
split_edge (e);
/* Find the loops. */
if (flow_loops_find (loops, LOOP_TREE) <= 1)
{
/* No loops. */
flow_loops_free (loops);
free (loops);
return NULL;
}
/* Not going to update these. */
free (loops->cfg.rc_order);
loops->cfg.rc_order = NULL;
free (loops->cfg.dfs_order);
loops->cfg.dfs_order = NULL;
/* Initialize structures for layout changes. */
cfg_layout_initialize (loops);
/* Create pre-headers. */
create_preheaders (loops, CP_SIMPLE_PREHEADERS | CP_INSIDE_CFGLAYOUT);
/* Force all latches to have only single successor. */
force_single_succ_latches (loops);
/* Mark irreducible loops. */
mark_irreducible_loops (loops);
/* Dump loops. */
flow_loops_dump (loops, dumpfile, NULL, 1);
#ifdef ENABLE_CHECKING
verify_dominators (loops->cfg.dom);
verify_loop_structure (loops);
#endif
return loops;
}
/* Finalize loop optimizer. */
void
loop_optimizer_finalize (loops, dumpfile)
struct loops *loops;
FILE *dumpfile;
{
basic_block bb;
/* Finalize layout changes. */
/* Make chain. */
FOR_EACH_BB (bb)
if (bb->next_bb != EXIT_BLOCK_PTR)
RBI (bb)->next = bb->next_bb;
/* Another dump. */
flow_loops_dump (loops, dumpfile, NULL, 1);
/* Clean up. */
flow_loops_free (loops);
free (loops);
/* Finalize changes. */
cfg_layout_finalize ();
/* Checking. */
#ifdef ENABLE_CHECKING
verify_flow_info ();
#endif
}
...@@ -151,6 +151,17 @@ DEFPARAM(PARAM_MAX_UNROLLED_INSNS, ...@@ -151,6 +151,17 @@ DEFPARAM(PARAM_MAX_UNROLLED_INSNS,
"The maximum number of instructions to consider to unroll in a loop", "The maximum number of instructions to consider to unroll in a loop",
100) 100)
/* The maximum number of insns of an unswitched loop. */
DEFPARAM(PARAM_MAX_UNSWITCH_INSNS,
"max-unswitch-insns",
"The maximum number of insns of an unswitched loop",
50)
/* The maximum level of recursion in unswitch_single_loop. */
DEFPARAM(PARAM_MAX_UNSWITCH_LEVEL,
"max-unswitch-level",
"The maximum number of unswitchings in a single loop",
3)
DEFPARAM(HOT_BB_COUNT_FRACTION, DEFPARAM(HOT_BB_COUNT_FRACTION,
"hot-bb-count-fraction", "hot-bb-count-fraction",
"Select fraction of the maximal count of repetitions of basic block in \ "Select fraction of the maximal count of repetitions of basic block in \
......
...@@ -239,6 +239,7 @@ enum dump_file_index ...@@ -239,6 +239,7 @@ enum dump_file_index
DFI_bp, DFI_bp,
DFI_ce1, DFI_ce1,
DFI_tracer, DFI_tracer,
DFI_loop2,
DFI_cse2, DFI_cse2,
DFI_life, DFI_life,
DFI_combine, DFI_combine,
...@@ -289,6 +290,7 @@ static struct dump_file_info dump_file[DFI_MAX] = ...@@ -289,6 +290,7 @@ static struct dump_file_info dump_file[DFI_MAX] =
{ "bp", 'b', 1, 0, 0 }, { "bp", 'b', 1, 0, 0 },
{ "ce1", 'C', 1, 0, 0 }, { "ce1", 'C', 1, 0, 0 },
{ "tracer", 'T', 1, 0, 0 }, { "tracer", 'T', 1, 0, 0 },
{ "loop2", 'L', 1, 0, 0 },
{ "cse2", 't', 1, 0, 0 }, { "cse2", 't', 1, 0, 0 },
{ "life", 'f', 1, 0, 0 }, /* Yes, duplicate enable switch. */ { "life", 'f', 1, 0, 0 }, /* Yes, duplicate enable switch. */
{ "combine", 'c', 1, 0, 0 }, { "combine", 'c', 1, 0, 0 },
...@@ -519,6 +521,9 @@ int flag_unroll_loops; ...@@ -519,6 +521,9 @@ int flag_unroll_loops;
int flag_unroll_all_loops; int flag_unroll_all_loops;
/* Nonzero enables loop unswitching. */
int flag_unswitch_loops;
/* Nonzero enables prefetch optimizations for arrays in loops. */ /* Nonzero enables prefetch optimizations for arrays in loops. */
int flag_prefetch_loop_arrays; int flag_prefetch_loop_arrays;
...@@ -997,6 +1002,8 @@ static const lang_independent_options f_options[] = ...@@ -997,6 +1002,8 @@ static const lang_independent_options f_options[] =
N_("Perform loop unrolling when iteration count is known") }, N_("Perform loop unrolling when iteration count is known") },
{"unroll-all-loops", &flag_unroll_all_loops, 1, {"unroll-all-loops", &flag_unroll_all_loops, 1,
N_("Perform loop unrolling for all loops") }, N_("Perform loop unrolling for all loops") },
{"unswitch-loops", &flag_unswitch_loops, 1,
N_("Perform loop unswitching") },
{"prefetch-loop-arrays", &flag_prefetch_loop_arrays, 1, {"prefetch-loop-arrays", &flag_prefetch_loop_arrays, 1,
N_("Generate prefetch instructions, if available, for arrays in loops") }, N_("Generate prefetch instructions, if available, for arrays in loops") },
{"move-all-movables", &flag_move_all_movables, 1, {"move-all-movables", &flag_move_all_movables, 1,
...@@ -3057,6 +3064,38 @@ rest_of_compilation (decl) ...@@ -3057,6 +3064,38 @@ rest_of_compilation (decl)
timevar_pop (TV_TRACER); timevar_pop (TV_TRACER);
} }
/* Perform loop optimalizations. It might be better to do them a bit
sooner, but we want the profile feedback to work more efficiently. */
if (optimize > 0
&& flag_unswitch_loops)
{
struct loops *loops;
timevar_push (TV_LOOP);
open_dump_file (DFI_loop2, decl);
if (rtl_dump_file)
dump_flow_info (rtl_dump_file);
loops = loop_optimizer_init (rtl_dump_file);
if (loops)
{
/* The optimalizations: */
if (flag_unswitch_loops)
unswitch_loops (loops);
loop_optimizer_finalize (loops, rtl_dump_file);
}
cleanup_cfg (CLEANUP_EXPENSIVE);
delete_trivially_dead_insns (insns, max_reg_num ());
reg_scan (insns, max_reg_num (), 0);
if (rtl_dump_file)
dump_flow_info (rtl_dump_file);
close_dump_file (DFI_loop2, print_rtl_with_bb, get_insns ());
timevar_pop (TV_LOOP);
ggc_collect ();
}
if (flag_rerun_cse_after_loop) if (flag_rerun_cse_after_loop)
{ {
timevar_push (TV_CSE2); timevar_push (TV_CSE2);
...@@ -4884,6 +4923,7 @@ parse_options_and_default_flags (argc, argv) ...@@ -4884,6 +4923,7 @@ parse_options_and_default_flags (argc, argv)
{ {
flag_inline_functions = 1; flag_inline_functions = 1;
flag_rename_registers = 1; flag_rename_registers = 1;
flag_unswitch_loops = 1;
} }
if (optimize < 2 || optimize_size) if (optimize < 2 || optimize_size)
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment