Makefile.in (cfgrtl.o): Add expr.h dependency.

* Makefile.in (cfgrtl.o): Add expr.h dependency.
	* cfgrtl.c: Include expr.h.
	(mark_killed_regs, safe_insert_insn_on_edge): New
	functions.
	* config/i386/i386.h (AVOID_CCMODE_COPIES): Define.
	* basic-block.h (safe_insert_insn_on_edge): Declare.

From-SVN: r68518
This commit is contained in:
Zdenek Dvorak 2003-06-26 08:13:27 +02:00 committed by Zdenek Dvorak
parent 9eee5e726d
commit ff25ef9976
5 changed files with 111 additions and 1 deletions

View File

@ -1,3 +1,12 @@
2003-06-24 Zdenek Dvorak <rakdver@atrey.karlin.mff.cuni.cz>
* Makefile.in (cfgrtl.o): Add expr.h dependency.
* cfgrtl.c: Include expr.h.
(mark_killed_regs, safe_insert_insn_on_edge): New
functions.
* config/i386/i386.h (AVOID_CCMODE_COPIES): Define.
* basic-block.h (safe_insert_insn_on_edge): Declare.
2003-06-26 Neil Booth <neil@daikokuya.co.uk>
* c-opts.c (missing_arg): Make non-static.

View File

@ -1659,7 +1659,7 @@ cfghooks.o: cfghooks.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(RTL_H) $(TR
$(BASIC_BLOCK_H) cfglayout.h
cfgrtl.o : cfgrtl.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(RTL_H) flags.h \
insn-config.h $(BASIC_BLOCK_H) $(REGS_H) hard-reg-set.h output.h toplev.h $(RECOG_H) \
function.h except.h $(GGC_H) $(TM_P_H) insn-config.h
function.h except.h $(GGC_H) $(TM_P_H) insn-config.h $(EXPR_H)
cfganal.o : cfganal.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(RTL_H) \
$(BASIC_BLOCK_H) hard-reg-set.h insn-config.h $(RECOG_H) $(GGC_H) $(TM_P_H)
cfgbuild.o : cfgbuild.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(RTL_H) flags.h \

View File

@ -340,6 +340,7 @@ extern void update_bb_for_insn PARAMS ((basic_block));
extern void free_basic_block_vars PARAMS ((int));
extern void insert_insn_on_edge PARAMS ((rtx, edge));
bool safe_insert_insn_on_edge (rtx, edge);
extern void commit_edge_insertions PARAMS ((void));
extern void commit_edge_insertions_watch_calls PARAMS ((void));

View File

@ -56,6 +56,7 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
#include "obstack.h"
#include "insn-config.h"
#include "cfglayout.h"
#include "expr.h"
/* Stubs in case we don't have a return insn. */
#ifndef HAVE_return
@ -88,6 +89,7 @@ static bool rtl_redirect_edge_and_branch (edge, basic_block);
static edge rtl_split_block (basic_block, void *);
static void rtl_dump_bb (basic_block, FILE *);
static int rtl_verify_flow_info_1 (void);
static void mark_killed_regs (rtx, rtx, void *);
/* Return true if NOTE is not one of the ones that must be kept paired,
so that we may simply delete it. */
@ -1305,6 +1307,101 @@ insert_insn_on_edge (rtx pattern, edge e)
end_sequence ();
}
/* Called from safe_insert_insn_on_edge through note_stores, marks live
registers that are killed by the store. */
static void
mark_killed_regs (rtx reg, rtx set ATTRIBUTE_UNUSED, void *data)
{
regset killed = data;
int regno, i;
if (GET_CODE (reg) == SUBREG)
reg = SUBREG_REG (reg);
if (!REG_P (reg))
return;
regno = REGNO (reg);
if (regno >= FIRST_PSEUDO_REGISTER)
SET_REGNO_REG_SET (killed, regno);
else
{
for (i = 0; i < HARD_REGNO_NREGS (regno, GET_MODE (reg)); i++)
SET_REGNO_REG_SET (killed, regno + i);
}
}
/* Similar to insert_insn_on_edge, tries to put INSN to edge E. Additionally
it checks whether this will not clobber the registers that are live on the
edge (i.e. it requieres liveness information to be up-to-date) and if there
are some, then it tries to save and restore them. Returns true if
succesful. */
bool
safe_insert_insn_on_edge (rtx insn, edge e)
{
rtx x;
regset_head killed_head;
regset killed = INITIALIZE_REG_SET (killed_head);
rtx save_regs = NULL_RTX;
int regno, noccmode;
enum machine_mode mode;
#ifdef AVOID_CCMODE_COPIES
noccmode = true;
#else
noccmode = false;
#endif
for (x = insn; x; x = NEXT_INSN (x))
if (INSN_P (x))
note_stores (PATTERN (x), mark_killed_regs, killed);
bitmap_operation (killed, killed, e->dest->global_live_at_start,
BITMAP_AND);
EXECUTE_IF_SET_IN_REG_SET (killed, 0, regno,
{
mode = regno < FIRST_PSEUDO_REGISTER
? reg_raw_mode[regno]
: GET_MODE (regno_reg_rtx[regno]);
if (mode == VOIDmode)
return false;
if (noccmode && mode == CCmode)
return false;
save_regs = alloc_EXPR_LIST (0,
alloc_EXPR_LIST (0,
gen_reg_rtx (mode),
gen_raw_REG (mode, regno)),
save_regs);
});
if (save_regs)
{
rtx from, to;
start_sequence ();
for (x = save_regs; x; x = XEXP (x, 1))
{
from = XEXP (XEXP (x, 0), 1);
to = XEXP (XEXP (x, 0), 0);
emit_move_insn (to, from);
}
emit_insn (insn);
for (x = save_regs; x; x = XEXP (x, 1))
{
from = XEXP (XEXP (x, 0), 0);
to = XEXP (XEXP (x, 0), 1);
emit_move_insn (to, from);
}
insn = get_insns ();
end_sequence ();
free_EXPR_LIST_list (&save_regs);
}
insert_insn_on_edge (insn, e);
FREE_REG_SET (killed);
return true;
}
/* Update the CFG for the instructions queued on edge E. */
static void

View File

@ -1123,6 +1123,9 @@ do { \
&& (TARGET_64BIT || !TARGET_PARTIAL_REG_STALL)) \
|| ((MODE2) == DImode && TARGET_64BIT))))
/* It is possible to write patterns to move flags; but until someone
does it, */
#define AVOID_CCMODE_COPIES
/* Specify the modes required to caller save a given hard regno.
We do this on i386 to prevent flags from being saved at all.