Commit f8682ff6 by Paolo Bonzini Committed by Paolo Bonzini

re PR rtl-optimization/41812 (test 20071030-1.c fails execution on powerpc64)

2009-11-30  Paolo Bonzini  <bonzini@gnu.org>

	PR rtl-optimization/41812
	* fwprop.c (local_md, local_lr): New globals.
	(process_defs, process_uses): Remove local_md argument.  Never
	consider dead pseudos to have singleton def-use chains.
	(single_def_use_enter_block): Perform LR simulation.
	(build_single_def_use_links): Remove local_md local variable.
	Add DF_NOTE.  Allocate local_lr.
	(fwprop_done): Do not remove DF_CHAIN, we do not use it anymore.
	* df-problems.c (df_md_scratch): New.
	(df_md_alloc, df_md_free): Allocate/free it.
	(df_md_local_compute): Only include live registers in init.
	(df_md_transfer_function): Prune the in-set computed by
	the confluence function, and the gen-set too.
	(df_simulate_one_insn_forwards): Fix typo.

From-SVN: r154753
parent da55c6da
2009-11-30 Paolo Bonzini <bonzini@gnu.org>
PR rtl-optimization/41812
* fwprop.c (local_md, local_lr): New globals.
(process_defs, process_uses): Remove local_md argument. Never
consider dead pseudos to have singleton def-use chains.
(single_def_use_enter_block): Perform LR simulation.
(build_single_def_use_links): Remove local_md local variable.
Add DF_NOTE. Allocate local_lr.
(fwprop_done): Do not remove DF_CHAIN, we do not use it anymore.
* df-problems.c (df_md_scratch): New.
(df_md_alloc, df_md_free): Allocate/free it.
(df_md_local_compute): Only include live registers in init.
(df_md_transfer_function): Prune the in-set computed by
the confluence function, and the gen-set too.
(df_simulate_one_insn_forwards): Fix typo.
2009-11-30 Hans-Peter Nilsson <hp@axis.com> 2009-11-30 Hans-Peter Nilsson <hp@axis.com>
PR rtl-optimization/40086 PR rtl-optimization/40086
...@@ -1574,10 +1574,9 @@ df_live_transfer_function (int bb_index) ...@@ -1574,10 +1574,9 @@ df_live_transfer_function (int bb_index)
bitmap gen = bb_info->gen; bitmap gen = bb_info->gen;
bitmap kill = bb_info->kill; bitmap kill = bb_info->kill;
/* We need to use a scratch set here so that the value returned from /* We need to use a scratch set here so that the value returned from this
this function invocation properly reflects if the sets changed in function invocation properly reflects whether the sets changed in a
a significant way; i.e. not just because the lr set was anded significant way; i.e. not just because the lr set was anded in. */
in. */
bitmap_and (df_live_scratch, gen, bb_lr_info->out); bitmap_and (df_live_scratch, gen, bb_lr_info->out);
/* No register may reach a location where it is not used. Thus /* No register may reach a location where it is not used. Thus
we trim the rr result to the places where it is used. */ we trim the rr result to the places where it is used. */
...@@ -3975,8 +3974,8 @@ df_simulate_one_insn_forwards (basic_block bb, rtx insn, bitmap live) ...@@ -3975,8 +3974,8 @@ df_simulate_one_insn_forwards (basic_block bb, rtx insn, bitmap live)
MULTIPLE DEFINITIONS MULTIPLE DEFINITIONS
Find the locations in the function reached by multiple definition sites Find the locations in the function reached by multiple definition sites
for a pseudo. In and out bitvectors are built for each basic for a live pseudo. In and out bitvectors are built for each basic
block. block. They are restricted for efficiency to live registers.
The gen and kill sets for the problem are obvious. Together they The gen and kill sets for the problem are obvious. Together they
include all defined registers in a basic block; the gen set includes include all defined registers in a basic block; the gen set includes
...@@ -4018,6 +4017,10 @@ df_simulate_one_insn_forwards (basic_block bb, rtx insn, bitmap live) ...@@ -4018,6 +4017,10 @@ df_simulate_one_insn_forwards (basic_block bb, rtx insn, bitmap live)
propagating the information to BB3's successors. propagating the information to BB3's successors.
---------------------------------------------------------------------------*/ ---------------------------------------------------------------------------*/
/* Scratch var used by transfer functions. This is used to do md analysis
only for live registers. */
static bitmap df_md_scratch;
/* Set basic block info. */ /* Set basic block info. */
static void static void
...@@ -4061,6 +4064,7 @@ df_md_alloc (bitmap all_blocks) ...@@ -4061,6 +4064,7 @@ df_md_alloc (bitmap all_blocks)
sizeof (struct df_md_bb_info), 50); sizeof (struct df_md_bb_info), 50);
df_grow_bb_info (df_md); df_grow_bb_info (df_md);
df_md_scratch = BITMAP_ALLOC (NULL);
EXECUTE_IF_SET_IN_BITMAP (all_blocks, 0, bb_index, bi) EXECUTE_IF_SET_IN_BITMAP (all_blocks, 0, bb_index, bi)
{ {
...@@ -4236,8 +4240,10 @@ df_md_local_compute (bitmap all_blocks) ...@@ -4236,8 +4240,10 @@ df_md_local_compute (bitmap all_blocks)
bitmap kill = df_md_get_bb_info (bb_index)->kill; bitmap kill = df_md_get_bb_info (bb_index)->kill;
EXECUTE_IF_SET_IN_BITMAP (frontiers[bb_index], 0, df_bb_index, bi2) EXECUTE_IF_SET_IN_BITMAP (frontiers[bb_index], 0, df_bb_index, bi2)
{ {
basic_block bb = BASIC_BLOCK (df_bb_index);
if (bitmap_bit_p (all_blocks, df_bb_index)) if (bitmap_bit_p (all_blocks, df_bb_index))
bitmap_ior_into (df_md_get_bb_info (df_bb_index)->init, kill); bitmap_ior_and_into (df_md_get_bb_info (df_bb_index)->init, kill,
df_get_live_in (bb));
} }
} }
...@@ -4267,13 +4273,23 @@ df_md_reset (bitmap all_blocks) ...@@ -4267,13 +4273,23 @@ df_md_reset (bitmap all_blocks)
static bool static bool
df_md_transfer_function (int bb_index) df_md_transfer_function (int bb_index)
{ {
basic_block bb = BASIC_BLOCK (bb_index);
struct df_md_bb_info *bb_info = df_md_get_bb_info (bb_index); struct df_md_bb_info *bb_info = df_md_get_bb_info (bb_index);
bitmap in = bb_info->in; bitmap in = bb_info->in;
bitmap out = bb_info->out; bitmap out = bb_info->out;
bitmap gen = bb_info->gen; bitmap gen = bb_info->gen;
bitmap kill = bb_info->kill; bitmap kill = bb_info->kill;
return bitmap_ior_and_compl (out, gen, in, kill); /* We need to use a scratch set here so that the value returned from this
function invocation properly reflects whether the sets changed in a
significant way; i.e. not just because the live set was anded in. */
bitmap_and (df_md_scratch, gen, df_get_live_out (bb));
/* Multiple definitions of a register are not relevant if it is not
live. Thus we trim the result to the places where it is live. */
bitmap_and_into (in, df_get_live_in (bb));
return bitmap_ior_and_compl (out, df_md_scratch, in, kill);
} }
/* Initialize the solution bit vectors for problem. */ /* Initialize the solution bit vectors for problem. */
...@@ -4336,6 +4352,7 @@ df_md_free (void) ...@@ -4336,6 +4352,7 @@ df_md_free (void)
} }
} }
BITMAP_FREE (df_md_scratch);
free_alloc_pool (df_md->block_pool); free_alloc_pool (df_md->block_pool);
df_md->block_info_size = 0; df_md->block_info_size = 0;
......
...@@ -118,10 +118,16 @@ static int num_changes; ...@@ -118,10 +118,16 @@ static int num_changes;
DEF_VEC_P(df_ref); DEF_VEC_P(df_ref);
DEF_VEC_ALLOC_P(df_ref,heap); DEF_VEC_ALLOC_P(df_ref,heap);
VEC(df_ref,heap) *use_def_ref; static VEC(df_ref,heap) *use_def_ref;
VEC(df_ref,heap) *reg_defs; static VEC(df_ref,heap) *reg_defs;
VEC(df_ref,heap) *reg_defs_stack; static VEC(df_ref,heap) *reg_defs_stack;
/* The MD bitmaps are trimmed to include only live registers to cut
memory usage on testcases like insn-recog.c. Track live registers
in the basic block and do not perform forward propagation if the
destination is a dead pseudo occurring in a note. */
static bitmap local_md;
static bitmap local_lr;
/* Return the only def in USE's use-def chain, or NULL if there is /* Return the only def in USE's use-def chain, or NULL if there is
more than one def in the chain. */ more than one def in the chain. */
...@@ -143,7 +149,7 @@ get_def_for_use (df_ref use) ...@@ -143,7 +149,7 @@ get_def_for_use (df_ref use)
(DF_REF_PARTIAL | DF_REF_CONDITIONAL | DF_REF_MAY_CLOBBER) (DF_REF_PARTIAL | DF_REF_CONDITIONAL | DF_REF_MAY_CLOBBER)
static void static void
process_defs (bitmap local_md, df_ref *def_rec, int top_flag) process_defs (df_ref *def_rec, int top_flag)
{ {
df_ref def; df_ref def;
while ((def = *def_rec++) != NULL) while ((def = *def_rec++) != NULL)
...@@ -188,7 +194,7 @@ process_defs (bitmap local_md, df_ref *def_rec, int top_flag) ...@@ -188,7 +194,7 @@ process_defs (bitmap local_md, df_ref *def_rec, int top_flag)
is an artificial use vector. */ is an artificial use vector. */
static void static void
process_uses (bitmap local_md, df_ref *use_rec, int top_flag) process_uses (df_ref *use_rec, int top_flag)
{ {
df_ref use; df_ref use;
while ((use = *use_rec++) != NULL) while ((use = *use_rec++) != NULL)
...@@ -196,7 +202,8 @@ process_uses (bitmap local_md, df_ref *use_rec, int top_flag) ...@@ -196,7 +202,8 @@ process_uses (bitmap local_md, df_ref *use_rec, int top_flag)
{ {
unsigned int uregno = DF_REF_REGNO (use); unsigned int uregno = DF_REF_REGNO (use);
if (VEC_index (df_ref, reg_defs, uregno) if (VEC_index (df_ref, reg_defs, uregno)
&& !bitmap_bit_p (local_md, uregno)) && !bitmap_bit_p (local_md, uregno)
&& bitmap_bit_p (local_lr, uregno))
VEC_replace (df_ref, use_def_ref, DF_REF_ID (use), VEC_replace (df_ref, use_def_ref, DF_REF_ID (use),
VEC_index (df_ref, reg_defs, uregno)); VEC_index (df_ref, reg_defs, uregno));
} }
...@@ -204,32 +211,36 @@ process_uses (bitmap local_md, df_ref *use_rec, int top_flag) ...@@ -204,32 +211,36 @@ process_uses (bitmap local_md, df_ref *use_rec, int top_flag)
static void static void
single_def_use_enter_block (struct dom_walk_data *walk_data, basic_block bb) single_def_use_enter_block (struct dom_walk_data *walk_data ATTRIBUTE_UNUSED,
basic_block bb)
{ {
bitmap local_md = (bitmap) walk_data->global_data;
int bb_index = bb->index; int bb_index = bb->index;
struct df_md_bb_info *bb_info = df_md_get_bb_info (bb_index); struct df_md_bb_info *md_bb_info = df_md_get_bb_info (bb_index);
struct df_lr_bb_info *lr_bb_info = df_lr_get_bb_info (bb_index);
rtx insn; rtx insn;
bitmap_copy (local_md, bb_info->in); bitmap_copy (local_md, md_bb_info->in);
bitmap_copy (local_lr, lr_bb_info->in);
/* Push a marker for the leave_block callback. */ /* Push a marker for the leave_block callback. */
VEC_safe_push (df_ref, heap, reg_defs_stack, NULL); VEC_safe_push (df_ref, heap, reg_defs_stack, NULL);
process_uses (local_md, df_get_artificial_uses (bb_index), DF_REF_AT_TOP); process_uses (df_get_artificial_uses (bb_index), DF_REF_AT_TOP);
process_defs (local_md, df_get_artificial_defs (bb_index), DF_REF_AT_TOP); process_defs (df_get_artificial_defs (bb_index), DF_REF_AT_TOP);
df_simulate_initialize_forwards (bb, local_lr);
FOR_BB_INSNS (bb, insn) FOR_BB_INSNS (bb, insn)
if (INSN_P (insn)) if (INSN_P (insn))
{ {
unsigned int uid = INSN_UID (insn); unsigned int uid = INSN_UID (insn);
process_uses (local_md, DF_INSN_UID_USES (uid), 0); process_uses (DF_INSN_UID_USES (uid), 0);
process_uses (local_md, DF_INSN_UID_EQ_USES (uid), 0); process_uses (DF_INSN_UID_EQ_USES (uid), 0);
process_defs (local_md, DF_INSN_UID_DEFS (uid), 0); process_defs (DF_INSN_UID_DEFS (uid), 0);
df_simulate_one_insn_forwards (bb, insn, local_lr);
} }
process_uses (local_md, df_get_artificial_uses (bb_index), 0); process_uses (df_get_artificial_uses (bb_index), 0);
process_defs (local_md, df_get_artificial_defs (bb_index), 0); process_defs (df_get_artificial_defs (bb_index), 0);
} }
/* Pop the definitions created in this basic block when leaving its /* Pop the definitions created in this basic block when leaving its
...@@ -260,12 +271,12 @@ static void ...@@ -260,12 +271,12 @@ static void
build_single_def_use_links (void) build_single_def_use_links (void)
{ {
struct dom_walk_data walk_data; struct dom_walk_data walk_data;
bitmap local_md;
/* We use the multiple definitions problem to compute our restricted /* We use the multiple definitions problem to compute our restricted
use-def chains. */ use-def chains. */
df_set_flags (DF_EQ_NOTES); df_set_flags (DF_EQ_NOTES);
df_md_add_problem (); df_md_add_problem ();
df_note_add_problem ();
df_analyze (); df_analyze ();
df_maybe_reorganize_use_refs (DF_REF_ORDER_BY_INSN_WITH_NOTES); df_maybe_reorganize_use_refs (DF_REF_ORDER_BY_INSN_WITH_NOTES);
...@@ -277,6 +288,7 @@ build_single_def_use_links (void) ...@@ -277,6 +288,7 @@ build_single_def_use_links (void)
reg_defs_stack = VEC_alloc (df_ref, heap, n_basic_blocks * 10); reg_defs_stack = VEC_alloc (df_ref, heap, n_basic_blocks * 10);
local_md = BITMAP_ALLOC (NULL); local_md = BITMAP_ALLOC (NULL);
local_lr = BITMAP_ALLOC (NULL);
/* Walk the dominator tree looking for single reaching definitions /* Walk the dominator tree looking for single reaching definitions
dominating the uses. This is similar to how SSA form is built. */ dominating the uses. This is similar to how SSA form is built. */
...@@ -284,12 +296,12 @@ build_single_def_use_links (void) ...@@ -284,12 +296,12 @@ build_single_def_use_links (void)
walk_data.initialize_block_local_data = NULL; walk_data.initialize_block_local_data = NULL;
walk_data.before_dom_children = single_def_use_enter_block; walk_data.before_dom_children = single_def_use_enter_block;
walk_data.after_dom_children = single_def_use_leave_block; walk_data.after_dom_children = single_def_use_leave_block;
walk_data.global_data = local_md;
init_walk_dominator_tree (&walk_data); init_walk_dominator_tree (&walk_data);
walk_dominator_tree (&walk_data, ENTRY_BLOCK_PTR); walk_dominator_tree (&walk_data, ENTRY_BLOCK_PTR);
fini_walk_dominator_tree (&walk_data); fini_walk_dominator_tree (&walk_data);
BITMAP_FREE (local_lr);
BITMAP_FREE (local_md); BITMAP_FREE (local_md);
VEC_free (df_ref, heap, reg_defs); VEC_free (df_ref, heap, reg_defs);
VEC_free (df_ref, heap, reg_defs_stack); VEC_free (df_ref, heap, reg_defs_stack);
...@@ -1385,11 +1397,9 @@ fwprop_done (void) ...@@ -1385,11 +1397,9 @@ fwprop_done (void)
fprintf (dump_file, fprintf (dump_file,
"\nNumber of successful forward propagations: %d\n\n", "\nNumber of successful forward propagations: %d\n\n",
num_changes); num_changes);
df_remove_problem (df_chain);
} }
/* Main entry point. */ /* Main entry point. */
static bool static bool
......
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