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:
Segher Boessenkool 2016-11-16 16:23:36 +01:00 committed by Segher Boessenkool
parent 307ca54339
commit 7157aa8583
5 changed files with 51 additions and 7 deletions

View File

@ -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>

View File

@ -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);

View File

@ -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);

View File

@ -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. */

View File

@ -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)
{
df_live_set_all_dirty ();
df_analyze ();
}
/* 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 ();
}