ia64.c (struct reg_write_state): Change into unsigned short bitfields rather than unsigned int...
* config/ia64/ia64.c (struct reg_write_state): Change into unsigned short bitfields rather than unsigned int, decrease first_pred to just 10 bits. (rws_insn): Change into a bitmap or if not ENABLE_CHECKING into two char array. (rws_insn_set, rws_insn_test): New functions. (in_safe_group_barrier): New variable. (rws_update): Remove first argument, always set rws_sum array. (rws_access_regno): Use rws_insn_set macro. Only call rws_update or update rws_sum if !in_safe_group_barrier, adjust rws_update args. (rtx_needs_barrier): Use rws_insn_test macro. (safe_group_barrier_needed): Don't save/restore rws_sum array, instead set/clear in_safe_group_barrier flag. From-SVN: r129861
This commit is contained in:
parent
7c4b32bcdc
commit
444a356a3b
@ -1,3 +1,20 @@
|
||||
2007-11-02 Jakub Jelinek <jakub@redhat.com>
|
||||
|
||||
* config/ia64/ia64.c (struct reg_write_state): Change into
|
||||
unsigned short bitfields rather than unsigned int, decrease
|
||||
first_pred to just 10 bits.
|
||||
(rws_insn): Change into a bitmap or if not ENABLE_CHECKING
|
||||
into two char array.
|
||||
(rws_insn_set, rws_insn_test): New functions.
|
||||
(in_safe_group_barrier): New variable.
|
||||
(rws_update): Remove first argument, always set rws_sum array.
|
||||
(rws_access_regno): Use rws_insn_set macro. Only call rws_update
|
||||
or update rws_sum if !in_safe_group_barrier, adjust rws_update
|
||||
args.
|
||||
(rtx_needs_barrier): Use rws_insn_test macro.
|
||||
(safe_group_barrier_needed): Don't save/restore rws_sum array,
|
||||
instead set/clear in_safe_group_barrier flag.
|
||||
|
||||
2007-11-02 Bob Wilson <bob.wilson@acm.org>
|
||||
|
||||
* config/xtensa/xtensa.c (xtensa_expand_prologue): Put a
|
||||
|
@ -5308,20 +5308,62 @@ ia64_safe_type (rtx insn)
|
||||
If a predicate register is written by an AND.ORCM we set WRITTEN_BY_AND
|
||||
to true; if it was written by an OR.ANDCM we set WRITTEN_BY_OR to true. */
|
||||
|
||||
#if GCC_VERSION >= 4000
|
||||
#define RWS_FIELD_TYPE __extension__ unsigned short
|
||||
#else
|
||||
#define RWS_FIELD_TYPE unsigned int
|
||||
#endif
|
||||
struct reg_write_state
|
||||
{
|
||||
unsigned int write_count : 2;
|
||||
unsigned int first_pred : 16;
|
||||
unsigned int written_by_fp : 1;
|
||||
unsigned int written_by_and : 1;
|
||||
unsigned int written_by_or : 1;
|
||||
RWS_FIELD_TYPE write_count : 2;
|
||||
RWS_FIELD_TYPE first_pred : 10;
|
||||
RWS_FIELD_TYPE written_by_fp : 1;
|
||||
RWS_FIELD_TYPE written_by_and : 1;
|
||||
RWS_FIELD_TYPE written_by_or : 1;
|
||||
};
|
||||
|
||||
/* Cumulative info for the current instruction group. */
|
||||
struct reg_write_state rws_sum[NUM_REGS];
|
||||
/* Info for the current instruction. This gets copied to rws_sum after a
|
||||
stop bit is emitted. */
|
||||
struct reg_write_state rws_insn[NUM_REGS];
|
||||
#ifdef ENABLE_CHECKING
|
||||
/* Bitmap whether a register has been written in the current insn. */
|
||||
HARD_REG_ELT_TYPE rws_insn[(NUM_REGS + HOST_BITS_PER_WIDEST_FAST_INT - 1)
|
||||
/ HOST_BITS_PER_WIDEST_FAST_INT];
|
||||
|
||||
static inline void
|
||||
rws_insn_set (int regno)
|
||||
{
|
||||
gcc_assert (!TEST_HARD_REG_BIT (rws_insn, regno));
|
||||
SET_HARD_REG_BIT (rws_insn, regno);
|
||||
}
|
||||
|
||||
static inline int
|
||||
rws_insn_test (int regno)
|
||||
{
|
||||
return TEST_HARD_REG_BIT (rws_insn, regno);
|
||||
}
|
||||
#else
|
||||
/* When not checking, track just REG_AR_CFM and REG_VOLATILE. */
|
||||
unsigned char rws_insn[2];
|
||||
|
||||
static inline void
|
||||
rws_insn_set (int regno)
|
||||
{
|
||||
if (regno == REG_AR_CFM)
|
||||
rws_insn[0] = 1;
|
||||
else if (regno == REG_VOLATILE)
|
||||
rws_insn[1] = 1;
|
||||
}
|
||||
|
||||
static inline int
|
||||
rws_insn_test (int regno)
|
||||
{
|
||||
if (regno == REG_AR_CFM)
|
||||
return rws_insn[0];
|
||||
if (regno == REG_VOLATILE)
|
||||
return rws_insn[1];
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Indicates whether this is the first instruction after a stop bit,
|
||||
in which case we don't need another stop bit. Without this,
|
||||
@ -5340,7 +5382,7 @@ struct reg_flags
|
||||
unsigned int is_sibcall : 1; /* Is this a sibling or normal call? */
|
||||
};
|
||||
|
||||
static void rws_update (struct reg_write_state *, int, struct reg_flags, int);
|
||||
static void rws_update (int, struct reg_flags, int);
|
||||
static int rws_access_regno (int, struct reg_flags, int);
|
||||
static int rws_access_reg (rtx, struct reg_flags, int);
|
||||
static void update_set_flags (rtx, struct reg_flags *);
|
||||
@ -5349,26 +5391,27 @@ static int rtx_needs_barrier (rtx, struct reg_flags, int);
|
||||
static void init_insn_group_barriers (void);
|
||||
static int group_barrier_needed (rtx);
|
||||
static int safe_group_barrier_needed (rtx);
|
||||
static int in_safe_group_barrier;
|
||||
|
||||
/* Update *RWS for REGNO, which is being written by the current instruction,
|
||||
with predicate PRED, and associated register flags in FLAGS. */
|
||||
|
||||
static void
|
||||
rws_update (struct reg_write_state *rws, int regno, struct reg_flags flags, int pred)
|
||||
rws_update (int regno, struct reg_flags flags, int pred)
|
||||
{
|
||||
if (pred)
|
||||
rws[regno].write_count++;
|
||||
rws_sum[regno].write_count++;
|
||||
else
|
||||
rws[regno].write_count = 2;
|
||||
rws[regno].written_by_fp |= flags.is_fp;
|
||||
rws_sum[regno].write_count = 2;
|
||||
rws_sum[regno].written_by_fp |= flags.is_fp;
|
||||
/* ??? Not tracking and/or across differing predicates. */
|
||||
rws[regno].written_by_and = flags.is_and;
|
||||
rws[regno].written_by_or = flags.is_or;
|
||||
rws[regno].first_pred = pred;
|
||||
rws_sum[regno].written_by_and = flags.is_and;
|
||||
rws_sum[regno].written_by_or = flags.is_or;
|
||||
rws_sum[regno].first_pred = pred;
|
||||
}
|
||||
|
||||
/* Handle an access to register REGNO of type FLAGS using predicate register
|
||||
PRED. Update rws_insn and rws_sum arrays. Return 1 if this access creates
|
||||
PRED. Update rws_sum array. Return 1 if this access creates
|
||||
a dependency with an earlier instruction in the same group. */
|
||||
|
||||
static int
|
||||
@ -5385,18 +5428,15 @@ rws_access_regno (int regno, struct reg_flags flags, int pred)
|
||||
{
|
||||
int write_count;
|
||||
|
||||
/* One insn writes same reg multiple times? */
|
||||
gcc_assert (!rws_insn[regno].write_count);
|
||||
|
||||
/* Update info for current instruction. */
|
||||
rws_update (rws_insn, regno, flags, pred);
|
||||
rws_insn_set (regno);
|
||||
write_count = rws_sum[regno].write_count;
|
||||
|
||||
switch (write_count)
|
||||
{
|
||||
case 0:
|
||||
/* The register has not been written yet. */
|
||||
rws_update (rws_sum, regno, flags, pred);
|
||||
if (!in_safe_group_barrier)
|
||||
rws_update (regno, flags, pred);
|
||||
break;
|
||||
|
||||
case 1:
|
||||
@ -5410,7 +5450,8 @@ rws_access_regno (int regno, struct reg_flags flags, int pred)
|
||||
;
|
||||
else if ((rws_sum[regno].first_pred ^ 1) != pred)
|
||||
need_barrier = 1;
|
||||
rws_update (rws_sum, regno, flags, pred);
|
||||
if (!in_safe_group_barrier)
|
||||
rws_update (regno, flags, pred);
|
||||
break;
|
||||
|
||||
case 2:
|
||||
@ -5422,8 +5463,11 @@ rws_access_regno (int regno, struct reg_flags flags, int pred)
|
||||
;
|
||||
else
|
||||
need_barrier = 1;
|
||||
rws_sum[regno].written_by_and = flags.is_and;
|
||||
rws_sum[regno].written_by_or = flags.is_or;
|
||||
if (!in_safe_group_barrier)
|
||||
{
|
||||
rws_sum[regno].written_by_and = flags.is_and;
|
||||
rws_sum[regno].written_by_or = flags.is_or;
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
@ -5635,7 +5679,7 @@ rtx_needs_barrier (rtx x, struct reg_flags flags, int pred)
|
||||
|
||||
/* Avoid multiple register writes, in case this is a pattern with
|
||||
multiple CALL rtx. This avoids a failure in rws_access_reg. */
|
||||
if (! flags.is_sibcall && ! rws_insn[REG_AR_CFM].write_count)
|
||||
if (! flags.is_sibcall && ! rws_insn_test (REG_AR_CFM))
|
||||
{
|
||||
new_flags.is_write = 1;
|
||||
need_barrier |= rws_access_regno (REG_RP, new_flags, pred);
|
||||
@ -5677,7 +5721,7 @@ rtx_needs_barrier (rtx x, struct reg_flags flags, int pred)
|
||||
{
|
||||
/* Avoid writing the register multiple times if we have multiple
|
||||
asm outputs. This avoids a failure in rws_access_reg. */
|
||||
if (! rws_insn[REG_VOLATILE].write_count)
|
||||
if (! rws_insn_test (REG_VOLATILE))
|
||||
{
|
||||
new_flags.is_write = 1;
|
||||
rws_access_regno (REG_VOLATILE, new_flags, pred);
|
||||
@ -6071,17 +6115,16 @@ group_barrier_needed (rtx insn)
|
||||
static int
|
||||
safe_group_barrier_needed (rtx insn)
|
||||
{
|
||||
struct reg_write_state rws_saved[NUM_REGS];
|
||||
int saved_first_instruction;
|
||||
int t;
|
||||
|
||||
memcpy (rws_saved, rws_sum, NUM_REGS * sizeof *rws_saved);
|
||||
saved_first_instruction = first_instruction;
|
||||
in_safe_group_barrier = 1;
|
||||
|
||||
t = group_barrier_needed (insn);
|
||||
|
||||
memcpy (rws_sum, rws_saved, NUM_REGS * sizeof *rws_saved);
|
||||
first_instruction = saved_first_instruction;
|
||||
in_safe_group_barrier = 0;
|
||||
|
||||
return t;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user