/* IRA processing allocno lives to build allocno live ranges.
- Copyright (C) 2006, 2007, 2008
+ Copyright (C) 2006, 2007, 2008, 2009
Free Software Foundation, Inc.
Contributed by Vladimir Makarov <vmakarov@redhat.com>.
#include "tm_p.h"
#include "target.h"
#include "flags.h"
+#include "except.h"
#include "hard-reg-set.h"
#include "basic-block.h"
#include "insn-config.h"
static void
update_allocno_pressure_excess_length (ira_allocno_t a)
{
- int start;
- enum reg_class cover_class;
+ int start, i;
+ enum reg_class cover_class, cl;
allocno_live_range_t p;
cover_class = ALLOCNO_COVER_CLASS (a);
- if (high_pressure_start_point[cover_class] < 0)
- return;
- p = ALLOCNO_LIVE_RANGES (a);
- ira_assert (p != NULL);
- start = (high_pressure_start_point[cover_class] > p->start
- ? high_pressure_start_point[cover_class] : p->start);
- ALLOCNO_EXCESS_PRESSURE_POINTS_NUM (a) += curr_point - start + 1;
+ for (i = 0;
+ (cl = ira_reg_class_super_classes[cover_class][i]) != LIM_REG_CLASSES;
+ i++)
+ {
+ if (high_pressure_start_point[cl] < 0)
+ continue;
+ p = ALLOCNO_LIVE_RANGES (a);
+ ira_assert (p != NULL);
+ start = (high_pressure_start_point[cl] > p->start
+ ? high_pressure_start_point[cl] : p->start);
+ ALLOCNO_EXCESS_PRESSURE_POINTS_NUM (a) += curr_point - start + 1;
+ }
}
/* Process the death of register REGNO. This updates hard_regs_live
static void
set_allocno_live (ira_allocno_t a)
{
- int nregs;
- enum reg_class cover_class;
+ int i;
+ enum reg_class cover_class, cl;
/* Invalidate because it is referenced. */
allocno_saved_at_call[ALLOCNO_NUM (a)] = 0;
IOR_HARD_REG_SET (ALLOCNO_CONFLICT_HARD_REGS (a), hard_regs_live);
IOR_HARD_REG_SET (ALLOCNO_TOTAL_CONFLICT_HARD_REGS (a), hard_regs_live);
cover_class = ALLOCNO_COVER_CLASS (a);
- nregs = ira_reg_class_nregs[cover_class][ALLOCNO_MODE (a)];
- curr_reg_pressure[cover_class] += nregs;
- if (high_pressure_start_point[cover_class] < 0
- && (curr_reg_pressure[cover_class]
- > ira_available_class_regs[cover_class]))
- high_pressure_start_point[cover_class] = curr_point;
- if (curr_bb_node->reg_pressure[cover_class]
- < curr_reg_pressure[cover_class])
- curr_bb_node->reg_pressure[cover_class] = curr_reg_pressure[cover_class];
+ for (i = 0;
+ (cl = ira_reg_class_super_classes[cover_class][i]) != LIM_REG_CLASSES;
+ i++)
+ {
+ curr_reg_pressure[cl] += ira_reg_class_nregs[cl][ALLOCNO_MODE (a)];
+ if (high_pressure_start_point[cl] < 0
+ && (curr_reg_pressure[cl] > ira_available_class_regs[cl]))
+ high_pressure_start_point[cl] = curr_point;
+ if (curr_bb_node->reg_pressure[cl] < curr_reg_pressure[cl])
+ curr_bb_node->reg_pressure[cl] = curr_reg_pressure[cl];
+ }
}
/* Mark allocno A as currently not living and update current register
static void
clear_allocno_live (ira_allocno_t a)
{
- unsigned int i;
- enum reg_class cover_class;
+ int i;
+ unsigned int j;
+ enum reg_class cover_class, cl;
+ bool set_p;
/* Invalidate because it is referenced. */
allocno_saved_at_call[ALLOCNO_NUM (a)] = 0;
if (sparseset_bit_p (allocnos_live, ALLOCNO_NUM (a)))
{
cover_class = ALLOCNO_COVER_CLASS (a);
- curr_reg_pressure[cover_class]
- -= ira_reg_class_nregs[cover_class][ALLOCNO_MODE (a)];
- ira_assert (curr_reg_pressure[cover_class] >= 0);
- if (high_pressure_start_point[cover_class] >= 0
- && (curr_reg_pressure[cover_class]
- <= ira_available_class_regs[cover_class]))
+ set_p = false;
+ for (i = 0;
+ (cl = ira_reg_class_super_classes[cover_class][i])
+ != LIM_REG_CLASSES;
+ i++)
{
- EXECUTE_IF_SET_IN_SPARSESET (allocnos_live, i)
- {
- update_allocno_pressure_excess_length (ira_allocnos[i]);
- }
- high_pressure_start_point[cover_class] = -1;
+ curr_reg_pressure[cl] -= ira_reg_class_nregs[cl][ALLOCNO_MODE (a)];
+ ira_assert (curr_reg_pressure[cl] >= 0);
+ if (high_pressure_start_point[cl] >= 0
+ && curr_reg_pressure[cl] <= ira_available_class_regs[cl])
+ set_p = true;
+ }
+ if (set_p)
+ {
+ EXECUTE_IF_SET_IN_SPARSESET (allocnos_live, j)
+ update_allocno_pressure_excess_length (ira_allocnos[j]);
+ for (i = 0;
+ (cl = ira_reg_class_super_classes[cover_class][i])
+ != LIM_REG_CLASSES;
+ i++)
+ if (high_pressure_start_point[cl] >= 0
+ && curr_reg_pressure[cl] <= ira_available_class_regs[cl])
+ high_pressure_start_point[cl] = -1;
+
}
}
sparseset_clear_bit (allocnos_live, ALLOCNO_NUM (a));
static void
mark_reg_live (rtx reg)
{
- int regno;
+ int i, regno;
gcc_assert (REG_P (reg));
regno = REGNO (reg);
else if (! TEST_HARD_REG_BIT (ira_no_alloc_regs, regno))
{
int last = regno + hard_regno_nregs[regno][GET_MODE (reg)];
- enum reg_class cover_class;
+ enum reg_class cover_class, cl;
while (regno < last)
{
&& ! TEST_HARD_REG_BIT (eliminable_regset, regno))
{
cover_class = ira_hard_regno_cover_class[regno];
- if (cover_class != NO_REGS)
+ for (i = 0;
+ (cl = ira_reg_class_super_classes[cover_class][i])
+ != LIM_REG_CLASSES;
+ i++)
{
- curr_reg_pressure[cover_class]++;
- if (high_pressure_start_point[cover_class] < 0
- && (curr_reg_pressure[cover_class]
- > ira_available_class_regs[cover_class]))
- high_pressure_start_point[cover_class] = curr_point;
+ curr_reg_pressure[cl]++;
+ if (high_pressure_start_point[cl] < 0
+ && (curr_reg_pressure[cl]
+ > ira_available_class_regs[cl]))
+ high_pressure_start_point[cl] = curr_point;
}
make_regno_born (regno);
- if (cover_class != NO_REGS
- && (curr_bb_node->reg_pressure[cover_class]
- < curr_reg_pressure[cover_class]))
- curr_bb_node->reg_pressure[cover_class]
- = curr_reg_pressure[cover_class];
+ for (i = 0;
+ (cl = ira_reg_class_super_classes[cover_class][i])
+ != LIM_REG_CLASSES;
+ i++)
+ {
+ if (curr_bb_node->reg_pressure[cl] < curr_reg_pressure[cl])
+ curr_bb_node->reg_pressure[cl] = curr_reg_pressure[cl];
+ }
}
regno++;
}
}
else if (! TEST_HARD_REG_BIT (ira_no_alloc_regs, regno))
{
- unsigned int i;
+ int i;
+ unsigned int j;
int last = regno + hard_regno_nregs[regno][GET_MODE (reg)];
- enum reg_class cover_class;
+ enum reg_class cover_class, cl;
+ bool set_p;
while (regno < last)
{
if (TEST_HARD_REG_BIT (hard_regs_live, regno))
{
+ set_p = false;
cover_class = ira_hard_regno_cover_class[regno];
- if (cover_class != NO_REGS)
+ for (i = 0;
+ (cl = ira_reg_class_super_classes[cover_class][i])
+ != LIM_REG_CLASSES;
+ i++)
+ {
+ curr_reg_pressure[cl]--;
+ if (high_pressure_start_point[cl] >= 0
+ && curr_reg_pressure[cl] <= ira_available_class_regs[cl])
+ set_p = true;
+ ira_assert (curr_reg_pressure[cl] >= 0);
+ }
+ if (set_p)
{
- curr_reg_pressure[cover_class]--;
- if (high_pressure_start_point[cover_class] >= 0
- && (curr_reg_pressure[cover_class]
- <= ira_available_class_regs[cover_class]))
- {
- EXECUTE_IF_SET_IN_SPARSESET (allocnos_live, i)
- {
- update_allocno_pressure_excess_length
- (ira_allocnos[i]);
- }
- high_pressure_start_point[cover_class] = -1;
- }
- ira_assert (curr_reg_pressure[cover_class] >= 0);
+ EXECUTE_IF_SET_IN_SPARSESET (allocnos_live, j)
+ update_allocno_pressure_excess_length (ira_allocnos[j]);
+ for (i = 0;
+ (cl = ira_reg_class_super_classes[cover_class][i])
+ != LIM_REG_CLASSES;
+ i++)
+ if (high_pressure_start_point[cl] >= 0
+ && (curr_reg_pressure[cl]
+ <= ira_available_class_regs[cl]))
+ high_pressure_start_point[cl] = -1;
}
make_regno_dead (regno);
}
if (GET_CODE (reg) == SUBREG)
reg = SUBREG_REG (reg);
-
+
if (! REG_P (reg) || REGNO (reg) < FIRST_PSEUDO_REGISTER)
return advance_p;
-
+
a = ira_curr_regno_allocno_map[REGNO (reg)];
if (! reg_classes_intersect_p (cl, ALLOCNO_COVER_CLASS (a)))
return advance_p;
{
if (! reg_classes_intersect_p (def_cl, use_cl))
return advance_p;
-
+
advance_p = make_pseudo_conflict (recog_data.operand[use],
use_cl, dreg, advance_p);
/* Reload may end up swapping commutative operands, so you
enum reg_class use_cl, acl;
bool advance_p;
rtx dreg = recog_data.operand[def];
-
+
if (def_cl == NO_REGS)
return;
-
+
if (GET_CODE (dreg) == SUBREG)
dreg = SUBREG_REG (dreg);
-
+
if (! REG_P (dreg) || REGNO (dreg) < FIRST_PSEUDO_REGISTER)
return;
-
+
a = ira_curr_regno_allocno_map[REGNO (dreg)];
acl = ALLOCNO_COVER_CLASS (a);
if (! reg_classes_intersect_p (acl, def_cl))
return;
-
+
advance_p = true;
-
+
for (use = 0; use < recog_data.n_operands; use++)
{
if (use == def || recog_data.operand_type[use] == OP_OUT)
- return;
-
+ continue;
+
if (recog_op_alt[use][alt].anything_ok)
use_cl = ALL_REGS;
else
use_cl = recog_op_alt[use][alt].cl;
-
+
advance_p = check_and_make_def_use_conflict (dreg, def_cl, use,
use_cl, advance_p);
-
+
if ((use_match = recog_op_alt[use][alt].matches) >= 0)
{
if (use_match == def)
- return;
-
+ continue;
+
if (recog_op_alt[use_match][alt].anything_ok)
use_cl = ALL_REGS;
else
if (DF_REF_FLAGS_IS_SET (*def_rec, DF_REF_MUST_CLOBBER))
{
rtx dreg = DF_REF_REG (*def_rec);
-
+
if (GET_CODE (dreg) == SUBREG)
dreg = SUBREG_REG (dreg);
if (! REG_P (dreg) || REGNO (dreg) >= FIRST_PSEUDO_REGISTER)
/* Hard register clobbers are believed to be early clobber
because there is no way to say that non-operand hard
- register clobbers are not early ones. */
+ register clobbers are not early ones. */
if (live_p)
mark_ref_live (*def_rec);
else
break;
case 'n':
- if (GET_CODE (op) == CONST_INT
+ if (CONST_INT_P (op)
|| (GET_CODE (op) == CONST_DOUBLE && GET_MODE (op) == VOIDmode)
|| (equiv_const != NULL_RTX
- && (GET_CODE (equiv_const) == CONST_INT
+ && (CONST_INT_P (equiv_const)
|| (GET_CODE (equiv_const) == CONST_DOUBLE
&& GET_MODE (equiv_const) == VOIDmode))))
return NO_REGS;
break;
-
+
case 's':
- if ((CONSTANT_P (op) && GET_CODE (op) != CONST_INT
+ if ((CONSTANT_P (op) && !CONST_INT_P (op)
&& (GET_CODE (op) != CONST_DOUBLE || GET_MODE (op) != VOIDmode))
|| (equiv_const != NULL_RTX
&& CONSTANT_P (equiv_const)
- && GET_CODE (equiv_const) != CONST_INT
+ && !CONST_INT_P (equiv_const)
&& (GET_CODE (equiv_const) != CONST_DOUBLE
|| GET_MODE (equiv_const) != VOIDmode)))
return NO_REGS;
break;
-
+
case 'I':
case 'J':
case 'K':
case 'N':
case 'O':
case 'P':
- if ((GET_CODE (op) == CONST_INT
+ if ((CONST_INT_P (op)
&& CONST_OK_FOR_CONSTRAINT_P (INTVAL (op), c, constraints))
|| (equiv_const != NULL_RTX
- && GET_CODE (equiv_const) == CONST_INT
+ && CONST_INT_P (equiv_const)
&& CONST_OK_FOR_CONSTRAINT_P (INTVAL (equiv_const),
c, constraints)))
return NO_REGS;
break;
-
+
case 'E':
case 'F':
if (GET_CODE (op) == CONST_DOUBLE
== MODE_VECTOR_FLOAT)))))
return NO_REGS;
break;
-
+
case 'G':
case 'H':
if ((GET_CODE (op) == CONST_DOUBLE
? GENERAL_REGS
: REG_CLASS_FROM_CONSTRAINT (c, constraints));
if ((cl != NO_REGS && next_cl != cl)
- || ira_available_class_regs[next_cl] > 1)
+ || (ira_available_class_regs[next_cl]
+ > ira_reg_class_nregs[next_cl][GET_MODE (op)]))
return NO_REGS;
cl = next_cl;
break;
-
+
case '0': case '1': case '2': case '3': case '4':
case '5': case '6': case '7': case '8': case '9':
next_cl
= single_reg_class (recog_data.constraints[c - '0'],
recog_data.operand[c - '0'], NULL_RTX);
- if ((cl != NO_REGS && next_cl != cl) || next_cl == NO_REGS
- || ira_available_class_regs[next_cl] > 1)
+ if ((cl != NO_REGS && next_cl != cl)
+ || next_cl == NO_REGS
+ || (ira_available_class_regs[next_cl]
+ > ira_reg_class_nregs[next_cl][GET_MODE (op)]))
return NO_REGS;
cl = next_cl;
break;
-
+
default:
return NO_REGS;
}
recog_data.operand[op_num], NULL_RTX);
}
+/* The function sets up hard register set *SET to hard registers which
+ might be used by insn reloads because the constraints are too
+ strict. */
+void
+ira_implicitly_set_insn_hard_regs (HARD_REG_SET *set)
+{
+ int i, c, regno = 0;
+ bool ignore_p;
+ enum reg_class cl;
+ rtx op;
+ enum machine_mode mode;
+
+ CLEAR_HARD_REG_SET (*set);
+ for (i = 0; i < recog_data.n_operands; i++)
+ {
+ op = recog_data.operand[i];
+
+ if (GET_CODE (op) == SUBREG)
+ op = SUBREG_REG (op);
+
+ if (GET_CODE (op) == SCRATCH
+ || (REG_P (op) && (regno = REGNO (op)) >= FIRST_PSEUDO_REGISTER))
+ {
+ const char *p = recog_data.constraints[i];
+
+ mode = (GET_CODE (op) == SCRATCH
+ ? GET_MODE (op) : PSEUDO_REGNO_MODE (regno));
+ cl = NO_REGS;
+ for (ignore_p = false; (c = *p); p += CONSTRAINT_LEN (c, p))
+ if (c == '#')
+ ignore_p = true;
+ else if (c == ',')
+ ignore_p = false;
+ else if (! ignore_p)
+ switch (c)
+ {
+ case 'r':
+ case 'a': case 'b': case 'c': case 'd': case 'e': case 'f':
+ case 'h': case 'j': case 'k': case 'l':
+ case 'q': case 't': case 'u':
+ case 'v': case 'w': case 'x': case 'y': case 'z':
+ case 'A': case 'B': case 'C': case 'D':
+ case 'Q': case 'R': case 'S': case 'T': case 'U':
+ case 'W': case 'Y': case 'Z':
+ cl = (c == 'r'
+ ? GENERAL_REGS
+ : REG_CLASS_FROM_CONSTRAINT (c, p));
+ if (cl != NO_REGS
+ && (ira_available_class_regs[cl]
+ <= ira_reg_class_nregs[cl][mode]))
+ IOR_HARD_REG_SET (*set, reg_class_contents[cl]);
+ break;
+ }
+ }
+ }
+}
/* Processes input operands, if IN_P, or output operands otherwise of
the current insn with FREQ to find allocno which can use only one
hard register and makes other currently living allocnos conflicting
{
int i, regno, cost;
unsigned int px;
- enum reg_class cl, cover_class;
+ enum reg_class cl;
rtx operand;
ira_allocno_t operand_a, a;
if (GET_CODE (operand) == SUBREG)
operand = SUBREG_REG (operand);
-
+
if (REG_P (operand)
&& (regno = REGNO (operand)) >= FIRST_PSEUDO_REGISTER)
{
[ira_class_hard_regs[cl][0]]) >= 0
&& reg_class_size[cl] <= (unsigned) CLASS_MAX_NREGS (cl, mode))
{
- /* ??? FREQ */
- cost = freq * (in_p
- ? ira_register_move_cost[mode][cover_class][cl]
- : ira_register_move_cost[mode][cl][cover_class]);
+ int i, size;
+ cost
+ = (freq
+ * (in_p
+ ? ira_get_register_move_cost (mode, cover_class, cl)
+ : ira_get_register_move_cost (mode, cl, cover_class)));
ira_allocate_and_set_costs
(&ALLOCNO_CONFLICT_HARD_REG_COSTS (operand_a), cover_class, 0);
- ALLOCNO_CONFLICT_HARD_REG_COSTS (operand_a)
- [ira_class_hard_reg_index
- [cover_class][ira_class_hard_regs[cl][0]]]
- -= cost;
+ size = ira_reg_class_nregs[cover_class][mode];
+ for (i = 0; i < size; i++)
+ ALLOCNO_CONFLICT_HARD_REG_COSTS (operand_a)
+ [ira_class_hard_reg_index
+ [cover_class][ira_class_hard_regs[cl][i]]]
+ -= cost;
}
}
EXECUTE_IF_SET_IN_SPARSESET (allocnos_live, px)
{
a = ira_allocnos[px];
- cover_class = ALLOCNO_COVER_CLASS (a);
if (a != operand_a)
{
/* We could increase costs of A instead of making it
}
}
+/* Return true when one of the predecessor edges of BB is marked with
+ EDGE_ABNORMAL_CALL or EDGE_EH. */
+static bool
+bb_has_abnormal_call_pred (basic_block bb)
+{
+ edge e;
+ edge_iterator ei;
+
+ FOR_EACH_EDGE (e, ei, bb->preds)
+ {
+ if (e->flags & (EDGE_ABNORMAL_CALL | EDGE_EH))
+ return true;
+ }
+ return false;
+}
+
/* Process insns of the basic block given by its LOOP_TREE_NODE to
update allocno live ranges, allocno hard register conflicts,
intersected calls, and register pressure info for allocnos for the
unsigned int j;
basic_block bb;
rtx insn;
- edge e;
- edge_iterator ei;
bitmap_iterator bi;
bitmap reg_live_out;
unsigned int px;
for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
if (TEST_HARD_REG_BIT (hard_regs_live, i))
{
- enum reg_class cover_class;
-
- cover_class = ira_hard_regno_cover_class[i];
- if (cover_class == NO_REGS)
- continue;
- curr_reg_pressure[cover_class]++;
- if (curr_bb_node->reg_pressure[cover_class]
- < curr_reg_pressure[cover_class])
- curr_bb_node->reg_pressure[cover_class]
- = curr_reg_pressure[cover_class];
- ira_assert (curr_reg_pressure[cover_class]
- <= ira_available_class_regs[cover_class]);
+ enum reg_class cover_class, cl;
+
+ cover_class = ira_class_translate[REGNO_REG_CLASS (i)];
+ for (j = 0;
+ (cl = ira_reg_class_super_classes[cover_class][j])
+ != LIM_REG_CLASSES;
+ j++)
+ {
+ curr_reg_pressure[cl]++;
+ if (curr_bb_node->reg_pressure[cl] < curr_reg_pressure[cl])
+ curr_bb_node->reg_pressure[cl] = curr_reg_pressure[cl];
+ ira_assert (curr_reg_pressure[cl]
+ <= ira_available_class_regs[cl]);
+ }
}
EXECUTE_IF_SET_IN_BITMAP (reg_live_out, FIRST_PSEUDO_REGISTER, j, bi)
{
ira_allocno_t a = ira_curr_regno_allocno_map[j];
-
+
if (a == NULL)
continue;
ira_assert (! sparseset_bit_p (allocnos_live, ALLOCNO_NUM (a)));
set_allocno_live (a);
make_regno_born (j);
}
-
+
freq = REG_FREQ_FROM_BB (bb);
if (freq == 0)
freq = 1;
{
df_ref *def_rec, *use_rec;
bool call_p;
-
- if (! INSN_P (insn))
+
+ if (!NONDEBUG_INSN_P (insn))
continue;
-
+
if (internal_flag_ira_verbose > 2 && ira_dump_file != NULL)
fprintf (ira_dump_file, " Insn %u(l%d): point = %d\n",
INSN_UID (insn), loop_tree_node->parent->loop->num,
}
}
}
-
+
extract_insn (insn);
preprocess_constraints ();
process_single_reg_class_operands (false, freq);
-
+
/* See which defined values die here. */
for (def_rec = DF_INSN_DEFS (insn); *def_rec; def_rec++)
if (!call_p || !DF_REF_FLAGS_IS_SET (*def_rec, DF_REF_MAY_CLOBBER))
EXECUTE_IF_SET_IN_SPARSESET (allocnos_live, i)
{
ira_allocno_t a = ira_allocnos[i];
-
+
if (allocno_saved_at_call[i] != last_call_num)
/* Here we are mimicking caller-save.c behaviour
which does not save hard register at a call if
SET_HARD_REG_SET (ALLOCNO_CONFLICT_HARD_REGS (a));
SET_HARD_REG_SET (ALLOCNO_TOTAL_CONFLICT_HARD_REGS (a));
}
+ if (can_throw_internal (insn))
+ {
+ IOR_HARD_REG_SET (ALLOCNO_TOTAL_CONFLICT_HARD_REGS (a),
+ call_used_reg_set);
+ IOR_HARD_REG_SET (ALLOCNO_CONFLICT_HARD_REGS (a),
+ call_used_reg_set);
+ }
}
}
-
+
make_early_clobber_and_input_conflicts ();
curr_point++;
mark_ref_live (*use_rec);
process_single_reg_class_operands (true, freq);
-
+
set_p = mark_hard_reg_early_clobbers (insn, true);
if (set_p)
for (use_rec = DF_INSN_USES (insn); *use_rec; use_rec++)
{
rtx ureg = DF_REF_REG (*use_rec);
-
+
if (GET_CODE (ureg) == SUBREG)
ureg = SUBREG_REG (ureg);
if (! REG_P (ureg) || REGNO (ureg) >= FIRST_PSEUDO_REGISTER)
continue;
-
+
mark_ref_live (*use_rec);
}
}
curr_point++;
}
+#ifdef EH_RETURN_DATA_REGNO
+ if (bb_has_eh_pred (bb))
+ for (j = 0; ; ++j)
+ {
+ unsigned int regno = EH_RETURN_DATA_REGNO (j);
+ if (regno == INVALID_REGNUM)
+ break;
+ make_regno_born (regno);
+ }
+#endif
+
/* Allocnos can't go in stack regs at the start of a basic block
that is reached by an abnormal edge. Likewise for call
clobbered regs, because caller-save, fixup_abnormal_edges and
possibly the table driven EH machinery are not quite ready to
handle such allocnos live across such edges. */
- FOR_EACH_EDGE (e, ei, bb->preds)
- if (e->flags & EDGE_ABNORMAL)
- break;
-
- if (e != NULL)
+ if (bb_has_abnormal_pred (bb))
{
#ifdef STACK_REGS
EXECUTE_IF_SET_IN_SPARSESET (allocnos_live, px)
/* No need to record conflicts for call clobbered regs if we
have nonlocal labels around, as we don't ever try to
allocate such regs in this case. */
- if (!cfun->has_nonlocal_label)
+ if (!cfun->has_nonlocal_label && bb_has_abnormal_call_pred (bb))
for (px = 0; px < FIRST_PSEUDO_REGISTER; px++)
if (call_used_regs[px])
make_regno_born (px);
allocno_live_range_t r;
bitmap born_or_died;
bitmap_iterator bi;
-
+
born_or_died = ira_allocate_bitmap ();
FOR_EACH_ALLOCNO (a, ai)
{