Index: struct-reorg.c =================================================================== --- struct-reorg.c (revision 114271) +++ struct-reorg.c (working copy) @@ -50,7 +50,7 @@ Software Foundation, 59 Temple Place - S #include "tree-pass.h" #include "struct-reorg.h" #include "opts.h" -#include "ipa-static.h" +#include "ipa-type-escape.h" /* ************** Static Global Data Structures ******************** */ @@ -156,13 +156,12 @@ struct malloc_struct struct malloc_struct *next; /* Next item in linked list. */ }; - +bool debug_mode = false; static struct pointer_set_t * visited_nodes; struct struct_tree_list *struct_reorg_malloc_list = NULL; struct malloc_struct *malloc_data_list = NULL; -static void debug_gimple (tree); static bool similar_struct_decls_p (tree, tree); static bool @@ -309,12 +308,6 @@ get_type_name (tree type_node) return NULL; } -static void -debug_gimple (tree t) -{ - print_generic_stmt (stdout, t, TDF_SLIM | TDF_BLOCKS | TDF_VOPS); -} - static void print_new_vars (struct new_var_data *new_vars) @@ -340,7 +333,7 @@ print_new_vars (struct new_var_data *new (char *) IDENTIFIER_POINTER (DECL_NAME (current->orig_var))); else fprintf (stdout, " of type %s\n", - current->orig_var->decl.uid, + DECL_UID (current->orig_var), type_name); for (cur_var = current->new_vars; cur_var; cur_var = cur_var->next) @@ -376,7 +369,7 @@ print_new_vars (struct new_var_data *new else fprintf (stdout, " declared in function '%s' of type '%s'\n", - var_decl->decl.uid, + DECL_UID (var_decl), (! global_context ? IDENTIFIER_POINTER (DECL_NAME (DECL_CONTEXT (var_decl))) : "global"), @@ -407,12 +401,11 @@ print_use_list (struct use_struct *uses_ } fprintf (stdout, " <%s>", current->offset ? "offset" : "other"); - print_generic_stmt (stdout, current->stmt, - TDF_SLIM | TDF_BLOCKS | TDF_VOPS); + print_generic_stmt (stdout, current->stmt, 0); } - } + /* Print out an individual new type (generated by this optimization). Helper function for print_new_types. */ @@ -769,10 +762,13 @@ get_stmt_accessed_fields_1 (tree stmt, t || (struct_var == op)) return 0; + if (TREE_CODE (struct_var) == SSA_NAME) + struct_var = SSA_NAME_VAR (struct_var); + if (TREE_CODE (struct_var) == VAR_DECL) struct_type = TREE_TYPE (struct_var); else if (TREE_CODE (struct_var) == INDIRECT_REF - || TREE_CODE (struct_var) == MEM_REF) + || TREE_CODE (struct_var) == TARGET_MEM_REF) struct_type = TREE_TYPE (TREE_TYPE (TREE_OPERAND (struct_var, 0))); if (struct_type && (TREE_CODE (struct_type) == ARRAY_TYPE)) @@ -949,22 +945,25 @@ build_f_acc_list_for_bb (struct data_str for (bsi = bsi_start (bb); ! bsi_end_p (bsi); bsi_next (&bsi)) { tree stmt = bsi_stmt (bsi); - int i; + unsigned i; + sbitmap_iterator sbi; + sbitmap_zero (fields); crr->distance_to_next += get_stmt_accessed_fields (stmt, ds, fields, bb, context); - EXECUTE_IF_SET_IN_SBITMAP (fields, 0, i, - /* The disntance to the next is zeroed here, if the next - access is in the same statement it will not be advanced - at all, and we will get a distance of zero. */ - crr->next = xcalloc (1, sizeof (struct bb_field_access)); - crr->next->f_index = i; - crr = crr->next; - /* Update the access count for a single field. */ - ds->fields[crr->f_index].count += bb->count; - ); + EXECUTE_IF_SET_IN_SBITMAP (fields, 0, i, sbi) + { + /* The disntance to the next is zeroed here, if the next + access is in the same statement it will not be advanced + at all, and we will get a distance of zero. */ + crr->next = xcalloc (1, sizeof (struct bb_field_access)); + crr->next->f_index = i; + crr = crr->next; + /* Update the access count for a single field. */ + ds->fields[crr->f_index].count += bb->count; + } } return head; } @@ -1325,7 +1324,8 @@ create_and_assemble_new_types (struct da if (TEST_BIT (field_info->fields_in_cluster, i)) { new_decl = copy_node (struct_data->fields[i].decl); - new_decl->decl.rtl = NULL; + if (HAS_RTL_P (new_decl)) + SET_DECL_RTL (new_decl, NULL); struct_data->fields[i].new_mapping = NULL; new_types->num_fields++; @@ -2279,14 +2138,14 @@ add_field_mallocs (tree cur_lhs, void_pointer_type = build_pointer_type (void_type_node); tmp_var1 = create_tmp_var_raw (void_pointer_type, NULL); gimple_add_tmp_var (tmp_var1); - call_stmt = build (MODIFY_EXPR, void_pointer_type, + call_stmt = build2 (MODIFY_EXPR, void_pointer_type, tmp_var1, call_expr); append_to_statement_list (call_stmt, new_mallocs_list); tmp_var2 = create_tmp_var_raw (save_type, NULL); gimple_add_tmp_var (tmp_var2); - convert_stmt = build (MODIFY_EXPR, save_type, + convert_stmt = build2 (MODIFY_EXPR, save_type, tmp_var2, build1 (CONVERT_EXPR, save_type, tmp_var1)); @@ -2294,7 +2153,7 @@ add_field_mallocs (tree cur_lhs, new_lhs = lang_hooks.optimize.build_field_reference (lang_hooks.optimize.build_pointer_ref (cur_lhs, ""), field_identifier); - new_malloc_stmt = build (MODIFY_EXPR, TREE_TYPE (new_lhs), + new_malloc_stmt = build2 (MODIFY_EXPR, TREE_TYPE (new_lhs), new_lhs, tmp_var2); @@ -2305,7 +2164,7 @@ add_field_mallocs (tree cur_lhs, tmp_var3 = create_tmp_var_raw (TREE_TYPE (new_rhs), NULL); gimple_add_tmp_var (tmp_var3); - assign_stmt = build (MODIFY_EXPR, TREE_TYPE (new_rhs), + assign_stmt = build2 (MODIFY_EXPR, TREE_TYPE (new_rhs), tmp_var3, new_rhs); append_to_statement_list (assign_stmt, new_mallocs_list); @@ -2376,7 +2236,7 @@ create_cascading_mallocs (struct malloc_ arg_list, NULL_TREE); - new_malloc_tree = build (MODIFY_EXPR, TREE_TYPE (cur_var->new_vars->data), + new_malloc_tree = build2 (MODIFY_EXPR, TREE_TYPE (cur_var->new_vars->data), cur_var->new_vars->data, build1 (NOP_EXPR, TREE_TYPE (cur_var->new_vars->data), call_expr)); @@ -2556,18 +2418,18 @@ create_new_mallocs (struct struct_list * if (! new_mallocs_list) new_mallocs_list = alloc_stmt_list (); - div_stmt = build (MODIFY_EXPR, integer_type_node, + div_stmt = build2 (MODIFY_EXPR, integer_type_node, new_malloc_factor_var, - build (TRUNC_DIV_EXPR, + build2 (TRUNC_DIV_EXPR, integer_type_node, old_malloc_size, orig_struct_size)); append_to_statement_list (div_stmt, &new_mallocs_list); - mult_stmt = build (MODIFY_EXPR, integer_type_node, + mult_stmt = build2 (MODIFY_EXPR, integer_type_node, new_malloc_size_var, - build (MULT_EXPR, + build2 (MULT_EXPR, integer_type_node, new_malloc_factor_var, new_struct_size)); @@ -2627,14 +2489,14 @@ create_new_mallocs (struct struct_list * arg_list, NULL_TREE); - call_stmt = build (MODIFY_EXPR, + call_stmt = build2 (MODIFY_EXPR, TREE_TYPE (TREE_TYPE (malloc_fn_decl)), new_malloc_result_var, call_expr); append_to_statement_list (call_stmt, &new_mallocs_list); - final_assignment_stmt = build (MODIFY_EXPR, + final_assignment_stmt = build2 (MODIFY_EXPR, TREE_TYPE (new_var_decl), new_var_decl, @@ -3087,8 +3074,8 @@ recursively_copy_node (tree old_node) int i = 0; new_node = copy_node (old_node); - if (DECL_P (new_node)) - new_node->decl.rtl = NULL; + if (DECL_P (new_node) && HAS_RTL_P (new_node)) + SET_DECL_RTL (new_node, NULL); for (i = 0; i < TREE_CODE_LENGTH (TREE_CODE (old_node)); i++) { @@ -3684,7 +3705,7 @@ update_field_accesses (struct struct_lis (old_var, ""), field_identifier)); else if (is_mem_ref) - new_stmt = build (MODIFY_EXPR, + new_stmt = build2 (MODIFY_EXPR, save_type, new_var, lang_hooks.optimize.build_field_reference @@ -3692,7 +3713,7 @@ update_field_accesses (struct struct_lis (old_var, mem_ref_index), field_identifier)); else if (is_array_ref) - new_stmt = build (MODIFY_EXPR, + new_stmt = build2 (MODIFY_EXPR, save_type, new_var, lang_hooks.optimize.build_field_reference @@ -3700,7 +3721,7 @@ update_field_accesses (struct struct_lis (old_var, array_ref_index), field_identifier)); else - new_stmt = build (MODIFY_EXPR, + new_stmt = build2 (MODIFY_EXPR, save_type, new_var, lang_hooks.optimize.build_field_reference @@ -3395,9 +3337,9 @@ update_struct_offset (struct struct_list gimple_add_tmp_var (index_var); - new_stmt = build (MODIFY_EXPR, new_int_type, + new_stmt = build2 (MODIFY_EXPR, new_int_type, index_var, - build (TRUNC_DIV_EXPR, + build2 (TRUNC_DIV_EXPR, new_int_type, arg0, orig_struct_size)); @@ -3422,9 +3364,9 @@ update_struct_offset (struct struct_list new_struct_size = lang_hooks.optimize.sizeof_type (new_struct_type, true, 0); - new_stmt1 = build (MODIFY_EXPR, new_int_type, + new_stmt1 = build2 (MODIFY_EXPR, new_int_type, size_var, - build (MULT_EXPR, + build2 (MULT_EXPR, new_int_type, index_var, new_struct_size)); @@ -3440,7 +3382,7 @@ update_struct_offset (struct struct_list if (!typecast_var) fatal_error ("Unable to find newly created var."); - new_stmt2 = build (MODIFY_EXPR, ptr_type, + new_stmt2 = build2 (MODIFY_EXPR, ptr_type, typecast_var, build1 (CONVERT_EXPR, ptr_type, size_var)); @@ -4391,12 +4389,12 @@ reorder_fields (struct data_structure *d new_types->name = NULL; new_types->next = NULL; - for (i = 0; i < ds->num_fields; i++) { idx = ds->struct_clustering->fields_order[i]; new_decl = copy_node (ds->fields[idx].decl); - new_decl->decl.rtl = NULL; + if (HAS_RTL_P (new_decl)) + SET_DECL_RTL (new_decl, NULL); if (!new_types->field_list) new_types->field_list = new_decl; else @@ -4870,10 +4918,20 @@ make_data_struct_node (struct struct_lis /* Check to see if it is legal to rearrange this structure. */ - /* - if (!ipa_static_type_contained_p (struct_type)) - return NULL; - */ + if (!ipa_type_escape_type_contained_p (struct_type)) + { + if ((struct_type = TYPE_NAME (struct_type))) + { + if (TREE_CODE (struct_type) == TYPE_DECL) + struct_type = DECL_NAME (struct_type); + + if (debug_mode) + fprintf (stderr, "structure type %s escapes.\n", + IDENTIFIER_POINTER (struct_type)); + } + return NULL; + } + /* At this time we don't want to mess with pre-initialized arrays, so if it's got a hard-coded initialization, don't @@ -4901,8 +4959,9 @@ make_data_struct_node (struct struct_lis if (TREE_CODE (struct_type) == TYPE_DECL) struct_type = DECL_NAME (struct_type); - fprintf (stderr, "A new data structure to analyze: %s\n", - IDENTIFIER_POINTER (struct_type)); + if (debug_mode) + fprintf (stderr, "A new data structure to analyze: %s\n", + IDENTIFIER_POINTER (struct_type)); } return new_node; @@ -4945,14 +5004,16 @@ build_data_structure_list (void) /* Function arguments. */ for (var_decl = DECL_ARGUMENTS (c_node->decl); - var_decl; var_decl = TREE_CHAIN (var_decl)) - if ((tmp = make_data_struct_node (data_struct_list, - var_decl))) - { - data_struct_list = tmp; - if (! func) - tmp->struct_data->in_extern_definition = true; - } + var_decl; var_decl = TREE_CHAIN (var_decl)) + { + if ((tmp = make_data_struct_node (data_struct_list, + var_decl))) + { + data_struct_list = tmp; + if (! func) + tmp->struct_data->in_extern_definition = true; + } + } if (! func) continue; @@ -4986,7 +5047,7 @@ build_data_structure_list (void) static void perform_escape_analysis (bitmap escaped_vars, bitmap escaped_types, - bitmap passed_types, bool type_check_p) + bitmap passed_types, bool type_check_p, FILE* vcg_dump) { struct cgraph_node *c_node; struct cgraph_edge *caller; @@ -5007,6 +5068,10 @@ perform_escape_analysis (bitmap escaped_ if (! (TREE_STATIC (fn_decl)) || (TREE_PUBLIC (fn_decl))) { + if (vcg_dump) + fprintf (vcg_dump, "Function %s is not static, or public.\n", + IDENTIFIER_POINTER (DECL_NAME (fn_decl))); + for (caller = c_node->callers; caller; caller = caller->next_caller) { tree call_stmt = caller->call_stmt; @@ -5033,13 +5098,22 @@ perform_escape_analysis (bitmap escaped_ if (DECL_P (arg)) { - bitmap_set_bit (escaped_vars, arg->decl.uid); + bitmap_set_bit (escaped_vars, DECL_UID (arg)); + if (vcg_dump) + fprintf (vcg_dump, "\tvariable %s escapes.\n", + IDENTIFIER_POINTER (DECL_NAME (arg))); + if (type_check_p - && (AGGREGATE_TYPE_P (arg_type)) + &&( AGGREGATE_TYPE_P (arg_type)) && !bitmap_bit_p (escaped_types, - arg_type->type.uid)) - bitmap_set_bit (escaped_types, - arg_type->type.uid); + TYPE_UID (arg_type))) + { + bitmap_set_bit (escaped_types, + TYPE_UID (arg_type)); + if (vcg_dump) + fprintf (vcg_dump, "\ttype %s escapes.\n", + IDENTIFIER_POINTER (TYPE_NAME (arg_type))); + } } } } @@ -5051,22 +5125,22 @@ perform_escape_analysis (bitmap escaped_ var_decl = TREE_CHAIN (var_decl)) { var_type = TREE_TYPE (var_decl); - bitmap_set_bit (passed_types, var_type->type.uid); + bitmap_set_bit (passed_types, TYPE_UID (var_type)); while (POINTER_TYPE_P (var_type)) { var_type = TREE_TYPE (var_type); - bitmap_set_bit (passed_types, var_type->type.uid); + bitmap_set_bit (passed_types, TYPE_UID (var_type)); } } /* For functions that are local to the current compilation, check arguments passed to any indirect function call. */ - for (caller = INDIRECT_CALLS (c_node); caller; + /* for (caller = INDIRECT_CALLS (c_node); caller; caller = NEXT_INDIRECT_CALL (caller)) { tree call_stmt = caller->call_stmt; - tree call_expr; /* = caller->call_stmt; */ + tree call_expr; tree arg_list; if (TREE_CODE (call_stmt) == CALL_EXPR) @@ -5077,7 +5151,7 @@ perform_escape_analysis (bitmap escaped_ else abort (); - if (0) + if (debug_mode) debug_gimple (call_expr); if (call_expr) @@ -5092,17 +5166,17 @@ perform_escape_analysis (bitmap escaped_ if (DECL_P (arg)) { - bitmap_set_bit (escaped_vars, arg->decl.uid); + bitmap_set_bit (escaped_vars, DECL_UID (arg)); if (type_check_p && (AGGREGATE_TYPE_P (arg_type)) && !bitmap_bit_p (escaped_types, - arg_type->type.uid)) + TYPE_UID (arg_type))) bitmap_set_bit (escaped_types, - arg_type->type.uid); + TYPE_UID (arg_type)); } - } - + } } + */ } } } @@ -5335,10 +5409,11 @@ reorg_structs (void) escaped_types = BITMAP_GGC_ALLOC (); passed_types = BITMAP_GGC_ALLOC (); perform_escape_analysis (escaped_vars, escaped_types, passed_types, - type_check_p); + type_check_p, vcg_dump); /* Stage 1: Build DATA_STRUCTURE list of the data structures that are valid for the transformation. */ + data_struct_list = build_data_structure_list (); /* Walk through entire program tree looking for: @@ -5350,8 +5425,6 @@ reorg_structs (void) algorithm, we should optimize this in the future. */ - if (vcg_dump) - fprintf (vcg_dump, "graph: {\n"); for (current_struct = data_struct_list; current_struct; current_struct = current_struct->next) @@ -5360,6 +5433,9 @@ reorg_structs (void) /* Stage 2: Determine what, if anything, we want to transform and how. */ + if (vcg_dump) + fprintf (vcg_dump, "\nCollecting data for structure %s ...\n", + get_type_name (crr_ds->decl)); for (c_node = cgraph_nodes; c_node; c_node = c_node->next) { struct function *func = DECL_STRUCT_FUNCTION (c_node->decl); @@ -5384,12 +5460,25 @@ reorg_structs (void) { struct data_structure *crr_ds = current_struct->struct_data; + if (vcg_dump) + fprintf (vcg_dump, "\nAnalizing data for structure %s ...\n", + get_type_name (crr_ds->decl)); if (crr_ds->count < (hotest_struct_count / COLD_STRUCTURE_RATIO)) - continue; + { + if (vcg_dump) + fprintf (vcg_dump, "\nThe structure %s is too cold.\n", + get_type_name (crr_ds->decl)); + continue; + } success = cache_aware_data_reorganization (crr_ds, reordering_only); - dump_cpg (stdout, crr_ds->cpg); - printout_field_reordering_hints (crr_ds, stdout); - printout_structure_splitting_hints (crr_ds, stdout); + if (vcg_dump) + { + fprintf (vcg_dump, "graph: {\n"); + dump_cpg (vcg_dump, crr_ds->cpg); + fprintf (vcg_dump, "}\n"); + printout_field_reordering_hints (crr_ds, vcg_dump); + printout_structure_splitting_hints (crr_ds, vcg_dump); + } free_cpg (crr_ds->cpg); crr_ds->cpg = NULL; } @@ -5398,7 +5487,11 @@ reorg_structs (void) collect_malloc_data (); - do_reorg (data_struct_list, passed_types, escaped_types); + if (vcg_dump) + fprintf (vcg_dump, "\nTransformation stage:\n"); + + + do_reorg (data_struct_list, passed_types, escaped_types, vcg_dump); /* Free up the memory allocated for the CRR_DS. */ @@ -5407,12 +5500,10 @@ reorg_structs (void) free_data_struct (current_struct->struct_data); if (vcg_dump) - { - fprintf (vcg_dump, "}\n"); fclose (vcg_dump); - } } + void add_call_to_malloc_list (tree fn_call) {