https://gcc.gnu.org/g:9a56435e6d00c4dfd7dbbc41bba84dce3a96395f
commit r17-5686-g9a56435e6d00c4dfd7dbbc41bba84dce3a96395f Author: Andrew MacLeod <[email protected]> Date: Wed Oct 28 10:49:47 2026 -0400 Eliminate ptr_info_def structure This eliminates the ptr_info_def structure, and puts the three component members directly into a prange_storage object. Assisted-by: Claude Opus 5 Assisted-by: GPT-6.1-Sol * tree-core.h (struct ptr_info_def): Remove declaration. * tree-ssanames.cc (range_info_p): Remove. (range_info_fits_p): Adjust. (ssa_name_prange_storage): Rename from ssa_name_ptr_info and adjust. (set_pt_solution): New. (get_pt_solution): Rename from get_ptr_info and adjust. (ssa_name_pt_solution): Adjust. (set_ssa_name_pt_solution): Adjust. (range_info_set_range): Adjust. (set_range_info): Adjust. (set_ptr_nonnull): Adjust. (get_nonzero_bits_1): Adjust. (get_known_nonzero_bits_1 ): Adjust. (get_ptr_info_alignment): Adjust. (mark_ptr_info_alignment_unknown): Adjust. (set_ptr_info_alignment): Adjust. (set_ssa_name_ptr_info): Remove. (duplicate_ssa_name_ptr_info): Adjust. (duplicate_ssa_name_range_info): Adjust. (duplicate_ssa_name_fn): Adjust. (reset_flow_sensitive_info): Adjust. (flow_sensitive_info_storage::save): Adjust. (flow_sensitive_info_storage::restore): Adjust. * tree-ssanames.h (struct ptr_info_def): Remove. (flow_sensitive_info_storage::align): Remove. (flow_sensitive_info_storage::misalign): Remove. * value-range-storage.cc (prange_storage::prange_storage): Set new fields. * value-range-storage.h (prange_storage::ptr_info): Remove. (prange_storage::pt): New. (prange_storage::align): New. (prange_storage::misalign): New. Diff: --- gcc/tree-core.h | 1 - gcc/tree-ssanames.cc | 211 +++++++++++++++++++-------------------------- gcc/tree-ssanames.h | 33 +------ gcc/value-range-storage.cc | 9 +- gcc/value-range-storage.h | 22 +++-- 5 files changed, 116 insertions(+), 160 deletions(-) diff --git a/gcc/tree-core.h b/gcc/tree-core.h index 6bab44f3c6d6..bea6bb5cc117 100644 --- a/gcc/tree-core.h +++ b/gcc/tree-core.h @@ -32,7 +32,6 @@ along with GCC; see the file COPYING3. If not see struct function; struct real_value; struct fixed_value; -struct ptr_info_def; struct die_struct; class irange; diff --git a/gcc/tree-ssanames.cc b/gcc/tree-ssanames.cc index 0660c6177677..9035d9bfdc00 100644 --- a/gcc/tree-ssanames.cc +++ b/gcc/tree-ssanames.cc @@ -73,20 +73,12 @@ unsigned int ssa_name_nodes_created; #define FREE_SSANAMES(fun) (fun)->gimple_df->free_ssanames #define FREE_SSANAMES_QUEUE(fun) (fun)->gimple_df->free_ssanames_queue -/* Return TRUE if NAME has global range info. */ - -inline bool -range_info_p (const_tree name) -{ - return SSA_NAME_RANGE_INFO (name); -} - /* Return TRUE if R fits in the global range of NAME. */ inline bool range_info_fits_p (tree name, const vrange &r) { - gcc_checking_assert (range_info_p (name)); + gcc_checking_assert (SSA_NAME_RANGE_INFO (name)); vrange_storage *mem = SSA_NAME_RANGE_INFO (name); return mem->fits_p (r); } @@ -111,38 +103,58 @@ range_info_free (tree name) ggc_free (mem); } -/* Return the aliasing information for ssa-name NAME, or NULL if there - is none. Return NULL for non pointer types. */ +/* Return NAME's pointer range storage, or NULL if none exists. */ -static inline struct ptr_info_def * -ssa_name_ptr_info (const_tree name) +static inline prange_storage * +ssa_name_prange_storage (const_tree name) { vrange_storage *mem = SSA_NAME_RANGE_INFO (name); if (!mem || mem->m_discriminator != VR_PRANGE) return NULL; - return static_cast <prange_storage *> (mem)->ptr_info; + return static_cast <prange_storage *> (mem); +} + +/* Attach PT to NAME, creating range storage if necessary. */ + +static void +set_pt_solution (tree name, pt_solution *pt) +{ + gcc_checking_assert (POINTER_TYPE_P (TREE_TYPE (name))); + if (!SSA_NAME_RANGE_INFO (name)) + SSA_NAME_RANGE_INFO (name) = ggc_alloc_vrange_storage (TREE_TYPE (name)); + ssa_name_prange_storage (name)->pt = pt; } -/* Defined below. */ -static struct ptr_info_def *get_ptr_info (tree); +/* Return NAME's solution, creating an unknown solution if necessary. */ -/* Return the points-to solution for ssa-name NAME. Return NULL if it has - none or is a non pointer types. */ +static pt_solution * +get_pt_solution (tree name) +{ + gcc_assert (POINTER_TYPE_P (TREE_TYPE (name))); + prange_storage *s = ssa_name_prange_storage (name); + if (s && s->pt) + return s->pt; + pt_solution *pt = ggc_cleared_alloc<pt_solution> (); + pt_solution_reset (pt); + set_pt_solution (name, pt); + return pt; +} + +/* Return NAME's points-to solution, or NULL if none exists. */ const pt_solution * ssa_name_pt_solution (const_tree name) { - struct ptr_info_def *pi = ssa_name_ptr_info (name); - return pi ? &pi->pt : NULL; + prange_storage *s = ssa_name_prange_storage (name); + return s ? s->pt : NULL; } -/* Make PT the points-to solution for NAME, which must have pointer type. */ +/* Make PT the points-to solution for NAME. */ void set_ssa_name_pt_solution (tree name, const pt_solution &pt) { - /* get_ptr_info asserts NAME is a pointer type. */ - get_ptr_info (name)->pt = pt; + *get_pt_solution (name) = pt; } /* Return the global range for NAME in R. */ @@ -159,20 +171,29 @@ range_info_get_range (const_tree name, vrange &r) inline bool range_info_set_range (tree name, const vrange &r) { - if (!range_info_p (name) || !range_info_fits_p (name, r)) + if (!SSA_NAME_RANGE_INFO (name) || !range_info_fits_p (name, r)) { - // Aliasing info belongs to NAME, not to the prange storage object which - // might get reallocated. ptr_info_def addresses may be cached - // elsewhere, so save and copy it back after any reallocation. - ptr_info_def *pi = ssa_name_ptr_info (name); - if (range_info_p (name)) + // Preserve SSA-owned points-to and alignment information when the + // variable-sized range storage must grow. + pt_solution *pt = NULL; + unsigned int align = 0, misalign = 0; + if (prange_storage *old = ssa_name_prange_storage (name)) + { + pt = old->pt; + align = old->align; + misalign = old->misalign; + } + if (SSA_NAME_RANGE_INFO (name)) range_info_free (name); vrange_storage *mem = range_info_alloc (name, r); - if (pi && mem) + if (mem && (pt || align)) { gcc_checking_assert (mem->m_discriminator == VR_PRANGE); - static_cast <prange_storage *> (mem)->ptr_info = pi; + prange_storage *s = static_cast <prange_storage *> (mem); + s->pt = pt; + s->align = align; + s->misalign = misalign; } return mem != NULL; } @@ -467,7 +488,7 @@ set_range_info (tree name, const vrange &r) // Pick up the current range, or VARYING if none. tree type = TREE_TYPE (name); value_range tmp (type); - if (range_info_p (name)) + if (SSA_NAME_RANGE_INFO (name)) range_info_get_range (name, tmp); else tmp.set_varying (type); @@ -478,9 +499,9 @@ set_range_info (tree name, const vrange &r) if (POINTER_TYPE_P (type)) { - // If R is nonnull and pi is not, set nonnull. - struct ptr_info_def *pi = get_ptr_info (name); - if (!tmp.contains_zero_p () && pi->pt.null) + // Preserve nonnullness in the points-to solution as well. + pt_solution *pt = get_pt_solution (name); + if (!tmp.contains_zero_p () && pt->null) set_ptr_nonnull (name); } @@ -508,8 +529,7 @@ void set_ptr_nonnull (tree name) { gcc_assert (POINTER_TYPE_P (TREE_TYPE (name))); - struct ptr_info_def *pi = get_ptr_info (name); - pi->pt.null = 0; + get_pt_solution (name)->null = 0; } /* Update the non-zero bits bitmask of NAME. */ @@ -574,7 +594,7 @@ get_nonzero_bits_1 (const_tree name) return wi::shwi (-1, precision); } - if (!range_info_p (name) || !irange::supports_p (TREE_TYPE (name))) + if (!SSA_NAME_RANGE_INFO (name) || !irange::supports_p (TREE_TYPE (name))) return wi::shwi (-1, precision); int_range_max tmp; @@ -622,7 +642,7 @@ get_known_nonzero_bits_1 (const_tree name) if (TREE_CODE (name) != SSA_NAME || POINTER_TYPE_P (TREE_TYPE (name))) return wi::shwi (0, precision); - if (!range_info_p (name) || !irange::supports_p (TREE_TYPE (name))) + if (!SSA_NAME_RANGE_INFO (name) || !irange::supports_p (TREE_TYPE (name))) return wi::shwi (0, precision); int_range_max tmp; @@ -776,7 +796,7 @@ bool get_ptr_info_alignment (const_tree name, unsigned int *alignp, unsigned int *misalignp) { - struct ptr_info_def *pi = ssa_name_ptr_info (name); + prange_storage *pi = ssa_name_prange_storage (name); if (pi && pi->align) { @@ -795,7 +815,7 @@ get_ptr_info_alignment (const_tree name, unsigned int *alignp, void mark_ptr_info_alignment_unknown (tree name) { - struct ptr_info_def *pi = ssa_name_ptr_info (name); + prange_storage *pi = ssa_name_prange_storage (name); if (pi) { @@ -815,50 +835,14 @@ set_ptr_info_alignment (tree name, unsigned int align, unsigned int misalign) gcc_assert ((align & (align - 1)) == 0); gcc_assert ((misalign & ~(align - 1)) == 0); - struct ptr_info_def *pi = get_ptr_info (name); + gcc_assert (POINTER_TYPE_P (TREE_TYPE (name))); + if (!SSA_NAME_RANGE_INFO (name)) + SSA_NAME_RANGE_INFO (name) = ggc_alloc_vrange_storage (TREE_TYPE (name)); + prange_storage *pi = ssa_name_prange_storage (name); pi->align = align; pi->misalign = misalign; } -/* Make PI the aliasing information for NAME. Allocate a VARYING range if - NAME does not already have a range. */ - -static void -set_ssa_name_ptr_info (tree name, struct ptr_info_def *pi) -{ - gcc_checking_assert (POINTER_TYPE_P (TREE_TYPE (name))); - - if (!range_info_p (name)) - SSA_NAME_RANGE_INFO (name) = ggc_alloc_vrange_storage (TREE_TYPE (name)); - - vrange_storage *mem = SSA_NAME_RANGE_INFO (name); - gcc_checking_assert (mem && mem->m_discriminator == VR_PRANGE); - static_cast <prange_storage *> (mem)->ptr_info = pi; -} - -/* Return the alias information associated with pointer T. It creates a - new instance if none existed. */ - -static struct ptr_info_def * -get_ptr_info (tree t) -{ - struct ptr_info_def *pi; - - gcc_assert (POINTER_TYPE_P (TREE_TYPE (t))); - - pi = ssa_name_ptr_info (t); - if (pi == NULL) - { - // The cleared allocation leaves align and misalign zero, which is - // what unknown alignment is, so there is nothing more to initialize. - pi = ggc_cleared_alloc<ptr_info_def> (); - pt_solution_reset (&pi->pt); - set_ssa_name_ptr_info (t, pi); - } - - return pi; -} - /* Creates a new SSA name using the template NAME tobe defined by statement STMT in function FN. */ @@ -887,18 +871,13 @@ void duplicate_ssa_name_ptr_info (tree dest, const pt_solution* pt) { gcc_assert (POINTER_TYPE_P (TREE_TYPE (dest))); - gcc_assert (!ssa_name_ptr_info (dest)); + gcc_assert (!ssa_name_pt_solution (dest)); if (!pt) return; - - struct ptr_info_def *new_ptr_info = ggc_alloc<ptr_info_def> (); - new_ptr_info->pt = *pt; - - // Alignment info is not copied, so its set to zero. - new_ptr_info->align = 0; - new_ptr_info->misalign = 0; - set_ssa_name_ptr_info (dest, new_ptr_info); + pt_solution *copy = ggc_alloc<pt_solution> (); + *copy = *pt; + set_pt_solution (dest, copy); } /* Give DEST its own copy of the points-to and alignment information of @@ -908,11 +887,11 @@ duplicate_ssa_name_ptr_info (tree dest, const pt_solution* pt) void duplicate_ssa_name_ptr_info (tree dest, tree src) { - struct ptr_info_def *ptr_info = (src ? ssa_name_ptr_info (src) : NULL); - if (!ptr_info) - return; + if (!src) + return; - duplicate_ssa_name_ptr_info (dest, &(ptr_info->pt)); + if (const pt_solution *pt = ssa_name_pt_solution (src)) + duplicate_ssa_name_ptr_info (dest, pt); } /* Copy any global range and aliasing information from SRC to NAME. */ @@ -920,9 +899,9 @@ duplicate_ssa_name_ptr_info (tree dest, tree src) void duplicate_ssa_name_range_info (tree name, tree src) { - gcc_checking_assert (!range_info_p (name)); + gcc_checking_assert (!SSA_NAME_RANGE_INFO (name)); - if (!range_info_p (src)) + if (!SSA_NAME_RANGE_INFO (src)) return; value_range src_range (TREE_TYPE (src)); @@ -964,7 +943,7 @@ duplicate_ssa_name_fn (struct function *fn, tree name, gimple *stmt) { tree new_name = copy_ssa_name_fn (fn, name, stmt); - if (range_info_p (name)) + if (SSA_NAME_RANGE_INFO (name)) duplicate_ssa_name_range_info (new_name, name); return new_name; @@ -978,15 +957,16 @@ void reset_flow_sensitive_info (tree name) { /* Aliasing info is not flow sensitive, so preserve it if present. */ - ptr_info_def *pi = ssa_name_ptr_info (name); + prange_storage *s = ssa_name_prange_storage (name); + pt_solution *pt = s ? s->pt : NULL; SSA_NAME_RANGE_INFO (name) = NULL; - if (pi) + if (pt) { - set_ssa_name_ptr_info (name, pi); + set_pt_solution (name, pt); /* [E]VRP can derive context sensitive alignment info and - non-nullness properties. We must reset both. */ - mark_ptr_info_alignment_unknown (name); - pi->pt.null = 1; + non-nullness properties. We must reset both. The alignment went + with the range storage above; only the nullness is left. */ + pt->null = 1; } // Clear range info in the current range query. @@ -1137,13 +1117,8 @@ flow_sensitive_info_storage::save (tree name) return; } state = -1; - if (!get_ptr_info_alignment (name, &align, &misalign)) - { - align = 0; - misalign = 0; - } - auto ptr_info = ssa_name_ptr_info (name); - null = ptr_info ? ptr_info->pt.null : true; + const pt_solution *pt = ssa_name_pt_solution (name); + null = pt ? pt->null : true; } /* Restore the flow sensitive info from NAME. */ @@ -1152,6 +1127,9 @@ void flow_sensitive_info_storage::restore (tree name) { gcc_assert (state != 0); + /* The storage carries the range, its bitmask and -- for now -- the + alignment, so reinstating it restores all three. Only the nullness + lives outside it. */ SSA_NAME_RANGE_INFO (name) = range_info; if (!POINTER_TYPE_P (TREE_TYPE (name))) { @@ -1159,16 +1137,9 @@ flow_sensitive_info_storage::restore (tree name) return; } gcc_assert (state == -1); - auto ptr_info = ssa_name_ptr_info (name); - /* If there was no flow sensitive info on the pointer - just return, there is nothing to restore to. */ - if (!ptr_info) - return; - if (align != 0) - set_ptr_info_alignment (name, align, misalign); - else - mark_ptr_info_alignment_unknown (name); - ssa_name_ptr_info (name)->pt.null = null; + prange_storage *s = ssa_name_prange_storage (name); + if (s && s->pt) + s->pt->null = null; } /* Save off the flow sensitive info from NAME. diff --git a/gcc/tree-ssanames.h b/gcc/tree-ssanames.h index 28fd467dc874..bbd5890c4ff1 100644 --- a/gcc/tree-ssanames.h +++ b/gcc/tree-ssanames.h @@ -20,32 +20,6 @@ along with GCC; see the file COPYING3. If not see #ifndef GCC_TREE_SSANAMES_H #define GCC_TREE_SSANAMES_H -/* Aliasing information for SSA_NAMEs representing pointer variables. */ - -struct GTY(()) ptr_info_def -{ - /* The points-to solution. */ - struct pt_solution pt; - - /* Alignment and misalignment of the pointer in bytes. Together - align and misalign specify low known bits of the pointer. - ptr & (align - 1) == misalign. */ - - /* When known, this is the power-of-two byte alignment of the object this - pointer points into. This is usually DECL_ALIGN_UNIT for decls and - MALLOC_ABI_ALIGNMENT for allocated storage. When the alignment is not - known, it is zero. Do not access directly: the only accessors are - get_ptr_info_alignment, set_ptr_info_alignment and - mark_ptr_info_alignment_unknown, and they take the SSA name rather - than this structure, so that the representation can move. */ - unsigned int align; - - /* When alignment is known, the byte offset this pointer differs from the - above alignment. Access only through the same helper functions as align - above. */ - unsigned int misalign; -}; - /* Return NAME's points-to solution, or NULL if it has none. Returns NULL for a non pointer type. */ extern const pt_solution *ssa_name_pt_solution (const_tree name); @@ -158,11 +132,10 @@ private: -1 means a pointer type is saved. -2 means a pointer type is saved but no information was saved. */ int state = 0; - /* The range info for non pointers */ + /* The range info, which for a pointer also carries the bitmask and the + alignment, so those need no separate slot here. */ vrange_storage *range_info = nullptr; - /* Flow sensitive pointer information. */ - unsigned int align = 0; - unsigned int misalign = 0; + /* Flow sensitive pointer information not held in the range. */ bool null = true; }; diff --git a/gcc/value-range-storage.cc b/gcc/value-range-storage.cc index b121ffac7543..35997372e7c6 100644 --- a/gcc/value-range-storage.cc +++ b/gcc/value-range-storage.cc @@ -638,9 +638,12 @@ prange_storage::alloc (vrange_internal_alloc &allocator, const prange &r, prange_storage::prange_storage (const prange &r) : vrange_storage (VR_PRANGE) { - // Aliasing info is not part of the range, so it is never copied from one. - // Only set_ssa_name_ptr_info() in tree-ssanames.cc ever makes this non-null. - ptr_info = NULL; + // None of these is part of the range, so none is ever copied from one. + // Only the accessors in tree-ssanames.cc ever make them non-zero, and + // range_info_set_range carries them across a reallocation. + pt = NULL; + align = 0; + misalign = 0; unsigned num_words; enum prange_kind kind = prange_format (r, num_words); diff --git a/gcc/value-range-storage.h b/gcc/value-range-storage.h index 46e98684360c..f4c264d5ede8 100644 --- a/gcc/value-range-storage.h +++ b/gcc/value-range-storage.h @@ -113,6 +113,13 @@ const unsigned int PRANGE_STORAGE_NINTS = 4; // Efficient memory storage for a prange. class GTY((tag ("VR_PRANGE"))) prange_storage : public vrange_storage { +private: + // vrange_storage ends after four bytes but the first pointer member below + // needs eight-byte alignment, so there is a four-byte hole. + enum prange_kind m_kind : 4; + unsigned int m_has_bitmask : 1; + unsigned int m_points_to_p : 1; + public: friend void gt_ggc_mx_vrange_storage(void *); friend void gt_pch_nx_vrange_storage(void *); @@ -126,18 +133,21 @@ public: bool fits_p (const prange &r) const; void dump () const; - // Pointer aliasing information. Managed separately, and reached only - // through the accessors in tree-ssanames.h. - struct ptr_info_def *ptr_info; + // The points-to solution for the SSA name is flow insensitive and is + // reached only through ssa_name_pt_solution. + struct pt_solution *pt; + + // Alignment and misalignment of the pointer in bytes. Together + // align and misalign specify low known bits of the pointer. + // ptr & (align - 1) == misalign. + unsigned int align; + unsigned int misalign; private: DISABLE_COPY_AND_ASSIGN (prange_storage); prange_storage (const prange &r); static enum prange_kind prange_format (const prange &r, unsigned &num_words); - enum prange_kind m_kind; - bool m_has_bitmask; - bool m_points_to_p; tree m_pt; // We don't use TRAILING_WIDE_INT_ACCESSOR because the getters here
