diff options
| author | Stefan Monnier | 2021-01-20 13:54:11 -0500 |
|---|---|---|
| committer | Stefan Monnier | 2021-01-20 14:13:15 -0500 |
| commit | 09bfb12edc57ace138090861e335366d8f1cc4b2 (patch) | |
| tree | 4376201648d122bca972bfc5ef7fbb29808e055f | |
| parent | 434057ad925cad3ebcae1802fab60733ae5decae (diff) | |
| download | emacs-09bfb12edc57ace138090861e335366d8f1cc4b2.tar.gz emacs-09bfb12edc57ace138090861e335366d8f1cc4b2.zip | |
* lisp/emacs-lisp/byte-opt.el (byte-optimize-lapcode): Re-indent
| -rw-r--r-- | lisp/emacs-lisp/byte-opt.el | 914 |
1 files changed, 457 insertions, 457 deletions
diff --git a/lisp/emacs-lisp/byte-opt.el b/lisp/emacs-lisp/byte-opt.el index f29f85b9650..6d1f4179ce1 100644 --- a/lisp/emacs-lisp/byte-opt.el +++ b/lisp/emacs-lisp/byte-opt.el | |||
| @@ -1561,467 +1561,467 @@ If FOR-EFFECT is non-nil, the return value is assumed to be of no importance." | |||
| 1561 | ;; You may notice that sequences like "dup varset discard" are | 1561 | ;; You may notice that sequences like "dup varset discard" are |
| 1562 | ;; optimized but sequences like "dup varset TAG1: discard" are not. | 1562 | ;; optimized but sequences like "dup varset TAG1: discard" are not. |
| 1563 | ;; You may be tempted to change this; resist that temptation. | 1563 | ;; You may be tempted to change this; resist that temptation. |
| 1564 | (cond ;; | 1564 | (cond |
| 1565 | ;; <side-effect-free> pop --> <deleted> | 1565 | ;; <side-effect-free> pop --> <deleted> |
| 1566 | ;; ...including: | 1566 | ;; ...including: |
| 1567 | ;; const-X pop --> <deleted> | 1567 | ;; const-X pop --> <deleted> |
| 1568 | ;; varref-X pop --> <deleted> | 1568 | ;; varref-X pop --> <deleted> |
| 1569 | ;; dup pop --> <deleted> | 1569 | ;; dup pop --> <deleted> |
| 1570 | ;; | 1570 | ;; |
| 1571 | ((and (eq 'byte-discard (car lap1)) | 1571 | ((and (eq 'byte-discard (car lap1)) |
| 1572 | (memq (car lap0) side-effect-free)) | 1572 | (memq (car lap0) side-effect-free)) |
| 1573 | (setq keep-going t) | 1573 | (setq keep-going t) |
| 1574 | (setq tmp (aref byte-stack+-info (symbol-value (car lap0)))) | 1574 | (setq tmp (aref byte-stack+-info (symbol-value (car lap0)))) |
| 1575 | (setq rest (cdr rest)) | 1575 | (setq rest (cdr rest)) |
| 1576 | (cond ((= tmp 1) | 1576 | (cond ((= tmp 1) |
| 1577 | (byte-compile-log-lap | 1577 | (byte-compile-log-lap |
| 1578 | " %s discard\t-->\t<deleted>" lap0) | 1578 | " %s discard\t-->\t<deleted>" lap0) |
| 1579 | (setq lap (delq lap0 (delq lap1 lap)))) | 1579 | (setq lap (delq lap0 (delq lap1 lap)))) |
| 1580 | ((= tmp 0) | 1580 | ((= tmp 0) |
| 1581 | (byte-compile-log-lap | 1581 | (byte-compile-log-lap |
| 1582 | " %s discard\t-->\t<deleted> discard" lap0) | 1582 | " %s discard\t-->\t<deleted> discard" lap0) |
| 1583 | (setq lap (delq lap0 lap))) | ||
| 1584 | ((= tmp -1) | ||
| 1585 | (byte-compile-log-lap | ||
| 1586 | " %s discard\t-->\tdiscard discard" lap0) | ||
| 1587 | (setcar lap0 'byte-discard) | ||
| 1588 | (setcdr lap0 0)) | ||
| 1589 | ((error "Optimizer error: too much on the stack")))) | ||
| 1590 | ;; | ||
| 1591 | ;; goto*-X X: --> X: | ||
| 1592 | ;; | ||
| 1593 | ((and (memq (car lap0) byte-goto-ops) | ||
| 1594 | (eq (cdr lap0) lap1)) | ||
| 1595 | (cond ((eq (car lap0) 'byte-goto) | ||
| 1596 | (setq lap (delq lap0 lap)) | ||
| 1597 | (setq tmp "<deleted>")) | ||
| 1598 | ((memq (car lap0) byte-goto-always-pop-ops) | ||
| 1599 | (setcar lap0 (setq tmp 'byte-discard)) | ||
| 1600 | (setcdr lap0 0)) | ||
| 1601 | ((error "Depth conflict at tag %d" (nth 2 lap0)))) | ||
| 1602 | (and (memq byte-optimize-log '(t byte)) | ||
| 1603 | (byte-compile-log " (goto %s) %s:\t-->\t%s %s:" | ||
| 1604 | (nth 1 lap1) (nth 1 lap1) | ||
| 1605 | tmp (nth 1 lap1))) | ||
| 1606 | (setq keep-going t)) | ||
| 1607 | ;; | ||
| 1608 | ;; varset-X varref-X --> dup varset-X | ||
| 1609 | ;; varbind-X varref-X --> dup varbind-X | ||
| 1610 | ;; const/dup varset-X varref-X --> const/dup varset-X const/dup | ||
| 1611 | ;; const/dup varbind-X varref-X --> const/dup varbind-X const/dup | ||
| 1612 | ;; The latter two can enable other optimizations. | ||
| 1613 | ;; | ||
| 1614 | ;; For lexical variables, we could do the same | ||
| 1615 | ;; stack-set-X+1 stack-ref-X --> dup stack-set-X+2 | ||
| 1616 | ;; but this is a very minor gain, since dup is stack-ref-0, | ||
| 1617 | ;; i.e. it's only better if X>5, and even then it comes | ||
| 1618 | ;; at the cost of an extra stack slot. Let's not bother. | ||
| 1619 | ((and (eq 'byte-varref (car lap2)) | ||
| 1620 | (eq (cdr lap1) (cdr lap2)) | ||
| 1621 | (memq (car lap1) '(byte-varset byte-varbind))) | ||
| 1622 | (if (and (setq tmp (memq (car (cdr lap2)) byte-boolean-vars)) | ||
| 1623 | (not (eq (car lap0) 'byte-constant))) | ||
| 1624 | nil | ||
| 1625 | (setq keep-going t) | ||
| 1626 | (if (memq (car lap0) '(byte-constant byte-dup)) | ||
| 1627 | (progn | ||
| 1628 | (setq tmp (if (or (not tmp) | ||
| 1629 | (macroexp--const-symbol-p | ||
| 1630 | (car (cdr lap0)))) | ||
| 1631 | (cdr lap0) | ||
| 1632 | (byte-compile-get-constant t))) | ||
| 1633 | (byte-compile-log-lap " %s %s %s\t-->\t%s %s %s" | ||
| 1634 | lap0 lap1 lap2 lap0 lap1 | ||
| 1635 | (cons (car lap0) tmp)) | ||
| 1636 | (setcar lap2 (car lap0)) | ||
| 1637 | (setcdr lap2 tmp)) | ||
| 1638 | (byte-compile-log-lap " %s %s\t-->\tdup %s" lap1 lap2 lap1) | ||
| 1639 | (setcar lap2 (car lap1)) | ||
| 1640 | (setcar lap1 'byte-dup) | ||
| 1641 | (setcdr lap1 0) | ||
| 1642 | ;; The stack depth gets locally increased, so we will | ||
| 1643 | ;; increase maxdepth in case depth = maxdepth here. | ||
| 1644 | ;; This can cause the third argument to byte-code to | ||
| 1645 | ;; be larger than necessary. | ||
| 1646 | (setq add-depth 1)))) | ||
| 1647 | ;; | ||
| 1648 | ;; dup varset-X discard --> varset-X | ||
| 1649 | ;; dup varbind-X discard --> varbind-X | ||
| 1650 | ;; dup stack-set-X discard --> stack-set-X-1 | ||
| 1651 | ;; (the varbind variant can emerge from other optimizations) | ||
| 1652 | ;; | ||
| 1653 | ((and (eq 'byte-dup (car lap0)) | ||
| 1654 | (eq 'byte-discard (car lap2)) | ||
| 1655 | (memq (car lap1) '(byte-varset byte-varbind | ||
| 1656 | byte-stack-set))) | ||
| 1657 | (byte-compile-log-lap " dup %s discard\t-->\t%s" lap1 lap1) | ||
| 1658 | (setq keep-going t | ||
| 1659 | rest (cdr rest)) | ||
| 1660 | (if (eq 'byte-stack-set (car lap1)) (cl-decf (cdr lap1))) | ||
| 1661 | (setq lap (delq lap0 (delq lap2 lap)))) | ||
| 1662 | ;; | ||
| 1663 | ;; not goto-X-if-nil --> goto-X-if-non-nil | ||
| 1664 | ;; not goto-X-if-non-nil --> goto-X-if-nil | ||
| 1665 | ;; | ||
| 1666 | ;; it is wrong to do the same thing for the -else-pop variants. | ||
| 1667 | ;; | ||
| 1668 | ((and (eq 'byte-not (car lap0)) | ||
| 1669 | (memq (car lap1) '(byte-goto-if-nil byte-goto-if-not-nil))) | ||
| 1670 | (byte-compile-log-lap " not %s\t-->\t%s" | ||
| 1671 | lap1 | ||
| 1672 | (cons | ||
| 1673 | (if (eq (car lap1) 'byte-goto-if-nil) | ||
| 1674 | 'byte-goto-if-not-nil | ||
| 1675 | 'byte-goto-if-nil) | ||
| 1676 | (cdr lap1))) | ||
| 1677 | (setcar lap1 (if (eq (car lap1) 'byte-goto-if-nil) | ||
| 1678 | 'byte-goto-if-not-nil | ||
| 1679 | 'byte-goto-if-nil)) | ||
| 1680 | (setq lap (delq lap0 lap)) | ||
| 1681 | (setq keep-going t)) | ||
| 1682 | ;; | ||
| 1683 | ;; goto-X-if-nil goto-Y X: --> goto-Y-if-non-nil X: | ||
| 1684 | ;; goto-X-if-non-nil goto-Y X: --> goto-Y-if-nil X: | ||
| 1685 | ;; | ||
| 1686 | ;; it is wrong to do the same thing for the -else-pop variants. | ||
| 1687 | ;; | ||
| 1688 | ((and (memq (car lap0) | ||
| 1689 | '(byte-goto-if-nil byte-goto-if-not-nil)) ; gotoX | ||
| 1690 | (eq 'byte-goto (car lap1)) ; gotoY | ||
| 1691 | (eq (cdr lap0) lap2)) ; TAG X | ||
| 1692 | (let ((inverse (if (eq 'byte-goto-if-nil (car lap0)) | ||
| 1693 | 'byte-goto-if-not-nil 'byte-goto-if-nil))) | ||
| 1694 | (byte-compile-log-lap " %s %s %s:\t-->\t%s %s:" | ||
| 1695 | lap0 lap1 lap2 | ||
| 1696 | (cons inverse (cdr lap1)) lap2) | ||
| 1697 | (setq lap (delq lap0 lap)) | ||
| 1698 | (setcar lap1 inverse) | ||
| 1699 | (setq keep-going t))) | ||
| 1700 | ;; | ||
| 1701 | ;; const goto-if-* --> whatever | ||
| 1702 | ;; | ||
| 1703 | ((and (eq 'byte-constant (car lap0)) | ||
| 1704 | (memq (car lap1) byte-conditional-ops) | ||
| 1705 | ;; If the `byte-constant's cdr is not a cons cell, it has | ||
| 1706 | ;; to be an index into the constant pool); even though | ||
| 1707 | ;; it'll be a constant, that constant is not known yet | ||
| 1708 | ;; (it's typically a free variable of a closure, so will | ||
| 1709 | ;; only be known when the closure will be built at | ||
| 1710 | ;; run-time). | ||
| 1711 | (consp (cdr lap0))) | ||
| 1712 | (cond ((if (memq (car lap1) '(byte-goto-if-nil | ||
| 1713 | byte-goto-if-nil-else-pop)) | ||
| 1714 | (car (cdr lap0)) | ||
| 1715 | (not (car (cdr lap0)))) | ||
| 1716 | (byte-compile-log-lap " %s %s\t-->\t<deleted>" | ||
| 1717 | lap0 lap1) | ||
| 1718 | (setq rest (cdr rest) | ||
| 1719 | lap (delq lap0 (delq lap1 lap)))) | ||
| 1720 | (t | ||
| 1721 | (byte-compile-log-lap " %s %s\t-->\t%s" | ||
| 1722 | lap0 lap1 | ||
| 1723 | (cons 'byte-goto (cdr lap1))) | ||
| 1724 | (when (memq (car lap1) byte-goto-always-pop-ops) | ||
| 1725 | (setq lap (delq lap0 lap))) | ||
| 1726 | (setcar lap1 'byte-goto))) | ||
| 1727 | (setq keep-going t)) | ||
| 1728 | ;; | ||
| 1729 | ;; varref-X varref-X --> varref-X dup | ||
| 1730 | ;; varref-X [dup ...] varref-X --> varref-X [dup ...] dup | ||
| 1731 | ;; stackref-X [dup ...] stackref-X+N --> stackref-X [dup ...] dup | ||
| 1732 | ;; We don't optimize the const-X variations on this here, | ||
| 1733 | ;; because that would inhibit some goto optimizations; we | ||
| 1734 | ;; optimize the const-X case after all other optimizations. | ||
| 1735 | ;; | ||
| 1736 | ((and (memq (car lap0) '(byte-varref byte-stack-ref)) | ||
| 1737 | (progn | ||
| 1738 | (setq tmp (cdr rest)) | ||
| 1739 | (setq tmp2 0) | ||
| 1740 | (while (eq (car (car tmp)) 'byte-dup) | ||
| 1741 | (setq tmp2 (1+ tmp2)) | ||
| 1742 | (setq tmp (cdr tmp))) | ||
| 1743 | t) | ||
| 1744 | (eq (if (eq 'byte-stack-ref (car lap0)) | ||
| 1745 | (+ tmp2 1 (cdr lap0)) | ||
| 1746 | (cdr lap0)) | ||
| 1747 | (cdr (car tmp))) | ||
| 1748 | (eq (car lap0) (car (car tmp)))) | ||
| 1749 | (if (memq byte-optimize-log '(t byte)) | ||
| 1750 | (let ((str "")) | ||
| 1751 | (setq tmp2 (cdr rest)) | ||
| 1752 | (while (not (eq tmp tmp2)) | ||
| 1753 | (setq tmp2 (cdr tmp2) | ||
| 1754 | str (concat str " dup"))) | ||
| 1755 | (byte-compile-log-lap " %s%s %s\t-->\t%s%s dup" | ||
| 1756 | lap0 str lap0 lap0 str))) | ||
| 1757 | (setq keep-going t) | ||
| 1758 | (setcar (car tmp) 'byte-dup) | ||
| 1759 | (setcdr (car tmp) 0) | ||
| 1760 | (setq rest tmp)) | ||
| 1761 | ;; | ||
| 1762 | ;; TAG1: TAG2: --> TAG1: <deleted> | ||
| 1763 | ;; (and other references to TAG2 are replaced with TAG1) | ||
| 1764 | ;; | ||
| 1765 | ((and (eq (car lap0) 'TAG) | ||
| 1766 | (eq (car lap1) 'TAG)) | ||
| 1767 | (and (memq byte-optimize-log '(t byte)) | ||
| 1768 | (byte-compile-log " adjacent tags %d and %d merged" | ||
| 1769 | (nth 1 lap1) (nth 1 lap0))) | ||
| 1770 | (setq tmp3 lap) | ||
| 1771 | (while (setq tmp2 (rassq lap0 tmp3)) | ||
| 1772 | (setcdr tmp2 lap1) | ||
| 1773 | (setq tmp3 (cdr (memq tmp2 tmp3)))) | ||
| 1774 | (setq lap (delq lap0 lap) | ||
| 1775 | keep-going t) | ||
| 1776 | ;; replace references to tag in jump tables, if any | ||
| 1777 | (dolist (table byte-compile-jump-tables) | ||
| 1778 | (maphash #'(lambda (value tag) | ||
| 1779 | (when (equal tag lap0) | ||
| 1780 | (puthash value lap1 table))) | ||
| 1781 | table))) | ||
| 1782 | ;; | ||
| 1783 | ;; unused-TAG: --> <deleted> | ||
| 1784 | ;; | ||
| 1785 | ((and (eq 'TAG (car lap0)) | ||
| 1786 | (not (rassq lap0 lap)) | ||
| 1787 | ;; make sure this tag isn't used in a jump-table | ||
| 1788 | (cl-loop for table in byte-compile-jump-tables | ||
| 1789 | when (member lap0 (hash-table-values table)) | ||
| 1790 | return nil finally return t)) | ||
| 1791 | (and (memq byte-optimize-log '(t byte)) | ||
| 1792 | (byte-compile-log " unused tag %d removed" (nth 1 lap0))) | ||
| 1793 | (setq lap (delq lap0 lap) | ||
| 1794 | keep-going t)) | ||
| 1795 | ;; | ||
| 1796 | ;; goto ... --> goto <delete until TAG or end> | ||
| 1797 | ;; return ... --> return <delete until TAG or end> | ||
| 1798 | ;; (unless a jump-table is being used, where deleting may affect | ||
| 1799 | ;; other valid case bodies) | ||
| 1800 | ;; | ||
| 1801 | ((and (memq (car lap0) '(byte-goto byte-return)) | ||
| 1802 | (not (memq (car lap1) '(TAG nil))) | ||
| 1803 | ;; FIXME: Instead of deferring simply when jump-tables are | ||
| 1804 | ;; being used, keep a list of tags used for switch tags and | ||
| 1805 | ;; use them instead (see `byte-compile-inline-lapcode'). | ||
| 1806 | (not byte-compile-jump-tables)) | ||
| 1807 | (setq tmp rest) | ||
| 1808 | (let ((i 0) | ||
| 1809 | (opt-p (memq byte-optimize-log '(t lap))) | ||
| 1810 | str deleted) | ||
| 1811 | (while (and (setq tmp (cdr tmp)) | ||
| 1812 | (not (eq 'TAG (car (car tmp))))) | ||
| 1813 | (if opt-p (setq deleted (cons (car tmp) deleted) | ||
| 1814 | str (concat str " %s") | ||
| 1815 | i (1+ i)))) | ||
| 1816 | (if opt-p | ||
| 1817 | (let ((tagstr | ||
| 1818 | (if (eq 'TAG (car (car tmp))) | ||
| 1819 | (format "%d:" (car (cdr (car tmp)))) | ||
| 1820 | (or (car tmp) "")))) | ||
| 1821 | (if (< i 6) | ||
| 1822 | (apply 'byte-compile-log-lap-1 | ||
| 1823 | (concat " %s" str | ||
| 1824 | " %s\t-->\t%s <deleted> %s") | ||
| 1825 | lap0 | ||
| 1826 | (nconc (nreverse deleted) | ||
| 1827 | (list tagstr lap0 tagstr))) | ||
| 1828 | (byte-compile-log-lap | ||
| 1829 | " %s <%d unreachable op%s> %s\t-->\t%s <deleted> %s" | ||
| 1830 | lap0 i (if (= i 1) "" "s") | ||
| 1831 | tagstr lap0 tagstr)))) | ||
| 1832 | (rplacd rest tmp)) | ||
| 1833 | (setq keep-going t)) | ||
| 1834 | ;; | ||
| 1835 | ;; <safe-op> unbind --> unbind <safe-op> | ||
| 1836 | ;; (this may enable other optimizations.) | ||
| 1837 | ;; | ||
| 1838 | ((and (eq 'byte-unbind (car lap1)) | ||
| 1839 | (memq (car lap0) byte-after-unbind-ops)) | ||
| 1840 | (byte-compile-log-lap " %s %s\t-->\t%s %s" lap0 lap1 lap1 lap0) | ||
| 1841 | (setcar rest lap1) | ||
| 1842 | (setcar (cdr rest) lap0) | ||
| 1843 | (setq keep-going t)) | ||
| 1844 | ;; | ||
| 1845 | ;; varbind-X unbind-N --> discard unbind-(N-1) | ||
| 1846 | ;; save-excursion unbind-N --> unbind-(N-1) | ||
| 1847 | ;; save-restriction unbind-N --> unbind-(N-1) | ||
| 1848 | ;; | ||
| 1849 | ((and (eq 'byte-unbind (car lap1)) | ||
| 1850 | (memq (car lap0) '(byte-varbind byte-save-excursion | ||
| 1851 | byte-save-restriction)) | ||
| 1852 | (< 0 (cdr lap1))) | ||
| 1853 | (if (zerop (setcdr lap1 (1- (cdr lap1)))) | ||
| 1854 | (delq lap1 rest)) | ||
| 1855 | (if (eq (car lap0) 'byte-varbind) | ||
| 1856 | (setcar rest (cons 'byte-discard 0)) | ||
| 1857 | (setq lap (delq lap0 lap))) | 1583 | (setq lap (delq lap0 lap))) |
| 1858 | (byte-compile-log-lap " %s %s\t-->\t%s %s" | 1584 | ((= tmp -1) |
| 1859 | lap0 (cons (car lap1) (1+ (cdr lap1))) | 1585 | (byte-compile-log-lap |
| 1860 | (if (eq (car lap0) 'byte-varbind) | 1586 | " %s discard\t-->\tdiscard discard" lap0) |
| 1861 | (car rest) | 1587 | (setcar lap0 'byte-discard) |
| 1862 | (car (cdr rest))) | 1588 | (setcdr lap0 0)) |
| 1863 | (if (and (/= 0 (cdr lap1)) | 1589 | ((error "Optimizer error: too much on the stack")))) |
| 1864 | (eq (car lap0) 'byte-varbind)) | 1590 | ;; |
| 1865 | (car (cdr rest)) | 1591 | ;; goto*-X X: --> X: |
| 1866 | "")) | 1592 | ;; |
| 1867 | (setq keep-going t)) | 1593 | ((and (memq (car lap0) byte-goto-ops) |
| 1868 | ;; | 1594 | (eq (cdr lap0) lap1)) |
| 1869 | ;; goto*-X ... X: goto-Y --> goto*-Y | 1595 | (cond ((eq (car lap0) 'byte-goto) |
| 1870 | ;; goto-X ... X: return --> return | 1596 | (setq lap (delq lap0 lap)) |
| 1871 | ;; | 1597 | (setq tmp "<deleted>")) |
| 1872 | ((and (memq (car lap0) byte-goto-ops) | 1598 | ((memq (car lap0) byte-goto-always-pop-ops) |
| 1873 | (memq (car (setq tmp (nth 1 (memq (cdr lap0) lap)))) | 1599 | (setcar lap0 (setq tmp 'byte-discard)) |
| 1874 | '(byte-goto byte-return))) | 1600 | (setcdr lap0 0)) |
| 1875 | (cond ((and (not (eq tmp lap0)) | 1601 | ((error "Depth conflict at tag %d" (nth 2 lap0)))) |
| 1876 | (or (eq (car lap0) 'byte-goto) | 1602 | (and (memq byte-optimize-log '(t byte)) |
| 1877 | (eq (car tmp) 'byte-goto))) | 1603 | (byte-compile-log " (goto %s) %s:\t-->\t%s %s:" |
| 1878 | (byte-compile-log-lap " %s [%s]\t-->\t%s" | 1604 | (nth 1 lap1) (nth 1 lap1) |
| 1879 | (car lap0) tmp tmp) | 1605 | tmp (nth 1 lap1))) |
| 1880 | (if (eq (car tmp) 'byte-return) | 1606 | (setq keep-going t)) |
| 1881 | (setcar lap0 'byte-return)) | 1607 | ;; |
| 1882 | (setcdr lap0 (cdr tmp)) | 1608 | ;; varset-X varref-X --> dup varset-X |
| 1883 | (setq keep-going t)))) | 1609 | ;; varbind-X varref-X --> dup varbind-X |
| 1884 | ;; | 1610 | ;; const/dup varset-X varref-X --> const/dup varset-X const/dup |
| 1885 | ;; goto-*-else-pop X ... X: goto-if-* --> whatever | 1611 | ;; const/dup varbind-X varref-X --> const/dup varbind-X const/dup |
| 1886 | ;; goto-*-else-pop X ... X: discard --> whatever | 1612 | ;; The latter two can enable other optimizations. |
| 1887 | ;; | 1613 | ;; |
| 1888 | ((and (memq (car lap0) '(byte-goto-if-nil-else-pop | 1614 | ;; For lexical variables, we could do the same |
| 1889 | byte-goto-if-not-nil-else-pop)) | 1615 | ;; stack-set-X+1 stack-ref-X --> dup stack-set-X+2 |
| 1890 | (memq (car (car (setq tmp (cdr (memq (cdr lap0) lap))))) | 1616 | ;; but this is a very minor gain, since dup is stack-ref-0, |
| 1891 | (eval-when-compile | 1617 | ;; i.e. it's only better if X>5, and even then it comes |
| 1892 | (cons 'byte-discard byte-conditional-ops))) | 1618 | ;; at the cost of an extra stack slot. Let's not bother. |
| 1893 | (not (eq lap0 (car tmp)))) | 1619 | ((and (eq 'byte-varref (car lap2)) |
| 1894 | (setq tmp2 (car tmp)) | 1620 | (eq (cdr lap1) (cdr lap2)) |
| 1895 | (setq tmp3 (assq (car lap0) '((byte-goto-if-nil-else-pop | 1621 | (memq (car lap1) '(byte-varset byte-varbind))) |
| 1896 | byte-goto-if-nil) | 1622 | (if (and (setq tmp (memq (car (cdr lap2)) byte-boolean-vars)) |
| 1897 | (byte-goto-if-not-nil-else-pop | 1623 | (not (eq (car lap0) 'byte-constant))) |
| 1898 | byte-goto-if-not-nil)))) | 1624 | nil |
| 1899 | (if (memq (car tmp2) tmp3) | 1625 | (setq keep-going t) |
| 1900 | (progn (setcar lap0 (car tmp2)) | 1626 | (if (memq (car lap0) '(byte-constant byte-dup)) |
| 1901 | (setcdr lap0 (cdr tmp2)) | 1627 | (progn |
| 1902 | (byte-compile-log-lap " %s-else-pop [%s]\t-->\t%s" | 1628 | (setq tmp (if (or (not tmp) |
| 1903 | (car lap0) tmp2 lap0)) | 1629 | (macroexp--const-symbol-p |
| 1904 | ;; Get rid of the -else-pop's and jump one step further. | 1630 | (car (cdr lap0)))) |
| 1631 | (cdr lap0) | ||
| 1632 | (byte-compile-get-constant t))) | ||
| 1633 | (byte-compile-log-lap " %s %s %s\t-->\t%s %s %s" | ||
| 1634 | lap0 lap1 lap2 lap0 lap1 | ||
| 1635 | (cons (car lap0) tmp)) | ||
| 1636 | (setcar lap2 (car lap0)) | ||
| 1637 | (setcdr lap2 tmp)) | ||
| 1638 | (byte-compile-log-lap " %s %s\t-->\tdup %s" lap1 lap2 lap1) | ||
| 1639 | (setcar lap2 (car lap1)) | ||
| 1640 | (setcar lap1 'byte-dup) | ||
| 1641 | (setcdr lap1 0) | ||
| 1642 | ;; The stack depth gets locally increased, so we will | ||
| 1643 | ;; increase maxdepth in case depth = maxdepth here. | ||
| 1644 | ;; This can cause the third argument to byte-code to | ||
| 1645 | ;; be larger than necessary. | ||
| 1646 | (setq add-depth 1)))) | ||
| 1647 | ;; | ||
| 1648 | ;; dup varset-X discard --> varset-X | ||
| 1649 | ;; dup varbind-X discard --> varbind-X | ||
| 1650 | ;; dup stack-set-X discard --> stack-set-X-1 | ||
| 1651 | ;; (the varbind variant can emerge from other optimizations) | ||
| 1652 | ;; | ||
| 1653 | ((and (eq 'byte-dup (car lap0)) | ||
| 1654 | (eq 'byte-discard (car lap2)) | ||
| 1655 | (memq (car lap1) '(byte-varset byte-varbind | ||
| 1656 | byte-stack-set))) | ||
| 1657 | (byte-compile-log-lap " dup %s discard\t-->\t%s" lap1 lap1) | ||
| 1658 | (setq keep-going t | ||
| 1659 | rest (cdr rest)) | ||
| 1660 | (if (eq 'byte-stack-set (car lap1)) (cl-decf (cdr lap1))) | ||
| 1661 | (setq lap (delq lap0 (delq lap2 lap)))) | ||
| 1662 | ;; | ||
| 1663 | ;; not goto-X-if-nil --> goto-X-if-non-nil | ||
| 1664 | ;; not goto-X-if-non-nil --> goto-X-if-nil | ||
| 1665 | ;; | ||
| 1666 | ;; it is wrong to do the same thing for the -else-pop variants. | ||
| 1667 | ;; | ||
| 1668 | ((and (eq 'byte-not (car lap0)) | ||
| 1669 | (memq (car lap1) '(byte-goto-if-nil byte-goto-if-not-nil))) | ||
| 1670 | (byte-compile-log-lap " not %s\t-->\t%s" | ||
| 1671 | lap1 | ||
| 1672 | (cons | ||
| 1673 | (if (eq (car lap1) 'byte-goto-if-nil) | ||
| 1674 | 'byte-goto-if-not-nil | ||
| 1675 | 'byte-goto-if-nil) | ||
| 1676 | (cdr lap1))) | ||
| 1677 | (setcar lap1 (if (eq (car lap1) 'byte-goto-if-nil) | ||
| 1678 | 'byte-goto-if-not-nil | ||
| 1679 | 'byte-goto-if-nil)) | ||
| 1680 | (setq lap (delq lap0 lap)) | ||
| 1681 | (setq keep-going t)) | ||
| 1682 | ;; | ||
| 1683 | ;; goto-X-if-nil goto-Y X: --> goto-Y-if-non-nil X: | ||
| 1684 | ;; goto-X-if-non-nil goto-Y X: --> goto-Y-if-nil X: | ||
| 1685 | ;; | ||
| 1686 | ;; it is wrong to do the same thing for the -else-pop variants. | ||
| 1687 | ;; | ||
| 1688 | ((and (memq (car lap0) | ||
| 1689 | '(byte-goto-if-nil byte-goto-if-not-nil)) ; gotoX | ||
| 1690 | (eq 'byte-goto (car lap1)) ; gotoY | ||
| 1691 | (eq (cdr lap0) lap2)) ; TAG X | ||
| 1692 | (let ((inverse (if (eq 'byte-goto-if-nil (car lap0)) | ||
| 1693 | 'byte-goto-if-not-nil 'byte-goto-if-nil))) | ||
| 1694 | (byte-compile-log-lap " %s %s %s:\t-->\t%s %s:" | ||
| 1695 | lap0 lap1 lap2 | ||
| 1696 | (cons inverse (cdr lap1)) lap2) | ||
| 1697 | (setq lap (delq lap0 lap)) | ||
| 1698 | (setcar lap1 inverse) | ||
| 1699 | (setq keep-going t))) | ||
| 1700 | ;; | ||
| 1701 | ;; const goto-if-* --> whatever | ||
| 1702 | ;; | ||
| 1703 | ((and (eq 'byte-constant (car lap0)) | ||
| 1704 | (memq (car lap1) byte-conditional-ops) | ||
| 1705 | ;; If the `byte-constant's cdr is not a cons cell, it has | ||
| 1706 | ;; to be an index into the constant pool); even though | ||
| 1707 | ;; it'll be a constant, that constant is not known yet | ||
| 1708 | ;; (it's typically a free variable of a closure, so will | ||
| 1709 | ;; only be known when the closure will be built at | ||
| 1710 | ;; run-time). | ||
| 1711 | (consp (cdr lap0))) | ||
| 1712 | (cond ((if (memq (car lap1) '(byte-goto-if-nil | ||
| 1713 | byte-goto-if-nil-else-pop)) | ||
| 1714 | (car (cdr lap0)) | ||
| 1715 | (not (car (cdr lap0)))) | ||
| 1716 | (byte-compile-log-lap " %s %s\t-->\t<deleted>" | ||
| 1717 | lap0 lap1) | ||
| 1718 | (setq rest (cdr rest) | ||
| 1719 | lap (delq lap0 (delq lap1 lap)))) | ||
| 1720 | (t | ||
| 1721 | (byte-compile-log-lap " %s %s\t-->\t%s" | ||
| 1722 | lap0 lap1 | ||
| 1723 | (cons 'byte-goto (cdr lap1))) | ||
| 1724 | (when (memq (car lap1) byte-goto-always-pop-ops) | ||
| 1725 | (setq lap (delq lap0 lap))) | ||
| 1726 | (setcar lap1 'byte-goto))) | ||
| 1727 | (setq keep-going t)) | ||
| 1728 | ;; | ||
| 1729 | ;; varref-X varref-X --> varref-X dup | ||
| 1730 | ;; varref-X [dup ...] varref-X --> varref-X [dup ...] dup | ||
| 1731 | ;; stackref-X [dup ...] stackref-X+N --> stackref-X [dup ...] dup | ||
| 1732 | ;; We don't optimize the const-X variations on this here, | ||
| 1733 | ;; because that would inhibit some goto optimizations; we | ||
| 1734 | ;; optimize the const-X case after all other optimizations. | ||
| 1735 | ;; | ||
| 1736 | ((and (memq (car lap0) '(byte-varref byte-stack-ref)) | ||
| 1737 | (progn | ||
| 1738 | (setq tmp (cdr rest)) | ||
| 1739 | (setq tmp2 0) | ||
| 1740 | (while (eq (car (car tmp)) 'byte-dup) | ||
| 1741 | (setq tmp2 (1+ tmp2)) | ||
| 1742 | (setq tmp (cdr tmp))) | ||
| 1743 | t) | ||
| 1744 | (eq (if (eq 'byte-stack-ref (car lap0)) | ||
| 1745 | (+ tmp2 1 (cdr lap0)) | ||
| 1746 | (cdr lap0)) | ||
| 1747 | (cdr (car tmp))) | ||
| 1748 | (eq (car lap0) (car (car tmp)))) | ||
| 1749 | (if (memq byte-optimize-log '(t byte)) | ||
| 1750 | (let ((str "")) | ||
| 1751 | (setq tmp2 (cdr rest)) | ||
| 1752 | (while (not (eq tmp tmp2)) | ||
| 1753 | (setq tmp2 (cdr tmp2) | ||
| 1754 | str (concat str " dup"))) | ||
| 1755 | (byte-compile-log-lap " %s%s %s\t-->\t%s%s dup" | ||
| 1756 | lap0 str lap0 lap0 str))) | ||
| 1757 | (setq keep-going t) | ||
| 1758 | (setcar (car tmp) 'byte-dup) | ||
| 1759 | (setcdr (car tmp) 0) | ||
| 1760 | (setq rest tmp)) | ||
| 1761 | ;; | ||
| 1762 | ;; TAG1: TAG2: --> TAG1: <deleted> | ||
| 1763 | ;; (and other references to TAG2 are replaced with TAG1) | ||
| 1764 | ;; | ||
| 1765 | ((and (eq (car lap0) 'TAG) | ||
| 1766 | (eq (car lap1) 'TAG)) | ||
| 1767 | (and (memq byte-optimize-log '(t byte)) | ||
| 1768 | (byte-compile-log " adjacent tags %d and %d merged" | ||
| 1769 | (nth 1 lap1) (nth 1 lap0))) | ||
| 1770 | (setq tmp3 lap) | ||
| 1771 | (while (setq tmp2 (rassq lap0 tmp3)) | ||
| 1772 | (setcdr tmp2 lap1) | ||
| 1773 | (setq tmp3 (cdr (memq tmp2 tmp3)))) | ||
| 1774 | (setq lap (delq lap0 lap) | ||
| 1775 | keep-going t) | ||
| 1776 | ;; replace references to tag in jump tables, if any | ||
| 1777 | (dolist (table byte-compile-jump-tables) | ||
| 1778 | (maphash #'(lambda (value tag) | ||
| 1779 | (when (equal tag lap0) | ||
| 1780 | (puthash value lap1 table))) | ||
| 1781 | table))) | ||
| 1782 | ;; | ||
| 1783 | ;; unused-TAG: --> <deleted> | ||
| 1784 | ;; | ||
| 1785 | ((and (eq 'TAG (car lap0)) | ||
| 1786 | (not (rassq lap0 lap)) | ||
| 1787 | ;; make sure this tag isn't used in a jump-table | ||
| 1788 | (cl-loop for table in byte-compile-jump-tables | ||
| 1789 | when (member lap0 (hash-table-values table)) | ||
| 1790 | return nil finally return t)) | ||
| 1791 | (and (memq byte-optimize-log '(t byte)) | ||
| 1792 | (byte-compile-log " unused tag %d removed" (nth 1 lap0))) | ||
| 1793 | (setq lap (delq lap0 lap) | ||
| 1794 | keep-going t)) | ||
| 1795 | ;; | ||
| 1796 | ;; goto ... --> goto <delete until TAG or end> | ||
| 1797 | ;; return ... --> return <delete until TAG or end> | ||
| 1798 | ;; (unless a jump-table is being used, where deleting may affect | ||
| 1799 | ;; other valid case bodies) | ||
| 1800 | ;; | ||
| 1801 | ((and (memq (car lap0) '(byte-goto byte-return)) | ||
| 1802 | (not (memq (car lap1) '(TAG nil))) | ||
| 1803 | ;; FIXME: Instead of deferring simply when jump-tables are | ||
| 1804 | ;; being used, keep a list of tags used for switch tags and | ||
| 1805 | ;; use them instead (see `byte-compile-inline-lapcode'). | ||
| 1806 | (not byte-compile-jump-tables)) | ||
| 1807 | (setq tmp rest) | ||
| 1808 | (let ((i 0) | ||
| 1809 | (opt-p (memq byte-optimize-log '(t lap))) | ||
| 1810 | str deleted) | ||
| 1811 | (while (and (setq tmp (cdr tmp)) | ||
| 1812 | (not (eq 'TAG (car (car tmp))))) | ||
| 1813 | (if opt-p (setq deleted (cons (car tmp) deleted) | ||
| 1814 | str (concat str " %s") | ||
| 1815 | i (1+ i)))) | ||
| 1816 | (if opt-p | ||
| 1817 | (let ((tagstr | ||
| 1818 | (if (eq 'TAG (car (car tmp))) | ||
| 1819 | (format "%d:" (car (cdr (car tmp)))) | ||
| 1820 | (or (car tmp) "")))) | ||
| 1821 | (if (< i 6) | ||
| 1822 | (apply 'byte-compile-log-lap-1 | ||
| 1823 | (concat " %s" str | ||
| 1824 | " %s\t-->\t%s <deleted> %s") | ||
| 1825 | lap0 | ||
| 1826 | (nconc (nreverse deleted) | ||
| 1827 | (list tagstr lap0 tagstr))) | ||
| 1828 | (byte-compile-log-lap | ||
| 1829 | " %s <%d unreachable op%s> %s\t-->\t%s <deleted> %s" | ||
| 1830 | lap0 i (if (= i 1) "" "s") | ||
| 1831 | tagstr lap0 tagstr)))) | ||
| 1832 | (rplacd rest tmp)) | ||
| 1833 | (setq keep-going t)) | ||
| 1834 | ;; | ||
| 1835 | ;; <safe-op> unbind --> unbind <safe-op> | ||
| 1836 | ;; (this may enable other optimizations.) | ||
| 1837 | ;; | ||
| 1838 | ((and (eq 'byte-unbind (car lap1)) | ||
| 1839 | (memq (car lap0) byte-after-unbind-ops)) | ||
| 1840 | (byte-compile-log-lap " %s %s\t-->\t%s %s" lap0 lap1 lap1 lap0) | ||
| 1841 | (setcar rest lap1) | ||
| 1842 | (setcar (cdr rest) lap0) | ||
| 1843 | (setq keep-going t)) | ||
| 1844 | ;; | ||
| 1845 | ;; varbind-X unbind-N --> discard unbind-(N-1) | ||
| 1846 | ;; save-excursion unbind-N --> unbind-(N-1) | ||
| 1847 | ;; save-restriction unbind-N --> unbind-(N-1) | ||
| 1848 | ;; | ||
| 1849 | ((and (eq 'byte-unbind (car lap1)) | ||
| 1850 | (memq (car lap0) '(byte-varbind byte-save-excursion | ||
| 1851 | byte-save-restriction)) | ||
| 1852 | (< 0 (cdr lap1))) | ||
| 1853 | (if (zerop (setcdr lap1 (1- (cdr lap1)))) | ||
| 1854 | (delq lap1 rest)) | ||
| 1855 | (if (eq (car lap0) 'byte-varbind) | ||
| 1856 | (setcar rest (cons 'byte-discard 0)) | ||
| 1857 | (setq lap (delq lap0 lap))) | ||
| 1858 | (byte-compile-log-lap " %s %s\t-->\t%s %s" | ||
| 1859 | lap0 (cons (car lap1) (1+ (cdr lap1))) | ||
| 1860 | (if (eq (car lap0) 'byte-varbind) | ||
| 1861 | (car rest) | ||
| 1862 | (car (cdr rest))) | ||
| 1863 | (if (and (/= 0 (cdr lap1)) | ||
| 1864 | (eq (car lap0) 'byte-varbind)) | ||
| 1865 | (car (cdr rest)) | ||
| 1866 | "")) | ||
| 1867 | (setq keep-going t)) | ||
| 1868 | ;; | ||
| 1869 | ;; goto*-X ... X: goto-Y --> goto*-Y | ||
| 1870 | ;; goto-X ... X: return --> return | ||
| 1871 | ;; | ||
| 1872 | ((and (memq (car lap0) byte-goto-ops) | ||
| 1873 | (memq (car (setq tmp (nth 1 (memq (cdr lap0) lap)))) | ||
| 1874 | '(byte-goto byte-return))) | ||
| 1875 | (cond ((and (not (eq tmp lap0)) | ||
| 1876 | (or (eq (car lap0) 'byte-goto) | ||
| 1877 | (eq (car tmp) 'byte-goto))) | ||
| 1878 | (byte-compile-log-lap " %s [%s]\t-->\t%s" | ||
| 1879 | (car lap0) tmp tmp) | ||
| 1880 | (if (eq (car tmp) 'byte-return) | ||
| 1881 | (setcar lap0 'byte-return)) | ||
| 1882 | (setcdr lap0 (cdr tmp)) | ||
| 1883 | (setq keep-going t)))) | ||
| 1884 | ;; | ||
| 1885 | ;; goto-*-else-pop X ... X: goto-if-* --> whatever | ||
| 1886 | ;; goto-*-else-pop X ... X: discard --> whatever | ||
| 1887 | ;; | ||
| 1888 | ((and (memq (car lap0) '(byte-goto-if-nil-else-pop | ||
| 1889 | byte-goto-if-not-nil-else-pop)) | ||
| 1890 | (memq (car (car (setq tmp (cdr (memq (cdr lap0) lap))))) | ||
| 1891 | (eval-when-compile | ||
| 1892 | (cons 'byte-discard byte-conditional-ops))) | ||
| 1893 | (not (eq lap0 (car tmp)))) | ||
| 1894 | (setq tmp2 (car tmp)) | ||
| 1895 | (setq tmp3 (assq (car lap0) '((byte-goto-if-nil-else-pop | ||
| 1896 | byte-goto-if-nil) | ||
| 1897 | (byte-goto-if-not-nil-else-pop | ||
| 1898 | byte-goto-if-not-nil)))) | ||
| 1899 | (if (memq (car tmp2) tmp3) | ||
| 1900 | (progn (setcar lap0 (car tmp2)) | ||
| 1901 | (setcdr lap0 (cdr tmp2)) | ||
| 1902 | (byte-compile-log-lap " %s-else-pop [%s]\t-->\t%s" | ||
| 1903 | (car lap0) tmp2 lap0)) | ||
| 1904 | ;; Get rid of the -else-pop's and jump one step further. | ||
| 1905 | (or (eq 'TAG (car (nth 1 tmp))) | ||
| 1906 | (setcdr tmp (cons (byte-compile-make-tag) | ||
| 1907 | (cdr tmp)))) | ||
| 1908 | (byte-compile-log-lap " %s [%s]\t-->\t%s <skip>" | ||
| 1909 | (car lap0) tmp2 (nth 1 tmp3)) | ||
| 1910 | (setcar lap0 (nth 1 tmp3)) | ||
| 1911 | (setcdr lap0 (nth 1 tmp))) | ||
| 1912 | (setq keep-going t)) | ||
| 1913 | ;; | ||
| 1914 | ;; const goto-X ... X: goto-if-* --> whatever | ||
| 1915 | ;; const goto-X ... X: discard --> whatever | ||
| 1916 | ;; | ||
| 1917 | ((and (eq (car lap0) 'byte-constant) | ||
| 1918 | (eq (car lap1) 'byte-goto) | ||
| 1919 | (memq (car (car (setq tmp (cdr (memq (cdr lap1) lap))))) | ||
| 1920 | (eval-when-compile | ||
| 1921 | (cons 'byte-discard byte-conditional-ops))) | ||
| 1922 | (not (eq lap1 (car tmp)))) | ||
| 1923 | (setq tmp2 (car tmp)) | ||
| 1924 | (cond ((when (consp (cdr lap0)) | ||
| 1925 | (memq (car tmp2) | ||
| 1926 | (if (null (car (cdr lap0))) | ||
| 1927 | '(byte-goto-if-nil byte-goto-if-nil-else-pop) | ||
| 1928 | '(byte-goto-if-not-nil | ||
| 1929 | byte-goto-if-not-nil-else-pop)))) | ||
| 1930 | (byte-compile-log-lap " %s goto [%s]\t-->\t%s %s" | ||
| 1931 | lap0 tmp2 lap0 tmp2) | ||
| 1932 | (setcar lap1 (car tmp2)) | ||
| 1933 | (setcdr lap1 (cdr tmp2)) | ||
| 1934 | ;; Let next step fix the (const,goto-if*) sequence. | ||
| 1935 | (setq rest (cons nil rest)) | ||
| 1936 | (setq keep-going t)) | ||
| 1937 | ((or (consp (cdr lap0)) | ||
| 1938 | (eq (car tmp2) 'byte-discard)) | ||
| 1939 | ;; Jump one step further | ||
| 1940 | (byte-compile-log-lap | ||
| 1941 | " %s goto [%s]\t-->\t<deleted> goto <skip>" | ||
| 1942 | lap0 tmp2) | ||
| 1905 | (or (eq 'TAG (car (nth 1 tmp))) | 1943 | (or (eq 'TAG (car (nth 1 tmp))) |
| 1906 | (setcdr tmp (cons (byte-compile-make-tag) | 1944 | (setcdr tmp (cons (byte-compile-make-tag) |
| 1907 | (cdr tmp)))) | 1945 | (cdr tmp)))) |
| 1908 | (byte-compile-log-lap " %s [%s]\t-->\t%s <skip>" | 1946 | (setcdr lap1 (car (cdr tmp))) |
| 1909 | (car lap0) tmp2 (nth 1 tmp3)) | 1947 | (setq lap (delq lap0 lap)) |
| 1910 | (setcar lap0 (nth 1 tmp3)) | 1948 | (setq keep-going t)))) |
| 1911 | (setcdr lap0 (nth 1 tmp))) | 1949 | ;; |
| 1912 | (setq keep-going t)) | 1950 | ;; X: varref-Y ... varset-Y goto-X --> |
| 1913 | ;; | 1951 | ;; X: varref-Y Z: ... dup varset-Y goto-Z |
| 1914 | ;; const goto-X ... X: goto-if-* --> whatever | 1952 | ;; (varset-X goto-BACK, BACK: varref-X --> copy the varref down.) |
| 1915 | ;; const goto-X ... X: discard --> whatever | 1953 | ;; (This is so usual for while loops that it is worth handling). |
| 1916 | ;; | 1954 | ;; |
| 1917 | ((and (eq (car lap0) 'byte-constant) | 1955 | ;; Here again, we could do it for stack-ref/stack-set, but |
| 1918 | (eq (car lap1) 'byte-goto) | 1956 | ;; that's replacing a stack-ref-Y with a stack-ref-0, which |
| 1919 | (memq (car (car (setq tmp (cdr (memq (cdr lap1) lap))))) | 1957 | ;; is a very minor improvement (if any), at the cost of |
| 1920 | (eval-when-compile | 1958 | ;; more stack use and more byte-code. Let's not do it. |
| 1921 | (cons 'byte-discard byte-conditional-ops))) | 1959 | ;; |
| 1922 | (not (eq lap1 (car tmp)))) | 1960 | ((and (eq (car lap1) 'byte-varset) |
| 1923 | (setq tmp2 (car tmp)) | 1961 | (eq (car lap2) 'byte-goto) |
| 1924 | (cond ((when (consp (cdr lap0)) | 1962 | (not (memq (cdr lap2) rest)) ;Backwards jump |
| 1925 | (memq (car tmp2) | 1963 | (eq (car (car (setq tmp (cdr (memq (cdr lap2) lap))))) |
| 1926 | (if (null (car (cdr lap0))) | 1964 | 'byte-varref) |
| 1927 | '(byte-goto-if-nil byte-goto-if-nil-else-pop) | 1965 | (eq (cdr (car tmp)) (cdr lap1)) |
| 1928 | '(byte-goto-if-not-nil | 1966 | (not (memq (car (cdr lap1)) byte-boolean-vars))) |
| 1929 | byte-goto-if-not-nil-else-pop)))) | 1967 | ;;(byte-compile-log-lap " Pulled %s to end of loop" (car tmp)) |
| 1930 | (byte-compile-log-lap " %s goto [%s]\t-->\t%s %s" | 1968 | (let ((newtag (byte-compile-make-tag))) |
| 1931 | lap0 tmp2 lap0 tmp2) | 1969 | (byte-compile-log-lap |
| 1932 | (setcar lap1 (car tmp2)) | 1970 | " %s: %s ... %s %s\t-->\t%s: %s %s: ... %s %s %s" |
| 1933 | (setcdr lap1 (cdr tmp2)) | 1971 | (nth 1 (cdr lap2)) (car tmp) |
| 1934 | ;; Let next step fix the (const,goto-if*) sequence. | 1972 | lap1 lap2 |
| 1935 | (setq rest (cons nil rest)) | 1973 | (nth 1 (cdr lap2)) (car tmp) |
| 1936 | (setq keep-going t)) | 1974 | (nth 1 newtag) 'byte-dup lap1 |
| 1937 | ((or (consp (cdr lap0)) | 1975 | (cons 'byte-goto newtag) |
| 1938 | (eq (car tmp2) 'byte-discard)) | 1976 | ) |
| 1939 | ;; Jump one step further | 1977 | (setcdr rest (cons (cons 'byte-dup 0) (cdr rest))) |
| 1940 | (byte-compile-log-lap | 1978 | (setcdr tmp (cons (setcdr lap2 newtag) (cdr tmp)))) |
| 1941 | " %s goto [%s]\t-->\t<deleted> goto <skip>" | 1979 | (setq add-depth 1) |
| 1942 | lap0 tmp2) | 1980 | (setq keep-going t)) |
| 1943 | (or (eq 'TAG (car (nth 1 tmp))) | 1981 | ;; |
| 1944 | (setcdr tmp (cons (byte-compile-make-tag) | 1982 | ;; goto-X Y: ... X: goto-if*-Y --> goto-if-not-*-X+1 Y: |
| 1945 | (cdr tmp)))) | 1983 | ;; (This can pull the loop test to the end of the loop) |
| 1946 | (setcdr lap1 (car (cdr tmp))) | 1984 | ;; |
| 1947 | (setq lap (delq lap0 lap)) | 1985 | ((and (eq (car lap0) 'byte-goto) |
| 1948 | (setq keep-going t)))) | 1986 | (eq (car lap1) 'TAG) |
| 1949 | ;; | 1987 | (eq lap1 |
| 1950 | ;; X: varref-Y ... varset-Y goto-X --> | 1988 | (cdr (car (setq tmp (cdr (memq (cdr lap0) lap)))))) |
| 1951 | ;; X: varref-Y Z: ... dup varset-Y goto-Z | 1989 | (memq (car (car tmp)) |
| 1952 | ;; (varset-X goto-BACK, BACK: varref-X --> copy the varref down.) | 1990 | '(byte-goto byte-goto-if-nil byte-goto-if-not-nil |
| 1953 | ;; (This is so usual for while loops that it is worth handling). | 1991 | byte-goto-if-nil-else-pop))) |
| 1954 | ;; | 1992 | ;; (byte-compile-log-lap " %s %s, %s %s --> moved conditional" |
| 1955 | ;; Here again, we could do it for stack-ref/stack-set, but | 1993 | ;; lap0 lap1 (cdr lap0) (car tmp)) |
| 1956 | ;; that's replacing a stack-ref-Y with a stack-ref-0, which | 1994 | (let ((newtag (byte-compile-make-tag))) |
| 1957 | ;; is a very minor improvement (if any), at the cost of | 1995 | (byte-compile-log-lap |
| 1958 | ;; more stack use and more byte-code. Let's not do it. | 1996 | "%s %s: ... %s: %s\t-->\t%s ... %s:" |
| 1959 | ;; | 1997 | lap0 (nth 1 lap1) (nth 1 (cdr lap0)) (car tmp) |
| 1960 | ((and (eq (car lap1) 'byte-varset) | 1998 | (cons (cdr (assq (car (car tmp)) |
| 1961 | (eq (car lap2) 'byte-goto) | 1999 | '((byte-goto-if-nil . byte-goto-if-not-nil) |
| 1962 | (not (memq (cdr lap2) rest)) ;Backwards jump | 2000 | (byte-goto-if-not-nil . byte-goto-if-nil) |
| 1963 | (eq (car (car (setq tmp (cdr (memq (cdr lap2) lap))))) | 2001 | (byte-goto-if-nil-else-pop . |
| 1964 | 'byte-varref) | 2002 | byte-goto-if-not-nil-else-pop) |
| 1965 | (eq (cdr (car tmp)) (cdr lap1)) | 2003 | (byte-goto-if-not-nil-else-pop . |
| 1966 | (not (memq (car (cdr lap1)) byte-boolean-vars))) | 2004 | byte-goto-if-nil-else-pop)))) |
| 1967 | ;;(byte-compile-log-lap " Pulled %s to end of loop" (car tmp)) | 2005 | newtag) |
| 1968 | (let ((newtag (byte-compile-make-tag))) | 2006 | |
| 1969 | (byte-compile-log-lap | 2007 | (nth 1 newtag) |
| 1970 | " %s: %s ... %s %s\t-->\t%s: %s %s: ... %s %s %s" | 2008 | ) |
| 1971 | (nth 1 (cdr lap2)) (car tmp) | 2009 | (setcdr tmp (cons (setcdr lap0 newtag) (cdr tmp))) |
| 1972 | lap1 lap2 | 2010 | (if (eq (car (car tmp)) 'byte-goto-if-nil-else-pop) |
| 1973 | (nth 1 (cdr lap2)) (car tmp) | 2011 | ;; We can handle this case but not the -if-not-nil case, |
| 1974 | (nth 1 newtag) 'byte-dup lap1 | 2012 | ;; because we won't know which non-nil constant to push. |
| 1975 | (cons 'byte-goto newtag) | 2013 | (setcdr rest (cons (cons 'byte-constant |
| 1976 | ) | 2014 | (byte-compile-get-constant nil)) |
| 1977 | (setcdr rest (cons (cons 'byte-dup 0) (cdr rest))) | 2015 | (cdr rest)))) |
| 1978 | (setcdr tmp (cons (setcdr lap2 newtag) (cdr tmp)))) | 2016 | (setcar lap0 (nth 1 (memq (car (car tmp)) |
| 1979 | (setq add-depth 1) | 2017 | '(byte-goto-if-nil-else-pop |
| 1980 | (setq keep-going t)) | 2018 | byte-goto-if-not-nil |
| 1981 | ;; | 2019 | byte-goto-if-nil |
| 1982 | ;; goto-X Y: ... X: goto-if*-Y --> goto-if-not-*-X+1 Y: | 2020 | byte-goto-if-not-nil |
| 1983 | ;; (This can pull the loop test to the end of the loop) | 2021 | byte-goto byte-goto)))) |
| 1984 | ;; | 2022 | ) |
| 1985 | ((and (eq (car lap0) 'byte-goto) | 2023 | (setq keep-going t)) |
| 1986 | (eq (car lap1) 'TAG) | 2024 | ) |
| 1987 | (eq lap1 | ||
| 1988 | (cdr (car (setq tmp (cdr (memq (cdr lap0) lap)))))) | ||
| 1989 | (memq (car (car tmp)) | ||
| 1990 | '(byte-goto byte-goto-if-nil byte-goto-if-not-nil | ||
| 1991 | byte-goto-if-nil-else-pop))) | ||
| 1992 | ;; (byte-compile-log-lap " %s %s, %s %s --> moved conditional" | ||
| 1993 | ;; lap0 lap1 (cdr lap0) (car tmp)) | ||
| 1994 | (let ((newtag (byte-compile-make-tag))) | ||
| 1995 | (byte-compile-log-lap | ||
| 1996 | "%s %s: ... %s: %s\t-->\t%s ... %s:" | ||
| 1997 | lap0 (nth 1 lap1) (nth 1 (cdr lap0)) (car tmp) | ||
| 1998 | (cons (cdr (assq (car (car tmp)) | ||
| 1999 | '((byte-goto-if-nil . byte-goto-if-not-nil) | ||
| 2000 | (byte-goto-if-not-nil . byte-goto-if-nil) | ||
| 2001 | (byte-goto-if-nil-else-pop . | ||
| 2002 | byte-goto-if-not-nil-else-pop) | ||
| 2003 | (byte-goto-if-not-nil-else-pop . | ||
| 2004 | byte-goto-if-nil-else-pop)))) | ||
| 2005 | newtag) | ||
| 2006 | |||
| 2007 | (nth 1 newtag) | ||
| 2008 | ) | ||
| 2009 | (setcdr tmp (cons (setcdr lap0 newtag) (cdr tmp))) | ||
| 2010 | (if (eq (car (car tmp)) 'byte-goto-if-nil-else-pop) | ||
| 2011 | ;; We can handle this case but not the -if-not-nil case, | ||
| 2012 | ;; because we won't know which non-nil constant to push. | ||
| 2013 | (setcdr rest (cons (cons 'byte-constant | ||
| 2014 | (byte-compile-get-constant nil)) | ||
| 2015 | (cdr rest)))) | ||
| 2016 | (setcar lap0 (nth 1 (memq (car (car tmp)) | ||
| 2017 | '(byte-goto-if-nil-else-pop | ||
| 2018 | byte-goto-if-not-nil | ||
| 2019 | byte-goto-if-nil | ||
| 2020 | byte-goto-if-not-nil | ||
| 2021 | byte-goto byte-goto)))) | ||
| 2022 | ) | ||
| 2023 | (setq keep-going t)) | ||
| 2024 | ) | ||
| 2025 | (setq rest (cdr rest))) | 2025 | (setq rest (cdr rest))) |
| 2026 | ) | 2026 | ) |
| 2027 | ;; Cleanup stage: | 2027 | ;; Cleanup stage: |