aboutsummaryrefslogtreecommitdiff
path: root/gcc/gcse.c
diff options
context:
space:
mode:
authorRoger Sayle <roger@eyesopen.com>2003-01-16 01:06:33 +0000
committerRoger Sayle <sayle@gcc.gnu.org>2003-01-16 01:06:33 +0000
commita013431213f7f27e2866350c9aaea8f12046d81c (patch)
tree2ecda5f756d588f0c8e2d12fbf3426b2b6eb164e /gcc/gcse.c
parent6b543e86f4a765f6a0b7be90e393b9a772c22a52 (diff)
downloadgcc-a013431213f7f27e2866350c9aaea8f12046d81c.zip
gcc-a013431213f7f27e2866350c9aaea8f12046d81c.tar.gz
gcc-a013431213f7f27e2866350c9aaea8f12046d81c.tar.bz2
gcse.c (one_cprop_pass): Change function arguments to take both cprop_jumps and bypass_jumps flags...
* gcse.c (one_cprop_pass): Change function arguments to take both cprop_jumps and bypass_jumps flags instead of just alter_jumps. (gcse_main): Update calls to one_cprop_pass, disabling bypassing. (bypass_jumps): New function to perform separate jump bypassing pass. * rtl.h (bypass_jumps): Add function prototype. * timevar.def (TV_BYPASS): New timing variable. * toplev.c (enum dump_file_index): Add new entry DFI_bypass. (dump_file): New entry for the bypass RTL dump file. (rest_of_compilation): Insert new jump bypassing optimization pass after loop. * doc/passes.texi: Document new pass. From-SVN: r61374
Diffstat (limited to 'gcc/gcse.c')
-rw-r--r--gcc/gcse.c129
1 files changed, 118 insertions, 11 deletions
diff --git a/gcc/gcse.c b/gcc/gcse.c
index ae0a1ba..e8976cb 100644
--- a/gcc/gcse.c
+++ b/gcc/gcse.c
@@ -1,6 +1,6 @@
/* Global common subexpression elimination/Partial redundancy elimination
and global constant/copy propagation for GNU compiler.
- Copyright (C) 1997, 1998, 1999, 2000, 2001, 2002
+ Copyright (C) 1997, 1998, 1999, 2000, 2001, 2002, 2003
Free Software Foundation, Inc.
This file is part of GCC.
@@ -614,7 +614,7 @@ static int load_killed_in_block_p PARAMS ((basic_block, int, rtx, int));
static void canon_list_insert PARAMS ((rtx, rtx, void *));
static int cprop_insn PARAMS ((rtx, int));
static int cprop PARAMS ((int));
-static int one_cprop_pass PARAMS ((int, int));
+static int one_cprop_pass PARAMS ((int, int, int));
static bool constprop_register PARAMS ((rtx, rtx, rtx, int));
static struct expr *find_bypass_set PARAMS ((int, int));
static int bypass_block PARAMS ((basic_block, rtx, rtx));
@@ -819,7 +819,7 @@ gcse_main (f, file)
/* Don't allow constant propagation to modify jumps
during this pass. */
- changed = one_cprop_pass (pass + 1, 0);
+ changed = one_cprop_pass (pass + 1, 0, 0);
if (optimize_size)
changed |= one_classic_gcse_pass (pass + 1);
@@ -886,7 +886,7 @@ gcse_main (f, file)
max_gcse_regno = max_reg_num ();
alloc_gcse_mem (f);
/* This time, go ahead and allow cprop to alter jumps. */
- one_cprop_pass (pass + 1, 1);
+ one_cprop_pass (pass + 1, 1, 0);
free_gcse_mem ();
if (file)
@@ -4463,20 +4463,22 @@ cprop (alter_jumps)
}
/* Perform one copy/constant propagation pass.
- F is the first insn in the function.
- PASS is the pass count. */
+ PASS is the pass count. If CPROP_JUMPS is true, perform constant
+ propagation into conditional jumps. If BYPASS_JUMPS is true,
+ perform conditional jump bypassing optimizations. */
static int
-one_cprop_pass (pass, alter_jumps)
+one_cprop_pass (pass, cprop_jumps, bypass_jumps)
int pass;
- int alter_jumps;
+ int cprop_jumps;
+ int bypass_jumps;
{
int changed = 0;
const_prop_count = 0;
copy_prop_count = 0;
- local_cprop_pass (alter_jumps);
+ local_cprop_pass (cprop_jumps);
alloc_hash_table (max_cuid, &set_hash_table, 1);
compute_hash_table (&set_hash_table);
@@ -4486,8 +4488,8 @@ one_cprop_pass (pass, alter_jumps)
{
alloc_cprop_mem (last_basic_block, set_hash_table.n_elems);
compute_cprop_data ();
- changed = cprop (alter_jumps);
- if (alter_jumps)
+ changed = cprop (cprop_jumps);
+ if (bypass_jumps)
changed |= bypass_conditional_jumps ();
free_cprop_mem ();
}
@@ -7348,4 +7350,109 @@ store_motion ()
end_alias_analysis ();
}
+
+/* Entry point for jump bypassing optimization pass. */
+
+int
+bypass_jumps (file)
+ FILE *file;
+{
+ int changed;
+
+ /* We do not construct an accurate cfg in functions which call
+ setjmp, so just punt to be safe. */
+ if (current_function_calls_setjmp)
+ return 0;
+
+ /* For calling dump_foo fns from gdb. */
+ debug_stderr = stderr;
+ gcse_file = file;
+
+ /* Identify the basic block information for this function, including
+ successors and predecessors. */
+ max_gcse_regno = max_reg_num ();
+
+ if (file)
+ dump_flow_info (file);
+
+ /* Return if there's nothing to do. */
+ if (n_basic_blocks <= 1)
+ return 0;
+
+ /* Trying to perform global optimizations on flow graphs which have
+ a high connectivity will take a long time and is unlikely to be
+ particularly useful.
+
+ In normal circumstances a cfg should have about twice as many edges
+ as blocks. But we do not want to punish small functions which have
+ a couple switch statements. So we require a relatively large number
+ of basic blocks and the ratio of edges to blocks to be high. */
+ if (n_basic_blocks > 1000 && n_edges / n_basic_blocks >= 20)
+ {
+ if (warn_disabled_optimization)
+ warning ("BYPASS disabled: %d > 1000 basic blocks and %d >= 20 edges/basic block",
+ n_basic_blocks, n_edges / n_basic_blocks);
+ return 0;
+ }
+
+ /* If allocating memory for the cprop bitmap would take up too much
+ storage it's better just to disable the optimization. */
+ if ((n_basic_blocks
+ * SBITMAP_SET_SIZE (max_gcse_regno)
+ * sizeof (SBITMAP_ELT_TYPE)) > MAX_GCSE_MEMORY)
+ {
+ if (warn_disabled_optimization)
+ warning ("GCSE disabled: %d basic blocks and %d registers",
+ n_basic_blocks, max_gcse_regno);
+
+ return 0;
+ }
+
+ /* See what modes support reg/reg copy operations. */
+ if (! can_copy_init_p)
+ {
+ compute_can_copy ();
+ can_copy_init_p = 1;
+ }
+
+ gcc_obstack_init (&gcse_obstack);
+ bytes_used = 0;
+
+ /* We need alias. */
+ init_alias_analysis ();
+
+ /* Record where pseudo-registers are set. This data is kept accurate
+ during each pass. ??? We could also record hard-reg information here
+ [since it's unchanging], however it is currently done during hash table
+ computation.
+
+ It may be tempting to compute MEM set information here too, but MEM sets
+ will be subject to code motion one day and thus we need to compute
+ information about memory sets when we build the hash tables. */
+
+ alloc_reg_set_mem (max_gcse_regno);
+ compute_sets (get_insns ());
+
+ max_gcse_regno = max_reg_num ();
+ alloc_gcse_mem (get_insns ());
+ changed = one_cprop_pass (1, 1, 1);
+ free_gcse_mem ();
+
+ if (file)
+ {
+ fprintf (file, "BYPASS of %s: %d basic blocks, ",
+ current_function_name, n_basic_blocks);
+ fprintf (file, "%d bytes\n\n", bytes_used);
+ }
+
+ obstack_free (&gcse_obstack, NULL);
+ free_reg_set_mem ();
+
+ /* We are finished with alias. */
+ end_alias_analysis ();
+ allocate_reg_info (max_reg_num (), FALSE, FALSE);
+
+ return changed;
+}
+
#include "gt-gcse.h"