diff options
author | Erick Ochoa <erick.ochoa@theobroma-systems.com> | 2020-09-14 14:37:30 +0200 |
---|---|---|
committer | Erick Ochoa <erick.ochoa@theobroma-systems.com> | 2020-09-18 19:04:24 +0200 |
commit | 15581391f3ce76fb74b5ab928fe9390f2e72b031 (patch) | |
tree | 913e80f5ebc9cd6c3164d9419f3d054f5b0fed13 | |
parent | e972a6db8f5a5c401ddb59a44c3ce2a42449f186 (diff) |
seems to be working
-rw-r--r-- | gcc/tree-ssa-structalias.c | 225 |
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; |