diff options
author | jakub <jakub@138bc75d-0d04-0410-961f-82ee72b054a4> | 2014-04-17 12:49:49 +0000 |
---|---|---|
committer | jakub <jakub@138bc75d-0d04-0410-961f-82ee72b054a4> | 2014-04-17 12:49:49 +0000 |
commit | e2ec52cad85e7fdd83aa32fbff941d42eeebbd8a (patch) | |
tree | 4c749de5dc4a776f1ab9f29f46405e370f12efcc | |
parent | 65b0537f9e9741318f7c8e738b6dd3b8f82f58b5 (diff) | |
download | gcc-e2ec52cad85e7fdd83aa32fbff941d42eeebbd8a.tar.gz |
* genmodes.c (struct mode_data): Add need_bytesize_adj field.
(blank_mode): Initialize it.
(emit_mode_size_inline, emit_mode_nunits_inline,
emit_mode_inner_inline): New functions.
(emit_insn_modes_h): Call them and surround their output with
#if GCC_VERSION >= 4001 ... #endif.
* machmode.h (GET_MODE_SIZE, GET_MODE_NUNITS, GET_MODE_INNER):
For GCC_VERSION >= 4001 use mode_*_inline routines instead of
mode_* arrays if the argument is __builtin_constant_p.
* lower-subreg.c (dump_choices): Make sure GET_MODE_SIZE argument
is enum machine_mode.
fortran/
* trans-types.c (gfc_init_kinds): Make sure GET_MODE_BITSIZE
argument is enum machine_mode.
git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@209484 138bc75d-0d04-0410-961f-82ee72b054a4
-rw-r--r-- | gcc/ChangeLog | 14 | ||||
-rw-r--r-- | gcc/fortran/ChangeLog | 5 | ||||
-rw-r--r-- | gcc/fortran/trans-types.c | 2 | ||||
-rw-r--r-- | gcc/genmodes.c | 109 | ||||
-rw-r--r-- | gcc/lower-subreg.c | 2 | ||||
-rw-r--r-- | gcc/machmode.h | 18 |
6 files changed, 147 insertions, 3 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog index ea9bb14a40b..ead28c2bf92 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,17 @@ +2014-04-17 Jakub Jelinek <jakub@redhat.com> + + * genmodes.c (struct mode_data): Add need_bytesize_adj field. + (blank_mode): Initialize it. + (emit_mode_size_inline, emit_mode_nunits_inline, + emit_mode_inner_inline): New functions. + (emit_insn_modes_h): Call them and surround their output with + #if GCC_VERSION >= 4001 ... #endif. + * machmode.h (GET_MODE_SIZE, GET_MODE_NUNITS, GET_MODE_INNER): + For GCC_VERSION >= 4001 use mode_*_inline routines instead of + mode_* arrays if the argument is __builtin_constant_p. + * lower-subreg.c (dump_choices): Make sure GET_MODE_SIZE argument + is enum machine_mode. + 2014-04-17 Trevor Saunders <tsaunders@mozilla.com> * passes.c (opt_pass::execute): Adjust. diff --git a/gcc/fortran/ChangeLog b/gcc/fortran/ChangeLog index 29ea5f7871c..d2b666040d0 100644 --- a/gcc/fortran/ChangeLog +++ b/gcc/fortran/ChangeLog @@ -1,3 +1,8 @@ +2014-04-17 Jakub Jelinek <jakub@redhat.com> + + * trans-types.c (gfc_init_kinds): Make sure GET_MODE_BITSIZE + argument is enum machine_mode. + 2014-04-13 Paul Thomas <pault@gcc.gnu.org> PR fortran/58085 diff --git a/gcc/fortran/trans-types.c b/gcc/fortran/trans-types.c index 59637f2d3cb..243feb7aedb 100644 --- a/gcc/fortran/trans-types.c +++ b/gcc/fortran/trans-types.c @@ -373,7 +373,7 @@ gfc_init_kinds (void) /* The middle end doesn't support constants larger than 2*HWI. Perhaps the target hook shouldn't have accepted these either, but just to be safe... */ - bitsize = GET_MODE_BITSIZE (mode); + bitsize = GET_MODE_BITSIZE ((enum machine_mode) mode); if (bitsize > 2*HOST_BITS_PER_WIDE_INT) continue; diff --git a/gcc/genmodes.c b/gcc/genmodes.c index 8cc3cdeeeb3..99078788c52 100644 --- a/gcc/genmodes.c +++ b/gcc/genmodes.c @@ -72,6 +72,8 @@ struct mode_data unsigned int counter; /* Rank ordering of modes */ unsigned int ibit; /* the number of integral bits */ unsigned int fbit; /* the number of fractional bits */ + bool need_bytesize_adj; /* true if this mode need dynamic size + adjustment */ }; static struct mode_data *modes[MAX_MODE_CLASS]; @@ -82,7 +84,7 @@ static const struct mode_data blank_mode = { 0, "<unknown>", MAX_MODE_CLASS, -1U, -1U, -1U, -1U, 0, 0, 0, 0, 0, - "<unknown>", 0, 0, 0, 0 + "<unknown>", 0, 0, 0, 0, false }; static htab_t modes_by_name; @@ -904,6 +906,105 @@ emit_max_int (void) printf ("#define MAX_BITSIZE_MODE_ANY_MODE (%d*BITS_PER_UNIT)\n", mmax); } +/* Emit mode_size_inline routine into insn-modes.h header. */ +static void +emit_mode_size_inline (void) +{ + int c; + struct mode_adjust *a; + struct mode_data *m; + + /* Size adjustments must be propagated to all containing modes. */ + for (a = adj_bytesize; a; a = a->next) + { + a->mode->need_bytesize_adj = true; + for (m = a->mode->contained; m; m = m->next_cont) + m->need_bytesize_adj = true; + } + + printf ("\ +#ifdef __cplusplus\n\ +inline __attribute__((__always_inline__))\n\ +#else\n\ +extern __inline__ __attribute__((__always_inline__, __gnu_inline__))\n\ +#endif\n\ +unsigned char\n\ +mode_size_inline (enum machine_mode mode)\n\ +{\n\ + extern %sunsigned char mode_size[NUM_MACHINE_MODES];\n\ + switch (mode)\n\ + {\n", adj_bytesize ? "" : "const "); + + for_all_modes (c, m) + if (!m->need_bytesize_adj) + printf (" case %smode: return %u;\n", m->name, m->bytesize); + + puts ("\ + default: return mode_size[mode];\n\ + }\n\ +}\n"); +} + +/* Emit mode_nunits_inline routine into insn-modes.h header. */ +static void +emit_mode_nunits_inline (void) +{ + int c; + struct mode_data *m; + + puts ("\ +#ifdef __cplusplus\n\ +inline __attribute__((__always_inline__))\n\ +#else\n\ +extern __inline__ __attribute__((__always_inline__, __gnu_inline__))\n\ +#endif\n\ +unsigned char\n\ +mode_nunits_inline (enum machine_mode mode)\n\ +{\n\ + extern const unsigned char mode_nunits[NUM_MACHINE_MODES];\n\ + switch (mode)\n\ + {"); + + for_all_modes (c, m) + printf (" case %smode: return %u;\n", m->name, m->ncomponents); + + puts ("\ + default: return mode_nunits[mode];\n\ + }\n\ +}\n"); +} + +/* Emit mode_inner_inline routine into insn-modes.h header. */ +static void +emit_mode_inner_inline (void) +{ + int c; + struct mode_data *m; + + puts ("\ +#ifdef __cplusplus\n\ +inline __attribute__((__always_inline__))\n\ +#else\n\ +extern __inline__ __attribute__((__always_inline__, __gnu_inline__))\n\ +#endif\n\ +unsigned char\n\ +mode_inner_inline (enum machine_mode mode)\n\ +{\n\ + extern const unsigned char mode_inner[NUM_MACHINE_MODES];\n\ + switch (mode)\n\ + {"); + + for_all_modes (c, m) + printf (" case %smode: return %smode;\n", m->name, + c != MODE_PARTIAL_INT && m->component + ? m->component->name : void_mode->name); + + puts ("\ + default: return mode_inner[mode];\n\ + }\n\ +}\n"); +} + static void emit_insn_modes_h (void) { @@ -969,6 +1070,12 @@ enum machine_mode\n{"); printf ("#define CONST_MODE_IBIT%s\n", adj_ibit ? "" : " const"); printf ("#define CONST_MODE_FBIT%s\n", adj_fbit ? "" : " const"); emit_max_int (); + puts ("\n#if GCC_VERSION >= 4001\n"); + emit_mode_size_inline (); + emit_mode_nunits_inline (); + emit_mode_inner_inline (); + puts ("#endif /* GCC_VERSION >= 4001 */"); + puts ("\ \n\ #endif /* insn-modes.h */"); diff --git a/gcc/lower-subreg.c b/gcc/lower-subreg.c index bdad2a6aa9c..ae935f76459 100644 --- a/gcc/lower-subreg.c +++ b/gcc/lower-subreg.c @@ -1371,7 +1371,7 @@ dump_choices (bool speed_p, const char *description) fprintf (dump_file, "Choices when optimizing for %s:\n", description); for (i = 0; i < MAX_MACHINE_MODE; i++) - if (GET_MODE_SIZE (i) > UNITS_PER_WORD) + if (GET_MODE_SIZE ((enum machine_mode) i) > UNITS_PER_WORD) fprintf (dump_file, " %s mode %s for copy lowering.\n", choices[speed_p].move_modes_to_split[i] ? "Splitting" diff --git a/gcc/machmode.h b/gcc/machmode.h index bc5d901d245..222e6263e0b 100644 --- a/gcc/machmode.h +++ b/gcc/machmode.h @@ -177,7 +177,13 @@ extern const unsigned char mode_class[NUM_MACHINE_MODES]; /* Get the size in bytes and bits of an object of mode MODE. */ extern CONST_MODE_SIZE unsigned char mode_size[NUM_MACHINE_MODES]; +#if GCC_VERSION >= 4001 +#define GET_MODE_SIZE(MODE) \ + ((unsigned short) (__builtin_constant_p (MODE) \ + ? mode_size_inline (MODE) : mode_size[MODE])) +#else #define GET_MODE_SIZE(MODE) ((unsigned short) mode_size[MODE]) +#endif #define GET_MODE_BITSIZE(MODE) \ ((unsigned short) (GET_MODE_SIZE (MODE) * BITS_PER_UNIT)) @@ -203,7 +209,13 @@ extern const unsigned HOST_WIDE_INT mode_mask_array[NUM_MACHINE_MODES]; /* Return the mode of the inner elements in a vector. */ extern const unsigned char mode_inner[NUM_MACHINE_MODES]; +#if GCC_VERSION >= 4001 +#define GET_MODE_INNER(MODE) \ + ((enum machine_mode) (__builtin_constant_p (MODE) \ + ? mode_inner_inline (MODE) : mode_inner[MODE])) +#else #define GET_MODE_INNER(MODE) ((enum machine_mode) mode_inner[MODE]) +#endif /* Get the size in bytes or bites of the basic parts of an object of mode MODE. */ @@ -224,7 +236,13 @@ extern const unsigned char mode_inner[NUM_MACHINE_MODES]; /* Get the number of units in the object. */ extern const unsigned char mode_nunits[NUM_MACHINE_MODES]; +#if GCC_VERSION >= 4001 +#define GET_MODE_NUNITS(MODE) \ + ((unsigned char) (__builtin_constant_p (MODE) \ + ? mode_nunits_inline (MODE) : mode_nunits[MODE])) +#else #define GET_MODE_NUNITS(MODE) mode_nunits[MODE] +#endif /* Get the next wider natural mode (eg, QI -> HI -> SI -> DI -> TI). */ |