Patchwork introduce VEC_qsort

login
register
mail settings
Submitter Nathan Froyd
Date Oct. 11, 2010, 3:32 a.m.
Message ID <20101011033202.GD24720@nightcrawler>
Download mbox | patch
Permalink /patch/67379/
State New
Headers show

Comments

Nathan Froyd - Oct. 11, 2010, 3:32 a.m.
The patch below takes a reasonably common idiom:

  qsort (VEC_address (T,V), VEC_length (T,V), sizeof (T), cmp);

and introduces VEC_qsort to handle some of the redundancy in the above
expression.

Bootstrapped on x86_64-unknown-linux-gnu.  Need an Ada OK for the
gcc-interface/utils2.c change.  OK to commit?

-Nathan

gcc/
	* vec.h (VEC_qsort): Define.
	* dbxout.c (output_used_types): Use it.
	* df-scan.c (df_sort_and_compress_refs): Likewise.
	(df_sort_and_compress_mws): Likewise.
	* genautomata.c (uniq_sort_alt_states): Likewise.
	(evaluate_equiv_classes): Likewise.
	(output_trans_table): Likewise.
	(output_state): Likewise.
	* gimplify.c (compare_case_labels): Likewise.
	* graphite-sese-to-poly.c (graphite_sort_dominated_info): Likewise.
	* ipa.c (build_cdtor_fns): Likewise.
	* lto.c (lto_wpa_write_files): Likewise.
	* sel-sched.c (fill_vec_av_set): Likewise.
	* tree-predcom.c (determine_roots_comp): Likewise.
	* tree-sra.c (sort_and_spliace_var_accesses): Likewise.
	(splice_param_accesses): Likewise.
	* tree-ssa-live.c (dump_enumerated_decls): Likewise.
	* tree-ssa-reassoc.c (undistribute_ops_list): Likewise.
	(reassociate_bb): Likewise.
	* tree-ssa-sccvn.c (sort_scc): Likewise.
	* tree-ssa-structalias.c (sort_fieldstack): Likewise.
gcc/ada/
	* gcc-interface/utils2.c (gnat_build_constructor): Use VEC_qsort.
Richard Guenther - Oct. 11, 2010, 10:08 a.m.
On Mon, Oct 11, 2010 at 5:32 AM, Nathan Froyd <froydnj@codesourcery.com> wrote:
> The patch below takes a reasonably common idiom:
>
>  qsort (VEC_address (T,V), VEC_length (T,V), sizeof (T), cmp);
>
> and introduces VEC_qsort to handle some of the redundancy in the above
> expression.
>
> Bootstrapped on x86_64-unknown-linux-gnu.  Need an Ada OK for the
> gcc-interface/utils2.c change.  OK to commit?

Ok.

Thanks,
Richard.

