]> git.ipfire.org Git - thirdparty/gcc.git/blob - gcc/cp/logic.cc
Update copyright years.
[thirdparty/gcc.git] / gcc / cp / logic.cc
1 /* Derivation and subsumption rules for constraints.
2 Copyright (C) 2013-2020 Free Software Foundation, Inc.
3 Contributed by Andrew Sutton (andrew.n.sutton@gmail.com)
4
5 This file is part of GCC.
6
7 GCC is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 3, or (at your option)
10 any later version.
11
12 GCC is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
16
17 You should have received a copy of the GNU General Public License
18 along with GCC; see the file COPYING3. If not see
19 <http://www.gnu.org/licenses/>. */
20
21 #include "config.h"
22 #define INCLUDE_LIST
23 #include "system.h"
24 #include "coretypes.h"
25 #include "tm.h"
26 #include "timevar.h"
27 #include "hash-set.h"
28 #include "machmode.h"
29 #include "vec.h"
30 #include "double-int.h"
31 #include "input.h"
32 #include "alias.h"
33 #include "symtab.h"
34 #include "wide-int.h"
35 #include "inchash.h"
36 #include "tree.h"
37 #include "stringpool.h"
38 #include "attribs.h"
39 #include "intl.h"
40 #include "flags.h"
41 #include "cp-tree.h"
42 #include "c-family/c-common.h"
43 #include "c-family/c-objc.h"
44 #include "cp-objcp-common.h"
45 #include "tree-inline.h"
46 #include "decl.h"
47 #include "toplev.h"
48 #include "type-utils.h"
49
50 /* Hash functions for atomic constrains. */
51
52 struct constraint_hash : default_hash_traits<tree>
53 {
54 static hashval_t hash (tree t)
55 {
56 return hash_atomic_constraint (t);
57 }
58
59 static bool equal (tree t1, tree t2)
60 {
61 return atomic_constraints_identical_p (t1, t2);
62 }
63 };
64
65 /* A conjunctive or disjunctive clause.
66
67 Each clause maintains an iterator that refers to the current
68 term, which is used in the linear decomposition of a formula
69 into CNF or DNF. */
70
71 struct clause
72 {
73 typedef std::list<tree>::iterator iterator;
74 typedef std::list<tree>::const_iterator const_iterator;
75
76 /* Initialize a clause with an initial term. */
77
78 clause (tree t)
79 {
80 m_terms.push_back (t);
81 if (TREE_CODE (t) == ATOMIC_CONSTR)
82 m_set.add (t);
83
84 m_current = m_terms.begin ();
85 }
86
87 /* Create a copy of the current term. The current
88 iterator is set to point to the same position in the
89 copied list of terms. */
90
91 clause (clause const& c)
92 : m_terms (c.m_terms), m_set (c.m_set), m_current (m_terms.begin ())
93 {
94 std::advance (m_current, std::distance (c.begin (), c.current ()));
95 }
96
97 /* Returns true when all terms are atoms. */
98
99 bool done () const
100 {
101 return m_current == end ();
102 }
103
104 /* Advance to the next term. */
105
106 void advance ()
107 {
108 gcc_assert (!done ());
109 ++m_current;
110 }
111
112 /* Replaces the current term at position ITER with T. If
113 T is an atomic constraint that already appears in the
114 clause, remove but do not replace ITER. Returns a pair
115 containing an iterator to the replace object or past
116 the erased object and a boolean value which is true if
117 an object was erased. */
118
119 std::pair<iterator, bool> replace (iterator iter, tree t)
120 {
121 gcc_assert (TREE_CODE (*iter) != ATOMIC_CONSTR);
122 if (TREE_CODE (t) == ATOMIC_CONSTR)
123 {
124 if (m_set.add (t))
125 return std::make_pair (m_terms.erase (iter), true);
126 }
127 *iter = t;
128 return std::make_pair (iter, false);
129 }
130
131 /* Inserts T before ITER in the list of terms. If T has
132 already is an atomic constraint that already appears in
133 the clause, no action is taken, and the current iterator
134 is returned. Returns a pair of an iterator to the inserted
135 object or ITER if no insertion occurred and a boolean
136 value which is true if an object was inserted. */
137
138 std::pair<iterator, bool> insert (iterator iter, tree t)
139 {
140 if (TREE_CODE (t) == ATOMIC_CONSTR)
141 {
142 if (m_set.add (t))
143 return std::make_pair (iter, false);
144 }
145 return std::make_pair (m_terms.insert (iter, t), true);
146 }
147
148 /* Replaces the current term with T. In the case where the
149 current term is erased (because T is redundant), update
150 the position of the current term to the next term. */
151
152 void replace (tree t)
153 {
154 m_current = replace (m_current, t).first;
155 }
156
157 /* Replace the current term with T1 and T2, in that order. */
158
159 void replace (tree t1, tree t2)
160 {
161 /* Replace the current term with t1. Ensure that iter points
162 to the term before which t2 will be inserted. Update the
163 current term as needed. */
164 std::pair<iterator, bool> rep = replace (m_current, t1);
165 if (rep.second)
166 m_current = rep.first;
167 else
168 ++rep.first;
169
170 /* Insert the t2. Make this the current term if we erased
171 the prior term. */
172 std::pair<iterator, bool> ins = insert (rep.first, t2);
173 if (rep.second && ins.second)
174 m_current = ins.first;
175 }
176
177 /* Returns true if the clause contains the term T. */
178
179 bool contains (tree t)
180 {
181 gcc_assert (TREE_CODE (t) == ATOMIC_CONSTR);
182 return m_set.contains (t);
183 }
184
185
186 /* Returns an iterator to the first clause in the formula. */
187
188 iterator begin ()
189 {
190 return m_terms.begin ();
191 }
192
193 /* Returns an iterator to the first clause in the formula. */
194
195 const_iterator begin () const
196 {
197 return m_terms.begin ();
198 }
199
200 /* Returns an iterator past the last clause in the formula. */
201
202 iterator end ()
203 {
204 return m_terms.end ();
205 }
206
207 /* Returns an iterator past the last clause in the formula. */
208
209 const_iterator end () const
210 {
211 return m_terms.end ();
212 }
213
214 /* Returns the current iterator. */
215
216 const_iterator current () const
217 {
218 return m_current;
219 }
220
221 std::list<tree> m_terms; /* The list of terms. */
222 hash_set<tree, false, constraint_hash> m_set; /* The set of atomic constraints. */
223 iterator m_current; /* The current term. */
224 };
225
226
227 /* A proof state owns a list of goals and tracks the
228 current sub-goal. The class also provides facilities
229 for managing subgoals and constructing term lists. */
230
231 struct formula
232 {
233 typedef std::list<clause>::iterator iterator;
234 typedef std::list<clause>::const_iterator const_iterator;
235
236 /* Construct a formula with an initial formula in a
237 single clause. */
238
239 formula (tree t)
240 {
241 /* This should call emplace_back(). There's a an extra copy being
242 invoked by using push_back(). */
243 m_clauses.push_back (t);
244 m_current = m_clauses.begin ();
245 }
246
247 /* Returns true when all clauses are atomic. */
248 bool done () const
249 {
250 return m_current == end ();
251 }
252
253 /* Advance to the next term. */
254 void advance ()
255 {
256 gcc_assert (!done ());
257 ++m_current;
258 }
259
260 /* Insert a copy of clause into the formula. This corresponds
261 to a distribution of one logical operation over the other. */
262
263 clause& branch ()
264 {
265 gcc_assert (!done ());
266 m_clauses.push_back (*m_current);
267 return m_clauses.back ();
268 }
269
270 /* Returns the position of the current clause. */
271
272 iterator current ()
273 {
274 return m_current;
275 }
276
277 /* Returns an iterator to the first clause in the formula. */
278
279 iterator begin ()
280 {
281 return m_clauses.begin ();
282 }
283
284 /* Returns an iterator to the first clause in the formula. */
285
286 const_iterator begin () const
287 {
288 return m_clauses.begin ();
289 }
290
291 /* Returns an iterator past the last clause in the formula. */
292
293 iterator end ()
294 {
295 return m_clauses.end ();
296 }
297
298 /* Returns an iterator past the last clause in the formula. */
299
300 const_iterator end () const
301 {
302 return m_clauses.end ();
303 }
304
305 std::list<clause> m_clauses; /* The list of clauses. */
306 iterator m_current; /* The current clause. */
307 };
308
309 void
310 debug (clause& c)
311 {
312 for (clause::iterator i = c.begin(); i != c.end(); ++i)
313 verbatim (" # %E", *i);
314 }
315
316 void
317 debug (formula& f)
318 {
319 for (formula::iterator i = f.begin(); i != f.end(); ++i)
320 {
321 verbatim ("(((");
322 debug (*i);
323 verbatim (")))");
324 }
325 }
326
327 /* The logical rules used to analyze a logical formula. The
328 "left" and "right" refer to the position of formula in a
329 sequent (as in sequent calculus). */
330
331 enum rules
332 {
333 left, right
334 };
335
336 /* Distribution counting. */
337
338 static inline bool
339 disjunction_p (tree t)
340 {
341 return TREE_CODE (t) == DISJ_CONSTR;
342 }
343
344 static inline bool
345 conjunction_p (tree t)
346 {
347 return TREE_CODE (t) == CONJ_CONSTR;
348 }
349
350 static inline bool
351 atomic_p (tree t)
352 {
353 return TREE_CODE (t) == ATOMIC_CONSTR;
354 }
355
356 /* Recursively count the number of clauses produced when converting T
357 to DNF. Returns a pair containing the number of clauses and a bool
358 value signifying that the the tree would be rewritten as a result of
359 distributing. In general, a conjunction for which this flag is set
360 is considered a disjunction for the purpose of counting. */
361
362 static std::pair<int, bool>
363 dnf_size_r (tree t)
364 {
365 if (atomic_p (t))
366 /* Atomic constraints produce no clauses. */
367 return std::make_pair (0, false);
368
369 /* For compound constraints, recursively count clauses and unpack
370 the results. */
371 tree lhs = TREE_OPERAND (t, 0);
372 tree rhs = TREE_OPERAND (t, 1);
373 std::pair<int, bool> p1 = dnf_size_r (lhs);
374 std::pair<int, bool> p2 = dnf_size_r (rhs);
375 int n1 = p1.first, n2 = p2.first;
376 bool d1 = p1.second, d2 = p2.second;
377
378 if (disjunction_p (t))
379 {
380 /* Matches constraints of the form P \/ Q. Disjunctions contribute
381 linearly to the number of constraints. When both P and Q are
382 disjunctions, clauses are added. When only one of P and Q
383 is a disjunction, an additional clause is produced. When neither
384 P nor Q are disjunctions, two clauses are produced. */
385 if (disjunction_p (lhs))
386 {
387 if (disjunction_p (rhs) || (conjunction_p (rhs) && d2))
388 /* Both P and Q are disjunctions. */
389 return std::make_pair (n1 + n2, d1 | d2);
390 else
391 /* Only LHS is a disjunction. */
392 return std::make_pair (1 + n1 + n2, d1 | d2);
393 gcc_unreachable ();
394 }
395 if (conjunction_p (lhs))
396 {
397 if ((disjunction_p (rhs) && d1) || (conjunction_p (rhs) && d1 && d2))
398 /* Both P and Q are disjunctions. */
399 return std::make_pair (n1 + n2, d1 | d2);
400 if (disjunction_p (rhs)
401 || (conjunction_p (rhs) && d1 != d2)
402 || (atomic_p (rhs) && d1))
403 /* Either LHS or RHS is a disjunction. */
404 return std::make_pair (1 + n1 + n2, d1 | d2);
405 else
406 /* Neither LHS nor RHS is a disjunction. */
407 return std::make_pair (2, false);
408 }
409 if (atomic_p (lhs))
410 {
411 if (disjunction_p (rhs) || (conjunction_p (rhs) && d2))
412 /* Only RHS is a disjunction. */
413 return std::make_pair (1 + n1 + n2, d1 | d2);
414 else
415 /* Neither LHS nor RHS is a disjunction. */
416 return std::make_pair (2, false);
417 }
418 }
419 else /* conjunction_p (t) */
420 {
421 /* Matches constraints of the form P /\ Q, possibly resulting
422 in the distribution of one side over the other. When both
423 P and Q are disjunctions, the number of clauses are multiplied.
424 When only one of P and Q is a disjunction, the the number of
425 clauses are added. Otherwise, neither side is a disjunction and
426 no clauses are created. */
427 if (disjunction_p (lhs))
428 {
429 if (disjunction_p (rhs) || (conjunction_p (rhs) && d2))
430 /* Both P and Q are disjunctions. */
431 return std::make_pair (n1 * n2, true);
432 else
433 /* Only LHS is a disjunction. */
434 return std::make_pair (n1 + n2, true);
435 gcc_unreachable ();
436 }
437 if (conjunction_p (lhs))
438 {
439 if ((disjunction_p (rhs) && d1) || (conjunction_p (rhs) && d1 && d2))
440 /* Both P and Q are disjunctions. */
441 return std::make_pair (n1 * n2, true);
442 if (disjunction_p (rhs)
443 || (conjunction_p (rhs) && d1 != d2)
444 || (atomic_p (rhs) && d1))
445 /* Either LHS or RHS is a disjunction. */
446 return std::make_pair (n1 + n2, true);
447 else
448 /* Neither LHS nor RHS is a disjunction. */
449 return std::make_pair (0, false);
450 }
451 if (atomic_p (lhs))
452 {
453 if (disjunction_p (rhs) || (conjunction_p (rhs) && d2))
454 /* Only RHS is a disjunction. */
455 return std::make_pair (n1 + n2, true);
456 else
457 /* Neither LHS nor RHS is a disjunction. */
458 return std::make_pair (0, false);
459 }
460 }
461 gcc_unreachable ();
462 }
463
464 /* Recursively count the number of clauses produced when converting T
465 to CNF. Returns a pair containing the number of clauses and a bool
466 value signifying that the the tree would be rewritten as a result of
467 distributing. In general, a disjunction for which this flag is set
468 is considered a conjunction for the purpose of counting. */
469
470 static std::pair<int, bool>
471 cnf_size_r (tree t)
472 {
473 if (atomic_p (t))
474 /* Atomic constraints produce no clauses. */
475 return std::make_pair (0, false);
476
477 /* For compound constraints, recursively count clauses and unpack
478 the results. */
479 tree lhs = TREE_OPERAND (t, 0);
480 tree rhs = TREE_OPERAND (t, 1);
481 std::pair<int, bool> p1 = cnf_size_r (lhs);
482 std::pair<int, bool> p2 = cnf_size_r (rhs);
483 int n1 = p1.first, n2 = p2.first;
484 bool d1 = p1.second, d2 = p2.second;
485
486 if (disjunction_p (t))
487 {
488 /* Matches constraints of the form P \/ Q, possibly resulting
489 in the distribution of one side over the other. When both
490 P and Q are conjunctions, the number of clauses are multiplied.
491 When only one of P and Q is a conjunction, the the number of
492 clauses are added. Otherwise, neither side is a conjunction and
493 no clauses are created. */
494 if (disjunction_p (lhs))
495 {
496 if ((disjunction_p (rhs) && d1 && d2) || (conjunction_p (rhs) && d1))
497 /* Both P and Q are conjunctions. */
498 return std::make_pair (n1 * n2, true);
499 if ((disjunction_p (rhs) && d1 != d2)
500 || conjunction_p (rhs)
501 || (atomic_p (rhs) && d1))
502 /* Either LHS or RHS is a conjunction. */
503 return std::make_pair (n1 + n2, true);
504 else
505 /* Neither LHS nor RHS is a conjunction. */
506 return std::make_pair (0, false);
507 gcc_unreachable ();
508 }
509 if (conjunction_p (lhs))
510 {
511 if ((disjunction_p (rhs) && d2) || conjunction_p (rhs))
512 /* Both LHS and RHS are conjunctions. */
513 return std::make_pair (n1 * n2, true);
514 else
515 /* Only LHS is a conjunction. */
516 return std::make_pair (n1 + n2, true);
517 }
518 if (atomic_p (lhs))
519 {
520 if ((disjunction_p (rhs) && d2) || conjunction_p (rhs))
521 /* Only RHS is a disjunction. */
522 return std::make_pair (n1 + n2, true);
523 else
524 /* Neither LHS nor RHS is a disjunction. */
525 return std::make_pair (0, false);
526 }
527 }
528 else /* conjunction_p (t) */
529 {
530 /* Matches constraints of the form P /\ Q. Conjunctions contribute
531 linearly to the number of constraints. When both P and Q are
532 conjunctions, clauses are added. When only one of P and Q
533 is a conjunction, an additional clause is produced. When neither
534 P nor Q are conjunctions, two clauses are produced. */
535 if (disjunction_p (lhs))
536 {
537 if ((disjunction_p (rhs) && d1 && d2) || (conjunction_p (rhs) && d1))
538 /* Both P and Q are conjunctions. */
539 return std::make_pair (n1 + n2, d1 | d2);
540 if ((disjunction_p (rhs) && d1 != d2)
541 || conjunction_p (rhs)
542 || (atomic_p (rhs) && d1))
543 /* Either LHS or RHS is a conjunction. */
544 return std::make_pair (1 + n1 + n2, d1 | d2);
545 else
546 /* Neither LHS nor RHS is a conjunction. */
547 return std::make_pair (2, false);
548 gcc_unreachable ();
549 }
550 if (conjunction_p (lhs))
551 {
552 if ((disjunction_p (rhs) && d2) || conjunction_p (rhs))
553 /* Both LHS and RHS are conjunctions. */
554 return std::make_pair (n1 + n2, d1 | d2);
555 else
556 /* Only LHS is a conjunction. */
557 return std::make_pair (1 + n1 + n2, d1 | d2);
558 }
559 if (atomic_p (lhs))
560 {
561 if ((disjunction_p (rhs) && d2) || conjunction_p (rhs))
562 /* Only RHS is a disjunction. */
563 return std::make_pair (1 + n1 + n2, d1 | d2);
564 else
565 /* Neither LHS nor RHS is a disjunction. */
566 return std::make_pair (2, false);
567 }
568 }
569 gcc_unreachable ();
570 }
571
572 /* Count the number conjunctive clauses that would be created
573 when rewriting T to DNF. */
574
575 static int
576 dnf_size (tree t)
577 {
578 std::pair<int, bool> result = dnf_size_r (t);
579 return result.first == 0 ? 1 : result.first;
580 }
581
582
583 /* Count the number disjunctive clauses that would be created
584 when rewriting T to CNF. */
585
586 static int
587 cnf_size (tree t)
588 {
589 std::pair<int, bool> result = cnf_size_r (t);
590 return result.first == 0 ? 1 : result.first;
591 }
592
593
594 /* A left-conjunction is replaced by its operands. */
595
596 void
597 replace_term (clause& c, tree t)
598 {
599 tree t1 = TREE_OPERAND (t, 0);
600 tree t2 = TREE_OPERAND (t, 1);
601 return c.replace (t1, t2);
602 }
603
604 /* Create a new clause in the formula by copying the current
605 clause. In the current clause, the term at CI is replaced
606 by the first operand, and in the new clause, it is replaced
607 by the second. */
608
609 void
610 branch_clause (formula& f, clause& c1, tree t)
611 {
612 tree t1 = TREE_OPERAND (t, 0);
613 tree t2 = TREE_OPERAND (t, 1);
614 clause& c2 = f.branch ();
615 c1.replace (t1);
616 c2.replace (t2);
617 }
618
619 /* Decompose t1 /\ t2 according to the rules R. */
620
621 inline void
622 decompose_conjuntion (formula& f, clause& c, tree t, rules r)
623 {
624 if (r == left)
625 replace_term (c, t);
626 else
627 branch_clause (f, c, t);
628 }
629
630 /* Decompose t1 \/ t2 according to the rules R. */
631
632 inline void
633 decompose_disjunction (formula& f, clause& c, tree t, rules r)
634 {
635 if (r == right)
636 replace_term (c, t);
637 else
638 branch_clause (f, c, t);
639 }
640
641 /* An atomic constraint is already decomposed. */
642 inline void
643 decompose_atom (clause& c)
644 {
645 c.advance ();
646 }
647
648 /* Decompose a term of clause C (in formula F) according to the
649 logical rules R. */
650
651 void
652 decompose_term (formula& f, clause& c, tree t, rules r)
653 {
654 switch (TREE_CODE (t))
655 {
656 case CONJ_CONSTR:
657 return decompose_conjuntion (f, c, t, r);
658 case DISJ_CONSTR:
659 return decompose_disjunction (f, c, t, r);
660 default:
661 return decompose_atom (c);
662 }
663 }
664
665 /* Decompose C (in F) using the logical rules R until it
666 is comprised of only atomic constraints. */
667
668 void
669 decompose_clause (formula& f, clause& c, rules r)
670 {
671 while (!c.done ())
672 decompose_term (f, c, *c.current (), r);
673 f.advance ();
674 }
675
676 /* Decompose the logical formula F according to the logical
677 rules determined by R. The result is a formula containing
678 clauses that contain only atomic terms. */
679
680 void
681 decompose_formula (formula& f, rules r)
682 {
683 while (!f.done ())
684 decompose_clause (f, *f.current (), r);
685 }
686
687 /* Fully decomposing T into a list of sequents, each comprised of
688 a list of atomic constraints, as if T were an antecedent. */
689
690 static formula
691 decompose_antecedents (tree t)
692 {
693 formula f (t);
694 decompose_formula (f, left);
695 return f;
696 }
697
698 /* Fully decomposing T into a list of sequents, each comprised of
699 a list of atomic constraints, as if T were a consequent. */
700
701 static formula
702 decompose_consequents (tree t)
703 {
704 formula f (t);
705 decompose_formula (f, right);
706 return f;
707 }
708
709 static bool derive_proof (clause&, tree, rules);
710
711 /* Derive a proof of both operands of T. */
712
713 static bool
714 derive_proof_for_both_operands (clause& c, tree t, rules r)
715 {
716 if (!derive_proof (c, TREE_OPERAND (t, 0), r))
717 return false;
718 return derive_proof (c, TREE_OPERAND (t, 1), r);
719 }
720
721 /* Derive a proof of either operand of T. */
722
723 static bool
724 derive_proof_for_either_operand (clause& c, tree t, rules r)
725 {
726 if (derive_proof (c, TREE_OPERAND (t, 0), r))
727 return true;
728 return derive_proof (c, TREE_OPERAND (t, 1), r);
729 }
730
731 /* Derive a proof of the atomic constraint T in clause C. */
732
733 static bool
734 derive_atomic_proof (clause& c, tree t)
735 {
736 return c.contains (t);
737 }
738
739 /* Derive a proof of T from the terms in C. */
740
741 static bool
742 derive_proof (clause& c, tree t, rules r)
743 {
744 switch (TREE_CODE (t))
745 {
746 case CONJ_CONSTR:
747 if (r == left)
748 return derive_proof_for_both_operands (c, t, r);
749 else
750 return derive_proof_for_either_operand (c, t, r);
751 case DISJ_CONSTR:
752 if (r == left)
753 return derive_proof_for_either_operand (c, t, r);
754 else
755 return derive_proof_for_both_operands (c, t, r);
756 default:
757 return derive_atomic_proof (c, t);
758 }
759 }
760
761 /* Derive a proof of T from disjunctive clauses in F. */
762
763 static bool
764 derive_proofs (formula& f, tree t, rules r)
765 {
766 for (formula::iterator i = f.begin(); i != f.end(); ++i)
767 if (!derive_proof (*i, t, r))
768 return false;
769 return true;
770 }
771
772 /* The largest number of clauses in CNF or DNF we accept as input
773 for subsumption. This an upper bound of 2^16 expressions. */
774 static int max_problem_size = 16;
775
776 static inline bool
777 diagnose_constraint_size (tree t)
778 {
779 error_at (input_location, "%qE exceeds the maximum constraint complexity", t);
780 return false;
781 }
782
783 /* Key/value pair for caching subsumption results. This associates a pair of
784 constraints with a boolean value indicating the result. */
785
786 struct GTY((for_user)) subsumption_entry
787 {
788 tree lhs;
789 tree rhs;
790 bool result;
791 };
792
793 /* Hashing function and equality for constraint entries. */
794
795 struct subsumption_hasher : ggc_ptr_hash<subsumption_entry>
796 {
797 static hashval_t hash (subsumption_entry *e)
798 {
799 hashval_t val = 0;
800 val = iterative_hash_constraint (e->lhs, val);
801 val = iterative_hash_constraint (e->rhs, val);
802 return val;
803 }
804
805 static bool equal (subsumption_entry *e1, subsumption_entry *e2)
806 {
807 if (!constraints_equivalent_p (e1->lhs, e2->lhs))
808 return false;
809 if (!constraints_equivalent_p (e1->rhs, e2->rhs))
810 return false;
811 return true;
812 }
813 };
814
815 /* Caches the results of subsumes_non_null(t1, t1). */
816
817 static GTY ((deletable)) hash_table<subsumption_hasher> *subsumption_cache;
818
819 /* Search for a previously cached subsumption result. */
820
821 static bool*
822 lookup_subsumption (tree t1, tree t2)
823 {
824 if (!subsumption_cache)
825 return NULL;
826 subsumption_entry elt = { t1, t2, false };
827 subsumption_entry* found = subsumption_cache->find (&elt);
828 if (found)
829 return &found->result;
830 else
831 return 0;
832 }
833
834 /* Save a subsumption result. */
835
836 static bool
837 save_subsumption (tree t1, tree t2, bool result)
838 {
839 if (!subsumption_cache)
840 subsumption_cache = hash_table<subsumption_hasher>::create_ggc(31);
841 subsumption_entry elt = {t1, t2, result};
842 subsumption_entry** slot = subsumption_cache->find_slot (&elt, INSERT);
843 subsumption_entry* entry = ggc_alloc<subsumption_entry> ();
844 *entry = elt;
845 *slot = entry;
846 return result;
847 }
848
849
850 /* Returns true if the LEFT constraint subsume the RIGHT constraints.
851 This is done by deriving a proof of the conclusions on the RIGHT
852 from the assumptions on the LEFT assumptions. */
853
854 static bool
855 subsumes_constraints_nonnull (tree lhs, tree rhs)
856 {
857 auto_timevar time (TV_CONSTRAINT_SUB);
858
859 if (bool *b = lookup_subsumption(lhs, rhs))
860 return *b;
861
862 int n1 = dnf_size (lhs);
863 int n2 = cnf_size (rhs);
864
865 /* Make sure we haven't exceeded the largest acceptable problem. */
866 if (std::min (n1, n2) >= max_problem_size)
867 {
868 if (n1 < n2)
869 diagnose_constraint_size (lhs);
870 else
871 diagnose_constraint_size (rhs);
872 return false;
873 }
874
875 /* Decompose the smaller of the two formulas, and recursively
876 check for implication of the larger. */
877 bool result;
878 if (n1 <= n2)
879 {
880 formula dnf = decompose_antecedents (lhs);
881 result = derive_proofs (dnf, rhs, left);
882 }
883 else
884 {
885 formula cnf = decompose_consequents (rhs);
886 result = derive_proofs (cnf, lhs, right);
887 }
888
889 return save_subsumption (lhs, rhs, result);
890 }
891
892 /* Returns true if the LEFT constraints subsume the RIGHT
893 constraints. */
894
895 bool
896 subsumes (tree lhs, tree rhs)
897 {
898 if (lhs == rhs)
899 return true;
900 if (!lhs || lhs == error_mark_node)
901 return false;
902 if (!rhs || rhs == error_mark_node)
903 return true;
904 return subsumes_constraints_nonnull (lhs, rhs);
905 }
906
907 #include "gt-cp-logic.h"