[gcc(refs/users/mikael/heads/refactor_descriptor_v05)] gimple-exec: prise en charge addresses de composant de variable
Mikael Morin
mikael@gcc.gnu.org
Mon May 19 16:16:33 GMT 2025
https://gcc.gnu.org/g:3e90e88548f90367050264a7c0ffb7c8cd47ee02
commit 3e90e88548f90367050264a7c0ffb7c8cd47ee02
Author: Mikael Morin <mikael@gcc.gnu.org>
Date: Fri Apr 18 15:15:42 2025 +0200
gimple-exec: prise en charge addresses de composant de variable
Diff:
---
gcc/cgraphunit.cc | 183 ++++++++++++++++++++++++++++++++++++++++++++++++++++--
1 file changed, 178 insertions(+), 5 deletions(-)
diff --git a/gcc/cgraphunit.cc b/gcc/cgraphunit.cc
index cc00a3ada919..a6dce6b42c6d 100644
--- a/gcc/cgraphunit.cc
+++ b/gcc/cgraphunit.cc
@@ -213,6 +213,7 @@ along with GCC; see the file COPYING3. If not see
#include "wide-int.h"
#include "selftest.h"
#include "tree-ssanames.h"
+#include "tree-dfa.h"
/* Queue of cgraph nodes scheduled to be added into cgraph. This is a
secondary queue used during optimization to accommodate passes that
@@ -3903,10 +3904,37 @@ exec_context::evaluate (tree expr) const
}
else
{
- data_storage *strg = find_reachable_var (TREE_OPERAND (expr, 0));
- gcc_assert (strg != nullptr);
- storage_address address (strg->get_ref (), 0);
- result.set_address (address);
+ poly_int64 offset;
+ tree var = get_addr_base_and_unit_offset (TREE_OPERAND (expr, 0),
+ &offset);
+
+ HOST_WIDE_INT off;
+ bool is_constant = offset.is_constant (&off);
+ gcc_assert (is_constant && off >= 0);
+ unsigned off_bits = off * CHAR_BIT;
+
+ if (TREE_CODE (var) == VAR_DECL)
+ {
+ data_storage *strg = find_reachable_var (var);
+ gcc_assert (strg != nullptr);
+ storage_address address (strg->get_ref (), off_bits);
+ result.set_address (address);
+ }
+ else if (TREE_CODE (var) == INDIRECT_REF
+ || TREE_CODE (var) == MEM_REF)
+ {
+ gcc_assert (TREE_CODE (var) == INDIRECT_REF
+ || integer_zerop (TREE_OPERAND (var, 1)));
+ data_value root_val = evaluate (TREE_OPERAND (var, 0));
+ gcc_assert (root_val.classify () == VAL_ADDRESS);
+ storage_address *root_addr = root_val.get_address ();
+ gcc_assert (root_addr != nullptr);
+ gcc_assert (root_addr->offset == 0);
+ storage_address address (root_addr->storage, off_bits);
+ result.set_address (address);
+ }
+ else
+ gcc_unreachable ();
}
return result;
}
@@ -4047,7 +4075,7 @@ data_value
exec_context::evaluate_binary (enum tree_code code, tree type, tree lhs, tree rhs) const
{
gcc_assert (TREE_TYPE (lhs) == TREE_TYPE (rhs)
- || (TREE_CODE (rhs) == INTEGER_CST
+ || (TREE_CODE (TREE_TYPE (rhs)) == INTEGER_TYPE
&& TREE_CODE (TREE_TYPE (lhs)) == INTEGER_TYPE
&& TYPE_PRECISION (TREE_TYPE (lhs)) == TYPE_PRECISION (TREE_TYPE (rhs))
&& TYPE_UNSIGNED (TREE_TYPE (lhs)) == TYPE_UNSIGNED (TREE_TYPE (rhs)))
@@ -4065,6 +4093,11 @@ exec_context::evaluate_binary (enum tree_code code, tree type, tree lhs, tree rh
enum value_type rhs_type = val_rhs.classify ();
if (lhs_type == VAL_CONSTANT && rhs_type == VAL_CONSTANT)
{
+ gcc_assert (TREE_TYPE (lhs) == TREE_TYPE (rhs)
+ || (TREE_CODE (rhs) == INTEGER_CST
+ && TREE_CODE (TREE_TYPE (lhs)) == INTEGER_TYPE
+ && TYPE_PRECISION (TREE_TYPE (lhs)) == TYPE_PRECISION (TREE_TYPE (rhs))
+ && TYPE_UNSIGNED (TREE_TYPE (lhs)) == TYPE_UNSIGNED (TREE_TYPE (rhs))));
tree lval = val_lhs.to_tree (TREE_TYPE (lhs));
tree rval = val_rhs.to_tree (TREE_TYPE (rhs));
tree t = fold_binary (code, type, lval, rval);
@@ -6805,6 +6838,146 @@ exec_context_evaluate_literal_tests ()
ASSERT_PRED1 (wi::fits_shwi_p, wi_value);
int int_value = wi_value.to_shwi ();
ASSERT_EQ (int_value, 13);
+
+ heap_memory mem2;
+ context_printer printer2;
+
+ tree derived = make_node (RECORD_TYPE);
+ tree field2 = build_decl (input_location, FIELD_DECL,
+ get_identifier ("field2"), integer_type_node);
+ DECL_CONTEXT (field2) = derived;
+ DECL_CHAIN (field2) = NULL_TREE;
+ tree field1 = build_decl (input_location, FIELD_DECL,
+ get_identifier ("field1"), integer_type_node);
+ DECL_CONTEXT (field1) = derived;
+ DECL_CHAIN (field1) = field2;
+ TYPE_FIELDS (derived) = field1;
+ layout_type (derived);
+
+ tree d = create_var (derived, "d");
+
+ vec<tree> decls2{};
+ decls2.safe_push (d);
+
+ context_builder builder2 {};
+ builder2.add_decls (&decls2);
+ exec_context ctx2 = builder2.build (mem2, printer2);
+
+ tree comp = fold_build3_loc (input_location, COMPONENT_REF,
+ integer_type_node, d, field2, NULL_TREE);
+ tree int_ptr = build_pointer_type (integer_type_node);
+ tree comp_addr = build1 (ADDR_EXPR, int_ptr, comp);
+
+ data_value val2 = ctx2.evaluate (comp_addr);
+ ASSERT_EQ (val2.classify (), VAL_ADDRESS);
+ storage_address *ptr_addr2 = val2.get_address ();
+ ASSERT_NE (ptr_addr2, nullptr);
+ data_storage &strg_ptr2 = ptr_addr2->storage.get ();
+ ASSERT_PRED1 (strg_ptr2.matches, d);
+ ASSERT_EQ (ptr_addr2->offset, HOST_BITS_PER_INT);
+
+ heap_memory mem3;
+ context_printer printer3;
+
+ tree derived3 = make_node (RECORD_TYPE);
+ tree d3_field2 = build_decl (input_location, FIELD_DECL,
+ get_identifier ("field2"), integer_type_node);
+ DECL_CONTEXT (d3_field2) = derived3;
+ DECL_CHAIN (d3_field2) = NULL_TREE;
+ tree d3_field1 = build_decl (input_location, FIELD_DECL,
+ get_identifier ("field1"), integer_type_node);
+ DECL_CONTEXT (d3_field1) = derived3;
+ DECL_CHAIN (d3_field1) = d3_field2;
+ TYPE_FIELDS (derived3) = d3_field1;
+ layout_type (derived3);
+
+ tree d3 = create_var (derived3, "d3");
+ tree ptr_d3 = build_pointer_type (derived3);
+ tree p3 = create_var (ptr_d3, "p3");
+
+ vec<tree> decls3{};
+ decls3.safe_push (d3);
+ decls3.safe_push (p3);
+
+ context_builder builder3 {};
+ builder3.add_decls (&decls3);
+ exec_context ctx3 = builder3.build (mem3, printer3);
+
+ data_storage *strg_d3 = ctx3.find_reachable_var (d3);
+ gcc_assert (strg_d3 != nullptr);
+ data_storage *strg_p3 = ctx3.find_reachable_var (p3);
+ gcc_assert (strg_p3 != nullptr);
+ storage_address addr_d3 (strg_d3->get_ref (), 0);
+ data_value val_p3 (ptr_d3);
+ val_p3.set_address (addr_d3);
+ strg_p3->set (val_p3);
+
+ tree deref_p3 = build_fold_indirect_ref_loc (input_location, p3);
+ tree comp3 = fold_build3_loc (input_location, COMPONENT_REF,
+ integer_type_node, deref_p3, d3_field2,
+ NULL_TREE);
+ tree int_ptr3 = build_pointer_type (integer_type_node);
+ tree comp_addr3 = build1 (ADDR_EXPR, int_ptr3, comp3);
+
+ data_value val3 = ctx3.evaluate (comp_addr3);
+ ASSERT_EQ (val3.classify (), VAL_ADDRESS);
+ storage_address *ptr_addr3 = val3.get_address ();
+ ASSERT_NE (ptr_addr3, nullptr);
+ data_storage &strg_ptr3 = ptr_addr3->storage.get ();
+ ASSERT_PRED1 (strg_ptr3.matches, d3);
+ ASSERT_EQ (ptr_addr3->offset, HOST_BITS_PER_INT);
+
+ heap_memory mem4;
+ context_printer printer4;
+
+ tree derived4 = make_node (RECORD_TYPE);
+ tree d4_field2 = build_decl (input_location, FIELD_DECL,
+ get_identifier ("field2"), integer_type_node);
+ DECL_CONTEXT (d4_field2) = derived4;
+ DECL_CHAIN (d4_field2) = NULL_TREE;
+ tree d4_field1 = build_decl (input_location, FIELD_DECL,
+ get_identifier ("field1"), integer_type_node);
+ DECL_CONTEXT (d4_field1) = derived4;
+ DECL_CHAIN (d4_field1) = d4_field2;
+ TYPE_FIELDS (derived4) = d4_field1;
+ layout_type (derived4);
+
+ tree d4 = create_var (derived4, "d4");
+ tree ptr_d4 = build_pointer_type (derived4);
+ tree p4 = create_var (ptr_d4, "p4");
+
+ vec<tree> decls4{};
+ decls4.safe_push (d4);
+ decls4.safe_push (p4);
+
+ context_builder builder4 {};
+ builder4.add_decls (&decls4);
+ exec_context ctx4 = builder4.build (mem4, printer4);
+
+ data_storage *strg_d4 = ctx4.find_reachable_var (d4);
+ gcc_assert (strg_d4 != nullptr);
+ data_storage *strg_p4 = ctx4.find_reachable_var (p4);
+ gcc_assert (strg_p4 != nullptr);
+ storage_address addr_d4 (strg_d4->get_ref (), 0);
+ data_value val_p4 (ptr_d4);
+ val_p4.set_address (addr_d4);
+ strg_p4->set (val_p4);
+
+ tree mem_p4 = fold_build2_loc (input_location, MEM_REF,
+ derived4, p4, build_int_cst (ptr_d4, 0));
+ tree comp4 = fold_build3_loc (input_location, COMPONENT_REF,
+ integer_type_node, mem_p4, d4_field2,
+ NULL_TREE);
+ tree int_ptr4 = build_pointer_type (integer_type_node);
+ tree comp_addr4 = build1 (ADDR_EXPR, int_ptr4, comp4);
+
+ data_value val4 = ctx4.evaluate (comp_addr4);
+ ASSERT_EQ (val4.classify (), VAL_ADDRESS);
+ storage_address *ptr_addr4 = val4.get_address ();
+ ASSERT_NE (ptr_addr4, nullptr);
+ data_storage &strg_ptr4 = ptr_addr4->storage.get ();
+ ASSERT_PRED1 (strg_ptr4.matches, d4);
+ ASSERT_EQ (ptr_addr4->offset, HOST_BITS_PER_INT);
}
void
More information about the Gcc-cvs
mailing list