> -Nathan
>
> gcc/
>        * vec.h (VEC_qsort): Define.
>        * dbxout.c (output_used_types): Use it.
>        * df-scan.c (df_sort_and_compress_refs): Likewise.
>        (df_sort_and_compress_mws): Likewise.
>        * genautomata.c (uniq_sort_alt_states): Likewise.
>        (evaluate_equiv_classes): Likewise.
>        (output_trans_table): Likewise.
>        (output_state): Likewise.
>        * gimplify.c (compare_case_labels): Likewise.
>        * graphite-sese-to-poly.c (graphite_sort_dominated_info): Likewise.
>        * ipa.c (build_cdtor_fns): Likewise.
>        * lto.c (lto_wpa_write_files): Likewise.
>        * sel-sched.c (fill_vec_av_set): Likewise.
>        * tree-predcom.c (determine_roots_comp): Likewise.
>        * tree-sra.c (sort_and_spliace_var_accesses): Likewise.
>        (splice_param_accesses): Likewise.
>        * tree-ssa-live.c (dump_enumerated_decls): Likewise.
>        * tree-ssa-reassoc.c (undistribute_ops_list): Likewise.
>        (reassociate_bb): Likewise.
>        * tree-ssa-sccvn.c (sort_scc): Likewise.
>        * tree-ssa-structalias.c (sort_fieldstack): Likewise.
> gcc/ada/
>        * gcc-interface/utils2.c (gnat_build_constructor): Use VEC_qsort.
>
> diff --git a/gcc/ada/gcc-interface/utils2.c b/gcc/ada/gcc-interface/utils2.c
> index c40223f..88edca4 100644
> --- a/gcc/ada/gcc-interface/utils2.c
> +++ b/gcc/ada/gcc-interface/utils2.c
> @@ -1562,8 +1562,7 @@ gnat_build_constructor (tree type, VEC(constructor_elt,gc) *v)
>      by increasing bit position.  This is necessary to ensure the
>      constructor can be output as static data.  */
>   if (allconstant && TREE_CODE (type) == RECORD_TYPE && n_elmts > 1)
> -    qsort (VEC_address (constructor_elt, v), n_elmts,
> -           sizeof (constructor_elt), compare_elmt_bitpos);
> +    VEC_qsort (constructor_elt, v, compare_elmt_bitpos);
>
>   result = build_constructor (type, v);
>   TREE_CONSTANT (result) = TREE_STATIC (result) = allconstant;
> diff --git a/gcc/dbxout.c b/gcc/dbxout.c
> index e5396b2..2eb4f0b 100644
> --- a/gcc/dbxout.c
> +++ b/gcc/dbxout.c
> @@ -2505,8 +2505,7 @@ output_used_types (void)
>       htab_traverse (cfun->used_types_hash, output_used_types_helper, &types);
>
>       /* Sort by UID to prevent dependence on hash table ordering.  */
> -      qsort (VEC_address (tree, types), VEC_length (tree, types),
> -            sizeof (tree), output_types_sort);
> +      VEC_qsort (tree, types, output_types_sort);
>
>       FOR_EACH_VEC_ELT (tree, types, i, type)
>        debug_queue_symbol (type);
> diff --git a/gcc/df-scan.c b/gcc/df-scan.c
> index 0b636e9..b2b88b5 100644
> --- a/gcc/df-scan.c
> +++ b/gcc/df-scan.c
> @@ -2392,8 +2392,7 @@ df_sort_and_compress_refs (VEC(df_ref,stack) **ref_vec)
>          of DF_REF_COMPARE.  */
>       if (i == count - 1)
>         return;
> -      qsort (VEC_address (df_ref, *ref_vec), count, sizeof (df_ref),
> -            df_ref_compare);
> +      VEC_qsort (df_ref, *ref_vec, df_ref_compare);
>     }
>
>   for (i=0; i<count-dist; i++)
> @@ -2492,8 +2491,7 @@ df_sort_and_compress_mws (VEC(df_mw_hardreg_ptr,stack) **mw_vec)
>         }
>     }
>   else
> -    qsort (VEC_address (df_mw_hardreg_ptr, *mw_vec), count,
> -          sizeof (struct df_mw_hardreg *), df_mw_compare);
> +    VEC_qsort (df_mw_hardreg_ptr, *mw_vec, df_mw_compare);
>
>   for (i=0; i<count-dist; i++)
>     {
> diff --git a/gcc/genautomata.c b/gcc/genautomata.c
> index ff024b6..afc97af 100644
> --- a/gcc/genautomata.c
> +++ b/gcc/genautomata.c
> @@ -3252,9 +3252,7 @@ uniq_sort_alt_states (alt_state_t alt_states_list)
>        curr_alt_state = curr_alt_state->next_alt_state)
>     VEC_safe_push (alt_state_t, heap, alt_states, curr_alt_state);
>
> -  qsort (VEC_address (alt_state_t, alt_states),
> -        VEC_length  (alt_state_t, alt_states),
> -        sizeof (alt_state_t), alt_state_cmp);
> +  VEC_qsort (alt_state_t, alt_states, alt_state_cmp);
>
>   prev_unique_state_ind = 0;
>   for (i = 1; i < VEC_length (alt_state_t, alt_states); i++)
> @@ -6004,9 +6002,7 @@ evaluate_equiv_classes (automaton_t automaton,
>   all_achieved_states = VEC_alloc (state_t, heap, 1500);
>   pass_states (automaton, add_achieved_state);
>   pass_states (automaton, cache_presence);
> -  qsort (VEC_address (state_t, all_achieved_states),
> -        VEC_length (state_t, all_achieved_states),
> -         sizeof (state_t), compare_states_for_equiv);
> +  VEC_qsort (state_t, all_achieved_states, compare_states_for_equiv);
>
>   odd_iteration_flag = 0;
>   new_equiv_class_num = init_equiv_class (all_achieved_states,
> @@ -7456,9 +7452,7 @@ output_trans_table (automaton_t automaton)
>      from the state (state with the maximum num is the first).  */
>   output_states_vect = 0;
>   pass_states (automaton, add_states_vect_el);
> -  qsort (VEC_address (state_t, output_states_vect),
> -        VEC_length (state_t, output_states_vect),
> -         sizeof (state_t), compare_transition_els_num);
> +  VEC_qsort (state_t, output_states_vect, compare_transition_els_num);
>
>   for (i = 0; i < VEC_length (state_t, output_states_vect); i++)
>     {
> @@ -8944,9 +8938,7 @@ output_state (state_t state)
>   fprintf (output_description_file,
>           state->new_cycle_p ? " (new cycle)\n" : "\n");
>   add_state_reservs (state);
> -  qsort (VEC_address (reserv_sets_t, state_reservs),
> -        VEC_length (reserv_sets_t, state_reservs),
> -         sizeof (reserv_sets_t), state_reservs_cmp);
> +  VEC_qsort (reserv_sets_t, state_reservs, state_reservs_cmp);
>   remove_state_duplicate_reservs ();
>   for (i = 0; i < VEC_length (reserv_sets_t, state_reservs); i++)
>     {
> diff --git a/gcc/gimplify.c b/gcc/gimplify.c
> index 994ffde..09ae44d 100644
> --- a/gcc/gimplify.c
> +++ b/gcc/gimplify.c
> @@ -1476,9 +1476,7 @@ compare_case_labels (const void *p1, const void *p2)
>  void
>  sort_case_labels (VEC(tree,heap)* label_vec)
>  {
> -  size_t len = VEC_length (tree, label_vec);
> -  qsort (VEC_address (tree, label_vec), len, sizeof (tree),
> -         compare_case_labels);
> +  VEC_qsort (tree, label_vec, compare_case_labels);
>  }
>
>
> diff --git a/gcc/graphite-sese-to-poly.c b/gcc/graphite-sese-to-poly.c
> index 87b226b..77930d5 100644
> --- a/gcc/graphite-sese-to-poly.c
> +++ b/gcc/graphite-sese-to-poly.c
> @@ -395,10 +395,7 @@ compare_bb_depths (const void *p1, const void *p2)
>  static void
>  graphite_sort_dominated_info (VEC (basic_block, heap) *dom)
>  {
> -  size_t len = VEC_length (basic_block, dom);
> -
> -  qsort (VEC_address (basic_block, dom), len, sizeof (basic_block),
> -        compare_bb_depths);
> +  VEC_qsort (basic_block, dom, compare_bb_depths);
>  }
>
>  /* Recursive helper function for build_scops_bbs.  */
> diff --git a/gcc/ipa.c b/gcc/ipa.c
> index 8eadd36..54bd6b0 100644
> --- a/gcc/ipa.c
> +++ b/gcc/ipa.c
> @@ -1558,20 +1558,14 @@ build_cdtor_fns (void)
>   if (!VEC_empty (tree, static_ctors))
>     {
>       gcc_assert (!targetm.have_ctors_dtors || in_lto_p);
> -      qsort (VEC_address (tree, static_ctors),
> -            VEC_length (tree, static_ctors),
> -            sizeof (tree),
> -            compare_ctor);
> +      VEC_qsort (tree, static_ctors, compare_ctor);
>       build_cdtor (/*ctor_p=*/true, static_ctors);
>     }
>
>   if (!VEC_empty (tree, static_dtors))
>     {
>       gcc_assert (!targetm.have_ctors_dtors || in_lto_p);
> -      qsort (VEC_address (tree, static_dtors),
> -            VEC_length (tree, static_dtors),
> -            sizeof (tree),
> -            compare_dtor);
> +      VEC_qsort (tree, static_dtors, compare_dtor);
>       build_cdtor (/*ctor_p=*/false, static_dtors);
>     }
>  }
> diff --git a/gcc/lto/lto.c b/gcc/lto/lto.c
> index 3baea80..d1a2206 100644
> --- a/gcc/lto/lto.c
> +++ b/gcc/lto/lto.c
> @@ -1475,8 +1475,7 @@ lto_wpa_write_files (void)
>   blen = strlen (temp_filename);
>
>   n_sets = VEC_length (ltrans_partition, ltrans_partitions);
> -  qsort (VEC_address (ltrans_partition, ltrans_partitions), n_sets,
> -        sizeof (ltrans_partition), cmp_partitions);
> +  VEC_qsort (ltrans_partition, ltrans_partitions, cmp_partitions);
>   for (i = 0; i < n_sets; i++)
>     {
>       size_t len;
> diff --git a/gcc/sel-sched.c b/gcc/sel-sched.c
> index 0e0c7c8..12af486 100644
> --- a/gcc/sel-sched.c
> +++ b/gcc/sel-sched.c
> @@ -3719,8 +3719,7 @@ fill_vec_av_set (av_set_t av, blist_t bnds, fence_t fence,
>     }
>
>   /* Sort the vector.  */
> -  qsort (VEC_address (expr_t, vec_av_set), VEC_length (expr_t, vec_av_set),
> -         sizeof (expr_t), sel_rank_for_schedule);
> +  VEC_qsort (expr_t, vec_av_set, sel_rank_for_schedule);
>
>   /* We record maximal priority of insns in av set for current instruction
>      group.  */
> @@ -3934,8 +3933,7 @@ fill_vec_av_set (av_set_t av, blist_t bnds, fence_t fence,
>     gcc_assert (min_need_stall == 0);
>
>   /* Sort the vector.  */
> -  qsort (VEC_address (expr_t, vec_av_set), VEC_length (expr_t, vec_av_set),
> -         sizeof (expr_t), sel_rank_for_schedule);
> +  VEC_qsort (expr_t, vec_av_set, sel_rank_for_schedule);
>
>   if (sched_verbose >= 4)
>     {
> diff --git a/gcc/tree-predcom.c b/gcc/tree-predcom.c
> index b90f5ce..3ebc5a0 100644
> --- a/gcc/tree-predcom.c
> +++ b/gcc/tree-predcom.c
> @@ -1192,8 +1192,7 @@ determine_roots_comp (struct loop *loop,
>       return;
>     }
>
> -  qsort (VEC_address (dref, comp->refs), VEC_length (dref, comp->refs),
> -        sizeof (dref), order_drefs);
> +  VEC_qsort (dref, comp->refs, order_drefs);
>
>   FOR_EACH_VEC_ELT (dref, comp->refs, i, a)
>     {
> diff --git a/gcc/tree-sra.c b/gcc/tree-sra.c
> index 06cb6ff..3328261 100644
> --- a/gcc/tree-sra.c
> +++ b/gcc/tree-sra.c
> @@ -1580,8 +1580,7 @@ sort_and_splice_var_accesses (tree var)
>   access_count = VEC_length (access_p, access_vec);
>
>   /* Sort by <OFFSET, SIZE>.  */
> -  qsort (VEC_address (access_p, access_vec), access_count, sizeof (access_p),
> -        compare_access_positions);
> +  VEC_qsort (access_p, access_vec, compare_access_positions);
>
>   i = 0;
>   while (i < access_count)
> @@ -3524,8 +3523,7 @@ splice_param_accesses (tree parm, bool *ro_grp)
>     return &no_accesses_representant;
>   access_count = VEC_length (access_p, access_vec);
>
> -  qsort (VEC_address (access_p, access_vec), access_count, sizeof (access_p),
> -        compare_access_positions);
> +  VEC_qsort (access_p, access_vec, compare_access_positions);
>
>   i = 0;
>   total_size = 0;
> diff --git a/gcc/tree-ssa-live.c b/gcc/tree-ssa-live.c
> index 715b5a7..232df84 100644
> --- a/gcc/tree-ssa-live.c
> +++ b/gcc/tree-ssa-live.c
> @@ -1256,9 +1256,7 @@ dump_enumerated_decls (FILE *file, int flags)
>          walk_gimple_stmt (&gsi, NULL, dump_enumerated_decls_push, &wi);
>     }
>   decl_list = (VEC (numbered_tree, heap) *) wi.info;
> -  qsort (VEC_address (numbered_tree, decl_list),
> -        VEC_length (numbered_tree, decl_list),
> -        sizeof (numbered_tree), compare_decls_by_uid);
> +  VEC_qsort (numbered_tree, decl_list, compare_decls_by_uid);
>   if (VEC_length (numbered_tree, decl_list))
>     {
>       unsigned ix;
> diff --git a/gcc/tree-ssa-reassoc.c b/gcc/tree-ssa-reassoc.c
> index f2264b6..b4cadfe 100644
> --- a/gcc/tree-ssa-reassoc.c
> +++ b/gcc/tree-ssa-reassoc.c
> @@ -1093,8 +1093,7 @@ undistribute_ops_list (enum tree_code opcode,
>   htab_delete (ctable);
>
>   /* Sort the counting table.  */
> -  qsort (VEC_address (oecount, cvec), VEC_length (oecount, cvec),
> -        sizeof (oecount), oecount_cmp);
> +  VEC_qsort (oecount, cvec, oecount_cmp);
>
>   if (dump_file && (dump_flags & TDF_DETAILS))
>     {
> @@ -2093,18 +2092,12 @@ reassociate_bb (basic_block bb)
>
>              gimple_set_visited (stmt, true);
>              linearize_expr_tree (&ops, stmt, true, true);
> -             qsort (VEC_address (operand_entry_t, ops),
> -                    VEC_length (operand_entry_t, ops),
> -                    sizeof (operand_entry_t),
> -                    sort_by_operand_rank);
> +             VEC_qsort (operand_entry_t, ops, sort_by_operand_rank);
>              optimize_ops_list (rhs_code, &ops);
>              if (undistribute_ops_list (rhs_code, &ops,
>                                         loop_containing_stmt (stmt)))
>                {
> -                 qsort (VEC_address (operand_entry_t, ops),
> -                        VEC_length (operand_entry_t, ops),
> -                        sizeof (operand_entry_t),
> -                        sort_by_operand_rank);
> +                 VEC_qsort (operand_entry_t, ops, sort_by_operand_rank);
>                  optimize_ops_list (rhs_code, &ops);
>                }
>
> diff --git a/gcc/tree-ssa-sccvn.c b/gcc/tree-ssa-sccvn.c
> index 33038b3..557c393 100644
> --- a/gcc/tree-ssa-sccvn.c
> +++ b/gcc/tree-ssa-sccvn.c
> @@ -3044,10 +3044,7 @@ compare_ops (const void *pa, const void *pb)
>  static void
>  sort_scc (VEC (tree, heap) *scc)
>  {
> -  qsort (VEC_address (tree, scc),
> -        VEC_length (tree, scc),
> -        sizeof (tree),
> -        compare_ops);
> +  VEC_qsort (tree, scc, compare_ops);
>  }
>
>  /* Insert the no longer used nary ONARY to the hash INFO.  */
> diff --git a/gcc/tree-ssa-structalias.c b/gcc/tree-ssa-structalias.c
> index 486e9b3..83cc953 100644
> --- a/gcc/tree-ssa-structalias.c
> +++ b/gcc/tree-ssa-structalias.c
> @@ -4972,10 +4972,7 @@ fieldoff_compare (const void *pa, const void *pb)
>  static void
>  sort_fieldstack (VEC(fieldoff_s,heap) *fieldstack)
>  {
> -  qsort (VEC_address (fieldoff_s, fieldstack),
> -        VEC_length (fieldoff_s, fieldstack),
> -        sizeof (fieldoff_s),
> -        fieldoff_compare);
> +  VEC_qsort (fieldoff_s, fieldstack, fieldoff_compare);
>  }
>
>  /* Return true if V is a tree that we can have subvars for.
> diff --git a/gcc/vec.h b/gcc/vec.h
> index 1d2f067..bc55592 100644
> --- a/gcc/vec.h
> +++ b/gcc/vec.h
> @@ -442,6 +442,12 @@ along with GCC; see the file COPYING3.  If not see
>
>  #define VEC_address(T,V)               (VEC_OP(T,base,address)(VEC_BASE(V)))
>
> +/* Conveniently sort the contents of the vector with qsort.
> +   void VEC_qsort (VEC(T) *v, int (*cmp_func)(const void *, const void *))  */
> +
> +#define VEC_qsort(T,V,CMP) qsort(VEC_address (T,V), VEC_length(T,V),   \
> +                                sizeof (T), CMP)
> +
>  /* Find the first index in the vector not less than the object.
>    unsigned VEC_T_lower_bound (VEC(T) *v, const T val,
>                                bool (*lessthan) (const T, const T)); // Integer
>
Eric Botcazou - Oct. 11, 2010, 10:20 a.m.
> gcc/ada/
> 	* gcc-interface/utils2.c (gnat_build_constructor): Use VEC_qsort.

OK, thanks.

Patch

diff --git a/gcc/ada/gcc-interface/utils2.c b/gcc/ada/gcc-interface/utils2.c
index c40223f..88edca4 100644
--- a/gcc/ada/gcc-interface/utils2.c
+++ b/gcc/ada/gcc-interface/utils2.c
@@ -1562,8 +1562,7 @@  gnat_build_constructor (tree type, VEC(constructor_elt,gc) *v)
      by increasing bit position.  This is necessary to ensure the
      constructor can be output as static data.  */
   if (allconstant && TREE_CODE (type) == RECORD_TYPE && n_elmts > 1)
-    qsort (VEC_address (constructor_elt, v), n_elmts,
-           sizeof (constructor_elt), compare_elmt_bitpos);
+    VEC_qsort (constructor_elt, v, compare_elmt_bitpos);
 
   result = build_constructor (type, v);
   TREE_CONSTANT (result) = TREE_STATIC (result) = allconstant;
diff --git a/gcc/dbxout.c b/gcc/dbxout.c
index e5396b2..2eb4f0b 100644
--- a/gcc/dbxout.c
+++ b/gcc/dbxout.c
@@ -2505,8 +2505,7 @@  output_used_types (void)
       htab_traverse (cfun->used_types_hash, output_used_types_helper, &types);
 
       /* Sort by UID to prevent dependence on hash table ordering.  */
-      qsort (VEC_address (tree, types), VEC_length (tree, types),
-	     sizeof (tree), output_types_sort);
+      VEC_qsort (tree, types, output_types_sort);
 
       FOR_EACH_VEC_ELT (tree, types, i, type)
 	debug_queue_symbol (type);
diff --git a/gcc/df-scan.c b/gcc/df-scan.c
index 0b636e9..b2b88b5 100644
--- a/gcc/df-scan.c
+++ b/gcc/df-scan.c
@@ -2392,8 +2392,7 @@  df_sort_and_compress_refs (VEC(df_ref,stack) **ref_vec)
          of DF_REF_COMPARE.  */
       if (i == count - 1)
         return;
-      qsort (VEC_address (df_ref, *ref_vec), count, sizeof (df_ref),
-	     df_ref_compare);
+      VEC_qsort (df_ref, *ref_vec, df_ref_compare);
     }
 
   for (i=0; i<count-dist; i++)
@@ -2492,8 +2491,7 @@  df_sort_and_compress_mws (VEC(df_mw_hardreg_ptr,stack) **mw_vec)
         }
     }
   else
-    qsort (VEC_address (df_mw_hardreg_ptr, *mw_vec), count,
-	   sizeof (struct df_mw_hardreg *), df_mw_compare);
+    VEC_qsort (df_mw_hardreg_ptr, *mw_vec, df_mw_compare);
 
   for (i=0; i<count-dist; i++)
     {
diff --git a/gcc/genautomata.c b/gcc/genautomata.c
index ff024b6..afc97af 100644
--- a/gcc/genautomata.c
+++ b/gcc/genautomata.c
@@ -3252,9 +3252,7 @@  uniq_sort_alt_states (alt_state_t alt_states_list)
        curr_alt_state = curr_alt_state->next_alt_state)
     VEC_safe_push (alt_state_t, heap, alt_states, curr_alt_state);
 
-  qsort (VEC_address (alt_state_t, alt_states),
-	 VEC_length  (alt_state_t, alt_states),
-	 sizeof (alt_state_t), alt_state_cmp);
+  VEC_qsort (alt_state_t, alt_states, alt_state_cmp);
 
   prev_unique_state_ind = 0;
   for (i = 1; i < VEC_length (alt_state_t, alt_states); i++)
@@ -6004,9 +6002,7 @@  evaluate_equiv_classes (automaton_t automaton,
   all_achieved_states = VEC_alloc (state_t, heap, 1500);
   pass_states (automaton, add_achieved_state);
   pass_states (automaton, cache_presence);
-  qsort (VEC_address (state_t, all_achieved_states),
-	 VEC_length (state_t, all_achieved_states),
-         sizeof (state_t), compare_states_for_equiv);
+  VEC_qsort (state_t, all_achieved_states, compare_states_for_equiv);
 
   odd_iteration_flag = 0;
   new_equiv_class_num = init_equiv_class (all_achieved_states,
@@ -7456,9 +7452,7 @@  output_trans_table (automaton_t automaton)
      from the state (state with the maximum num is the first).  */
   output_states_vect = 0;
   pass_states (automaton, add_states_vect_el);
-  qsort (VEC_address (state_t, output_states_vect),
-	 VEC_length (state_t, output_states_vect),
-         sizeof (state_t), compare_transition_els_num);
+  VEC_qsort (state_t, output_states_vect, compare_transition_els_num);
 
   for (i = 0; i < VEC_length (state_t, output_states_vect); i++)
     {
@@ -8944,9 +8938,7 @@  output_state (state_t state)
   fprintf (output_description_file,
 	   state->new_cycle_p ? " (new cycle)\n" : "\n");
   add_state_reservs (state);
-  qsort (VEC_address (reserv_sets_t, state_reservs),
-	 VEC_length (reserv_sets_t, state_reservs),
-         sizeof (reserv_sets_t), state_reservs_cmp);
+  VEC_qsort (reserv_sets_t, state_reservs, state_reservs_cmp);
   remove_state_duplicate_reservs ();
   for (i = 0; i < VEC_length (reserv_sets_t, state_reservs); i++)
     {
diff --git a/gcc/gimplify.c b/gcc/gimplify.c
index 994ffde..09ae44d 100644
--- a/gcc/gimplify.c
+++ b/gcc/gimplify.c
@@ -1476,9 +1476,7 @@  compare_case_labels (const void *p1, const void *p2)
 void
 sort_case_labels (VEC(tree,heap)* label_vec)
 {
-  size_t len = VEC_length (tree, label_vec);
-  qsort (VEC_address (tree, label_vec), len, sizeof (tree),
-         compare_case_labels);
+  VEC_qsort (tree, label_vec, compare_case_labels);
 }
 
 
diff --git a/gcc/graphite-sese-to-poly.c b/gcc/graphite-sese-to-poly.c
index 87b226b..77930d5 100644
--- a/gcc/graphite-sese-to-poly.c
+++ b/gcc/graphite-sese-to-poly.c
@@ -395,10 +395,7 @@  compare_bb_depths (const void *p1, const void *p2)
 static void
 graphite_sort_dominated_info (VEC (basic_block, heap) *dom)
 {
-  size_t len = VEC_length (basic_block, dom);
-
-  qsort (VEC_address (basic_block, dom), len, sizeof (basic_block),
-	 compare_bb_depths);
+  VEC_qsort (basic_block, dom, compare_bb_depths);
 }
 
 /* Recursive helper function for build_scops_bbs.  */
diff --git a/gcc/ipa.c b/gcc/ipa.c
index 8eadd36..54bd6b0 100644
--- a/gcc/ipa.c
+++ b/gcc/ipa.c
@@ -1558,20 +1558,14 @@  build_cdtor_fns (void)
   if (!VEC_empty (tree, static_ctors))
     {
       gcc_assert (!targetm.have_ctors_dtors || in_lto_p);
-      qsort (VEC_address (tree, static_ctors),
-	     VEC_length (tree, static_ctors),
-	     sizeof (tree),
-	     compare_ctor);
+      VEC_qsort (tree, static_ctors, compare_ctor);
       build_cdtor (/*ctor_p=*/true, static_ctors);
     }
 
   if (!VEC_empty (tree, static_dtors))
     {
       gcc_assert (!targetm.have_ctors_dtors || in_lto_p);
-      qsort (VEC_address (tree, static_dtors),
-	     VEC_length (tree, static_dtors),
-	     sizeof (tree),
-	     compare_dtor);
+      VEC_qsort (tree, static_dtors, compare_dtor);
       build_cdtor (/*ctor_p=*/false, static_dtors);
     }
 }
diff --git a/gcc/lto/lto.c b/gcc/lto/lto.c
index 3baea80..d1a2206 100644
--- a/gcc/lto/lto.c
+++ b/gcc/lto/lto.c
@@ -1475,8 +1475,7 @@  lto_wpa_write_files (void)
   blen = strlen (temp_filename);
 
   n_sets = VEC_length (ltrans_partition, ltrans_partitions);
-  qsort (VEC_address (ltrans_partition, ltrans_partitions), n_sets,
-	 sizeof (ltrans_partition), cmp_partitions);
+  VEC_qsort (ltrans_partition, ltrans_partitions, cmp_partitions);
   for (i = 0; i < n_sets; i++)
     {
       size_t len;
diff --git a/gcc/sel-sched.c b/gcc/sel-sched.c
index 0e0c7c8..12af486 100644
--- a/gcc/sel-sched.c
+++ b/gcc/sel-sched.c
@@ -3719,8 +3719,7 @@  fill_vec_av_set (av_set_t av, blist_t bnds, fence_t fence,
     }
 
   /* Sort the vector.  */
-  qsort (VEC_address (expr_t, vec_av_set), VEC_length (expr_t, vec_av_set),
-         sizeof (expr_t), sel_rank_for_schedule);
+  VEC_qsort (expr_t, vec_av_set, sel_rank_for_schedule);
 
   /* We record maximal priority of insns in av set for current instruction
      group.  */
@@ -3934,8 +3933,7 @@  fill_vec_av_set (av_set_t av, blist_t bnds, fence_t fence,
     gcc_assert (min_need_stall == 0);
 
   /* Sort the vector.  */
-  qsort (VEC_address (expr_t, vec_av_set), VEC_length (expr_t, vec_av_set),
-         sizeof (expr_t), sel_rank_for_schedule);
+  VEC_qsort (expr_t, vec_av_set, sel_rank_for_schedule);
 
   if (sched_verbose >= 4)
     {
diff --git a/gcc/tree-predcom.c b/gcc/tree-predcom.c
index b90f5ce..3ebc5a0 100644
--- a/gcc/tree-predcom.c
+++ b/gcc/tree-predcom.c
@@ -1192,8 +1192,7 @@  determine_roots_comp (struct loop *loop,
       return;
     }
 
-  qsort (VEC_address (dref, comp->refs), VEC_length (dref, comp->refs),
-	 sizeof (dref), order_drefs);
+  VEC_qsort (dref, comp->refs, order_drefs);
 
   FOR_EACH_VEC_ELT (dref, comp->refs, i, a)
     {
diff --git a/gcc/tree-sra.c b/gcc/tree-sra.c
index 06cb6ff..3328261 100644
--- a/gcc/tree-sra.c
+++ b/gcc/tree-sra.c
@@ -1580,8 +1580,7 @@  sort_and_splice_var_accesses (tree var)
   access_count = VEC_length (access_p, access_vec);
 
   /* Sort by <OFFSET, SIZE>.  */
-  qsort (VEC_address (access_p, access_vec), access_count, sizeof (access_p),
-	 compare_access_positions);
+  VEC_qsort (access_p, access_vec, compare_access_positions);
 
   i = 0;
   while (i < access_count)
@@ -3524,8 +3523,7 @@  splice_param_accesses (tree parm, bool *ro_grp)
     return &no_accesses_representant;
   access_count = VEC_length (access_p, access_vec);
 
-  qsort (VEC_address (access_p, access_vec), access_count, sizeof (access_p),
-	 compare_access_positions);
+  VEC_qsort (access_p, access_vec, compare_access_positions);
 
   i = 0;
   total_size = 0;
diff --git a/gcc/tree-ssa-live.c b/gcc/tree-ssa-live.c
index 715b5a7..232df84 100644
--- a/gcc/tree-ssa-live.c
+++ b/gcc/tree-ssa-live.c
@@ -1256,9 +1256,7 @@  dump_enumerated_decls (FILE *file, int flags)
 	  walk_gimple_stmt (&gsi, NULL, dump_enumerated_decls_push, &wi);
     }
   decl_list = (VEC (numbered_tree, heap) *) wi.info;
-  qsort (VEC_address (numbered_tree, decl_list),
-	 VEC_length (numbered_tree, decl_list),
-	 sizeof (numbered_tree), compare_decls_by_uid);
+  VEC_qsort (numbered_tree, decl_list, compare_decls_by_uid);
   if (VEC_length (numbered_tree, decl_list))
     {
       unsigned ix;
diff --git a/gcc/tree-ssa-reassoc.c b/gcc/tree-ssa-reassoc.c
index f2264b6..b4cadfe 100644
--- a/gcc/tree-ssa-reassoc.c
+++ b/gcc/tree-ssa-reassoc.c
@@ -1093,8 +1093,7 @@  undistribute_ops_list (enum tree_code opcode,
   htab_delete (ctable);
 
   /* Sort the counting table.  */
-  qsort (VEC_address (oecount, cvec), VEC_length (oecount, cvec),
-	 sizeof (oecount), oecount_cmp);
+  VEC_qsort (oecount, cvec, oecount_cmp);
 
   if (dump_file && (dump_flags & TDF_DETAILS))
     {
@@ -2093,18 +2092,12 @@  reassociate_bb (basic_block bb)
 
 	      gimple_set_visited (stmt, true);
 	      linearize_expr_tree (&ops, stmt, true, true);
-	      qsort (VEC_address (operand_entry_t, ops),
-		     VEC_length (operand_entry_t, ops),
-		     sizeof (operand_entry_t),
-		     sort_by_operand_rank);
+	      VEC_qsort (operand_entry_t, ops, sort_by_operand_rank);
 	      optimize_ops_list (rhs_code, &ops);
 	      if (undistribute_ops_list (rhs_code, &ops,
 					 loop_containing_stmt (stmt)))
 		{
-		  qsort (VEC_address (operand_entry_t, ops),
-			 VEC_length (operand_entry_t, ops),
-			 sizeof (operand_entry_t),
-			 sort_by_operand_rank);
+		  VEC_qsort (operand_entry_t, ops, sort_by_operand_rank);
 		  optimize_ops_list (rhs_code, &ops);
 		}
 
diff --git a/gcc/tree-ssa-sccvn.c b/gcc/tree-ssa-sccvn.c
index 33038b3..557c393 100644
--- a/gcc/tree-ssa-sccvn.c
+++ b/gcc/tree-ssa-sccvn.c
@@ -3044,10 +3044,7 @@  compare_ops (const void *pa, const void *pb)
 static void
 sort_scc (VEC (tree, heap) *scc)
 {
-  qsort (VEC_address (tree, scc),
-	 VEC_length (tree, scc),
-	 sizeof (tree),
-	 compare_ops);
+  VEC_qsort (tree, scc, compare_ops);
 }
 
 /* Insert the no longer used nary ONARY to the hash INFO.  */
diff --git a/gcc/tree-ssa-structalias.c b/gcc/tree-ssa-structalias.c
index 486e9b3..83cc953 100644
--- a/gcc/tree-ssa-structalias.c
+++ b/gcc/tree-ssa-structalias.c
@@ -4972,10 +4972,7 @@  fieldoff_compare (const void *pa, const void *pb)
 static void
 sort_fieldstack (VEC(fieldoff_s,heap) *fieldstack)
 {
-  qsort (VEC_address (fieldoff_s, fieldstack),
-	 VEC_length (fieldoff_s, fieldstack),
-	 sizeof (fieldoff_s),
-	 fieldoff_compare);
+  VEC_qsort (fieldoff_s, fieldstack, fieldoff_compare);
 }
 
 /* Return true if V is a tree that we can have subvars for.
diff --git a/gcc/vec.h b/gcc/vec.h
index 1d2f067..bc55592 100644
--- a/gcc/vec.h
+++ b/gcc/vec.h
@@ -442,6 +442,12 @@  along with GCC; see the file COPYING3.  If not see
 
 #define VEC_address(T,V)		(VEC_OP(T,base,address)(VEC_BASE(V)))
 
+/* Conveniently sort the contents of the vector with qsort.
+   void VEC_qsort (VEC(T) *v, int (*cmp_func)(const void *, const void *))  */
+
+#define VEC_qsort(T,V,CMP) qsort(VEC_address (T,V), VEC_length(T,V),	\
+				 sizeof (T), CMP)
+
 /* Find the first index in the vector not less than the object.
    unsigned VEC_T_lower_bound (VEC(T) *v, const T val,
                                bool (*lessthan) (const T, const T)); // Integer