diff options
author | Erick Ochoa <erick.ochoa@theobroma-systems.com> | 2020-02-13 22:55:33 +0100 |
---|---|---|
committer | Erick Ochoa <erick.ochoa@theobroma-systems.com> | 2020-05-14 14:45:33 +0200 |
commit | 2a6fe0cc583289e1692c222d4e973d856251ef2c (patch) | |
tree | b8e00781afe26afa912253d4a83ef86a82097167 /gcc/ipa-str-reorg-dead-field-eliminate.c | |
parent | 002f50a6a4b5077e76591bc02e4125217defb626 (diff) |
wip
Diffstat (limited to 'gcc/ipa-str-reorg-dead-field-eliminate.c')
-rw-r--r-- | gcc/ipa-str-reorg-dead-field-eliminate.c | 181 |
1 files changed, 173 insertions, 8 deletions
diff --git a/gcc/ipa-str-reorg-dead-field-eliminate.c b/gcc/ipa-str-reorg-dead-field-eliminate.c index 2b25400846c..5e589f70875 100644 --- a/gcc/ipa-str-reorg-dead-field-eliminate.c +++ b/gcc/ipa-str-reorg-dead-field-eliminate.c @@ -278,6 +278,24 @@ make_pointer_name(const_tree pointer) } static const char* +make_reference_name(const_tree ref) +{ + test_log("making reference name", 0); + gcc_assert(TREE_CODE(ref) == REFERENCE_TYPE); + const_tree base_type = TREE_TYPE(ref); + const char* old_name = get_type_name(base_type); + char *ptr; + static const char* prefix = "&"; + static const char *suffix = ".reorg"; + int new_size = strlen(prefix) + strlen(old_name) + strlen(suffix); + int retval = asprintf(&ptr, "%s%s%s", prefix, old_name, suffix); + gcc_assert(retval == new_size); + test_log("here %s", 0, ptr); + return ptr; +} + + +static const char* make_array_name(const_tree array) { gcc_assert(TREE_CODE(array) == ARRAY_TYPE); @@ -703,6 +721,18 @@ get_pointer_name(const_tree pointer) } static const char* +get_reference_name(const_tree ref) +{ + gcc_assert(ref); + gcc_assert(TREE_CODE(ref) == REFERENCE_TYPE); + const bool is_modified = TYPE_NAME(ref); + if (is_modified) return IDENTIFIER_POINTER(TYPE_NAME(ref)); + + const char* new_pointer_name = make_reference_name(ref); + return new_pointer_name; +} + +static const char* get_type_name(const_tree type) { enum tree_code code = TREE_CODE(type); @@ -717,6 +747,9 @@ get_type_name(const_tree type) case RECORD_TYPE: return get_record_name(type); break; + case REFERENCE_TYPE: + return get_reference_name(type); + break; default: //TODO: generalize even more? //wait for experimental results to dictate what @@ -813,6 +846,18 @@ filter_out_boring_array(const_tree array, hash_map<const_tree, tree>&map) } static bool +filter_out_boring_reference(const_tree ref, hash_map<const_tree, tree>&map) +{ + enum tree_code code = TREE_CODE(ref); + gcc_assert(code == REFERENCE_TYPE); + test_log("in filter out boring reference", 0); + bool retval = filter_out_boring_type(TREE_TYPE(ref), map); + if (retval) { test_log("we are getting a reference", 0); } + return retval; +} + + +static bool filter_out_boring_type(const_tree type, hash_map<const_tree, tree> &map) { if (!type) { @@ -844,6 +889,9 @@ filter_out_boring_type(const_tree type, hash_map<const_tree, tree> &map) case RECORD_TYPE: retval = filter_out_boring_record(type, map); break; + case REFERENCE_TYPE: + retval = filter_out_boring_reference(type, map); + break; default: { test_log("default in tree code %s", 0, get_tree_code_name(code)); @@ -877,6 +925,40 @@ filter_parm_decls(tree parm_decl, hash_map<const_tree, tree>& type_map) return filter_out_boring_type(type, type_map); } +static bool +filter_ssa_decls(tree ssa, hash_map<const_tree, tree>& type_map) +{ + tree type = TREE_TYPE(ssa); + test_log("in SSA decl %s", 0, get_type_name(type)); + return filter_out_boring_type(type, type_map); +} + +static bool +collect_ssa_decls(cgraph_node *cnode, bool (*filter)(tree, hash_map<const_tree, tree>&), hash_map<const_tree, tree>& decl_map) +{ + unsigned i; + tree name; + push_cfun(DECL_STRUCT_FUNCTION(cnode->decl)); + cnode->get_untransformed_body(); + if (!cnode->decl) return false; + FOR_EACH_SSA_NAME (i, name, cfun) + { + bool filter_out = (*filter)(name, decl_map); + if (filter_out) continue; + + tree type = TREE_TYPE(name); + tree *ptr = decl_map.get(type); + if (ptr) continue; + + const char* type_identifier = get_type_name(type); + test_log("collecting,%s", 0, type_identifier); + decl_map.put(type, NULL); + } + pop_cfun(); + return false; + +} + static void collect_parm_declarations(cgraph_node *cnode, bool (*filter)(tree, hash_map<const_tree, tree>&), hash_map<const_tree, tree> &decl_map) { @@ -898,6 +980,40 @@ collect_parm_declarations(cgraph_node *cnode, bool (*filter)(tree, hash_map<cons } } +static void +collect_stmt(gimple*stmt, bool(*filter)(tree, hash_map<const_tree, tree>&), hash_map<const_tree, tree> &decl_map) +{ + //TODO... + gcc_unreachable(); +} + +static void +collect_basic_block(basic_block bb, bool(*filter)(tree, hash_map<const_tree, tree>&), hash_map<const_tree, tree> &decl_map) +{ + gcc_assert(bb); + for (gimple_stmt_iterator gsi = gsi_start_bb(bb); !gsi_end_p(gsi); gsi_next(&gsi)) + { + gimple *stmt = gsi_stmt(gsi); + collect_stmt(stmt, filter, decl_map); + } +} + +static void +collect_function_body(cgraph_node *cnode, bool(*filter)(tree, hash_map<const_tree, tree>&), hash_map<const_tree, tree> &decl_map) +{ + gcc_assert(cnode); + cnode->get_untransformed_body(); + basic_block bb = NULL; + function *func = DECL_STRUCT_FUNCTION (cnode->decl); + push_cfun(func); + FOR_EACH_BB_FN (bb, func) + { + collect_basic_block(bb, filter, decl_map); + } + pop_cfun(); + print_function(cnode); +} + //TODO: It would be nice to have this as an iterator //TODO: Maybe after the filter, there should be //a function that takes a type and gets you @@ -975,6 +1091,7 @@ collect_orig_structs(hash_map<const_tree, tree> &type_map) { print_function(cnode); collect_parm_declarations(cnode, &filter_parm_decls, type_map); + //collect_function_body(cnode, &filter_ssa_decls, type_map); collect_local_declarations(cnode, &filter_var_decls, type_map); } } @@ -1128,6 +1245,13 @@ make_new_pointer_based_on_old(const_tree old, } +static const_tree +make_new_reference_based_on_old(const_tree old, + hash_map<const_tree, const_tree>* mod_type_map) +{ + gcc_unreachable(); +} + //TODO: //This needs a new parameter that allows //us to say **how** we modify the type. @@ -1157,6 +1281,9 @@ make_new_type_based_on_old(const_tree old, case RECORD_TYPE: return make_new_record_based_on_old(old, mod_type_map); break; + case REFERENCE_TYPE: + return make_new_reference_based_on_old(old, mod_type_map); + break; default: return old; break; @@ -1360,6 +1487,7 @@ rewrite_mem_ref_def(tree expr, hash_map<const_tree, const_tree> &type_map, const gcc_assert(expr); gcc_assert(TREE_CODE(expr) == MEM_REF); tree type = TREE_TYPE(expr); + const_tree *new_type_ptr = type_map.get(type); if (new_type_ptr) TREE_TYPE(expr) = (tree) *new_type_ptr; @@ -1469,6 +1597,36 @@ rewrite_array_ref_def(tree expr, hash_map<const_tree, const_tree> &type_map, con } +static tree +rewrite_pointer_plus_def_rhs_variable_replace_constants_implementation +(gimple_stmt_iterator &gsi, tree pointer, tree variable, const_tree old_type) +{ + + tree pointer_type = TREE_TYPE(pointer); + gcc_assert(TREE_CODE(pointer_type) == POINTER_TYPE); + enum tree_code code = TREE_CODE(variable); + gcc_assert(TREE_CODE(variable) == SSA_NAME); + tree variable_type = TREE_TYPE(variable); + gcc_assert(TREE_CODE(variable_type) == INTEGER_TYPE); + 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 new_base_type = TREE_TYPE(TREE_TYPE(pointer)); + tree new_struct_size_tree_1 = TYPE_SIZE_UNIT(new_base_type); + int new_struct_size_int = tree_to_shwi(new_struct_size_tree_1); + + // avoid modifications + if (old_struct_size_int == new_struct_size_int) return NULL; + + // I need to walk up the use-def chain of the operands. + // If I see a old_struct_size_int, I need to replace it with + // new_struct_size_int + // + // The problem is, how are we going to detect offsets. + // That seems more complicated... + // Will they always be the next statement? +} + //TODO: //rewrite_pointer_plus_def_rhs_constant is a special case of //rewrite_pointer_plus_def_rhs_variable. @@ -1565,6 +1723,9 @@ rewrite_pointer_plus_def_rhs(gimple *stmt, gimple_stmt_iterator &gsi, tree lhs, const_tree *new_op0_type = type_map.get(op0_type); test_log("rewrite_pointer_plus has old_type %s", 0, new_op0_type ? "true" : "false"); //gcc_assert(!new_op0_type); + test_log("rewrite_pointer_plus op0_type %s", 0, get_type_name(op0_type)); + if (new_op0_type) + test_log("rewrite_pointer_plus new_op0_type %s", 0, get_type_name(*new_op0_type)); rewrite_expr(op0, type_map, 0); rewrite_expr(op1, type_map, 0); @@ -1573,9 +1734,11 @@ rewrite_pointer_plus_def_rhs(gimple *stmt, gimple_stmt_iterator &gsi, tree lhs, const char* new_type_name = new_op0_type ? get_type_name(*new_op0_type) : get_type_name(op0_type); //TODO: I'd prefer to have a parameter //that tells me what to change + test_log("rewrite_pointer_plus new_type_name %s", 0, new_type_name); //several stack frames above. const_tree *inverse_type_ptr = inverse.get(op0_type); bool not_in_map_nor_inverse = !new_op0_type && !inverse_type_ptr; + test_log("continuing? %s", 0, not_in_map_nor_inverse ? "false" : "true"); if (not_in_map_nor_inverse) return false; const_tree old_type = new_op0_type ? (const_tree) op0_type : *inverse_type_ptr; @@ -1644,13 +1807,11 @@ rewrite_assign_rhs(gimple *stmt, gimple_stmt_iterator &gsi, hash_map<const_tree, return retval; } break; - case POINTER_DIFF_EXPR: + default: { - // It's weird. Test case #4 - // uses this, but the answer - // is to do nothing... + print_gimple_stmt(dump_file, stmt, 0); + test_log("DEFAULT HERE: %s", 0, get_tree_code_name(code)); } - default: break; } @@ -1997,7 +2158,6 @@ rewrite_function(cgraph_node *cnode, hash_map<const_tree, const_tree> &type_map, rewrite_function_return_type(cnode, type_map); rewrite_function_body(cnode, type_map, inverse); rewrite_local_decls(cnode, type_map); - rewrite_global_decls(type_map); } static void @@ -2018,17 +2178,22 @@ rewrite_references_to_modified_structs_internal(const_tree const &old_type, __attribute__((unused))void*) { const char* identifier = get_type_name(old_type); - test_log("rewriting,%s,%s", 0, identifier, get_type_name(*new_type)); + tree old_struct_size_tree_1 = TYPE_SIZE_UNIT(*new_type); + tree old_struct_size_tree_2 = TYPE_SIZE_UNIT(old_type); + int old_struct_size_int = old_struct_size_tree_1 && (old_struct_size_tree_1 != NULL_TREE) ? tree_to_shwi(old_struct_size_tree_1) : -1; + int old_struct_size_int_2 = old_struct_size_tree_2 && (old_struct_size_tree_2 != NULL_TREE) ? tree_to_shwi(old_struct_size_tree_2) : -1; + test_log("rewriting,%s,%s,%d,%d", 0, identifier, get_type_name(*new_type), old_struct_size_int_2, old_struct_size_int); return true; } static void rewrite_references_to_modified_structs(hash_map<const_tree, const_tree> &type_map, hash_map<const_tree, const_tree> &inverse) { - type_map.traverse<void*, rewrite_references_to_modified_structs_internal>(NULL); //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); } bool |