On Thu, Oct 15, 2026 at 11:09:27AM +0200, Richard Biener wrote:
> Oh, yeah - I remember asking for that for general CTORs. I wonder whether
> for STRING_CST and RAW_DATA_CST we could instead limit
> MIN (vr.upper_bound - vr.lower_bound, size), thus allow inspecting 32
> elements of a [10000] array because we can efficiently access the Nth
> element for STRING_CST (and RAW_DATA_CST?) rather than having
> to walk (or besarch) the CTOR.
If we change what the param means, then sure, we can do all kinds of stuff.
Note, for COMPONENT_REFs, we also walk the CONSTRUCTOR_ELTS (though unlike
the array cases we have early exit in that case instead of walking
everything). And (at least when using FIELD_DECL pointer comparison (see my
previously posted workaround patch for the slower case), the COMPONENT_REF
check is much cheaper compile time wise than the intersect_p + union_
thing. So, if we let the limit propagate in m_cnt member and let each
function decrement it by whatever cost it sees and punt if we run out of
limit, we can do different things for the different cases.
Count the COMPONENT_REFs checks or not? If yes, count with the same cost (1
for each, or count COMPONENT_REFs as 1 and ARRAY_REFs as 2 or 4)?
For ARRAY_REFs CONSTRUCTOR, CONSTRUCTOR_NELTS is I guess what we care about,
if we have say { [32 ... 1024] = 42 }; then no matter what the array size
is, we need to do just one intersects_p and one union_.
For STRING_CST and RAW_DATA_CSTs, we could then say count number of
intersecting bytes
wide_int cnt = wi::zero (TYPE_PRECISION (type));
for (unsigned i = 0; i < idx_r.num_pairs (); ++i)
{
wide_int l = idx_r.lower_bound (i);
wide_int u = idx_r.upper_bound (i);
if (wi::lt_p (u, min, TYPE_SIGN (type))
|| wi::gt_p (l, max, TYPE_SIGN (type))
continue;
l = wi::max (l, min, TYPE_SIGN (type));
u = wi::min (u, max, TYPE_SIGN (type));
cnt += u - l + 1;
}
(where for RAW_DATA_CST min/max are actually lo and hi).
And then punt if we don't have at least cnt actions till limit (or
for RAW_DATA_CST that minus 1, because we've already counted the
RAW_DATA_CST in the CONSTRUCTOR_NELTS). Otherwise we could decide
on how to implement it based on the exact cnt value, TREE_STRING_LENGTH
/ RAW_DATA_LENGTH, for small TREE_STRING_LENGTH/RAW_DATA_LENGTH it isn't
worth to do anything extra and can do what I posted in the patch, for
very long sizes of those we need to do the smart walk on indexes
(basically exactly the same loop as above, just instead of the cnt += u - l
+ 1 loop over the elements), and based on whether cnt > 256 + epsilon
or not it could also switch in between doing union_ on each case or having
a 256 bool array, gather what bytes appear and then loop over that array
and union_ that.
Or, for small TREE_STRING_LENGTH / RAW_DATA_LENGTH, even don't do the above
cnt computation and just do what the patch does and count that length into
the limit, and only if it is larger do the smarter things.
Do you want those changes as part of this patch, or can that be done
incrementally?
Jakub