aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorVladimir Makarov <vmakarov@redhat.com>2008-06-10 17:14:25 +0000
committerVladimir Makarov <vmakarov@redhat.com>2008-06-10 17:14:25 +0000
commit74c088ea4d4931ebdd44bb990bb38b9464b97801 (patch)
tree8cd2108f099c98d6526625e757514de8a151e742 /gcc
parentfdfc34fd608fcdf61110ff185917de001defc2b9 (diff)
2008-06-10 Vladimir Makarov <vmakarov@redhat.com>
* common.opt (fira-move-spills): Remove. * caller-save.c: Add more comments. (save_call_clobbered_regs): Remove flag_ira_move_spills. * doc/invoke.texi (-fno-ira-move-spills): Remove. git-svn-id: https://gcc.gnu.org/svn/gcc/branches/ira@136634 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'gcc')
-rw-r--r--gcc/ChangeLog9
-rw-r--r--gcc/caller-save.c153
-rw-r--r--gcc/common.opt4
-rw-r--r--gcc/doc/invoke.texi8
4 files changed, 132 insertions, 42 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index f242175cf87..181d0e1db48 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,12 @@
+2008-06-10 Vladimir Makarov <vmakarov@redhat.com>
+
+ * common.opt (fira-move-spills): Remove.
+
+ * caller-save.c: Add more comments.
+ (save_call_clobbered_regs): Remove flag_ira_move_spills.
+
+ * doc/invoke.texi (-fno-ira-move-spills): Remove.
+
2008-06-06 Vladimir Makarov <vmakarov@redhat.com>
* ira-build.c (ira_flattening): Check first info propagation.
diff --git a/gcc/caller-save.c b/gcc/caller-save.c
index 436915e1fad..39bc34d2515 100644
--- a/gcc/caller-save.c
+++ b/gcc/caller-save.c
@@ -1,6 +1,6 @@
/* Save and restore call-clobbered registers which are live across a call.
Copyright (C) 1989, 1992, 1994, 1995, 1997, 1998, 1999, 2000,
- 2001, 2002, 2003, 2004, 2005, 2006, 2007 Free Software Foundation, Inc.
+ 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008 Free Software Foundation, Inc.
This file is part of GCC.
@@ -775,7 +775,55 @@ setup_save_areas (void)
/* This page contains code for global analysis for better placement
- save/restore insn when IRA is used. */
+ save/restore insn when IRA is used.
+
+ First, we calculate local BB info in function calculate_local_save_info:
+ o hard registers set/mentioned in basic blocks (they prevents
+ moving corresponding saves/restores further up/down in CFG) --
+ see comments for save_kill/restore_kill.
+ o hard registers needed to be saved/restored around calls and
+ which are not set/mentioned before/after the call in the basic
+ block -- see comments for save_gen/restore_gen.
+ o free hard registers at the basic block start -- see comments
+ for free_gen. This set can be different from save_gen. For
+ example, in the following situation
+
+ BB:
+ ...
+ insn using R
+ ...
+ call through which R live through and should be saved/restored.
+ ...
+
+ save_gen contains R because we can put save at the BB start but
+ free_gen does not contain R because we can not use R for other
+ purposes from the BB start till the insn using R.
+
+ Second, we calculate the global info for placement saves/restores
+ in functions -- see comments for save_in, save_out, restore_in,
+ restore_out, free_in, free_out.
+
+ The equations for the global info calculation are not trivial
+ because we can not put saves/restores on CFG edges as the reload
+ can not work when new BBs added. For example, it means that all
+ save_out set of BB should be a subset of intersections of save_in
+ of all successors of the BB. Preventing putting the code on edges
+ makes data flow problem bidirectional. The data flow functions are
+ also complicated by necessity to propagate saving modes (e.g. x86
+ fp register can be saved in XFmode or DFmode).
+
+ The equations do not permit to propagate info into the loops
+ because we can not put saves/restores in more frequently executed
+ points. But if the loop does not contains references for a hard
+ register, we permit to propagate info for the register into the
+ loop because the info will be propagated through all the loop and
+ as consequence corresponding saves/restores will be moved through
+ the loop.
+
+ Third, using this info we place saves/restores and set up member
+ `saved' in function save_call_clobbered_regs.
+
+ */
/* The following structure contains basic block data flow information
used to optimize save/restore placement. Data flow equations are
@@ -857,7 +905,11 @@ calculate_local_save_info (void)
HARD_REG_SET this_insn_sets, save_gen, restore_gen, free_gen, temp_set;
unsigned regno;
reg_set_iterator rsi;
+ /* A map: hard register being saved to the mode used for its
+ saving. */
enum machine_mode save_mode[FIRST_PSEUDO_REGISTER];
+ /* A map: hard register being saved to the pseudo-register assigned
+ to the hard register at given point. */
int save_pseudo[FIRST_PSEUDO_REGISTER];
CLEAR_HARD_REG_SET (save_gen);
@@ -1090,8 +1142,14 @@ calculate_local_save_info (void)
}
}
-/* The function used by the DF equation solver to propagate restore
- info through block with BB_INDEX. */
+/* The transfer function used by the DF equation solver to propagate restore
+ info through block with BB_INDEX according to the following
+ equation:
+
+ bb.restore_out = (bb.restore_in - bb.restore_kill) U bb.restore_gen.
+
+ The function also propagates saving modes of the hard
+ registers. */
static bool
restore_trans_fun (int bb_index)
{
@@ -1122,7 +1180,7 @@ restore_trans_fun (int bb_index)
return false;
}
-/* The function used by the DF equation solver to set up restore info
+/* The confluence function used by the DF equation solver to set up restore info
for a block BB without predecessor. */
static void
restore_con_fun_0 (basic_block bb)
@@ -1130,8 +1188,17 @@ restore_con_fun_0 (basic_block bb)
CLEAR_HARD_REG_SET (BB_INFO (bb)->restore_in);
}
-/* The function used by the DF equation solver to propagate restore info
- from predecessor to successor on edge E. */
+/* The confluence function used by the DF equation solver to propagate
+ restore info from predecessor to successor on edge E (pred->bb)
+ according to the following equation:
+
+ bb.restore_in = empty for entry block or one with empty_restore_in_p
+ | ^(pred.restore_out - pred.restore_here) ^ bb.live_at_start
+
+ If the edge is a loop enter we do not propagate the info because we
+ don't want to put restores in more frequently executed places.
+
+ */
static void
restore_con_fun_n (edge e)
{
@@ -1232,8 +1299,15 @@ calculate_restore_here (void)
return changed_p;
}
-/* The function used by the DF equation solver to propagate save
- info through block with BB_INDEX. */
+/* The transfer function used by the DF equation solver to propagate save info
+ through block with BB_INDEX according to the following
+ equation:
+
+ bb.save_in = ((bb.save_out - bb.save_kill) U bb.save_gen) - bb.restore_in.
+
+ The function also propagates saving modes of the hard
+ registers. */
+
static bool
save_trans_fun (int bb_index)
{
@@ -1265,16 +1339,24 @@ save_trans_fun (int bb_index)
return false;
}
-/* The function used by the DF equation solver to set up save info
- for a block BB without successor. */
+/* The confluence function used by the DF equation solver to set up
+ save info for a block BB without successor. */
static void
save_con_fun_0 (basic_block bb)
{
CLEAR_HARD_REG_SET (BB_INFO (bb)->save_out);
}
-/* The function used by the DF equation solver to propagate save info
- from successor to predecessor on edge E. */
+/* The confluence function used by the DF equation solver to propagate
+ save info from successor to predecessor on edge E (bb->succ)
+ according to the following equation:
+
+ bb.save_out = empty for exit block or one with empty_save_out_p
+ | ^(succ.save_in - succ.save_here) ^ bb.live_at_end
+
+ If the edge is a loop exit we do not propagate the info because we
+ don't want to put saves in more frequently executed places.
+*/
static void
save_con_fun_n (edge e)
{
@@ -1319,7 +1401,7 @@ save_con_fun_n (edge e)
}
}
-/* The function calculates global save information according
+/* The transfer function calculates global save information according
to the following equations:
bb.save_out = empty for exit block or one with empty_save_out_p
@@ -1370,8 +1452,14 @@ calculate_save_here (void)
return changed_p;
}
-/* The function used by the DF equation solver to propagate free
- info through block with BB_INDEX. */
+/* The transfer function used by the DF equation solver to propagate
+ free info through block with BB_INDEX according to the following
+ equation:
+
+ bb.free_in = ((bb.free_out - bb.save_kill - bb.restore_kill) U bb.free_gen)
+ - bb.save_here)
+
+*/
static bool
free_trans_fun (int bb_index)
{
@@ -1391,16 +1479,20 @@ free_trans_fun (int bb_index)
return false;
}
-/* The function used by the DF equation solver to set up free info
- for a block BB without successor. */
+/* The confluence function used by the DF equation solver to set up
+ free info for a block BB without successor. */
static void
free_con_fun_0 (basic_block bb)
{
CLEAR_HARD_REG_SET (BB_INFO (bb)->free_out);
}
-/* The function used by the DF equation solver to propagate free info
- from successor to predecessor on edge E. */
+/* The confluence function used by the DF equation solver to propagate
+ free info from successor to predecessor on edge E (bb->succ)
+ according to the following equation:
+
+ bb.free_out = ^succ.free_in
+*/
static void
free_con_fun_n (edge e)
{
@@ -1637,7 +1729,7 @@ save_call_clobbered_regs (void)
int save_pseudo[FIRST_PSEUDO_REGISTER];
int free_pseudo[FIRST_PSEUDO_REGISTER];
- if (flag_ira && optimize && flag_ira_move_spills)
+ if (flag_ira && optimize)
{
/* Do global analysis for better placement of spill code. */
alloc_aux_for_blocks (sizeof (struct bb_info));
@@ -1652,7 +1744,7 @@ save_call_clobbered_regs (void)
CLEAR_HARD_REG_SET (hard_regs_saved);
n_regs_saved = 0;
- if (flag_ira && flag_ira_move_spills && reload_insn_chain != NULL)
+ if (flag_ira && reload_insn_chain != NULL)
{
bb_info = BB_INFO_BY_INDEX (reload_insn_chain->block);
set_hard_reg_saved (bb_info->restore_in,
@@ -1673,7 +1765,7 @@ save_call_clobbered_regs (void)
{
if (n_regs_saved)
{
- if ((!flag_ira || !flag_ira_move_spills) && code == JUMP_INSN)
+ if (!flag_ira && code == JUMP_INSN)
/* Restore all registers if this is a JUMP_INSN. */
COPY_HARD_REG_SET (referenced_regs, hard_regs_saved);
else
@@ -1695,7 +1787,7 @@ save_call_clobbered_regs (void)
regno += insert_restore (chain, 1, regno, MOVE_MAX_WORDS,
save_mode, save_pseudo);
- if (flag_ira && optimize && flag_ira_move_spills)
+ if (flag_ira && optimize)
{
gcc_assert (before == regno);
save_mode[before] = VOIDmode;
@@ -1767,7 +1859,7 @@ save_call_clobbered_regs (void)
get_call_invalidated_used_regs (insn, &used_regs, false);
AND_HARD_REG_SET (hard_regs_to_save, used_regs);
- if (flag_ira & flag_ira_move_spills)
+ if (flag_ira)
IOR_HARD_REG_SET (hard_regs_saved, hard_regs_to_save);
else
{
@@ -1798,7 +1890,7 @@ save_call_clobbered_regs (void)
remain saved. If the last insn in the block is a JUMP_INSN, put
the restore before the insn, otherwise, put it after the insn. */
- if (flag_ira && optimize && flag_ira_move_spills)
+ if (flag_ira && optimize)
set_hard_reg_saved
(BB_INFO_BY_INDEX (chain->block)->restore_here,
BB_INFO_BY_INDEX (chain->block)->restore_out_mode, save_mode,
@@ -1814,7 +1906,7 @@ save_call_clobbered_regs (void)
regno += insert_restore (chain, JUMP_P (insn),
regno, MOVE_MAX_WORDS, save_mode,
save_pseudo);
- if (flag_ira && optimize && flag_ira_move_spills)
+ if (flag_ira && optimize)
{
gcc_assert (before == regno);
save_mode[before] = VOIDmode;
@@ -1822,8 +1914,7 @@ save_call_clobbered_regs (void)
}
}
- if (flag_ira && optimize
- && flag_ira_move_spills && next_bb_info != NULL)
+ if (flag_ira && optimize && next_bb_info != NULL)
set_hard_reg_saved (next_bb_info->restore_in,
next_bb_info->restore_in_mode, save_mode,
next_bb_info->restore_in_pseudo, save_pseudo);
@@ -1831,7 +1922,7 @@ save_call_clobbered_regs (void)
}
}
- if (!flag_ira || !flag_ira_move_spills)
+ if (!flag_ira)
return;
CLEAR_HARD_REG_SET (hard_regs_to_save);
@@ -2086,7 +2177,7 @@ save_call_clobbered_regs (void)
{
free (loop->aux);
}
- if (flag_ira && optimize && flag_ira_move_spills)
+ if (flag_ira && optimize)
free_aux_for_blocks ();
}
diff --git a/gcc/common.opt b/gcc/common.opt
index 90b3293e5dd..9c6799e222b 100644
--- a/gcc/common.opt
+++ b/gcc/common.opt
@@ -657,10 +657,6 @@ fira-ipra
Common Report Var(flag_ira_ipra) Init(0)
Inter-procedural register allocation for IRA.
-fira-move-spills
-Common Report Var(flag_ira_move_spills) Init(1)
-Increase gap between the corresponding save and restore insns.
-
fira-propagate-cost
Common Report Var(flag_ira_propagate_cost) Init(0)
Propagate hard reg costs down for regional or mixed ira allocation algorithm.
diff --git a/gcc/doc/invoke.texi b/gcc/doc/invoke.texi
index c652b932bb2..76e07d431c0 100644
--- a/gcc/doc/invoke.texi
+++ b/gcc/doc/invoke.texi
@@ -333,7 +333,7 @@ Objective-C and Objective-C++ Dialects}.
-finline-small-functions -fipa-cp -fipa-marix-reorg -fipa-pta @gol
-fipa-pure-const -fipa-reference -fipa-struct-reorg @gol
-fipa-type-escape -fira -fira-algorithm=@var{algorithm} @gol
--fira-coalesce -fira-ipra -fno-ira-move-spills @gol
+-fira-coalesce -fira-ipra @gol
-fira-propagate-cost -fno-ira-share-save-slots @gol
-fno-ira-share-spill-slots -fira-verbose=@var{n} @gol
-fivopts -fkeep-inline-functions -fkeep-static-consts @gol
@@ -5696,12 +5696,6 @@ the integrated register allocator (@acronym{IRA}) is used.
This is an experimental option used to propagate hard reg costs down
to nested regions for regional or mixed ira allocation algorithm.
-@item -fno-ira-move-spills
-@opindex fno-ira-move-spills
-Switch off increasing gap between the corresponding save and restore
-insns. All saves and the corresponding restores of call used hard
-registers living through a call will be in the same basic block.
-
@item -fno-ira-share-save-slots
@opindex fno-ira-share-save-slots
Switch off sharing stack slots used for saving call used hard