diff --git a/gcc/lto/ChangeLog b/gcc/lto/ChangeLog index d3d7ffd484e..1f203a1a1b3 100644 --- a/gcc/lto/ChangeLog +++ b/gcc/lto/ChangeLog @@ -1,3 +1,20 @@ +2011-10-02 Andi Kleen + + * lto-object.c (lto_obj_add_section_data): Add list. + (lto_obj_add_section): Fill in list. + (ltoobj_build_section_table): Pass through list. + * lto.c (file_data_list): Declare. + (create_subid_section_table): Pass arguments directly. + Fill in list of file_datas. + (lwstate): Delete. + (lto_create_files_from_ids): Pass in direct arguments. + Don't maintain list. + (lto_file_read): Use explicit section and file data lists. + (lto_read_all_file_options): Pass in section_list. + * lto.h (lto_obj_build_section_table): Add list. + (lto_section_slot): Add next. + (lto_section_list): Declare. + 2011-10-02 Jan Hubicka PR lto/47247 diff --git a/gcc/lto/lto-object.c b/gcc/lto/lto-object.c index 3be58dec380..daf3bd002a3 100644 --- a/gcc/lto/lto-object.c +++ b/gcc/lto/lto-object.c @@ -204,6 +204,8 @@ struct lto_obj_add_section_data htab_t section_hash_table; /* The offset of this file. */ off_t base_offset; + /* List in linker order */ + struct lto_section_list *list; }; /* This is called for each section in the file. */ @@ -218,6 +220,7 @@ lto_obj_add_section (void *data, const char *name, off_t offset, char *new_name; struct lto_section_slot s_slot; void **slot; + struct lto_section_list *list = loasd->list; if (strncmp (name, LTO_SECTION_NAME_PREFIX, strlen (LTO_SECTION_NAME_PREFIX)) != 0) @@ -228,12 +231,21 @@ lto_obj_add_section (void *data, const char *name, off_t offset, slot = htab_find_slot (section_hash_table, &s_slot, INSERT); if (*slot == NULL) { - struct lto_section_slot *new_slot = XNEW (struct lto_section_slot); + struct lto_section_slot *new_slot = XCNEW (struct lto_section_slot); new_slot->name = new_name; new_slot->start = loasd->base_offset + offset; new_slot->len = length; *slot = new_slot; + + if (list != NULL) + { + if (!list->first) + list->first = new_slot; + if (list->last) + list->last->next = new_slot; + list->last = new_slot; + } } else { @@ -248,7 +260,7 @@ lto_obj_add_section (void *data, const char *name, off_t offset, the start and size of each section in the .o file. */ htab_t -lto_obj_build_section_table (lto_file *lto_file) +lto_obj_build_section_table (lto_file *lto_file, struct lto_section_list *list) { struct lto_simple_object *lo = (struct lto_simple_object *) lto_file; htab_t section_hash_table; @@ -261,6 +273,7 @@ lto_obj_build_section_table (lto_file *lto_file) gcc_assert (lo->sobj_r != NULL && lo->sobj_w == NULL); loasd.section_hash_table = section_hash_table; loasd.base_offset = lo->base.offset; + loasd.list = list; errmsg = simple_object_find_sections (lo->sobj_r, lto_obj_add_section, &loasd, &err); if (errmsg != NULL) diff --git a/gcc/lto/lto.c b/gcc/lto/lto.c index 778e33eee01..a77eeb48c55 100644 --- a/gcc/lto/lto.c +++ b/gcc/lto/lto.c @@ -1052,6 +1052,12 @@ lto_resolution_read (splay_tree file_ids, FILE *resolution, lto_file *file) } } +/* List of file_decl_datas */ +struct file_data_list + { + struct lto_file_decl_data *first, *last; + }; + /* Is the name for a id'ed LTO section? */ static int @@ -1068,11 +1074,10 @@ lto_section_with_id (const char *name, unsigned HOST_WIDE_INT *id) /* Create file_data of each sub file id */ static int -create_subid_section_table (void **slot, void *data) +create_subid_section_table (struct lto_section_slot *ls, splay_tree file_ids, + struct file_data_list *list) { struct lto_section_slot s_slot, *new_slot; - struct lto_section_slot *ls = *(struct lto_section_slot **)slot; - splay_tree file_ids = (splay_tree)data; unsigned HOST_WIDE_INT id; splay_tree_node nd; void **hash_slot; @@ -1095,6 +1100,13 @@ create_subid_section_table (void **slot, void *data) file_data->id = id; file_data->section_hash_table = lto_obj_create_section_hash_table ();; lto_splay_tree_insert (file_ids, id, file_data); + + /* Maintain list in linker order */ + if (!list->first) + list->first = file_data; + if (list->last) + list->last->next = file_data; + list->last = file_data; } /* Copy section into sub module hash table */ @@ -1129,27 +1141,17 @@ lto_file_finalize (struct lto_file_decl_data *file_data, lto_file *file) lto_free_section_data (file_data, LTO_section_decls, NULL, data, len); } -struct lwstate +/* Finalize FILE_DATA in FILE and increase COUNT. */ + +static int +lto_create_files_from_ids (lto_file *file, struct lto_file_decl_data *file_data, + int *count) { - lto_file *file; - struct lto_file_decl_data **file_data; - int *count; -}; - -/* Traverse ids and create a list of file_datas out of it. */ - -static int lto_create_files_from_ids (splay_tree_node node, void *data) -{ - struct lwstate *lw = (struct lwstate *)data; - struct lto_file_decl_data *file_data = (struct lto_file_decl_data *)node->value; - - lto_file_finalize (file_data, lw->file); + lto_file_finalize (file_data, file); if (cgraph_dump_file) fprintf (cgraph_dump_file, "Creating file %s with sub id " HOST_WIDE_INT_PRINT_HEX "\n", file_data->file_name, file_data->id); - file_data->next = *lw->file_data; - *lw->file_data = file_data; - (*lw->count)++; + (*count)++; return 0; } @@ -1166,29 +1168,31 @@ lto_file_read (lto_file *file, FILE *resolution_file, int *count) struct lto_file_decl_data *file_data = NULL; splay_tree file_ids; htab_t section_hash_table; - struct lwstate state; - - section_hash_table = lto_obj_build_section_table (file); + struct lto_section_slot *section; + struct file_data_list file_list; + struct lto_section_list section_list; + + memset (§ion_list, 0, sizeof (struct lto_section_list)); + section_hash_table = lto_obj_build_section_table (file, §ion_list); /* Find all sub modules in the object and put their sections into new hash tables in a splay tree. */ file_ids = lto_splay_tree_new (); - htab_traverse (section_hash_table, create_subid_section_table, file_ids); - + memset (&file_list, 0, sizeof (struct file_data_list)); + for (section = section_list.first; section != NULL; section = section->next) + create_subid_section_table (section, file_ids, &file_list); + /* Add resolutions to file ids */ lto_resolution_read (file_ids, resolution_file, file); - /* Finalize each lto file for each submodule in the merged object - and create list for returning. */ - state.file = file; - state.file_data = &file_data; - state.count = count; - splay_tree_foreach (file_ids, lto_create_files_from_ids, &state); - + /* Finalize each lto file for each submodule in the merged object */ + for (file_data = file_list.first; file_data != NULL; file_data = file_data->next) + lto_create_files_from_ids (file, file_data, count); + splay_tree_delete (file_ids); htab_delete (section_hash_table); - return file_data; + return file_list.first; } #if HAVE_MMAP_FILE && HAVE_SYSCONF && defined _SC_PAGE_SIZE @@ -2427,7 +2431,7 @@ lto_read_all_file_options (void) file_data = XCNEW (struct lto_file_decl_data); file_data->file_name = file->filename; - file_data->section_hash_table = lto_obj_build_section_table (file); + file_data->section_hash_table = lto_obj_build_section_table (file, NULL); lto_read_file_options (file_data); diff --git a/gcc/lto/lto.h b/gcc/lto/lto.h index 8110ace2749..43fcca649ea 100644 --- a/gcc/lto/lto.h +++ b/gcc/lto/lto.h @@ -43,7 +43,8 @@ extern void lto_read_all_file_options (void); /* In lto-elf.c or lto-coff.c */ extern lto_file *lto_obj_file_open (const char *filename, bool writable); extern void lto_obj_file_close (lto_file *file); -extern htab_t lto_obj_build_section_table (lto_file *file); +struct lto_section_list; +extern htab_t lto_obj_build_section_table (lto_file *file, struct lto_section_list *list); extern htab_t lto_obj_create_section_hash_table (void); extern void lto_obj_begin_section (const char *name); extern void lto_obj_append_data (const void *data, size_t len, void *block); @@ -58,6 +59,13 @@ struct lto_section_slot const char *name; intptr_t start; size_t len; + struct lto_section_slot *next; +}; + +/* A list of section slots */ +struct lto_section_list +{ + struct lto_section_slot *first, *last; }; int64_t lto_parse_hex (const char *p);