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;
add_referenced_var (*res);
if (exact_log2 (struct_size_int) == -1)
- new_stmt = build_gimple_modify_stmt (num, struct_size);
+ {
+ tree size = build_int_cst (TREE_TYPE (num), struct_size_int);
+ new_stmt = build_gimple_modify_stmt (*res, build2 (MULT_EXPR,
+ TREE_TYPE (num),
+ num, size));
+ }
else
{
tree C = build_int_cst (TREE_TYPE (num), exact_log2 (struct_size_int));
tree new_acc;
tree field_id = DECL_NAME (acc->field_decl);
VEC (type_wrapper_t, heap) *wrapper = VEC_alloc (type_wrapper_t, heap, 10);
- type_wrapper_t wr;
type_wrapper_t *wr_p = NULL;
while (TREE_CODE (ref_var) == INDIRECT_REF
|| TREE_CODE (ref_var) == ARRAY_REF)
{
+ type_wrapper_t wr;
+
if ( TREE_CODE (ref_var) == INDIRECT_REF)
{
wr.wrap = 0;
wr.domain = 0;
}
- else if (TREE_CODE (ref_var) == ARRAY_REF)
+ else
{
wr.wrap = 1;
wr.domain = TREE_OPERAND (ref_var, 1);
s0 = (str0 != length) ? true : false;
s1 = (str1 != length) ? true : false;
- gcc_assert ((!s0 && s1) || (!s1 && s0));
+ gcc_assert (s0 || s1);
+ /* For now we allow only comparison with 0 or NULL. */
+ gcc_assert (integer_zerop (arg0) || integer_zerop (arg1));
- str = s0 ? VEC_index (structure, structures, str0):
- VEC_index (structure, structures, str1);
- arg = s0 ? arg0 : arg1;
- pos = s0 ? 0 : 1;
+ str = integer_zerop (arg0) ?
+ VEC_index (structure, structures, str1):
+ VEC_index (structure, structures, str0);
+ arg = integer_zerop (arg0) ? arg1 : arg0;
+ pos = integer_zerop (arg0) ? 1 : 0;
for (i = 0; VEC_iterate (tree, str->new_types, i, type); i++)
{
append_to_statement_list (new_stmt, new_stmts);
/* Generate new call for malloc. */
- malloc_res = create_tmp_var (integer_type_node, NULL);
+ malloc_res = create_tmp_var (ptr_type_node, NULL);
if (malloc_res)
add_referenced_var (malloc_res);
else
{
if (initialized && unsuitable_types && *unsuitable_types)
- add_unsuitable_type (unsuitable_types, type);
+ {
+ if (dump_file)
+ {
+ fprintf (dump_file, "The type ");
+ print_generic_expr (dump_file, type, 0);
+ fprintf (dump_file, " is initialized...Excluded.");
+ }
+ add_unsuitable_type (unsuitable_types, type);
+ }
*type_p = type;
return true;
}
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);
}
s0 = (str0 != length) ? true : false;
s1 = (str1 != length) ? true : false;
+
+ if (!s0 && !s1)
+ return false;
- if (!((!s0 && s1) || (!s1 && s0)))
+ /* For now we allow only comparison with 0 or NULL. */
+ if (!integer_zerop (arg0) && !integer_zerop (arg1))
return false;
return true;
unsigned i = find_structure (type);
if (i != VEC_length (structure, structures))
- remove_structure (i);
+ {
+ if (dump_file)
+ {
+ fprintf (dump_file, "\nThe type ");
+ print_generic_expr (dump_file, type, 0);
+ fprintf (dump_file, " has bitfield.");
+ }
+ remove_structure (i);
+ }
}
break;
we can deal with. */
if (!decompose_access (str->decl, acc))
{
+ if (dump_file)
+ {
+ fprintf (dump_file, "\nThe type ");
+ print_generic_expr (dump_file, type, 0);
+ fprintf (dump_file,
+ " has complicate access in statement ");
+ print_generic_stmt (dump_file, stmt, 0);
+ }
+
remove_structure (i);
free (acc);
}
}
/* This function checks whether an access statement, pointed by SLOT,
- is a condition we are capable to transform. If not, it removes
- the structure with index, represented by DATA, from the vector
- of structures. */
+ is a condition we are capable to transform. It returns false if not,
+ setting bool *DATA to false. */
static int
safe_cond_expr_check (void **slot, void *data)
{
struct access_site *acc = *(struct access_site **) slot;
- if (TREE_CODE (acc->stmt) == COND_EXPR)
+ if (TREE_CODE (acc->stmt) == COND_EXPR
+ && !is_safe_cond_expr (acc->stmt))
{
- if (!is_safe_cond_expr (acc->stmt))
- remove_structure (*(unsigned *) data);
+ if (dump_file)
+ {
+ fprintf (dump_file, "\nUnsafe conditional statement ");
+ print_generic_stmt (dump_file, acc->stmt, 0);
+ }
+ *(bool *) data = false;
+ return 0;
}
return 1;
}
add_alloc_site (node->decl, stmt, str);
}
else
- remove_structure (i);
+ {
+ if (dump_file)
+ {
+ fprintf (dump_file,
+ "\nUnsupported allocation function ");
+ print_generic_stmt (dump_file, stmt, 0);
+ }
+ remove_structure (i);
+ }
}
}
}
d_str str;
unsigned i;
- for (i = 0; VEC_iterate (structure, structures, i, str); i++)
- if (str->accs)
- htab_traverse (str->accs, safe_cond_expr_check, &i);
+ i = 0;
+ while (VEC_iterate (structure, structures, i, str))
+ {
+ bool safe_p = true;
+
+ if (str->accs)
+ htab_traverse (str->accs, safe_cond_expr_check, &safe_p);
+ if (!safe_p)
+ remove_structure (i);
+ else
+ i++;
+ }
}
/* We exclude from non-field accesses of the structure
/* 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, "\nCounter of field \"");
print_generic_expr (dump_file, str->fields[i].decl, 0);
- fprintf (dump_file, "\" is " HOST_WIDE_INT_PRINT_DEC,
+ fprintf (dump_file, "\" is " HOST_WIDEST_INT_PRINT_DEC,
str->fields[i].count);
}
str->count += str->fields[i].count;
{
fprintf (dump_file, "\nCounter of struct \"");
print_generic_expr (dump_file, str->decl, 0);
- fprintf (dump_file, "\" is " HOST_WIDE_INT_PRINT_DEC, str->count);
+ 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
pop_cfun ();
}
- cfun = NULL;
+ set_cfun (NULL);
}
/* This function creates new global struct variables.
" this optimization:\n");
for (i = 0; VEC_iterate (structure, structures, i, str); i++)
- for (j = 0; VEC_iterate (tree, str->new_types, j, type); j++)
- dump_struct_type (type, 2, 0);
+ {
+ if (dump_file)
+ {
+ fprintf (dump_file, "\nFor type ");
+ dump_struct_type (str->decl, 2, 0);
+ fprintf (dump_file, "\nthe number of new types is %d\n",
+ VEC_length (tree, str->new_types));
+ }
+ for (j = 0; VEC_iterate (tree, str->new_types, j, type); j++)
+ dump_struct_type (type, 2, 0);
+ }
}
/* This function creates new types to replace old structure types. */
remove_unsuitable_types (unsuitable_types);
VEC_free (tree, heap, unsuitable_types);
-
- if (!VEC_length (structure, structures))
- {
- if (dump_file)
- fprintf (dump_file, "\nNo structures to transform. Exiting...");
- return;
- }
}
/* Collect structure allocation sites. In case of arrays
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. */
- for (i = 0; VEC_iterate (structure, structures, i, str); i++)
- if (str->count * 100 < (hotest * STRUCT_REORG_COLD_STRUCT_RATIO))
- remove_structure (i);
+ i = 0;
+ while (VEC_iterate (structure, structures, i, str))
+ if (str->count * 100 < (hottest * STRUCT_REORG_COLD_STRUCT_RATIO))
+ {
+ if (dump_file)
+ {
+ fprintf (dump_file, "\nThe structure ");
+ print_generic_expr (dump_file, str->decl, 0);
+ fprintf (dump_file, " is cold.");
+ }
+ remove_structure (i);
+ }
+ else
+ i++;
}
/* This function decomposes original structure into substructures,
{
/* Check that there is a work to do. */
if (!VEC_length (structure, structures))
- return;
+ {
+ if (dump_file)
+ fprintf (dump_file, "\nNo structures to transform. Exiting...");
+ return;
+ }
+ else
+ {
+ if (dump_file)
+ {
+ fprintf (dump_file, "\nNumber of structures to transform is %d",
+ VEC_length (structure, structures));
+ }
+ }
/* Generate new types. */
create_new_types ();