summaryrefslogtreecommitdiff
path: root/gcc/ipa-str-reorg-dead-field-eliminate.c
diff options
context:
space:
mode:
authorErick Ochoa <erick.ochoa@theobroma-systems.com>2020-02-20 18:08:53 +0100
committerErick Ochoa <erick.ochoa@theobroma-systems.com>2020-05-14 14:45:35 +0200
commite04979eb0ccd73f8d4ce86494bec3b2630cad7bf (patch)
tree38d80916790fa6a2364d9e2bdbe6cefed8202bfa /gcc/ipa-str-reorg-dead-field-eliminate.c
parent1167d523151f4463c19be24508bcc4f575631750 (diff)
Refactoring
Diffstat (limited to 'gcc/ipa-str-reorg-dead-field-eliminate.c')
-rw-r--r--gcc/ipa-str-reorg-dead-field-eliminate.c188
1 files changed, 60 insertions, 128 deletions
diff --git a/gcc/ipa-str-reorg-dead-field-eliminate.c b/gcc/ipa-str-reorg-dead-field-eliminate.c
index 874a542171f..0d0fef8c26e 100644
--- a/gcc/ipa-str-reorg-dead-field-eliminate.c
+++ b/gcc/ipa-str-reorg-dead-field-eliminate.c
@@ -1575,14 +1575,14 @@ rewrite_mem_ref_def(tree expr, hash_map<const_tree, const_tree> &type_map, const
int old_offset = tree_to_uhwi(op1);
if (old_offset == 0 || !new_type_ptr) return retval;
- // We are optizing and we might have op1_size != 0
- // TODO: FIXME:
- // Can we get another type to get the old size?
- // I don't like this hack where if the type is an array we have 8
tree old_struct_size = TYPE_SIZE_UNIT(type);
- int old_type_size_int = TREE_CODE(type) == ARRAY_TYPE ? 8 : tree_to_shwi(old_struct_size);
+ int old_type_size_int = tree_to_shwi(old_struct_size);
+ test_log("old_type = %s", 0, get_type_name(type));
+ test_log("old_type_size = %d", 0, tree_to_shwi(old_struct_size));
tree new_struct_size = TYPE_SIZE_UNIT((tree)*new_type_ptr);
- int new_type_size_int = TREE_CODE(type) == ARRAY_TYPE ? 8 : tree_to_shwi(new_struct_size);
+ int new_type_size_int = tree_to_shwi(new_struct_size);
+ test_log("new_type = %s", 0, get_type_name((tree)*new_type_ptr));
+ test_log("new_type_size = %d", 0, tree_to_shwi(new_struct_size));
int multiple = old_offset / old_type_size_int;
int offset = multiple * new_type_size_int;
int remainder = old_offset % old_type_size_int;
@@ -1597,7 +1597,6 @@ rewrite_mem_ref_def(tree expr, hash_map<const_tree, const_tree> &type_map, const
tree new_offset_tree = build_int_cst(TREE_TYPE(op1), new_offset);
TREE_OPERAND(expr, 1) = new_offset_tree;
- test_log("2020-02-18 old_offset = %d, old_type_size_int = %d, new_offset = %d", 0, old_offset, old_type_size_int, new_offset);
gcc_assert(old_offset % old_type_size_int == 0);
// TREE_OPERAND(expr, 2) cannot be accessed.
@@ -1696,7 +1695,7 @@ rewrite_array_ref_def(tree expr, hash_map<const_tree, const_tree> &type_map, con
return true;
}
-static tree
+static void
rewrite_pointer_diff_def_rhs_variable_replace_constants_implementation
(gimple_stmt_iterator &gsi, tree lhs, tree pointer, tree variable, const_tree old_type)
{
@@ -1741,7 +1740,6 @@ rewrite_pointer_diff_def_rhs_variable_replace_constants_implementation
tree new_struct_size_const = build_int_cst(TREE_TYPE(divisor), new_struct_size_int);
gimple_set_op(stmt, 2, new_struct_size_const);
}
- return NULL;
}
static tree
@@ -1779,7 +1777,10 @@ rewrite_pointer_plus_def_rhs_variable_replace_constants_implementation
const_tree old_base_type = TREE_TYPE(old_type);
tree old_struct_size_tree_1 = TYPE_SIZE_UNIT(old_base_type);
int old_struct_size_int = tree_to_shwi(old_struct_size_tree_1);
- const_tree unit_type = TREE_TYPE(TREE_TYPE(lhs));
+ const_tree pointer_to_unit_type = TREE_TYPE(lhs);
+ tree new_struct_pointer_tree = TYPE_SIZE_UNIT(pointer_to_unit_type);
+ int new_struct_pointer_int = tree_to_shwi(new_struct_pointer_tree);
+ const_tree unit_type = TREE_TYPE(pointer_to_unit_type);
tree new_struct_size_tree_1 = TYPE_SIZE_UNIT(unit_type);
int new_struct_size_int = tree_to_shwi(new_struct_size_tree_1);
@@ -1801,26 +1802,55 @@ rewrite_pointer_plus_def_rhs_variable_replace_constants_implementation
// and where that field maps to the new struct...
// gcc_assert(is_modulo);
- int field_accessed_offset = 0;
- bool is_modulo = old_unit_size_one_plus % old_struct_size_int == 0;
- if (!is_modulo) {
- // TODO: I believe that all field_accessed will be modulo.
- // The only time I have encountered where it is not modulo,
- // is when we use profile information from a previous run
- // that has been modified...
- // I want an assertion that says
- // if (-fprofile-generate) assert(is_modulo)
- // if (-fprofile-use) skip
- int field_accessed = old_unit_size_one_plus % old_struct_size_int;
- test_log("offset_accessed = %d type_name = %s", 0, field_accessed, get_type_name(old_base_type));
- const_tree field_accessed_tree = get_field_with_offset_unsafe(old_base_type, field_accessed);
- const char* field_accessed_name = field_accessed_tree ? get_field_name(field_accessed_tree) : "NONE";
- const_tree new_field_accessed = field_accessed_tree ? get_field_with_name(unit_type, field_accessed_name) : NULL;
- field_accessed_offset = field_accessed_tree ? get_field_offset(new_field_accessed) : field_accessed;
+ bool is_modulo_old = old_unit_size_one_plus % old_struct_size_int == 0;
+ bool is_modulo_new = old_unit_size_one_plus % new_struct_size_int == 0;
+ // If we are not in flag_profile_use
+ // we will always be a modulo
+ if (!flag_profile_use) gcc_assert(is_modulo_old);
+
+ test_log("old plus constant = %d", 0, old_unit_size_one_plus);
+ test_log("old struct size int = %d", 0, old_struct_size_int);
+ test_log("new struct size int = %d", 0, new_struct_size_int);
+ test_log("old_unit_size_one_plus modulo new_struct_pointer_int = %d", 0, old_unit_size_one_plus % new_struct_size_int);
+
+ //FIXME:
+ //The problem is that if flag_profile_use is enabled,
+ //then we can potentially **predict** the offset
+ //to be the correct one. But not always?
+ //Therefore, we really do not have an idea if we are using
+ //a value obtained from profiling or one from "correctness".
+ if (flag_profile_use) {
+ bool is_from_profiling = is_modulo_new;
+ bool is_from_correctness = is_modulo_old;
+ gcc_assert(is_from_correctness || is_from_profiling);
}
+ int field_accessed_offset = old_unit_size_one_plus % old_struct_size_int;
+
+ if (flag_profile_use && is_modulo_new) gcc_assert(field_accessed_offset != 0);
+ /*
+ int field_accessed_offset = 0;
+ bool is_modulo = old_unit_size_one_plus % old_struct_size_int == 0;
+ if (!is_modulo) {
+ // TODO: I believe that all field_accessed will be modulo.
+ // The only time I have encountered where it is not modulo,
+ // is when we use profile information from a previous run
+ // that has been modified...
+ // I want an assertion that sa
+ int field_accessed = old_unit_size_one_plus % old_struct_size_int;
+ test_log("offset_accessed = %d type_name = %s", 0, field_accessed, get_type_name(old_base_type));
+ const_tree field_accessed_tree = get_field_with_offset_unsafe(old_base_type, field_accessed);
+ const char* field_accessed_name = field_accessed_tree ? get_field_name(field_accessed_tree) : "NONE";
+ const_tree new_field_accessed = field_accessed_tree ? get_field_with_name(unit_type, field_accessed_name) : NULL;
+ field_accessed_offset = field_accessed_tree ? get_field_offset(new_field_accessed) : field_accessed;
+ }
+
+ */
int new_plus_constant_int = old_unit_size_one_plus / old_struct_size_int * new_struct_size_int + field_accessed_offset;
+
+ //if (flag_profile_use && is_modulo_new) gcc_assert(field_accessed_offset % new_struct_size_int == 0);
+
tree new_plus_constant = build_int_cst(TREE_TYPE(constant_plus), new_plus_constant_int);
gimple_set_op(to_change, 2, new_plus_constant);
@@ -2114,40 +2144,11 @@ rewrite_pointer_diff_def_rhs(gimple *stmt, gimple_stmt_iterator &gsi, tree lhs,
bool has_integer_constant = (TREE_CODE(integer_constant) == INTEGER_CST);
// I want to know if this is an invariant.
- if (has_integer_constant) gcc_assert(TREE_CODE(op1) == INTEGER_CST);
+ if (has_integer_constant) gcc_unreachable();
- switch(has_integer_constant)
- {
- case true:
- {
- // TODO: FIXME FOR NOW.
- gcc_unreachable();
- tree pointer = is_op1_int_cst ? op0 : op1;
- tree pointer_type = TREE_TYPE(pointer);
- tree new_constant = rewrite_pointer_plus_def_rhs_integer_constant(pointer, integer_constant, old_type);
- unsigned int operand = is_op1_int_cst ? 2 : 1;
- gimple_set_op(stmt, operand, new_constant);
- }
- break;
- case false:
- {
- // I want to know if this is an invariant.
- tree op0_type = TREE_TYPE(op0);
- gcc_assert(TREE_CODE(op0_type) == POINTER_TYPE);
- tree new_variable = rewrite_pointer_diff_def_rhs_variable_replace_constants_implementation(gsi, lhs, op0, op1, old_type);
- if (!new_variable) return false;
- // We need to set the operand of the next statement...
- // we need the stmt where we are now.
- gsi_next(&gsi);
- gimple *curr_stmt = gsi_stmt(gsi);
- gimple_set_op(curr_stmt, 1, new_variable);
- gsi_prev(&gsi);
- }
- break;
- default:
- gcc_unreachable();
- break;
- }
+ // I want to know if this is an invariant.
+ gcc_assert(TREE_CODE(op0_type) == POINTER_TYPE);
+ rewrite_pointer_diff_def_rhs_variable_replace_constants_implementation(gsi, lhs, op0, op1, old_type);
return true;
}
@@ -2235,7 +2236,6 @@ rewrite_call_lhs(gimple *stmt, gimple_stmt_iterator &gsi, hash_map<const_tree, c
//LHS can be null. Example `foo()`
if (!lhs) return;
- //TODO: is there anything else I need to do?
rewrite_expr(lhs, type_map, 0);
}
@@ -2243,34 +2243,19 @@ static void
rewrite_call_rhs(gimple *stmt, gimple_stmt_iterator &gsi, hash_map<const_tree, const_tree> &type_map, hash_map<const_tree, const_tree> &inverse)
{
gcc_assert(stmt);
- // PRETTY SURE YOU MUST HAVE A FUNCTION
- // TO CALL
tree fn = gimple_call_fn (stmt);
gcc_assert(fn);
gcall *call = dyn_cast<gcall*>(stmt);
tree return_type = gimple_call_return_type(call);
test_log("what is the return type %s", 0, get_type_name(return_type));
- //TODO: What happens with void?
gcc_assert(return_type);
- // We need to modify the types of the variables that are passed here...
unsigned args = gimple_call_num_args(stmt);
for (unsigned i = 0; i < args; i++)
{
tree arg = gimple_call_arg(stmt, i);
rewrite_expr(arg, type_map, 0);
}
-
- /*
- * This is not the way to do it.
- TREE_TYPE(fn) = (tree) *new_type;
- gcall *call_new = dyn_cast<gcall*>(stmt);
- tree return_type_new = gimple_call_return_type(call);
- test_log("after what is the return type %s", 0, get_type_name(return_type_new));
- */
-
-
-
}
static void
@@ -2406,8 +2391,6 @@ rewrite_local_decl(tree var_decl, hash_map<const_tree, const_tree> &type_map)
const_tree new_type = *new_type_ptr;
gcc_assert(new_type);
- //FIXME: We know these are record types
- //make more general later.
const char* identifier_old = get_type_name(type);
const char* identifier_new = get_type_name(new_type);
test_write("rewriting,local_decl");
@@ -2480,7 +2463,6 @@ rewrite_function_return_type(tree expr, hash_map<const_tree, const_tree> &type_m
// TODO: We do not support method's yet.
gcc_assert(TREE_CODE(function_type) == FUNCTION_TYPE);
tree function_return_type = TREE_TYPE(function_type);
- //TODO: What happens with void return
gcc_assert(function_return_type);
test_log("before rewrite_function_return_type %s", indent, get_type_name(function_return_type));
@@ -2516,16 +2498,6 @@ rewrite_global_decl(varpool_node *vnode, hash_map<const_tree, const_tree> &type_
symtab_node *f_node = ref->referring;
cgraph_node *f_cnode = dyn_cast<cgraph_node *> (f_node);
- // TODO: place assertion for interesting ones
- // interesting types MUST have functions?
- /*
- if (!f_cnode)
- {
- if (dump_file) fprintf (dump_file, "skipping variable %s due to static initialization\n", vnode->name ());
- return;
- }
- */
-
test_log("rewriting global declaration", 0);
rewrite_local_decl(vnode->decl, type_map);
test_print_generic_decl(vnode->decl);
@@ -2589,8 +2561,6 @@ rewrite_references_to_modified_structs_internal(const_tree const &old_type,
static void
rewrite_references_to_modified_structs(hash_map<const_tree, const_tree> &type_map, hash_map<const_tree, const_tree> &inverse)
{
- //FIXME: You'll need to iterate over more than just
- //defined functions.
type_map.traverse<void*, rewrite_references_to_modified_structs_internal>(NULL);
rewrite_functions(type_map, inverse);
rewrite_global_decls(type_map);
@@ -2643,41 +2613,3 @@ str_reorg_dead_field_eliminate( Info *info)
return iphw_execute();
}
-typedef vec<struct ipa_ref *> ipa_ref_vec;
-
-static bool
-ipa_initcall_get_writes_and_reads (varpool_node *vnode, ipa_ref_vec *writes, ipa_ref_vec *reads)
-{
- int i;
- struct ipa_ref *ref;
-
- if (dump_file) fprintf (dump_file, "%s for variable '%s'.\n", __func__, vnode->name ());
- /* Only IPA_REF_STORE and IPA_REF_LOAD left. */
- for (i = 0; vnode->iterate_referring (i, ref); i++)
- {
- symtab_node *f_node = ref->referring;
- cgraph_node *f_cnode = dyn_cast<cgraph_node *> (f_node);
-
- /*
- if (!f_cnode)
- {
- if (dump_file) fprintf (dump_file, "skipping variable %s due to static initialization\n", vnode->name ());
- return false;
- }
- */
- // it is possible that f_cnode is NULL if the dyn_cast fails.
- // If the dyn_cast fails, this is an example of static initialization.
- //const char *identifier = IDENTIFIER_POINTER (DECL_NAME (f_cnode->decl));
- // This is the suffix we are adding to our clones.
- // Therefore, if we find the suffix in the identifier,
- // that means that we found a variable in a clone and
- // we would like to skip it.
- // TODO: make this a global static for easier changes...
- const char *suffix = "test.0";
- //if (strstr (identifier, suffix) != NULL) continue;
-
- if (ref->use == IPA_REF_STORE) writes->safe_push (ref);
- if (ref->use == IPA_REF_LOAD) reads->safe_push (ref);
- }
- return true;
-}