On Fri, Nov 01, 2013 at 01:35:35PM +0100, Jakub Jelinek wrote: > So, IMHO much better would be to have an enum simd_clone_arg_type which > would be > enum simd_clone_arg_type > { > SIMD_CLONE_ARG_TYPE_VECTOR, > SIMD_CLONE_ARG_TYPE_UNIFORM, > SIMD_CLONE_ARG_TYPE_LINEAR_CONSTANT_STEP, > SIMD_CLONE_ARG_TYPE_LINEAR_VARIABLE_STEP > }; > drop uniform bitfield, change linear_stride_num to > say union { unsigned HOST_WIDE_INT linear_constant_step; int > linear_step_argno; }; > or similar.
I've committed this to gomp-4_0-branch as follow-up to your patch: 2013-11-01 Jakub Jelinek <ja...@redhat.com> * cgraph.h (enum linear_stride_type): Remove. (enum simd_clone_arg_type): New. (struct simd_clone_arg): Remove linear_stride, linear_stride_num and uniform fields. Add arg_type and linear_step. * omp-low.c (simd_clone_struct_copy): Formatting. (simd_clone_struct_alloc): Likewise. Use size_t. (simd_clone_clauses_extract, simd_clone_compute_base_data_type, simd_clone_adjust_argument_types): Adjust for struct simd_clone_arg changes. (simd_clone_mangle): Likewise. Handle negative linear step. --- gcc/cgraph.h.jj 2013-11-01 17:11:42.000000000 +0100 +++ gcc/cgraph.h 2013-11-01 17:24:59.472995514 +0100 @@ -250,10 +250,12 @@ struct GTY(()) cgraph_clone_info bitmap combined_args_to_skip; }; -enum linear_stride_type { - LINEAR_STRIDE_NO, - LINEAR_STRIDE_YES_CONSTANT, - LINEAR_STRIDE_YES_VARIABLE +enum simd_clone_arg_type +{ + SIMD_CLONE_ARG_TYPE_VECTOR, + SIMD_CLONE_ARG_TYPE_UNIFORM, + SIMD_CLONE_ARG_TYPE_LINEAR_CONSTANT_STEP, + SIMD_CLONE_ARG_TYPE_LINEAR_VARIABLE_STEP }; /* Function arguments in the original function of a SIMD clone. @@ -282,28 +284,17 @@ struct GTY(()) simd_clone_arg { tree simd_array; /* A SIMD clone's argument can be either linear (constant or - variable), uniform, or vector. If the argument is neither linear - or uniform, the default is vector. */ + variable), uniform, or vector. */ + enum simd_clone_arg_type arg_type; - /* If the linear stride is a constant, `linear_stride' is - LINEAR_STRIDE_YES_CONSTANT, and `linear_stride_num' holds - the numeric stride. - - If the linear stride is variable, `linear_stride' is - LINEAR_STRIDE_YES_VARIABLE, and `linear_stride_num' contains - the function argument containing the stride (as an index into the - function arguments starting at 0). - - Otherwise, `linear_stride' is LINEAR_STRIDE_NO and - `linear_stride_num' is unused. */ - enum linear_stride_type linear_stride; - unsigned HOST_WIDE_INT linear_stride_num; + /* For arg_type SIMD_CLONE_ARG_TYPE_LINEAR_CONSTANT_STEP this is + the constant linear step, if arg_type is + SIMD_CLONE_ARG_TYPE_LINEAR_VARIABLE_STEP, this is index of + the uniform argument holding the step, otherwise 0. */ + HOST_WIDE_INT linear_step; /* Variable alignment if available, otherwise 0. */ unsigned int alignment; - - /* True if variable is uniform. */ - unsigned int uniform : 1; }; /* Specific data for a SIMD function clone. */ --- gcc/omp-low.c.jj 2013-11-01 17:11:42.000000000 +0100 +++ gcc/omp-low.c 2013-11-01 17:41:26.635904034 +0100 @@ -10561,8 +10561,8 @@ static struct simd_clone * simd_clone_struct_alloc (int nargs) { struct simd_clone *clone_info; - int len = sizeof (struct simd_clone) - + nargs * sizeof (struct simd_clone_arg); + size_t len = (sizeof (struct simd_clone) + + nargs * sizeof (struct simd_clone_arg)); clone_info = ggc_alloc_cleared_simd_clone_stat (len PASS_MEM_STAT); return clone_info; } @@ -10572,8 +10572,8 @@ simd_clone_struct_alloc (int nargs) static inline void simd_clone_struct_copy (struct simd_clone *to, struct simd_clone *from) { - memcpy (to, from, sizeof (struct simd_clone) - + from->nargs * sizeof (struct simd_clone_arg)); + memcpy (to, from, (sizeof (struct simd_clone) + + from->nargs * sizeof (struct simd_clone_arg))); } /* Given a simd clone in NEW_NODE, extract the simd specific @@ -10637,31 +10637,27 @@ simd_clone_clauses_extract (struct cgrap int argno = TREE_INT_CST_LOW (decl); if (OMP_CLAUSE_LINEAR_VARIABLE_STRIDE (t)) { - clone_info->args[argno].linear_stride - = LINEAR_STRIDE_YES_VARIABLE; - clone_info->args[argno].linear_stride_num - = TREE_INT_CST_LOW (step); - gcc_assert (!TREE_INT_CST_HIGH (step)); + clone_info->args[argno].arg_type + = SIMD_CLONE_ARG_TYPE_LINEAR_VARIABLE_STEP; + clone_info->args[argno].linear_step + = tree_low_cst (step, 0); + gcc_assert (clone_info->args[argno].linear_step >= 0 + && clone_info->args[argno].linear_step < n); } else { - if (TREE_INT_CST_HIGH (step)) - { - /* It looks like this can't really happen, since the - front-ends generally issue: - - warning: integer constant is too large for its type. - - But let's assume somehow we got past all that. */ - warning_at (DECL_SOURCE_LOCATION (decl), 0, - "ignoring large linear step"); - } + if (!host_integerp (step, 0)) + warning_at (OMP_CLAUSE_LOCATION (t), 0, + "ignoring large linear step"); + else if (integer_zerop (step)) + warning_at (OMP_CLAUSE_LOCATION (t), 0, + "ignoring zero linear step"); else { - clone_info->args[argno].linear_stride - = LINEAR_STRIDE_YES_CONSTANT; - clone_info->args[argno].linear_stride_num - = TREE_INT_CST_LOW (step); + clone_info->args[argno].arg_type + = SIMD_CLONE_ARG_TYPE_LINEAR_CONSTANT_STEP; + clone_info->args[argno].linear_step + = tree_low_cst (step, 0); } } break; @@ -10670,7 +10666,8 @@ simd_clone_clauses_extract (struct cgrap { tree decl = OMP_CLAUSE_DECL (t); int argno = tree_low_cst (decl, 1); - clone_info->args[argno].uniform = 1; + clone_info->args[argno].arg_type + = SIMD_CLONE_ARG_TYPE_UNIFORM; break; } case OMP_CLAUSE_ALIGNED: @@ -10731,14 +10728,12 @@ simd_clone_compute_base_data_type (struc { argno_map map (fndecl); for (unsigned int i = 0; i < new_node->simdclone->nargs; ++i) - { - struct simd_clone_arg arg = new_node->simdclone->args[i]; - if (!arg.uniform && arg.linear_stride == LINEAR_STRIDE_NO) - { - type = TREE_TYPE (map[i]); - break; - } - } + if (new_node->simdclone->args[i].arg_type + == SIMD_CLONE_ARG_TYPE_VECTOR) + { + type = TREE_TYPE (map[i]); + break; + } } /* c) If the characteristic data type determined by a) or b) above @@ -10824,20 +10819,25 @@ simd_clone_mangle (struct cgraph_node *o { struct simd_clone_arg arg = new_node->simdclone->args[n]; - if (arg.uniform) + if (arg.arg_type == SIMD_CLONE_ARG_TYPE_UNIFORM) pp_character (&pp, 'u'); - else if (arg.linear_stride == LINEAR_STRIDE_YES_CONSTANT) + else if (arg.arg_type == SIMD_CLONE_ARG_TYPE_LINEAR_CONSTANT_STEP) { - gcc_assert (arg.linear_stride_num != 0); + gcc_assert (arg.linear_step != 0); pp_character (&pp, 'l'); - if (arg.linear_stride_num > 1) - pp_unsigned_wide_integer (&pp, - arg.linear_stride_num); + if (arg.linear_step > 0) + pp_unsigned_wide_integer (&pp, arg.linear_step); + else + { + pp_character (&pp, 'n'); + pp_unsigned_wide_integer (&pp, (-(unsigned HOST_WIDE_INT) + arg.linear_step)); + } } - else if (arg.linear_stride == LINEAR_STRIDE_YES_VARIABLE) + else if (arg.arg_type == SIMD_CLONE_ARG_TYPE_LINEAR_VARIABLE_STEP) { pp_character (&pp, 's'); - pp_unsigned_wide_integer (&pp, arg.linear_stride_num); + pp_unsigned_wide_integer (&pp, arg.linear_step); } else pp_character (&pp, 'v'); @@ -10975,8 +10975,7 @@ simd_clone_adjust_argument_types (struct node->simdclone->args[i].orig_arg = parm; - if (node->simdclone->args[i].uniform - || node->simdclone->args[i].linear_stride != LINEAR_STRIDE_NO) + if (node->simdclone->args[i].arg_type != SIMD_CLONE_ARG_TYPE_VECTOR) { /* No adjustment necessary for scalar arguments. */ adj.copy_param = 1; Jakub