[gcc(refs/users/mikael/heads/refactor_descriptor_v01)] Décomposition de la mise à jour des structures champ par champ
Mikael Morin
mikael@gcc.gnu.org
Thu Mar 6 18:35:16 GMT 2025
https://gcc.gnu.org/g:219b7511d0400fe2eb400dcfc618486d4931a908
commit 219b7511d0400fe2eb400dcfc618486d4931a908
Author: Mikael Morin <mikael@gcc.gnu.org>
Date: Wed Mar 5 23:06:05 2025 +0100
Décomposition de la mise à jour des structures champ par champ
Diff:
---
gcc/cgraphunit.cc | 490 +++++++++++++-----------------------------------------
1 file changed, 115 insertions(+), 375 deletions(-)
diff --git a/gcc/cgraphunit.cc b/gcc/cgraphunit.cc
index 660a39584d61..cc59fece0984 100644
--- a/gcc/cgraphunit.cc
+++ b/gcc/cgraphunit.cc
@@ -2581,7 +2581,7 @@ public:
void print_function_exit (struct function * func);
void print_bb_jump (edge e);
void print_bb_entry (basic_block bb);
- tree print_first_data_ref_part (exec_context & context, tree data_ref, unsigned offset);
+ tree print_first_data_ref_part (exec_context & context, tree data_ref, const data_value & value, unsigned offset, int * ignored_bits);
void print_value_update (exec_context & context, tree, const data_value &);
void end_stmt (gimple *);
void print_at (const data_value & value, tree type, unsigned offset, unsigned width);
@@ -2864,7 +2864,7 @@ context_printer::print_bb_entry (basic_block bb)
static tree
-pick_subref_at (tree var_ref, unsigned offset)
+pick_subref_at (tree var_ref, unsigned offset, int * ignored_bits)
{
tree ref = var_ref;
unsigned remaining_offset = offset;
@@ -2893,7 +2893,20 @@ pick_subref_at (tree var_ref, unsigned offset)
HOST_WIDE_INT next_position;
next_position = int_bit_position (next_field);
if (next_position > remaining_offset)
- break;
+ {
+ if (field_position >= remaining_offset)
+ break;
+
+ unsigned field_size;
+ if (!get_constant_type_size (TREE_TYPE (field), field_size))
+ gcc_unreachable ();
+
+ // Continue if the remaining offset is not within
+ // the current field, even if the next field is
+ // after the remaining offset as in the case of padding.
+ if (field_position + field_size > remaining_offset)
+ break;
+ }
field = next_field;
field_position = next_position;
@@ -2906,18 +2919,33 @@ pick_subref_at (tree var_ref, unsigned offset)
ref = build3 (COMPONENT_REF, TREE_TYPE (field),
ref, field, NULL_TREE);
- remaining_offset -= field_position;
+ if (field_position > remaining_offset)
+ {
+ gcc_assert (ignored_bits != nullptr);
+ *ignored_bits = field_position - remaining_offset;
+ remaining_offset = 0;
+ }
+ else
+ remaining_offset -= field_position;
}
else
break;
}
- gcc_assert (remaining_offset == 0);
- return ref;
+
+ if (remaining_offset == 0)
+ return ref;
+ else
+ {
+ gcc_assert (ignored_bits != nullptr);
+ *ignored_bits = remaining_offset;
+ return NULL_TREE;
+ }
}
static tree
-find_mem_ref_replacement (exec_context & context, tree data_ref, unsigned offset)
+find_mem_ref_replacement (exec_context & context, tree data_ref,
+ unsigned offset)
{
tree ptr = TREE_OPERAND (data_ref, 0);
data_value ptr_val = context.evaluate (ptr);
@@ -2936,21 +2964,21 @@ find_mem_ref_replacement (exec_context & context, tree data_ref, unsigned offset
if (var_type == access_type)
return var_ref;
else
- {
- tree access_offset = TREE_OPERAND (data_ref, 1);
- gcc_assert (TREE_CONSTANT (access_offset));
- gcc_assert (tree_fits_shwi_p (access_offset));
- HOST_WIDE_INT shwi_offset = tree_to_shwi (access_offset);
- gcc_assert (offset < UINT_MAX - shwi_offset);
- HOST_WIDE_INT remaining_offset = shwi_offset * CHAR_BIT + offset;
-
- return pick_subref_at (var_ref, remaining_offset);
- }
+ {
+ tree access_offset = TREE_OPERAND (data_ref, 1);
+ gcc_assert (TREE_CONSTANT (access_offset));
+ gcc_assert (tree_fits_shwi_p (access_offset));
+ HOST_WIDE_INT shwi_offset = tree_to_shwi (access_offset);
+ gcc_assert (offset < UINT_MAX - shwi_offset);
+ HOST_WIDE_INT remaining_offset = shwi_offset * CHAR_BIT + offset;
+
+ return pick_subref_at (var_ref, remaining_offset, nullptr);
+ }
}
tree
-context_printer::print_first_data_ref_part (exec_context & context, tree data_ref, unsigned offset)
+context_printer::print_first_data_ref_part (exec_context & context, tree data_ref, const data_value & value, unsigned offset, int * ignored_bits)
{
switch (TREE_CODE (data_ref))
{
@@ -2959,13 +2987,23 @@ context_printer::print_first_data_ref_part (exec_context & context, tree data_re
tree mem_replacement = find_mem_ref_replacement (context, data_ref,
offset);
if (mem_replacement != NULL_TREE)
- return print_first_data_ref_part (context, mem_replacement, 0);
+ return print_first_data_ref_part (context, mem_replacement, value, 0, ignored_bits);
}
/* Fall through. */
default:
- tree ref = pick_subref_at (data_ref, offset);
+ tree ref = pick_subref_at (data_ref, offset, ignored_bits);
+ if (ref == NULL_TREE)
+ {
+ gcc_assert (ignored_bits != nullptr
+ && *ignored_bits > 0);
+ return NULL_TREE;
+ }
+
+ pp_indent (&pp);
+ pp_character (&pp, '#');
+ pp_space (&pp);
print (ref);
return TREE_TYPE (ref);
}
@@ -2978,20 +3016,28 @@ context_printer::print_value_update (exec_context & context, tree lhs, const dat
unsigned width = get_constant_type_size (TREE_TYPE (lhs));
while (previously_done < width)
{
- pp_indent (&pp);
- pp_character (&pp, '#');
- pp_space (&pp);
- tree type_output = print_first_data_ref_part (context, lhs, previously_done);
+ int ignored_bits = 0;
+ tree type_done = print_first_data_ref_part (context, lhs, value,
+ previously_done,
+ &ignored_bits);
+ if (type_done == NULL_TREE)
+ {
+ gcc_assert (ignored_bits > 0);
+ previously_done += ignored_bits;
+ continue;
+ }
+
unsigned just_done;
- gcc_assert (get_constant_type_size (type_output, just_done));
+ if (!get_constant_type_size (type_done, just_done))
+ gcc_unreachable ();
gcc_assert (just_done > 0);
- gcc_assert (just_done <= width - previously_done);
+ gcc_assert (just_done + ignored_bits <= width - previously_done);
pp_space (&pp);
pp_equal (&pp);
pp_space (&pp);
- print_at (value, type_output, previously_done, just_done);
+ print_at (value, type_done, previously_done + ignored_bits, just_done);
print_newline ();
- previously_done += just_done;
+ previously_done += just_done + ignored_bits;
}
}
@@ -5384,350 +5430,6 @@ data_storage_set_at_tests ()
}
-void
-context_printer_print_first_data_ref_part_tests ()
-{
- vec<tree> empty{};
-
- tree der2i = make_node (RECORD_TYPE);
- tree der2i_i2 = build_decl (input_location, FIELD_DECL,
- get_identifier ("der2i_i2"), integer_type_node);
- DECL_CONTEXT (der2i_i2) = der2i;
- DECL_CHAIN (der2i_i2) = NULL_TREE;
- tree der2i_i1 = build_decl (input_location, FIELD_DECL,
- get_identifier ("der2i_i1"), integer_type_node);
- DECL_CONTEXT (der2i_i1) = der2i;
- DECL_CHAIN (der2i_i1) = der2i_i2;
- TYPE_FIELDS (der2i) = der2i_i1;
- layout_type (der2i);
-
- tree var2i = create_var (der2i, "var2i");
-
- heap_memory mem1;
- context_printer printer1;
- pretty_printer & pp1 = printer1.pp;
- exec_context ctx1 = context_builder ().build (mem1, printer1);
-
- tree res1 = printer1.print_first_data_ref_part (ctx1, var2i, 0);
-
- ASSERT_EQ (res1, integer_type_node);
- const char * str1 = pp_formatted_text (&pp1);
- ASSERT_STREQ (str1, "var2i.der2i_i1");
-
-
- context_printer printer2;
- pretty_printer & pp2 = printer2.pp;
-
- vec<tree> decls2{};
- decls2.safe_push (var2i);
-
- context_builder builder2 {};
- builder2.add_decls (&decls2);
- exec_context ctx2 = builder2.build (mem1, printer2);
-
- tree mem_var2i = build2 (MEM_REF, der2i,
- build1 (ADDR_EXPR, ptr_type_node, var2i),
- build_zero_cst (ptr_type_node));
-
- tree res2 = printer2.print_first_data_ref_part (ctx2, mem_var2i, 0);
-
- ASSERT_EQ (res2, integer_type_node);
- const char * str2 = pp_formatted_text (&pp2);
- ASSERT_STREQ (str2, "var2i.der2i_i1");
-
-
- context_printer printer3;
- pretty_printer & pp3 = printer3.pp;
-
- context_builder builder3 {};
- builder3.add_decls (&decls2);
- exec_context ctx3 = builder3.build (mem1, printer3);
-
- tree long_var2i = build2 (MEM_REF, long_integer_type_node,
- build1 (ADDR_EXPR, ptr_type_node, var2i),
- build_zero_cst (ptr_type_node));
-
- tree res3 = printer3.print_first_data_ref_part (ctx3, long_var2i, 0);
-
- ASSERT_EQ (res3, integer_type_node);
- const char * str3 = pp_formatted_text (&pp3);
- ASSERT_STREQ (str3, "var2i.der2i_i1");
-
-
- tree der2s = make_node (RECORD_TYPE);
- tree der2s_s2 = build_decl (input_location, FIELD_DECL,
- get_identifier ("der2s_s2"),
- short_integer_type_node);
- DECL_CONTEXT (der2s_s2) = der2s;
- DECL_CHAIN (der2s_s2) = NULL_TREE;
- tree der2s_s1 = build_decl (input_location, FIELD_DECL,
- get_identifier ("der2s_s1"),
- short_integer_type_node);
- DECL_CONTEXT (der2s_s1) = der2s;
- DECL_CHAIN (der2s_s1) = der2s_s2;
- TYPE_FIELDS (der2s) = der2s_s1;
- layout_type (der2s);
-
-
- tree der1d1i = make_node (RECORD_TYPE);
- tree der1d1i_i2 = build_decl (input_location, FIELD_DECL,
- get_identifier ("der1d1i_i2"), integer_type_node);
- DECL_CONTEXT (der1d1i_i2) = der1d1i;
- DECL_CHAIN (der1d1i_i2) = NULL_TREE;
- tree der1d1i_d1 = build_decl (input_location, FIELD_DECL,
- get_identifier ("der1d1i_d1"), der2s);
- DECL_CONTEXT (der1d1i_d1) = der1d1i;
- DECL_CHAIN (der1d1i_d1) = der1d1i_i2;
- TYPE_FIELDS (der1d1i) = der1d1i_d1;
- layout_type (der1d1i);
-
- tree var1d1i = create_var (der1d1i, "var1d1i");
-
- context_printer printer4;
- pretty_printer & pp4 = printer4.pp;
-
- vec<tree> decls4{};
- decls4.safe_push (var1d1i);
-
- context_builder builder4 {};
- builder4.add_decls (&decls4);
- exec_context ctx4 = builder4.build (mem1, printer4);
-
- tree mem_var1d1i = build2 (MEM_REF, long_integer_type_node,
- build1 (ADDR_EXPR, ptr_type_node, var1d1i),
- build_zero_cst (ptr_type_node));
-
- tree res4 = printer4.print_first_data_ref_part (ctx4, mem_var1d1i, 0);
-
- ASSERT_EQ (res4, short_integer_type_node);
- const char * str4 = pp_formatted_text (&pp4);
- ASSERT_STREQ (str4, "var1d1i.der1d1i_d1.der2s_s1");
-
-
- context_printer printer5;
- pretty_printer & pp5 = printer5.pp;
-
- context_builder builder5 {};
- builder5.add_decls (&decls4);
- exec_context ctx5 = builder5.build (mem1, printer5);
-
- tree mem_var1d1i_s2 = build2 (MEM_REF, short_integer_type_node,
- build1 (ADDR_EXPR, ptr_type_node, var1d1i),
- build_int_cst (ptr_type_node,
- sizeof (short)));
-
- tree res5 = printer5.print_first_data_ref_part (ctx5, mem_var1d1i_s2, 0);
-
- ASSERT_EQ (res5, short_integer_type_node);
- const char * str5 = pp_formatted_text (&pp5);
- ASSERT_STREQ (str5, "var1d1i.der1d1i_d1.der2s_s2");
-
-
- tree der4c = make_node (RECORD_TYPE);
- tree der4c_c4 = build_decl (input_location, FIELD_DECL,
- get_identifier ("der4c_c4"),
- char_type_node);
- DECL_CONTEXT (der4c_c4) = der4c;
- DECL_CHAIN (der4c_c4) = NULL_TREE;
- tree der4c_c3 = build_decl (input_location, FIELD_DECL,
- get_identifier ("der4c_c3"),
- char_type_node);
- DECL_CONTEXT (der4c_c3) = der4c;
- DECL_CHAIN (der4c_c3) = der4c_c4;
- tree der4c_c2 = build_decl (input_location, FIELD_DECL,
- get_identifier ("der4c_c2"),
- char_type_node);
- DECL_CONTEXT (der4c_c2) = der4c;
- DECL_CHAIN (der4c_c2) = der4c_c3;
- tree der4c_c1 = build_decl (input_location, FIELD_DECL,
- get_identifier ("der4c_c1"),
- char_type_node);
- DECL_CONTEXT (der4c_c1) = der4c;
- DECL_CHAIN (der4c_c1) = der4c_c2;
- TYPE_FIELDS (der4c) = der4c_c1;
- layout_type (der4c);
-
- tree var4c = create_var (der4c, "var4c");
-
- context_printer printer6;
- pretty_printer & pp6 = printer6.pp;
-
- vec<tree> decls6{};
- decls6.safe_push (var4c);
-
- context_builder builder6 {};
- builder6.add_decls (&decls6);
- exec_context ctx6 = builder6.build (mem1, printer6);
-
- tree mem_var4c = build2 (MEM_REF, long_integer_type_node,
- build1 (ADDR_EXPR, ptr_type_node, var4c),
- build_int_cst (ptr_type_node, 2));
-
- tree res6 = printer6.print_first_data_ref_part (ctx6, mem_var4c, 0);
-
- ASSERT_EQ (res6, char_type_node);
- const char * str6 = pp_formatted_text (&pp6);
- ASSERT_STREQ (str6, "var4c.der4c_c3");
-
-
- tree der1i1d = make_node (RECORD_TYPE);
- tree der1i1d_d2 = build_decl (input_location, FIELD_DECL,
- get_identifier ("der1i1d_d2"),
- der4c);
- DECL_CONTEXT (der1i1d_d2) = der1i1d;
- DECL_CHAIN (der1i1d_d2) = NULL_TREE;
- tree der1i1d_i1 = build_decl (input_location, FIELD_DECL,
- get_identifier ("der1i1d_i1"),
- integer_type_node);
- DECL_CONTEXT (der1i1d_i1) = der1i1d;
- DECL_CHAIN (der1i1d_i1) = der1i1d_d2;
- TYPE_FIELDS (der1i1d) = der1i1d_i1;
- layout_type (der1i1d);
-
- tree var1i1d = create_var (der1i1d, "var1i1d");
-
- context_printer printer7;
- pretty_printer & pp7 = printer7.pp;
-
- vec<tree> decls7{};
- decls7.safe_push (var1i1d);
-
- context_builder builder7 {};
- builder7.add_decls (&decls7);
- exec_context ctx7 = builder7.build (mem1, printer7);
-
- tree mem_var1i1d = build2 (MEM_REF, char_type_node,
- build1 (ADDR_EXPR, ptr_type_node, var1i1d),
- build_int_cst (ptr_type_node,
- sizeof (int) + 1));
-
- tree res7 = printer7.print_first_data_ref_part (ctx7, mem_var1i1d, 0);
-
- ASSERT_EQ (res7, char_type_node);
- const char * str7 = pp_formatted_text (&pp7);
- ASSERT_STREQ (str7, "var1i1d.der1i1d_d2.der4c_c2");
-
-
- tree i5 = build_array_type_nelts (integer_type_node, 5);
-
- tree var_i5 = create_var (i5, "var_i5");
-
- context_printer printer8;
- pretty_printer & pp8 = printer8.pp;
-
- vec<tree> decls8{};
- decls8.safe_push (var_i5);
-
- context_builder builder8 {};
- builder8.add_decls (&decls8);
- exec_context ctx8 = builder8.build (mem1, printer8);
-
- tree mem_var_i5 = build2 (MEM_REF, char_type_node,
- build1 (ADDR_EXPR, ptr_type_node, var_i5),
- build_int_cst (ptr_type_node,
- 3 * sizeof (int)));
-
- tree res8 = printer8.print_first_data_ref_part (ctx8, mem_var_i5, 0);
-
- ASSERT_EQ (res8, integer_type_node);
- const char * str8 = pp_formatted_text (&pp8);
- ASSERT_STREQ (str8, "var_i5[3]");
-
-
- context_printer printer9;
- pretty_printer & pp9 = printer9.pp;
-
- context_builder builder9 {};
- builder9.add_decls (&decls8);
- exec_context ctx9 = builder9.build (mem1, printer9);
-
- tree mem2_var_i5 = build2 (MEM_REF, char_type_node,
- build1 (ADDR_EXPR, ptr_type_node, var_i5),
- build_int_cst (ptr_type_node,
- sizeof (int)));
-
- tree res9 = printer9.print_first_data_ref_part (ctx9, mem2_var_i5,
- HOST_BITS_PER_INT);
-
- ASSERT_EQ (res9, integer_type_node);
- const char * str9 = pp_formatted_text (&pp9);
- ASSERT_STREQ (str9, "var_i5[2]");
-
-
- tree a5c4 = build_array_type_nelts (der4c, 5);
-
- tree der1i1a5d = make_node (RECORD_TYPE);
- tree der1i1a5d_a5d2 = build_decl (input_location, FIELD_DECL,
- get_identifier ("der1i1a5d_a5d2"),
- a5c4);
- DECL_CONTEXT (der1i1a5d_a5d2) = der1i1a5d;
- DECL_CHAIN (der1i1a5d_a5d2) = NULL_TREE;
- tree der1i1a5d_i1 = build_decl (input_location, FIELD_DECL,
- get_identifier ("der1i1a5d_i1"),
- integer_type_node);
- DECL_CONTEXT (der1i1a5d_i1) = der1i1a5d;
- DECL_CHAIN (der1i1a5d_i1) = der1i1a5d_a5d2;
- TYPE_FIELDS (der1i1a5d) = der1i1a5d_i1;
- layout_type (der1i1a5d);
-
- tree var_d1i1a5d = create_var (der1i1a5d, "var_d1i1a5d");
-
- context_printer printer10;
- pretty_printer & pp10 = printer10.pp;
-
- vec<tree> decls10{};
- decls10.safe_push (var_d1i1a5d);
-
- context_builder builder10 {};
- builder10.add_decls (&decls10);
- exec_context ctx10 = builder10.build (mem1, printer10);
-
- tree mem_var_d1i1a5d = build2 (MEM_REF, char_type_node,
- build1 (ADDR_EXPR, ptr_type_node, var_d1i1a5d),
- build_int_cst (ptr_type_node,
- sizeof (int) + 13));
-
- tree res10 = printer10.print_first_data_ref_part (ctx10, mem_var_d1i1a5d, 0);
-
- ASSERT_EQ (res10, char_type_node);
- const char * str10 = pp_formatted_text (&pp10);
- ASSERT_STREQ (str10, "var_d1i1a5d.der1i1a5d_a5d2[3].der4c_c2");
-
-
- tree var_i = create_var (integer_type_node, "var_i");
- tree ptr = create_var (ptr_type_node, "ptr");
-
- context_printer printer11;
- pretty_printer & pp11 = printer11.pp;
-
- vec<tree> decls11{};
- decls11.safe_push (var_i);
- decls11.safe_push (ptr);
-
- context_builder builder11 {};
- builder11.add_decls (&decls11);
- exec_context ctx11 = builder11.build (mem1, printer11);
-
- data_storage *var_storage = ctx11.find_reachable_var (var_i);
- storage_address var_address (var_storage->get_ref (), 0);
-
- data_value ptr_val (ptr_type_node);
- ptr_val.set_address (var_address);
-
- data_storage *ptr_storage = ctx11.find_reachable_var (ptr);
- ptr_storage->set (ptr_val);
-
- tree ref_ptr = build2 (MEM_REF, integer_type_node, ptr,
- build_zero_cst (ptr_type_node));
-
- tree res11 = printer11.print_first_data_ref_part (ctx11, ref_ptr, 0);
-
- ASSERT_EQ (res11, integer_type_node);
- const char * str11 = pp_formatted_text (&pp11);
- ASSERT_STREQ (str11, "var_i");
-}
-
-
void
context_printer_print_value_update_tests ()
{
@@ -5930,6 +5632,45 @@ context_printer_print_value_update_tests ()
const char *str6 = pp_formatted_text (&pp6);
ASSERT_STREQ (str6, "# var2i.der2i_i1_bis = 12\n# var2i.der2i_i2_bis = 7\n");
+
+
+ context_printer printer7;
+ pretty_printer & pp7 = printer7.pp;
+ pp_buffer (&pp7)->m_flush_p = false;
+
+ tree der1c1i = make_node (RECORD_TYPE);
+ tree der1c1i_i2 = build_decl (input_location, FIELD_DECL,
+ get_identifier ("der1c1i_i2"),
+ integer_type_node);
+ DECL_CONTEXT (der1c1i_i2) = der1c1i;
+ DECL_CHAIN (der1c1i_i2) = NULL_TREE;
+ tree der1c1i_c1 = build_decl (input_location, FIELD_DECL,
+ get_identifier ("der1c1i_c1"),
+ char_type_node);
+ DECL_CONTEXT (der1c1i_c1) = der1c1i;
+ DECL_CHAIN (der1c1i_c1) = der1c1i_i2;
+ TYPE_FIELDS (der1c1i) = der1c1i_c1;
+ layout_type (der1c1i);
+
+ tree var1c1i = create_var (der1c1i, "var1c1i");
+
+ vec<tree> decls7;
+ decls7.safe_push (var1c1i);
+
+ context_builder builder7;
+ builder7.add_decls (&decls7);
+ exec_context ctx7 = builder7.build (mem, printer7);
+
+ wide_int wi3 = wi::shwi (3, CHAR_BIT);
+ wide_int wi11 = wi::shwi (11, HOST_BITS_PER_INT);
+ data_value cstr_3_11 (der1c1i);
+ cstr_3_11.set_cst_at (wi3, 0);
+ cstr_3_11.set_cst_at (wi11, int_bit_position (der1c1i_i2));
+
+ printer7.print_value_update (ctx7, var1c1i, cstr_3_11);
+
+ const char *str7 = pp_formatted_text (&pp7);
+ ASSERT_STREQ (str7, "# var1c1i.der1c1i_c1 = 3\n# var1c1i.der1c1i_i2 = 11\n");
}
@@ -6492,7 +6233,7 @@ exec_context_evaluate_constructor_tests ()
tree var3 = create_var (integer_type_node, "var3");
- vec<tree> decls3;
+ vec<tree> decls3 {};
decls3.safe_push (var3);
context_builder builder3;
@@ -6549,7 +6290,7 @@ exec_context_evaluate_unary_tests ()
tree c1 = create_var (char_type_node, "c1");
- vec<tree> decls1;
+ vec<tree> decls1 {};
decls1.safe_push (c1);
context_builder builder1;
@@ -7471,7 +7212,6 @@ gimple_exec_cc_tests ()
data_value_set_at_tests ();
data_value_print_tests ();
data_storage_set_at_tests ();
- context_printer_print_first_data_ref_part_tests ();
context_printer_print_value_update_tests ();
exec_context_evaluate_tests ();
exec_context_evaluate_literal_tests ();
More information about the Gcc-cvs
mailing list