df: Change defs in entry and uses in exit block during separate shrink-wrapping
So far all target implementations of the separate shrink-wrapping hooks use the DF LIVE info to figure out around which basic blocks the non- volatile registers need to be saved. This is done by looking at the IN+GEN+KILL sets of the basic blocks. However, that doesn't work for registers that DF says are defined in the entry block, or used in the exit block. This patch introduces a local flag DF_SCAN_EMPTY_ENTRY_EXIT that says no registers should be defined in the entry block, and none used in the exit block. It also makes try_shrink_wrapping_separate use it. The rs6000 port is changed to use IN+GEN+KILL for the LR component. * config/rs6000/rs6000.c (rs6000_components_for_bb): Mark the LR component as used also if LR_REGNO is a live input to the bb. * df-scan.c (df_get_entry_block_def_set): Return immediately after clearing the set if DF_SCAN_EMPTY_ENTRY_EXIT is set. (df_get_exit_block_use_set): Ditto. * df.h (df_scan_flags): New enum. * shrink-wrap.c (try_shrink_wrapping_separate): Set DF_SCAN_EMPTY_ENTRY_EXIT in df_scan->local_flags, and call df_update_entry_block_defs and df_update_exit_block_uses at the start; clear the flag and call those functions at the end. From-SVN: r242497
This commit is contained in:
parent
307ca54339
commit
7157aa8583
@ -1,3 +1,16 @@
|
||||
2016-11-16 Segher Boessenkool <segher@kernel.crashing.org>
|
||||
|
||||
* config/rs6000/rs6000.c (rs6000_components_for_bb): Mark the LR
|
||||
component as used also if LR_REGNO is a live input to the bb.
|
||||
* df-scan.c (df_get_entry_block_def_set): Return immediately after
|
||||
clearing the set if DF_SCAN_EMPTY_ENTRY_EXIT is set.
|
||||
(df_get_exit_block_use_set): Ditto.
|
||||
* df.h (df_scan_flags): New enum.
|
||||
* shrink-wrap.c (try_shrink_wrapping_separate): Set
|
||||
DF_SCAN_EMPTY_ENTRY_EXIT in df_scan->local_flags, and call
|
||||
df_update_entry_block_defs and df_update_exit_block_uses
|
||||
at the start; clear the flag and call those functions at the end.
|
||||
|
||||
2016-11-16 Richard Sandiford <richard.sandiford@arm.com>
|
||||
Alan Hayward <alan.hayward@arm.com>
|
||||
David Sherwood <david.sherwood@arm.com>
|
||||
|
@ -27823,7 +27823,8 @@ rs6000_components_for_bb (basic_block bb)
|
||||
bitmap_set_bit (components, regno);
|
||||
|
||||
/* LR needs to be saved around a bb if it is killed in that bb. */
|
||||
if (bitmap_bit_p (gen, LR_REGNO)
|
||||
if (bitmap_bit_p (in, LR_REGNO)
|
||||
|| bitmap_bit_p (gen, LR_REGNO)
|
||||
|| bitmap_bit_p (kill, LR_REGNO))
|
||||
bitmap_set_bit (components, 0);
|
||||
|
||||
|
@ -3506,6 +3506,14 @@ df_get_entry_block_def_set (bitmap entry_block_defs)
|
||||
|
||||
bitmap_clear (entry_block_defs);
|
||||
|
||||
/* For separate shrink-wrapping we use LIVE to analyze which basic blocks
|
||||
need a prologue for some component to be executed before that block,
|
||||
and we do not care about any other registers. Hence, we do not want
|
||||
any register for any component defined in the entry block, and we can
|
||||
just leave all registers undefined. */
|
||||
if (df_scan->local_flags & DF_SCAN_EMPTY_ENTRY_EXIT)
|
||||
return;
|
||||
|
||||
for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
|
||||
{
|
||||
if (global_regs[i])
|
||||
@ -3665,6 +3673,14 @@ df_get_exit_block_use_set (bitmap exit_block_uses)
|
||||
|
||||
bitmap_clear (exit_block_uses);
|
||||
|
||||
/* For separate shrink-wrapping we use LIVE to analyze which basic blocks
|
||||
need an epilogue for some component to be executed after that block,
|
||||
and we do not care about any other registers. Hence, we do not want
|
||||
any register for any component seen as used in the exit block, and we
|
||||
can just say no registers at all are used. */
|
||||
if (df_scan->local_flags & DF_SCAN_EMPTY_ENTRY_EXIT)
|
||||
return;
|
||||
|
||||
/* Stack pointer is always live at the exit. */
|
||||
bitmap_set_bit (exit_block_uses, STACK_POINTER_REGNUM);
|
||||
|
||||
|
7
gcc/df.h
7
gcc/df.h
@ -450,6 +450,13 @@ enum df_chain_flags
|
||||
DF_UD_CHAIN = 2 /* Build UD chains. */
|
||||
};
|
||||
|
||||
enum df_scan_flags
|
||||
{
|
||||
/* Flags for the SCAN problem. */
|
||||
DF_SCAN_EMPTY_ENTRY_EXIT = 1 /* Don't define any registers in the entry
|
||||
block; don't use any in the exit block. */
|
||||
};
|
||||
|
||||
enum df_changeable_flags
|
||||
{
|
||||
/* Scanning flags. */
|
||||
|
@ -1682,7 +1682,13 @@ try_shrink_wrapping_separate (basic_block first_bb)
|
||||
if (!components)
|
||||
return;
|
||||
|
||||
/* We need LIVE info. */
|
||||
/* We need LIVE info, not defining anything in the entry block and not
|
||||
using anything in the exit block. A block then needs a component if
|
||||
the register for that component is in the IN or GEN or KILL set for
|
||||
that block. */
|
||||
df_scan->local_flags |= DF_SCAN_EMPTY_ENTRY_EXIT;
|
||||
df_update_entry_block_defs ();
|
||||
df_update_exit_block_uses ();
|
||||
df_live_add_problem ();
|
||||
df_live_set_all_dirty ();
|
||||
df_analyze ();
|
||||
@ -1748,9 +1754,10 @@ try_shrink_wrapping_separate (basic_block first_bb)
|
||||
free_dominance_info (CDI_DOMINATORS);
|
||||
free_dominance_info (CDI_POST_DOMINATORS);
|
||||
|
||||
if (crtl->shrink_wrapped_separate)
|
||||
{
|
||||
/* All done. */
|
||||
df_scan->local_flags &= ~DF_SCAN_EMPTY_ENTRY_EXIT;
|
||||
df_update_entry_block_defs ();
|
||||
df_update_exit_block_uses ();
|
||||
df_live_set_all_dirty ();
|
||||
df_analyze ();
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user