diff options
author | Erick Ochoa <erick.ochoa@theobroma-systems.com> | 2020-02-20 18:08:53 +0100 |
---|---|---|
committer | Erick Ochoa <erick.ochoa@theobroma-systems.com> | 2020-05-14 14:45:35 +0200 |
commit | e04979eb0ccd73f8d4ce86494bec3b2630cad7bf (patch) | |
tree | 38d80916790fa6a2364d9e2bdbe6cefed8202bfa /gcc/ipa-str-reorg-dead-field-eliminate.c | |
parent | 1167d523151f4463c19be24508bcc4f575631750 (diff) |
Refactoring
Diffstat (limited to 'gcc/ipa-str-reorg-dead-field-eliminate.c')
-rw-r--r-- | gcc/ipa-str-reorg-dead-field-eliminate.c | 188 |
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; -} |