summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorErick Ochoa <erick.ochoa@theobroma-systems.com>2020-09-14 14:37:30 +0200
committerErick Ochoa <erick.ochoa@theobroma-systems.com>2020-09-18 19:04:24 +0200
commit15581391f3ce76fb74b5ab928fe9390f2e72b031 (patch)
tree913e80f5ebc9cd6c3164d9419f3d054f5b0fed13
parente972a6db8f5a5c401ddb59a44c3ce2a42449f186 (diff)
seems to be working
-rw-r--r--gcc/tree-ssa-structalias.c225
1 files changed, 95 insertions, 130 deletions
diff --git a/gcc/tree-ssa-structalias.c b/gcc/tree-ssa-structalias.c
index ec90be9eed3..245172fe812 100644
--- a/gcc/tree-ssa-structalias.c
+++ b/gcc/tree-ssa-structalias.c
@@ -8842,6 +8842,7 @@ get_vector_of_alias_sets(vec<bitmap> &alias_sets_unique, hash_map<tree, bitmap>
alias_sets_unique.safe_push(a_i);
index_map.insert({a_i, index});
index++;
+ if (dump_file) fprintf(dump_file, "%d insert ( %s )\n", index, alias_get_name((*i).first));
}
}
@@ -8888,7 +8889,7 @@ static bool
is_there_a_field_access(tree lhsOrRhs1, bool &can_handle, tree *_struct, tree *field, unsigned &offset_constant)
{
gcc_assert(lhsOrRhs1);
- const enum tree_code code = TREE_CODE(lhsOrRhs1);
+ enum tree_code code = TREE_CODE(lhsOrRhs1);
bool definitely = false;
bool maybe = false;
can_handle = false;
@@ -8899,8 +8900,8 @@ is_there_a_field_access(tree lhsOrRhs1, bool &can_handle, tree *_struct, tree *f
*_struct = TREE_OPERAND(lhsOrRhs1, 0);
*field = TREE_OPERAND(lhsOrRhs1, 1);
case ADDR_EXPR:
- maybe = true;
case SSA_NAME:
+ maybe = true;
case VAR_DECL:
case LT_EXPR:
case POINTER_PLUS_EXPR:
@@ -8910,24 +8911,20 @@ is_there_a_field_access(tree lhsOrRhs1, bool &can_handle, tree *_struct, tree *f
break;
}
- if (dump_file) fprintf(dump_file, "get_tree_code_name = %s\n", get_tree_code_name(code));
-
//if (definitely) return true;
if (!can_handle) return false;
if (!maybe) return false;
- if (dump_file) fprintf(dump_file, "we have some work to do: %s\n", get_tree_code_name(code));
-
tree addr_expr_0 = definitely ? lhsOrRhs1 : NULL;
if (ADDR_EXPR == code)
{
addr_expr_0 = TREE_OPERAND(lhsOrRhs1, 0);
}
- const enum tree_code code_addr_expr_0 = TREE_CODE(addr_expr_0);
+ //code = TREE_CODE(addr_expr_0);
definitely = true;
poly_uint64 offset = 0;
- if (COMPONENT_REF == code_addr_expr_0)
+ if (COMPONENT_REF == code)
{
// This is the struct.
*field = TREE_OPERAND(addr_expr_0, 1);
@@ -8942,10 +8939,14 @@ is_there_a_field_access(tree lhsOrRhs1, bool &can_handle, tree *_struct, tree *f
{
offset = (offset << LOG2_BITS_PER_UNIT) + bit_offset;
}
- if (dump_file) fprintf(dump_file, "field\n");
- if (dump_file) print_generic_expr(dump_file, *field);
- if (dump_file) fprintf(dump_file, "\n");
offset_constant = offset.to_constant();
+
+ const enum tree_code code_possibly_memref = TREE_CODE(*_struct);
+ if (MEM_REF == code_possibly_memref)
+ {
+ // pointer
+ *_struct = TREE_OPERAND(*_struct, 0);
+ }
}
return definitely;
@@ -8953,7 +8954,7 @@ is_there_a_field_access(tree lhsOrRhs1, bool &can_handle, tree *_struct, tree *f
static void
-label_to_edges(tree def, unsigned index_i, bitmap a_i, hash_set<bitmap> &invalid, hash_map<tree, bitmap> &tree_map, std::map<bitmap, unsigned> &index_map, struct graph_edge ***table, struct graph* SSG, hash_map<struct graph_edge*, bitmap> &edge_labels)
+label_to_edges(tree def, unsigned index_rhs, bitmap a_i, hash_set<bitmap> &invalid, hash_map<tree, bitmap> &tree_map, std::map<bitmap, unsigned> &index_map, struct graph_edge ***table, struct graph* SSG, hash_map<struct graph_edge*, bitmap> &edge_labels)
{
gcc_assert(def);
gimple *use = NULL;
@@ -8969,6 +8970,8 @@ label_to_edges(tree def, unsigned index_i, bitmap a_i, hash_set<bitmap> &invalid
if (!is_alias_set_valid) BREAK_FROM_IMM_USE_STMT(iterator);
if (is_call) continue;
+ if (dump_file) print_gimple_expr (dump_file, use, 0);
+ if (dump_file) fprintf(dump_file, "\n");
tree rhs1 = gimple_assign_rhs1 (use);
bool can_handle_rhs = false;
tree _struct_rhs = NULL;
@@ -8987,28 +8990,34 @@ label_to_edges(tree def, unsigned index_i, bitmap a_i, hash_set<bitmap> &invalid
const bool dont_care = !field_rhs && !field_lhs;
if (dont_care) continue;
- tree lhs_alias_set = field_lhs ? _struct_lhs : lhs;
- tree rhs_alias_set = field_rhs ? _struct_rhs : rhs1;
+ tree lhs_alias_set = _struct_lhs ? _struct_lhs : lhs;
+ tree rhs_alias_set = _struct_rhs ? _struct_rhs : rhs1;
// If we do have this, then we need a bidirectional edge...
// which we haven't implemented.
gcc_assert(field_lhs != field_rhs);
- direction_from_to = field_rhs && !field_lhs;
+ const bool is_rhs_source = field_rhs;
+ if (dump_file) fprintf(dump_file, "is_rhs_source1 = %s\n", is_rhs_source ? "t" :"F");
+ //direction_from_to = field_rhs && !field_lhs;
// So now we need to find out which alias-set lhs belongs...
bitmap *alias_set_to_ptr = tree_map.get (lhs_alias_set);
+ if (dump_file) fprintf(dump_file, "inspecting source of error\n");
+ const enum tree_code code = TREE_CODE(lhs_alias_set);
+ if (dump_file) fprintf(dump_file, "code = %s\n", get_tree_code_name(code));
+ if (dump_file) print_generic_expr(dump_file, lhs_alias_set);
+ if (dump_file) fprintf(dump_file, "\n");
// I think this is fine...
if (!alias_set_to_ptr) continue;
bitmap alias_set_to = *alias_set_to_ptr;
// what is the index of this alias_set?
const bool index_j_exists = index_map.find(alias_set_to) != index_map.end();
// I think this is still fine...
- if (dump_file) fprintf(dump_file, "index_j_exists %s\n", index_j_exists ? "T" : "F");
if (!index_j_exists) continue;
unsigned index_j = index_map.at(alias_set_to);
// now we have from and to
// in index_i and index_j
- unsigned i_i = direction_from_to ? index_i : index_j;
- unsigned i_j = direction_from_to ? index_j : index_i;
+ unsigned i_i = is_rhs_source ? index_rhs : index_j;
+ unsigned i_j = is_rhs_source ? index_j : index_rhs;
struct graph_edge *e = table[i_i][i_j];
// So, if there's no edge
// or if there's an edge
@@ -9018,17 +9027,15 @@ label_to_edges(tree def, unsigned index_i, bitmap a_i, hash_set<bitmap> &invalid
// What we need to do here is make sure that there's
// an edge and that it is labeled with the field offset
// that points to index_j...
- if (dump_file) fprintf(dump_file, "HERE HERE\n");
if (dump_file) print_gimple_expr (dump_file, use, 0);
if (dump_file) fprintf(dump_file, "\n");
-
bitmap *label_ptr = edge_labels.get (e);
bitmap label = label_ptr ? *label_ptr : BITMAP_ALLOC(&alias_obstack);
- unsigned offset_constant = direction_from_to ? offset_rhs : offset_lhs;
- if (dump_file) fprintf(dump_file, "offset_constant = %ld", offset_constant);
+ unsigned offset_constant = is_rhs_source ? offset_rhs : offset_lhs;
bitmap_set_bit (label, offset_constant);
edge_labels.put (e, label);
+ if (dump_file) fprintf(dump_file, "HERE HERE, table [%u][%u] = %ld\n", i_i, i_j, offset_constant);
}
@@ -9036,129 +9043,85 @@ label_to_edges(tree def, unsigned index_i, bitmap a_i, hash_set<bitmap> &invalid
}
static tree
-label_from_edges(gimple* def, unsigned index_i, bitmap a_i, hash_set<bitmap> &invalid, hash_map<tree, bitmap> &tree_map, std::map<bitmap, unsigned> &index_map, struct graph_edge ***table, struct graph* SSG, hash_map<struct graph_edge*, bitmap> &edge_labels)
+label_from_edges(gimple* def, unsigned index_lhs, bitmap a_i, hash_set<bitmap> &invalid, hash_map<tree, bitmap> &tree_map, std::map<bitmap, unsigned> &index_map, struct graph_edge ***table, struct graph* SSG, hash_map<struct graph_edge*, bitmap> &edge_labels)
{
+ gcc_assert(def);
if (dump_file) print_gimple_expr(dump_file, def, 0);
if (dump_file) fprintf(dump_file, "\n");
- gcc_assert(def);
const enum gimple_code gcode = gimple_code(def);
- tree lhs = NULL;
bool interesting = false;
+ tree lhs = NULL;
switch (gcode)
{
- case GIMPLE_ASSIGN:
- lhs = gimple_assign_lhs (def);
- interesting = true;
- break;
- case GIMPLE_CALL:
- lhs = gimple_call_lhs (def);
- break;
- default:
- invalid.add (a_i);
- break;
+ case GIMPLE_ASSIGN:
+ lhs = gimple_assign_lhs (def);
+ interesting = true;
+ break;
+ case GIMPLE_CALL:
+ lhs = gimple_call_lhs (def);
+ break;
+ default:
+ invalid.add (a_i);
+ break;
}
-
- if (!lhs || !interesting) return lhs;
-
- tree rhs1 = gimple_assign_rhs1 (def);
- gcc_assert(rhs1);
- const enum tree_code rhs_code = TREE_CODE(rhs1);
- interesting = false;
- switch (rhs_code)
- {
- case COMPONENT_REF:
- case ADDR_EXPR:
- interesting = true;
- break;
- case VAR_DECL:
- case LT_EXPR:
- case POINTER_PLUS_EXPR:
- break;
- default:
- // TODO: Not sure about this...
- invalid.add(a_i);
- break;
- }
-
if (!interesting) return lhs;
- // Here, I think we can assert that rhs is pointing to lhs
- // So let's get the bitmap which corresponds to rhs1
- // rhs1 is an expression... what we need is the tree that corresponds to the
- // declaration?
- tree handle = rhs1;
- if (ADDR_EXPR == rhs_code)
- {
- handle = TREE_OPERAND(rhs1, 0);
- }
-
- enum tree_code handle_code = TREE_CODE(handle);
- tree field = NULL;
- poly_uint64 offset = 0;
- if (COMPONENT_REF == handle_code)
- {
- // This is the struct.
- field = TREE_OPERAND(handle, 1);
- handle = TREE_OPERAND(handle, 0);
- const enum tree_code fcode = TREE_CODE(field);
- const bool is_field_decl = FIELD_DECL == fcode;
- gcc_assert(is_field_decl);
-
- poly_uint64 bit_offset;
- if (poly_int_tree_p (DECL_FIELD_OFFSET (field), &offset)
- && poly_int_tree_p (DECL_FIELD_BIT_OFFSET (field), &bit_offset))
- {
- offset = (offset << LOG2_BITS_PER_UNIT) + bit_offset;
- }
- if (dump_file) fprintf(dump_file, "field\n");
- if (dump_file) print_generic_expr(dump_file, field);
- if (dump_file) fprintf(dump_file, "\n");
- }
-
-
- handle_code = TREE_CODE(handle);
- // here handle can be a MEM_REF or a VAR_DECL
- if (MEM_REF == handle_code)
- {
- // pointer
- handle = TREE_OPERAND(handle, 0);
- }
-
- // here we have VAR_DECL or SSA_NAME
- handle_code = TREE_CODE(handle);
-
- const bool is_ssa_name = SSA_NAME == handle_code;
- //const bool is_var_decl = VAR_DECL == handle_code;
- const bool is_valid = is_ssa_name;// || is_var_decl;
- // Just in case for the safety of the hello world example...
- if (!is_valid) return lhs;
-
- // So now... is handle in any of the alias-sets?
- bitmap *a_j_ptr = tree_map.get(handle);
- // This is fine
- if (!a_j_ptr) return lhs;
- bitmap a_j = *a_j_ptr;
-
- //return lhs;
- const bool index_j_exists = index_map.find(a_j) != index_map.end();
+ tree rhs1 = gimple_assign_rhs1 (def);
+ bool can_handle_rhs = false;
+ tree _struct_rhs = NULL;
+ tree field_rhs = NULL;
+ unsigned offset_rhs = 0;
+ is_there_a_field_access(rhs1, can_handle_rhs, &_struct_rhs, &field_rhs, offset_rhs);
+
+ lhs = gimple_assign_lhs (def);
+ bool can_handle_lhs = false;
+ tree _struct_lhs = NULL;
+ tree field_lhs = NULL;
+ unsigned offset_lhs = 0;
+ is_there_a_field_access(lhs, can_handle_lhs, &_struct_lhs, &field_lhs, offset_lhs);
+
+ // So, if there's no field access at all we just don't care.
+ const bool dont_care = !field_rhs && !field_lhs;
+ if (dont_care) return lhs;
+
+ tree lhs_alias_set = _struct_lhs ? _struct_lhs : lhs;
+ tree rhs_alias_set = _struct_rhs ? _struct_rhs : rhs1;
+ // If we do have this, then we need a bidirectional edge...
+ // which we haven't implemented.
+ gcc_assert(field_lhs != field_rhs);
+ bool direction_from_to = field_lhs && !field_rhs;
+ const bool is_rhs_source = field_rhs;
+ if (dump_file) fprintf(dump_file, "is_rhs_source2 = %s\n", is_rhs_source ? "t" :"F");
+
+ // So now we need to find out which alias-set lhs belongs...
+ bitmap *alias_set_to_ptr = tree_map.get (rhs_alias_set);
+ // I think this is fine...
+ if (!alias_set_to_ptr) return lhs;
+ bitmap alias_set_to = *alias_set_to_ptr;
+ // what is the index of this alias_set?
+ const bool index_j_exists = index_map.find(alias_set_to) != index_map.end();
// I think this is still fine...
if (!index_j_exists) return lhs;
- unsigned index_j = index_map.at(a_j);
- // Note [j][i]
- //
- // This is because we are in the definition of variable in a_i
- // So j will point to i
- struct graph_edge *e = table[index_j][index_i];
- if (!e) e = add_edge(SSG, index_j, index_i);
- table[index_j][index_i] = e;
-
+ unsigned index_j = index_map.at(alias_set_to);
+ // now we have from and to
+ // in index_i and index_j
+ unsigned i_i = is_rhs_source ? index_j : index_lhs;
+ unsigned i_j = is_rhs_source ? index_lhs: index_j;
+ struct graph_edge *e = table[i_i][i_j];
+
+ if (!e) e = add_edge(SSG, i_i, i_j);
+ table[i_i][i_j] = e;
+ // What we need to do here is make sure that there's
+ // an edge and that it is labeled with the field offset
+ // that points to index_j...
+
bitmap *label_ptr = edge_labels.get (e);
bitmap label = label_ptr ? *label_ptr : BITMAP_ALLOC(&alias_obstack);
- unsigned offset_constant = offset.to_constant();
+ unsigned offset_constant = direction_from_to ? offset_lhs : offset_rhs;
+ if (dump_file) fprintf(dump_file, "table [%u][%u] = %ld\n", i_i, i_j, offset_constant);
bitmap_set_bit (label, offset_constant);
edge_labels.put (e, label);
-
return lhs;
}
@@ -9190,6 +9153,7 @@ compute_alias_sets()
for (unsigned i = 0; i < cardinality; i++)
{
edge_table[i] = (struct graph_edge **) xmalloc(cardinality * sizeof(struct graph_edge**));
+ memset(edge_table[i], 0, sizeof(graph_edge**) * cardinality);
}
struct graph *SSG = compute_SSG (alias_set_unique, edge_table);
gcc_assert(SSG);
@@ -9199,10 +9163,10 @@ compute_alias_sets()
// I wonder if I can just look at the uses of the decl...
hash_set<bitmap> invalid;
hash_map<struct graph_edge *, bitmap> labels;
- unsigned index_i = 0;
- for (auto i = alias_set_unique.begin(), e = alias_set_unique.end(); i != e; ++i, index_i++)
+ for (auto i = alias_set_unique.begin(), e = alias_set_unique.end(); i != e; ++i)
{
bitmap a_i = *i;
+ unsigned index_i = index_map.at(a_i);
unsigned j = 0;
bitmap_iterator bi;
EXECUTE_IF_SET_IN_BITMAP (a_i, 0, j, bi)
@@ -9241,6 +9205,7 @@ compute_alias_sets()
for (auto i = labels.begin(), e = labels.end(); i != e; ++i)
{
struct graph_edge *ed = (*i).first;
+ if (!ed) continue;
if (dump_file) fprintf(dump_file, "source = %d, dest = %d\n", ed->src, ed->dest);
bitmap fields = (*i).second;
unsigned j = 0;