Commit e90b336f by Jeff Law Committed by Jeff Law

re PR rtl-optimization/41619 (ICE in insert_save (caller-save.c) for SPEC CPU2000's 252.eon)


	PR rtl-optimization/41619
	* caller-save.c (setup_save_areas): Break out code to determine
	which hard regs are live across calls by examining the reload chains
	so that it is always used.
	Eliminate code which checked REG_N_CALLS_CROSSED.

	PR rtl-optimization/41619
	* gcc.dg/pr41619.c: New.

From-SVN: r169095
parent 3ffe07e1
2011-01-21 Jeff Law <law@redhat.com>
PR rtl-optimization/41619
* caller-save.c (setup_save_areas): Break out code to determine
which hard regs are live across calls by examining the reload chains
so that it is always used.
Eliminate code which checked REG_N_CALLS_CROSSED.
2011-01-21 Jakub Jelinek <jakub@redhat.com> 2011-01-21 Jakub Jelinek <jakub@redhat.com>
PR tree-optimization/47355 PR tree-optimization/47355
......
/* Save and restore call-clobbered registers which are live across a call. /* Save and restore call-clobbered registers which are live across a call.
Copyright (C) 1989, 1992, 1994, 1995, 1997, 1998, 1999, 2000, Copyright (C) 1989, 1992, 1994, 1995, 1997, 1998, 1999, 2000,
2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011
Free Software Foundation, Inc. Free Software Foundation, Inc.
This file is part of GCC. This file is part of GCC.
...@@ -416,43 +416,19 @@ saved_hard_reg_compare_func (const void *v1p, const void *v2p) ...@@ -416,43 +416,19 @@ saved_hard_reg_compare_func (const void *v1p, const void *v2p)
void void
setup_save_areas (void) setup_save_areas (void)
{ {
int i, j, k; int i, j, k, freq;
unsigned int r;
HARD_REG_SET hard_regs_used; HARD_REG_SET hard_regs_used;
struct saved_hard_reg *saved_reg;
/* Allocate space in the save area for the largest multi-register rtx insn;
pseudos first, then work backwards to single register
pseudos. */
/* Find and record all call-used hard-registers in this function. */
CLEAR_HARD_REG_SET (hard_regs_used);
for (i = FIRST_PSEUDO_REGISTER; i < max_regno; i++)
if (reg_renumber[i] >= 0 && REG_N_CALLS_CROSSED (i) > 0)
{
unsigned int regno = reg_renumber[i];
unsigned int endregno
= end_hard_regno (GET_MODE (regno_reg_rtx[i]), regno);
for (r = regno; r < endregno; r++)
if (call_used_regs[r])
SET_HARD_REG_BIT (hard_regs_used, r);
}
if (optimize && flag_ira_share_save_slots)
{
rtx insn, slot;
struct insn_chain *chain, *next; struct insn_chain *chain, *next;
char *saved_reg_conflicts;
unsigned int regno; unsigned int regno;
int next_k, freq;
struct saved_hard_reg *saved_reg, *saved_reg2, *saved_reg3;
int call_saved_regs_num;
struct saved_hard_reg *call_saved_regs[FIRST_PSEUDO_REGISTER];
HARD_REG_SET hard_regs_to_save, used_regs, this_insn_sets; HARD_REG_SET hard_regs_to_save, used_regs, this_insn_sets;
reg_set_iterator rsi; reg_set_iterator rsi;
int best_slot_num;
int prev_save_slots_num;
rtx prev_save_slots[FIRST_PSEUDO_REGISTER];
CLEAR_HARD_REG_SET (hard_regs_used);
/* Find every CALL_INSN and record which hard regs are live across the
call into HARD_REG_MAP and HARD_REGS_USED. */
initiate_saved_hard_regs (); initiate_saved_hard_regs ();
/* Create hard reg saved regs. */ /* Create hard reg saved regs. */
for (chain = reload_insn_chain; chain != 0; chain = next) for (chain = reload_insn_chain; chain != 0; chain = next)
...@@ -488,6 +464,7 @@ setup_save_areas (void) ...@@ -488,6 +464,7 @@ setup_save_areas (void)
hard_reg_map[regno]->call_freq += freq; hard_reg_map[regno]->call_freq += freq;
else else
saved_reg = new_saved_hard_reg (regno, freq); saved_reg = new_saved_hard_reg (regno, freq);
SET_HARD_REG_BIT (hard_regs_used, regno);
} }
/* Look through all live pseudos, mark their hard registers. */ /* Look through all live pseudos, mark their hard registers. */
EXECUTE_IF_SET_IN_REG_SET EXECUTE_IF_SET_IN_REG_SET
...@@ -508,9 +485,24 @@ setup_save_areas (void) ...@@ -508,9 +485,24 @@ setup_save_areas (void)
else else
saved_reg = new_saved_hard_reg (r, freq); saved_reg = new_saved_hard_reg (r, freq);
SET_HARD_REG_BIT (hard_regs_to_save, r); SET_HARD_REG_BIT (hard_regs_to_save, r);
SET_HARD_REG_BIT (hard_regs_used, r);
} }
} }
} }
/* If requested, figure out which hard regs can share save slots. */
if (optimize && flag_ira_share_save_slots)
{
rtx slot;
char *saved_reg_conflicts;
int next_k;
struct saved_hard_reg *saved_reg2, *saved_reg3;
int call_saved_regs_num;
struct saved_hard_reg *call_saved_regs[FIRST_PSEUDO_REGISTER];
int best_slot_num;
int prev_save_slots_num;
rtx prev_save_slots[FIRST_PSEUDO_REGISTER];
/* Find saved hard register conflicts. */ /* Find saved hard register conflicts. */
saved_reg_conflicts = (char *) xmalloc (saved_regs_num * saved_regs_num); saved_reg_conflicts = (char *) xmalloc (saved_regs_num * saved_regs_num);
memset (saved_reg_conflicts, 0, saved_regs_num * saved_regs_num); memset (saved_reg_conflicts, 0, saved_regs_num * saved_regs_num);
...@@ -668,8 +660,10 @@ setup_save_areas (void) ...@@ -668,8 +660,10 @@ setup_save_areas (void)
} }
else else
{ {
/* Now run through all the call-used hard-registers and allocate /* We are not sharing slots.
space for them in the caller-save area. Try to allocate space
Run through all the call-used hard-registers and allocate
space for each in the caller-save area. Try to allocate space
in a manner which allows multi-register saves/restores to be done. */ in a manner which allows multi-register saves/restores to be done. */
for (i = 0; i < FIRST_PSEUDO_REGISTER; i++) for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
......
2011-01-21 Jeff Law <law@redhat.com>
PR rtl-optimization/41619
* gcc.dg/pr41619.c: New.
2011-01-21 Jakub Jelinek <jakub@redhat.com> 2011-01-21 Jakub Jelinek <jakub@redhat.com>
PR tree-optimization/47355 PR tree-optimization/47355
......
/* { dg-do compile } */
/* { dg-options "-O2 -fno-ira-share-save-slots" } */
struct A {};
int foo();
struct A bar(double x)
{
double y;
if (foo())
y = 1 / x;
return bar(y);
}
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