GCC Bugzilla – Attachment 4118 Details for
Bug 10962
[3.3 regression] lookup_field is a linear search on a linked list (can be slow if large struct)
Home
|
New
|
Browse
|
Search
|
[?]
|
Reports
|
Help
|
New Account
|
Log In
Remember
[x]
|
Forgot Password
Login:
[x]
Patch for 3.4
fixPR10962.diff (text/plain), 14.88 KB, created by
Andrew Pinski
on 2003-05-31 12:24:53 UTC
(
hide
)
Description:
Patch for 3.4
Filename:
MIME Type:
Creator:
Andrew Pinski
Created:
2003-05-31 12:24:53 UTC
Size:
14.88 KB
patch
obsolete
>fixPR10962.diff:éºþ=mBIN×Index: c-typeck.c >=================================================================== >RCS file: /cvs/gcc/gcc/gcc/c-typeck.c,v >retrieving revision 1.238 >diff -u -d -b -w -u -p -r1.238 c-typeck.c >--- c-typeck.c 5 May 2003 20:31:42 -0000 1.238 >+++ c-typeck.c 30 May 2003 21:01:36 -0000 >@@ -1038,11 +1038,11 @@ lookup_field (decl, component) > if (TYPE_LANG_SPECIFIC (type)) > { > int bot, top, half; >- tree *field_array = &TYPE_LANG_SPECIFIC (type)->elts[0]; >+ tree *field_array = &TYPE_LANG_SPECIFIC (type)->s->elts[0]; > > field = TYPE_FIELDS (type); > bot = 0; >- top = TYPE_LANG_SPECIFIC (type)->len; >+ top = TYPE_LANG_SPECIFIC (type)->s->len; > while (top - bot > 1) > { > half = (top - bot + 1) >> 1; >Index: c-decl.c >=================================================================== >RCS file: /cvs/gcc/gcc/gcc/c-decl.c,v >retrieving revision 1.390 >diff -u -d -b -w -u -p -r1.390 c-decl.c >--- c-decl.c 22 May 2003 19:39:13 -0000 1.390 >+++ c-decl.c 30 May 2003 21:01:38 -0000 >@@ -5162,6 +5164,56 @@ finish_struct (t, fieldlist, attributes) > > TYPE_FIELDS (t) = fieldlist; > >+ /* If there are lots of fields, sort so we can look through them fast. >+ We arbitrarily consider 16 or more elts to be "a lot". */ >+ >+ { >+ int len = 0; >+ >+ for (x = fieldlist; x; x = TREE_CHAIN (x)) >+ { >+ if (len > 15 || DECL_NAME (x) == NULL) >+ break; >+ len += 1; >+ } >+ >+ if (len > 15) >+ { >+ tree *field_array; >+ struct lang_type *space; >+ struct sorted_fields_type *space2; >+ >+ len += list_length (x); >+ >+ /* Use the same allocation policy here that make_node uses, to >+ ensure that this lives as long as the rest of the struct decl. >+ All decls in an inline function need to be saved. */ >+ >+ space = ggc_alloc (sizeof (struct lang_type)); >+ space2 = ggc_alloc (sizeof (struct sorted_fields_type) + len * sizeof (tree)); >+ >+ len = 0; >+ space->s = space2; >+ field_array = &space2->elts[0]; >+ for (x = fieldlist; x; x = TREE_CHAIN (x)) >+ { >+ field_array[len++] = x; >+ >+ /* if there is anonymous struct or union break out of the loop */ >+ if (DECL_NAME (x) == NULL) >+ break; >+ } >+ /* found no anonymous struct/union add the TYPE_LANG_SPECIFIC. */ >+ if (x == NULL) >+ { >+ TYPE_LANG_SPECIFIC (t) = space; >+ TYPE_LANG_SPECIFIC (t)->s->len = len; >+ field_array = TYPE_LANG_SPECIFIC (t)->s->elts; >+ qsort (field_array, len, sizeof (tree), field_decl_cmp); >+ } >+ } >+ } >+ > for (x = TYPE_MAIN_VARIANT (t); x; x = TYPE_NEXT_VARIANT (x)) > { > TYPE_FIELDS (x) = TYPE_FIELDS (t); >Index: c-common.c >=================================================================== >RCS file: /cvs/gcc/gcc/gcc/c-common.c,v >retrieving revision 1.417 >diff -u -d -b -w -u -p -r1.417 c-common.c >--- c-common.c 19 May 2003 19:19:42 -0000 1.417 >+++ c-common.c 30 May 2003 21:01:39 -0000 >@@ -800,6 +800,7 @@ static void check_nonnull_arg PARAMS (( > static bool nonnull_check_p PARAMS ((tree, unsigned HOST_WIDE_INT)); > static bool get_nonnull_operand PARAMS ((tree, > unsigned HOST_WIDE_INT *)); >+static int resort_field_decl_cmp (const void *, const void *); > > /* Table of machine-independent attributes common to all C-like languages. */ > const struct attribute_spec c_common_attribute_table[] = >@@ -6195,6 +6196,72 @@ check_function_arguments_recurse (callba > } > > (*callback) (ctx, param, param_num); >+} >+ >+/* Function to help qsort sort FIELD_DECLs by name order. */ >+ >+int >+field_decl_cmp (const void *x_p, const void *y_p) >+{ >+ const tree *const x = x_p; >+ const tree *const y = y_p; >+ if (DECL_NAME (*x) == DECL_NAME (*y)) >+ /* A nontype is "greater" than a type. */ >+ return (TREE_CODE (*y) == TYPE_DECL) - (TREE_CODE (*x) == TYPE_DECL); >+ if (DECL_NAME (*x) == NULL_TREE) >+ return -1; >+ if (DECL_NAME (*y) == NULL_TREE) >+ return 1; >+ if (DECL_NAME (*x) < DECL_NAME (*y)) >+ return -1; >+ return 1; >+} >+ >+static struct { >+ gt_pointer_operator new_value; >+ void *cookie; >+} resort_data; >+ >+/* This routine compares two fields like field_decl_cmp but using the >+pointer operator in resort_data. */ >+ >+static int >+resort_field_decl_cmp (const void *x_p, const void *y_p) >+{ >+ const tree *const x = x_p; >+ const tree *const y = y_p; >+ >+ if (DECL_NAME (*x) == DECL_NAME (*y)) >+ /* A nontype is "greater" than a type. */ >+ return (TREE_CODE (*y) == TYPE_DECL) - (TREE_CODE (*x) == TYPE_DECL); >+ if (DECL_NAME (*x) == NULL_TREE) >+ return -1; >+ if (DECL_NAME (*y) == NULL_TREE) >+ return 1; >+ { >+ tree d1 = DECL_NAME (*x); >+ tree d2 = DECL_NAME (*y); >+ resort_data.new_value (&d1, resort_data.cookie); >+ resort_data.new_value (&d2, resort_data.cookie); >+ if (d1 < d2) >+ return -1; >+ } >+ return 1; >+} >+ >+/* Resort DECL_SORTED_FIELDS because pointers have been reordered. */ >+ >+void >+resort_sorted_fields (void *obj, >+ void *orig_obj ATTRIBUTE_UNUSED , >+ gt_pointer_operator new_value, >+ void *cookie) >+{ >+ struct sorted_fields_type *sf = obj; >+ resort_data.new_value = new_value; >+ resort_data.cookie = cookie; >+ qsort (&sf->elts[0], sf->len, sizeof (tree), >+ resort_field_decl_cmp); > } > > #include "gt-c-common.h" >Index: c-common.h >=================================================================== >RCS file: /cvs/gcc/gcc/gcc/c-common.h,v >retrieving revision 1.181 >diff -u -d -b -w -u -p -r1.181 c-common.h >--- c-common.h 21 May 2003 11:13:17 -0000 1.181 >+++ c-common.h 30 May 2003 21:01:40 -0000 >@@ -24,6 +24,7 @@ Software Foundation, 59 Temple Place - S > > #include "splay-tree.h" > #include "cpplib.h" >+#include "ggc.h" > > /* Usage of TREE_LANG_FLAG_?: > 0: COMPOUND_STMT_NO_SCOPE (in COMPOUND_STMT). >@@ -223,6 +224,13 @@ struct c_common_identifier GTY(()) > > extern GTY(()) tree c_global_trees[CTI_MAX]; > >+/* In a RECORD_TYPE, a sorted array of the fields of the type, not a tree for size reasons. */ >+struct sorted_fields_type GTY(()) >+{ >+ int len; >+ tree GTY((length ("%h.len"))) elts[1]; >+}; >+ > /* Mark which labels are explicitly declared. > These may be shadowed, and may be referenced from nested functions. */ > #define C_DECLARED_LABEL_FLAG(label) TREE_LANG_FLAG_1 (label) >@@ -337,6 +345,9 @@ extern void c_finish_while_stmt_cond PA > enum sw_kind { SW_PARAM = 0, SW_LOCAL, SW_GLOBAL }; > extern void shadow_warning PARAMS ((enum sw_kind, > const char *, tree)); >+extern int field_decl_cmp (const void *, const void *); >+extern void resort_sorted_fields >+ (void *, void *, gt_pointer_operator, void *); > > /* Extra information associated with a DECL. Other C dialects extend > this structure in various ways. The C front-end only uses this >Index: ggc.h >=================================================================== >RCS file: /cvs/gcc/gcc/gcc/ggc.h,v >retrieving revision 1.50 >diff -u -d -b -w -u -p -r1.50 ggc.h >--- ggc.h 3 Apr 2003 21:00:56 -0000 1.50 >+++ ggc.h 30 May 2003 21:01:40 -0000 >@@ -18,6 +18,9 @@ along with GCC; see the file COPYING. I > Software Foundation, 59 Temple Place - Suite 330, Boston, MA > 02111-1307, USA. */ > >+#ifndef GCC_GGC_H >+#define GCC_GGC_H >+ > /* Symbols are marked with `ggc' for `gcc gc' so as not to interfere with > an external gc library that might be linked in. */ > >@@ -268,3 +271,4 @@ extern void stringpool_statistics PARAMS > extern int ggc_min_expand_heuristic PARAMS ((void)); > extern int ggc_min_heapsize_heuristic PARAMS ((void)); > extern void init_ggc_heuristics PARAMS ((void)); >+#endif >Index: c-tree.h >=================================================================== >RCS file: /cvs/gcc/gcc/gcc/c-tree.h,v >retrieving revision 1.113 >diff -u -d -b -w -u -p -r1.113 c-tree.h >--- c-tree.h 11 Apr 2003 04:26:49 -0000 1.113 >+++ c-tree.h 30 May 2003 21:01:40 -0000 >@@ -109,8 +109,7 @@ struct lang_decl GTY(()) > /* In a RECORD_TYPE, a sorted array of the fields of the type. */ > struct lang_type GTY(()) > { >- int len; >- tree GTY((length ("%h.len"))) elts[1]; >+ struct sorted_fields_type * GTY ((reorder ("resort_sorted_fields"))) s; > }; > > /* Record whether a type or decl was written with nonconstant size. >Index: cp/class.c >=================================================================== >RCS file: /cvs/gcc/gcc/gcc/cp/class.c,v >retrieving revision 1.541 >diff -u -d -b -w -u -p -r1.541 class.c >--- cp/class.c 20 May 2003 20:52:33 -0000 1.541 >+++ cp/class.c 30 May 2003 21:01:42 -0000 >@@ -124,8 +124,6 @@ static tree modify_all_vtables (tree, tr > static void determine_primary_base (tree); > static void finish_struct_methods (tree); > static void maybe_warn_about_overly_private_class (tree); >-static int field_decl_cmp (const void *, const void *); >-static int resort_field_decl_cmp (const void *, const void *); > static int method_name_cmp (const void *, const void *); > static int resort_method_name_cmp (const void *, const void *); > static void add_implicitly_declared_members (tree, int, int, int); >@@ -136,7 +134,7 @@ static tree build_vtable_entry_ref (tree > static tree build_vtbl_ref_1 (tree, tree); > static tree build_vtbl_initializer (tree, tree, tree, tree, int *); > static int count_fields (tree); >-static int add_fields_to_vec (tree, tree, int); >+static int add_fields_to_record_type (tree, struct sorted_fields_type*, int); > static void check_bitfield_decl (tree); > static void check_field_decl (tree, tree, int *, int *, int *, int *); > static void check_field_decls (tree, tree *, int *, int *, int *); >@@ -1712,72 +1710,11 @@ maybe_warn_about_overly_private_class (t > } > } > >-/* Function to help qsort sort FIELD_DECLs by name order. */ >- >-static int >-field_decl_cmp (const void* x_p, const void* y_p) >-{ >- const tree *const x = x_p; >- const tree *const y = y_p; >- if (DECL_NAME (*x) == DECL_NAME (*y)) >- /* A nontype is "greater" than a type. */ >- return DECL_DECLARES_TYPE_P (*y) - DECL_DECLARES_TYPE_P (*x); >- if (DECL_NAME (*x) == NULL_TREE) >- return -1; >- if (DECL_NAME (*y) == NULL_TREE) >- return 1; >- if (DECL_NAME (*x) < DECL_NAME (*y)) >- return -1; >- return 1; >-} >- > static struct { > gt_pointer_operator new_value; > void *cookie; > } resort_data; > >-/* This routine compares two fields like field_decl_cmp but using the >- pointer operator in resort_data. */ >- >-static int >-resort_field_decl_cmp (const void* x_p, const void* y_p) >-{ >- const tree *const x = x_p; >- const tree *const y = y_p; >- >- if (DECL_NAME (*x) == DECL_NAME (*y)) >- /* A nontype is "greater" than a type. */ >- return DECL_DECLARES_TYPE_P (*y) - DECL_DECLARES_TYPE_P (*x); >- if (DECL_NAME (*x) == NULL_TREE) >- return -1; >- if (DECL_NAME (*y) == NULL_TREE) >- return 1; >- { >- tree d1 = DECL_NAME (*x); >- tree d2 = DECL_NAME (*y); >- resort_data.new_value (&d1, resort_data.cookie); >- resort_data.new_value (&d2, resort_data.cookie); >- if (d1 < d2) >- return -1; >- } >- return 1; >-} >- >-/* Resort DECL_SORTED_FIELDS because pointers have been reordered. */ >- >-void >-resort_sorted_fields (void* obj, >- void* orig_obj ATTRIBUTE_UNUSED , >- gt_pointer_operator new_value, >- void* cookie) >-{ >- tree sf = obj; >- resort_data.new_value = new_value; >- resort_data.cookie = cookie; >- qsort (&TREE_VEC_ELT (sf, 0), TREE_VEC_LENGTH (sf), sizeof (tree), >- resort_field_decl_cmp); >-} >- > /* Comparison function to compare two TYPE_METHOD_VEC entries by name. */ > > static int >@@ -2787,18 +2724,18 @@ count_fields (tree fields) > } > > /* Subroutine of finish_struct_1. Recursively add all the fields in the >- TREE_LIST FIELDS to the TREE_VEC FIELD_VEC, starting at offset IDX. */ >+ TREE_LIST FIELDS to the SORTED_FIELDS_TYPE elts, starting at offset IDX. */ > > static int >-add_fields_to_vec (tree fields, tree field_vec, int idx) >+add_fields_to_record_type (tree fields, struct sorted_fields_type *field_vec, int idx) > { > tree x; > for (x = fields; x; x = TREE_CHAIN (x)) > { > if (TREE_CODE (x) == FIELD_DECL && ANON_AGGR_TYPE_P (TREE_TYPE (x))) >- idx = add_fields_to_vec (TYPE_FIELDS (TREE_TYPE (x)), field_vec, idx); >+ idx = add_fields_to_record_type (TYPE_FIELDS (TREE_TYPE (x)), field_vec, idx); > else >- TREE_VEC_ELT (field_vec, idx++) = x; >+ field_vec->elts[idx++] = x; > } > return idx; > } >@@ -5167,9 +5104,11 @@ finish_struct_1 (tree t) > n_fields = count_fields (TYPE_FIELDS (t)); > if (n_fields > 7) > { >- tree field_vec = make_tree_vec (n_fields); >- add_fields_to_vec (TYPE_FIELDS (t), field_vec, 0); >- qsort (&TREE_VEC_ELT (field_vec, 0), n_fields, sizeof (tree), >+ struct sorted_fields_type *field_vec = ggc_alloc (sizeof (struct sorted_fields_type) >+ + n_fields * sizeof (tree)); >+ field_vec->len = n_fields; >+ add_fields_to_record_type (TYPE_FIELDS (t), field_vec, 0); >+ qsort (field_vec->elts, n_fields, sizeof (tree), > field_decl_cmp); > if (! DECL_LANG_SPECIFIC (TYPE_MAIN_DECL (t))) > retrofit_lang_decl (TYPE_MAIN_DECL (t)); >Index: cp/cp-tree.h >=================================================================== >RCS file: /cvs/gcc/gcc/gcc/cp/cp-tree.h,v >retrieving revision 1.847 >diff -u -d -b -w -u -p -r1.847 cp-tree.h >--- cp/cp-tree.h 18 May 2003 13:40:52 -0000 1.847 >+++ cp/cp-tree.h 30 May 2003 21:01:44 -0000 >@@ -1709,7 +1709,7 @@ struct lang_decl GTY(()) > > union lang_decl_u3 > { >- tree GTY ((tag ("0"), reorder ("resort_sorted_fields"))) >+ struct sorted_fields_type * GTY ((tag ("0"), reorder ("resort_sorted_fields"))) > sorted_fields; > struct cp_token_cache * GTY ((tag ("2"))) pending_inline_info; > struct language_function * GTY ((tag ("1"))) >@@ -3522,8 +3522,6 @@ extern tree convert_to_base > extern tree build_vtbl_ref (tree, tree); > extern tree build_vfn_ref (tree, tree); > extern tree get_vtable_decl (tree, int); >-extern void resort_sorted_fields >- (void *, void *, gt_pointer_operator, void *); > extern void resort_type_method_vec > (void *, void *, gt_pointer_operator, void *); > extern void add_method (tree, tree, int); >Index: cp/search.c >=================================================================== >RCS file: /cvs/gcc/gcc/gcc/cp/search.c,v >retrieving revision 1.263 >diff -u -d -b -w -u -p -r1.263 search.c >--- cp/search.c 18 May 2003 13:40:54 -0000 1.263 >+++ cp/search.c 30 May 2003 21:01:45 -0000 >@@ -449,8 +449,8 @@ lookup_field_1 (tree type, tree name, bo > && DECL_LANG_SPECIFIC (TYPE_NAME (type)) > && DECL_SORTED_FIELDS (TYPE_NAME (type))) > { >- tree *fields = &TREE_VEC_ELT (DECL_SORTED_FIELDS (TYPE_NAME (type)), 0); >- int lo = 0, hi = TREE_VEC_LENGTH (DECL_SORTED_FIELDS (TYPE_NAME (type))); >+ tree *fields = &DECL_SORTED_FIELDS (TYPE_NAME (type))->elts[0]; >+ int lo = 0, hi = DECL_SORTED_FIELDS (TYPE_NAME (type))->len; > int i; > > while (lo < hi) >
You cannot view the attachment while viewing its details because your browser does not support IFRAMEs.
View the attachment on a separate page
.
View Attachment As Raw
Actions:
View
Attachments on
bug 10962
:
4072
|
4088
| 4118