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-13 22:55:33 +0100
committerErick Ochoa <erick.ochoa@theobroma-systems.com>2020-05-14 14:45:33 +0200
commit2a6fe0cc583289e1692c222d4e973d856251ef2c (patch)
treeb8e00781afe26afa912253d4a83ef86a82097167 /gcc/ipa-str-reorg-dead-field-eliminate.c
parent002f50a6a4b5077e76591bc02e4125217defb626 (diff)
wip
Diffstat (limited to 'gcc/ipa-str-reorg-dead-field-eliminate.c')
-rw-r--r--gcc/ipa-str-reorg-dead-field-eliminate.c181
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