/* Struct-reorg optimization.
- Copyright (C) 2007 Free Software Foundation, Inc.
+ Copyright (C) 2007, 2008 Free Software Foundation, Inc.
Contributed by Olga Golovanevsky <olga@il.ibm.com>
(Initial version of this code was developed
by Caroline Tice and Mostafa Hagog.)
typedef const struct func_alloc_sites *const_fallocs_t;
/* All allocation sites in the program. */
-htab_t alloc_sites;
+htab_t alloc_sites = NULL;
/* New global variables. Generated once for whole program. */
htab_t new_global_vars;
{
tree size_def_stmt = SSA_NAME_DEF_STMT (arg);
- /* If allocation statementt was of the form
+ /* If the allocation statement was of the form
D.2229_10 = <alloc_func> (D.2228_9);
then size_def_stmt can be D.2228_9 = num.3_8 * 8; */
/* This function checks whether the access ACC of structure type STR
- is of the form suitable for tranformation. If yes, it returns true.
+ is of the form suitable for transformation. If yes, it returns true.
False otherwise. */
static bool
}
/* This function returns the structure field access, defined by STMT,
- if it is aready in hashtable of function accesses F_ACCS. */
+ if it is already in hashtable of function accesses F_ACCS. */
static struct field_access_site *
is_in_field_accs (tree stmt, htab_t f_accs)
return 1;
}
-/* This funciton updates statements in STMT_LIST with BB info. */
+/* This function updates statements in STMT_LIST with BB info. */
static void
add_bb_info (basic_block bb, tree stmt_list)
htab_hash_pointer (decl));
}
-/* Given original varaiable ORIG_VAR, this function returns
+/* Given original variable ORIG_VAR, this function returns
new variable corresponding to it of NEW_TYPE type. */
static tree
tree ref = r_pos->ref;
tree t = *tp;
- if (t == ref)
+ if (t == ref || (TREE_CODE (t) == SSA_NAME && SSA_NAME_VAR (t) == ref))
{
r_pos->pos = tp;
return t;
case ENUMERAL_TYPE:
{
tree field1;
- /* Compare fields of struture. */
+ /* Compare fields of structure. */
for (field1 = TYPE_FIELDS (type1); field1;
field1 = TREE_CHAIN (field1))
{
/* This function returns a tree representing
the number of instances of structure STR_DECL allocated
- by allocation STMT. If new statments are generated,
+ by allocation STMT. If new statements are generated,
they are filled into NEW_STMTS_P. */
static tree
appropriate new name for the new variable. */
old_name = IDENTIFIER_POINTER (DECL_NAME (orig_decl));
- prefix = alloca (strlen (old_name) + 1);
+ prefix = XALLOCAVEC (char, strlen (old_name) + 1);
strcpy (prefix, old_name);
ASM_FORMAT_PRIVATE_NAME (new_name, prefix, i);
return get_identifier (new_name);
return 1;
}
-/* This function frees memory allocated for strcuture clusters,
+/* This function frees memory allocated for structure clusters,
starting from CLUSTER. */
static void
htab_traverse (accs, dump_acc, NULL);
}
+/* This function is a callback for alloc_sites hashtable
+ traversal. SLOT is a pointer to fallocs_t. This function
+ removes all allocations of the structure defined by DATA. */
+
+static int
+remove_str_allocs_in_func (void **slot, void *data)
+{
+ fallocs_t fallocs = *(fallocs_t *) slot;
+ unsigned i = 0;
+ alloc_site_t *call;
+
+ while (VEC_iterate (alloc_site_t, fallocs->allocs, i, call))
+ {
+ if (call->str == (d_str) data)
+ VEC_ordered_remove (alloc_site_t, fallocs->allocs, i);
+ else
+ i++;
+ }
+
+ return 1;
+}
+
+/* This function remove all entries corresponding to the STR structure
+ from alloc_sites hashtable. */
+
+static void
+remove_str_allocs (d_str str)
+{
+ if (!str)
+ return;
+
+ if (alloc_sites)
+ htab_traverse (alloc_sites, remove_str_allocs_in_func, str);
+}
+
/* This function removes the structure with index I from structures vector. */
static void
if (i >= VEC_length (structure, structures))
return;
- str = VEC_index (structure, structures, i);
+ str = VEC_index (structure, structures, i);
+
+ /* Before removing the structure str, we have to remove its
+ allocations from alloc_sites hashtable. */
+ remove_str_allocs (str);
free_data_struct (str);
VEC_ordered_remove (structure, structures, i);
}
/* Currently we support only EQ_EXPR or NE_EXPR conditions.
- COND_STNT is a condition statement to check. */
+ COND_STMT is a condition statement to check. */
static bool
is_safe_cond_expr (tree cond_stmt)
ASM_FORMAT_PRIVATE_NAME(tmp_name, "struct", str_num);
len = strlen (tmp_name ? tmp_name : orig_name) + strlen ("_sub");
- prefix = alloca (len + 1);
+ prefix = XALLOCAVEC (char, len + 1);
memcpy (prefix, tmp_name ? tmp_name : orig_name,
strlen (tmp_name ? tmp_name : orig_name));
strcpy (prefix + strlen (tmp_name ? tmp_name : orig_name), "_sub");
}
/* This function adds to UNSUITABLE_TYPES those types that escape
- due to results of ipa-type-escpae analysis. See ipa-type-escpae.[c,h]. */
+ due to results of ipa-type-escape analysis. See ipa-type-escape.[c,h]. */
static void
exclude_escaping_types_1 (VEC (tree, heap) **unsuitable_types)
htab_traverse (dt.str->accs, exclude_from_accs, &dt);
}
-/* Collect accesses to the structure types that apear in basic bloack BB. */
+/* Collect accesses to the structure types that appear in basic block BB. */
static void
collect_accesses_in_bb (basic_block bb)
}
}
-/* This function generates cluster substructure that cointains FIELDS.
- The cluster added to the set of clusters of the structure SRT. */
+/* This function generates cluster substructure that contains FIELDS.
+ The cluster added to the set of clusters of the structure STR. */
static void
gen_cluster (sbitmap fields, d_str str)
add_structure (type);
/* Check function local variables. */
- for (var_list = fn->unexpanded_var_list; var_list;
+ for (var_list = fn->local_decls; var_list;
var_list = TREE_CHAIN (var_list))
{
var = TREE_VALUE (var_list);
/* This function summarizes counts of the fields into the structure count. */
static void
-sum_counts (d_str str, gcov_type *hotest)
+sum_counts (d_str str, gcov_type *hottest)
{
int i;
fprintf (dump_file, "\" is " HOST_WIDEST_INT_PRINT_DEC, str->count);
}
- if (str->count > *hotest)
- *hotest = str->count;
+ if (str->count > *hottest)
+ *hottest = str->count;
}
/* This function peels the field into separate structure if it's
}
set_cfun (NULL);
+ bitmap_obstack_release (NULL);
}
/* This function creates new global struct variables.
static void
exclude_cold_structs (void)
{
- gcov_type hotest = 0;
+ gcov_type hottest = 0;
unsigned i;
d_str str;
/* We summarize counts of fields of a structure into the structure count. */
for (i = 0; VEC_iterate (structure, structures, i, str); i++)
- sum_counts (str, &hotest);
+ sum_counts (str, &hottest);
/* Remove cold structures from structures vector. */
i = 0;
while (VEC_iterate (structure, structures, i, str))
- if (str->count * 100 < (hotest * STRUCT_REORG_COLD_STRUCT_RATIO))
+ if (str->count * 100 < (hottest * STRUCT_REORG_COLD_STRUCT_RATIO))
{
if (dump_file)
{
&& (optimize > 0);
}
-struct tree_opt_pass pass_ipa_struct_reorg =
+struct simple_ipa_opt_pass pass_ipa_struct_reorg =
{
+ {
+ SIMPLE_IPA_PASS,
"ipa_struct_reorg", /* name */
struct_reorg_gate, /* gate */
reorg_structs_drive, /* execute */
0, /* properties_provided */
0, /* properties_destroyed */
TODO_verify_ssa, /* todo_flags_start */
- TODO_dump_func | TODO_verify_ssa, /* todo_flags_finish */
- 0 /* letter */
+ TODO_dump_func | TODO_verify_ssa /* todo_flags_finish */
+ }
};