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 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 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 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 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 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" 908