diff options
author | Jakub Jelinek <jakub@redhat.com> | 2007-11-02 21:38:11 +0100 |
---|---|---|
committer | Jakub Jelinek <jakub@gcc.gnu.org> | 2007-11-02 21:38:11 +0100 |
commit | 444a356a3bc8de75d802214b2ef110ebec78a72c (patch) | |
tree | 9cb08fa7ebf021f07a343dbee0dd920495b48f32 /gcc/config | |
parent | 7c4b32bcdc8455d77f73eb56e8fec9ca74fe6be2 (diff) | |
download | gcc-444a356a3bc8de75d802214b2ef110ebec78a72c.zip gcc-444a356a3bc8de75d802214b2ef110ebec78a72c.tar.gz gcc-444a356a3bc8de75d802214b2ef110ebec78a72c.tar.bz2 |
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
Diffstat (limited to 'gcc/config')
-rw-r--r-- | gcc/config/ia64/ia64.c | 105 |
1 files changed, 74 insertions, 31 deletions
diff --git a/gcc/config/ia64/ia64.c b/gcc/config/ia64/ia64.c index 537f9f0..a75e68e 100644 --- a/gcc/config/ia64/ia64.c +++ b/gcc/config/ia64/ia64.c @@ -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; } |