return true;
}
+/* Cache wide_int CST into the TYPE_CACHED_VALUES cache for TYPE.
+ SLOT is the slot entry to store it in, and MAX_SLOTS is the maximum
+ number of slots that can be cached for the type. */
+
+static inline tree
+cache_wide_int_in_type_cache (tree type, const wide_int &cst,
+ int slot, int max_slots)
+{
+ gcc_checking_assert (slot >= 0);
+ /* Initialize cache. */
+ if (!TYPE_CACHED_VALUES_P (type))
+ {
+ TYPE_CACHED_VALUES_P (type) = 1;
+ TYPE_CACHED_VALUES (type) = make_tree_vec (max_slots);
+ }
+ tree t = TREE_VEC_ELT (TYPE_CACHED_VALUES (type), slot);
+ if (!t)
+ {
+ /* Create a new shared int. */
+ t = build_new_int_cst (type, cst);
+ TREE_VEC_ELT (TYPE_CACHED_VALUES (type), slot) = t;
+ }
+ return t;
+}
+
/* Create an INT_CST node of TYPE and value CST.
The returned node is always shared. For small integers we use a
per-type vector cache, for larger ones we use a single hash table.
wide_int cst = wide_int::from (pcst, prec, sgn);
unsigned int ext_len = get_int_cst_ext_nunits (type, cst);
+ enum tree_code code = TREE_CODE (type);
+ if (code == POINTER_TYPE || code == REFERENCE_TYPE)
+ {
+ /* Cache NULL pointer and zero bounds. */
+ if (cst == 0)
+ ix = 0;
+ /* Cache upper bounds of pointers. */
+ else if (cst == wi::max_value (prec, sgn))
+ ix = 1;
+ /* Cache 1 which is used for a non-zero range. */
+ else if (cst == 1)
+ ix = 2;
+
+ if (ix >= 0)
+ {
+ t = cache_wide_int_in_type_cache (type, cst, ix, 3);
+ /* Make sure no one is clobbering the shared constant. */
+ gcc_checking_assert (TREE_TYPE (t) == type
+ && cst == wi::to_wide (t));
+ return t;
+ }
+ }
if (ext_len == 1)
{
/* We just need to store a single HOST_WIDE_INT. */
else
hwi = cst.to_shwi ();
- switch (TREE_CODE (type))
+ switch (code)
{
case NULLPTR_TYPE:
gcc_assert (hwi == 0);
case POINTER_TYPE:
case REFERENCE_TYPE:
- /* Cache NULL pointer and zero bounds. */
- if (hwi == 0)
- {
- limit = 1;
- ix = 0;
- }
+ /* Ignore pointers, as they were already handled above. */
break;
case BOOLEAN_TYPE:
if (ix >= 0)
{
- /* Look for it in the type's vector of small shared ints. */
- if (!TYPE_CACHED_VALUES_P (type))
- {
- TYPE_CACHED_VALUES_P (type) = 1;
- TYPE_CACHED_VALUES (type) = make_tree_vec (limit);
- }
-
- t = TREE_VEC_ELT (TYPE_CACHED_VALUES (type), ix);
- if (t)
- /* Make sure no one is clobbering the shared constant. */
- gcc_checking_assert (TREE_TYPE (t) == type
- && TREE_INT_CST_NUNITS (t) == 1
- && TREE_INT_CST_OFFSET_NUNITS (t) == 1
- && TREE_INT_CST_EXT_NUNITS (t) == 1
- && TREE_INT_CST_ELT (t, 0) == hwi);
- else
- {
- /* Create a new shared int. */
- t = build_new_int_cst (type, cst);
- TREE_VEC_ELT (TYPE_CACHED_VALUES (type), ix) = t;
- }
+ t = cache_wide_int_in_type_cache (type, cst, ix, limit);
+ /* Make sure no one is clobbering the shared constant. */
+ gcc_checking_assert (TREE_TYPE (t) == type
+ && TREE_INT_CST_NUNITS (t) == 1
+ && TREE_INT_CST_OFFSET_NUNITS (t) == 1
+ && TREE_INT_CST_EXT_NUNITS (t) == 1
+ && TREE_INT_CST_ELT (t, 0) == hwi);
+ return t;
}
else
{