{
static hashval_t hash (sat_entry *e)
{
- /* Since normalize_atom caches the ATOMIC_CONSTRs it returns,
- we can assume pointer-based identity for fast hashing and
- comparison. Even if this assumption is violated, that's
- okay, we'll just get a cache miss. */
+ if (ATOMIC_CONSTR_MAP_INSTANTIATED_P (e->constr))
+ {
+ /* Atoms with instantiated mappings are built during satisfaction.
+ They live only inside the sat_cache, and we build one to query
+ the cache with each time we instantiate a mapping. */
+ gcc_assert (!e->args);
+ return hash_atomic_constraint (e->constr);
+ }
+
+ /* Atoms with uninstantiated mappings are built during normalization.
+ Since normalize_atom caches the atoms it returns, we can assume
+ pointer-based identity for fast hashing and comparison. Even if this
+ assumption is violated, that's okay, we'll just get a cache miss. */
hashval_t value = htab_hash_pointer (e->constr);
+
return iterative_hash_template_arg (e->args, value);
}
static bool equal (sat_entry *e1, sat_entry *e2)
{
- /* As in sat_hasher::hash. */
+ if (ATOMIC_CONSTR_MAP_INSTANTIATED_P (e1->constr)
+ != ATOMIC_CONSTR_MAP_INSTANTIATED_P (e2->constr))
+ return false;
+
+ /* See sat_hasher::hash. */
+ if (ATOMIC_CONSTR_MAP_INSTANTIATED_P (e1->constr))
+ {
+ gcc_assert (!e1->args && !e2->args);
+ return atomic_constraints_identical_p (e1->constr, e2->constr);
+ }
+
if (e1->constr != e2->constr)
return false;
return template_args_equal (e1->args, e2->args);
return cache.save (boolean_false_node);
}
+ /* Now build a new atom using the instantiated mapping. We use
+ this atom as a second key to the satisfaction cache, and we
+ also pass it to diagnose_atomic_constraint so that diagnostics
+ which refer to the atom display the instantiated mapping. */
+ t = copy_node (t);
+ ATOMIC_CONSTR_MAP (t) = map;
+ gcc_assert (!ATOMIC_CONSTR_MAP_INSTANTIATED_P (t));
+ ATOMIC_CONSTR_MAP_INSTANTIATED_P (t) = true;
+ satisfaction_cache inst_cache (t, /*args=*/NULL_TREE, info.complain);
+ if (tree r = inst_cache.get ())
+ return cache.save (r);
+
/* Rebuild the argument vector from the parameter mapping. */
args = get_mapped_args (map);
is not satisfied. Replay the substitution. */
if (info.noisy ())
tsubst_expr (expr, args, info.complain, info.in_decl, false);
- return cache.save (boolean_false_node);
+ return cache.save (inst_cache.save (boolean_false_node));
}
/* [17.4.1.2] ... lvalue-to-rvalue conversion is performed as necessary,
and EXPR shall be a constant expression of type bool. */
result = force_rvalue (result, info.complain);
if (result == error_mark_node)
- return cache.save (error_mark_node);
+ return cache.save (inst_cache.save (error_mark_node));
if (!same_type_p (TREE_TYPE (result), boolean_type_node))
{
if (info.noisy ())
diagnose_atomic_constraint (t, map, result, info);
- return cache.save (error_mark_node);
+ return cache.save (inst_cache.save (error_mark_node));
}
/* Compute the value of the constraint. */
if (result == boolean_false_node && info.noisy ())
diagnose_atomic_constraint (t, map, result, info);
- return cache.save (result);
+ return cache.save (inst_cache.save (result));
}
/* Determine if the normalized constraint T is satisfied.
diagnose_requires_expr (expr, map, info.in_decl);
break;
default:
- tree a = copy_node (t);
- ATOMIC_CONSTR_MAP (a) = map;
if (!same_type_p (TREE_TYPE (result), boolean_type_node))
error_at (loc, "constraint %qE has type %qT, not %<bool%>",
- a, TREE_TYPE (result));
+ t, TREE_TYPE (result));
else
- inform (loc, "the expression %qE evaluated to %<false%>", a);
- ggc_free (a);
+ inform (loc, "the expression %qE evaluated to %<false%>", t);
}
}
REINTERPRET_CAST_P (in NOP_EXPR)
ALIGNOF_EXPR_STD_P (in ALIGNOF_EXPR)
OVL_DEDUP_P (in OVERLOAD)
+ ATOMIC_CONSTR_MAP_INSTANTIATED_P (in ATOMIC_CONSTR)
1: IDENTIFIER_KIND_BIT_1 (in IDENTIFIER_NODE)
TI_PENDING_TEMPLATE_FLAG.
TEMPLATE_PARMS_FOR_INLINE.
#define ATOMIC_CONSTR_MAP(NODE) \
TREE_OPERAND (TREE_CHECK (NODE, ATOMIC_CONSTR), 0)
+/* Whether the parameter mapping of this atomic constraint
+ is already instantiated with concrete template arguments.
+ Used only in satisfy_atom and in the satisfaction cache. */
+#define ATOMIC_CONSTR_MAP_INSTANTIATED_P(NODE) \
+ TREE_LANG_FLAG_0 (ATOMIC_CONSTR_CHECK (NODE))
+
/* The expression of an atomic constraint. */
#define ATOMIC_CONSTR_EXPR(NODE) \
CONSTR_EXPR (ATOMIC_CONSTR_CHECK (NODE))