1606 }
1607
1608 // If an operand is infinity or the divisor is +/- zero, punt.
1609 if (!g_isfinite(f1) || !g_isfinite(f2) || x2 == 0 || x2 == min_jlong) {
1610 return nullptr;
1611 }
1612
1613 // We must be modulo'ing 2 double constants.
1614 // Make sure that the sign of the fmod is equal to the sign of the dividend
1615 jlong xr = jlong_cast(fmod(f1, f2));
1616 if ((x1 ^ xr) < 0) {
1617 xr ^= min_jlong;
1618 }
1619
1620 return replace_with_con(igvn, TypeD::make(jdouble_cast(xr)));
1621 }
1622
1623 Node* ModFloatingNode::replace_with_con(PhaseIterGVN* phase, const Type* con) {
1624 Compile* C = phase->C;
1625 Node* con_node = phase->makecon(con);
1626 CallProjections projs;
1627 extract_projections(&projs, false, false);
1628 phase->replace_node(projs.fallthrough_proj, in(TypeFunc::Control));
1629 if (projs.fallthrough_catchproj != nullptr) {
1630 phase->replace_node(projs.fallthrough_catchproj, in(TypeFunc::Control));
1631 }
1632 if (projs.fallthrough_memproj != nullptr) {
1633 phase->replace_node(projs.fallthrough_memproj, in(TypeFunc::Memory));
1634 }
1635 if (projs.catchall_memproj != nullptr) {
1636 phase->replace_node(projs.catchall_memproj, C->top());
1637 }
1638 if (projs.fallthrough_ioproj != nullptr) {
1639 phase->replace_node(projs.fallthrough_ioproj, in(TypeFunc::I_O));
1640 }
1641 assert(projs.catchall_ioproj == nullptr, "no exceptions from floating mod");
1642 assert(projs.catchall_catchproj == nullptr, "no exceptions from floating mod");
1643 if (projs.resproj != nullptr) {
1644 phase->replace_node(projs.resproj, con_node);
1645 }
1646 phase->replace_node(this, C->top());
1647 C->remove_macro_node(this);
1648 disconnect_inputs(C);
1649 return nullptr;
1650 }
1651
1652 //=============================================================================
1653
1654 DivModNode::DivModNode( Node *c, Node *dividend, Node *divisor ) : MultiNode(3) {
1655 init_req(0, c);
1656 init_req(1, dividend);
1657 init_req(2, divisor);
1658 }
1659
1660 DivModNode* DivModNode::make(Node* div_or_mod, BasicType bt, bool is_unsigned) {
1661 assert(bt == T_INT || bt == T_LONG, "only int or long input pattern accepted");
1662
1663 if (bt == T_INT) {
1664 if (is_unsigned) {
1684 DivModINode* divmod = new DivModINode(n->in(0), n->in(1), n->in(2));
1685 Node* dproj = new ProjNode(divmod, DivModNode::div_proj_num);
1686 Node* mproj = new ProjNode(divmod, DivModNode::mod_proj_num);
1687 return divmod;
1688 }
1689
1690 //------------------------------make------------------------------------------
1691 DivModLNode* DivModLNode::make(Node* div_or_mod) {
1692 Node* n = div_or_mod;
1693 assert(n->Opcode() == Op_DivL || n->Opcode() == Op_ModL,
1694 "only div or mod input pattern accepted");
1695
1696 DivModLNode* divmod = new DivModLNode(n->in(0), n->in(1), n->in(2));
1697 Node* dproj = new ProjNode(divmod, DivModNode::div_proj_num);
1698 Node* mproj = new ProjNode(divmod, DivModNode::mod_proj_num);
1699 return divmod;
1700 }
1701
1702 //------------------------------match------------------------------------------
1703 // return result(s) along with their RegMask info
1704 Node *DivModINode::match( const ProjNode *proj, const Matcher *match ) {
1705 uint ideal_reg = proj->ideal_reg();
1706 RegMask rm;
1707 if (proj->_con == div_proj_num) {
1708 rm = match->divI_proj_mask();
1709 } else {
1710 assert(proj->_con == mod_proj_num, "must be div or mod projection");
1711 rm = match->modI_proj_mask();
1712 }
1713 return new MachProjNode(this, proj->_con, rm, ideal_reg);
1714 }
1715
1716
1717 //------------------------------match------------------------------------------
1718 // return result(s) along with their RegMask info
1719 Node *DivModLNode::match( const ProjNode *proj, const Matcher *match ) {
1720 uint ideal_reg = proj->ideal_reg();
1721 RegMask rm;
1722 if (proj->_con == div_proj_num) {
1723 rm = match->divL_proj_mask();
1724 } else {
1725 assert(proj->_con == mod_proj_num, "must be div or mod projection");
1726 rm = match->modL_proj_mask();
1727 }
1728 return new MachProjNode(this, proj->_con, rm, ideal_reg);
1729 }
1730
1731 //------------------------------make------------------------------------------
1732 UDivModINode* UDivModINode::make(Node* div_or_mod) {
1733 Node* n = div_or_mod;
1734 assert(n->Opcode() == Op_UDivI || n->Opcode() == Op_UModI,
1735 "only div or mod input pattern accepted");
1736
1737 UDivModINode* divmod = new UDivModINode(n->in(0), n->in(1), n->in(2));
1738 Node* dproj = new ProjNode(divmod, DivModNode::div_proj_num);
1739 Node* mproj = new ProjNode(divmod, DivModNode::mod_proj_num);
1740 return divmod;
1741 }
1742
1743 //------------------------------make------------------------------------------
1744 UDivModLNode* UDivModLNode::make(Node* div_or_mod) {
1745 Node* n = div_or_mod;
1746 assert(n->Opcode() == Op_UDivL || n->Opcode() == Op_UModL,
1747 "only div or mod input pattern accepted");
1748
1749 UDivModLNode* divmod = new UDivModLNode(n->in(0), n->in(1), n->in(2));
1750 Node* dproj = new ProjNode(divmod, DivModNode::div_proj_num);
1751 Node* mproj = new ProjNode(divmod, DivModNode::mod_proj_num);
1752 return divmod;
1753 }
1754
1755 //------------------------------match------------------------------------------
1756 // return result(s) along with their RegMask info
1757 Node* UDivModINode::match( const ProjNode *proj, const Matcher *match ) {
1758 uint ideal_reg = proj->ideal_reg();
1759 RegMask rm;
1760 if (proj->_con == div_proj_num) {
1761 rm = match->divI_proj_mask();
1762 } else {
1763 assert(proj->_con == mod_proj_num, "must be div or mod projection");
1764 rm = match->modI_proj_mask();
1765 }
1766 return new MachProjNode(this, proj->_con, rm, ideal_reg);
1767 }
1768
1769
1770 //------------------------------match------------------------------------------
1771 // return result(s) along with their RegMask info
1772 Node* UDivModLNode::match( const ProjNode *proj, const Matcher *match ) {
1773 uint ideal_reg = proj->ideal_reg();
1774 RegMask rm;
1775 if (proj->_con == div_proj_num) {
1776 rm = match->divL_proj_mask();
1777 } else {
1778 assert(proj->_con == mod_proj_num, "must be div or mod projection");
1779 rm = match->modL_proj_mask();
1780 }
1781 return new MachProjNode(this, proj->_con, rm, ideal_reg);
1782 }
|
1606 }
1607
1608 // If an operand is infinity or the divisor is +/- zero, punt.
1609 if (!g_isfinite(f1) || !g_isfinite(f2) || x2 == 0 || x2 == min_jlong) {
1610 return nullptr;
1611 }
1612
1613 // We must be modulo'ing 2 double constants.
1614 // Make sure that the sign of the fmod is equal to the sign of the dividend
1615 jlong xr = jlong_cast(fmod(f1, f2));
1616 if ((x1 ^ xr) < 0) {
1617 xr ^= min_jlong;
1618 }
1619
1620 return replace_with_con(igvn, TypeD::make(jdouble_cast(xr)));
1621 }
1622
1623 Node* ModFloatingNode::replace_with_con(PhaseIterGVN* phase, const Type* con) {
1624 Compile* C = phase->C;
1625 Node* con_node = phase->makecon(con);
1626 CallProjections* projs = extract_projections(false, false);
1627 phase->replace_node(projs->fallthrough_proj, in(TypeFunc::Control));
1628 if (projs->fallthrough_catchproj != nullptr) {
1629 phase->replace_node(projs->fallthrough_catchproj, in(TypeFunc::Control));
1630 }
1631 if (projs->fallthrough_memproj != nullptr) {
1632 phase->replace_node(projs->fallthrough_memproj, in(TypeFunc::Memory));
1633 }
1634 if (projs->catchall_memproj != nullptr) {
1635 phase->replace_node(projs->catchall_memproj, C->top());
1636 }
1637 if (projs->fallthrough_ioproj != nullptr) {
1638 phase->replace_node(projs->fallthrough_ioproj, in(TypeFunc::I_O));
1639 }
1640 assert(projs->catchall_ioproj == nullptr, "no exceptions from floating mod");
1641 assert(projs->catchall_catchproj == nullptr, "no exceptions from floating mod");
1642 if (projs->resproj[0] != nullptr) {
1643 phase->replace_node(projs->resproj[0], con_node);
1644 }
1645 phase->replace_node(this, C->top());
1646 C->remove_macro_node(this);
1647 disconnect_inputs(C);
1648 return nullptr;
1649 }
1650
1651 //=============================================================================
1652
1653 DivModNode::DivModNode( Node *c, Node *dividend, Node *divisor ) : MultiNode(3) {
1654 init_req(0, c);
1655 init_req(1, dividend);
1656 init_req(2, divisor);
1657 }
1658
1659 DivModNode* DivModNode::make(Node* div_or_mod, BasicType bt, bool is_unsigned) {
1660 assert(bt == T_INT || bt == T_LONG, "only int or long input pattern accepted");
1661
1662 if (bt == T_INT) {
1663 if (is_unsigned) {
1683 DivModINode* divmod = new DivModINode(n->in(0), n->in(1), n->in(2));
1684 Node* dproj = new ProjNode(divmod, DivModNode::div_proj_num);
1685 Node* mproj = new ProjNode(divmod, DivModNode::mod_proj_num);
1686 return divmod;
1687 }
1688
1689 //------------------------------make------------------------------------------
1690 DivModLNode* DivModLNode::make(Node* div_or_mod) {
1691 Node* n = div_or_mod;
1692 assert(n->Opcode() == Op_DivL || n->Opcode() == Op_ModL,
1693 "only div or mod input pattern accepted");
1694
1695 DivModLNode* divmod = new DivModLNode(n->in(0), n->in(1), n->in(2));
1696 Node* dproj = new ProjNode(divmod, DivModNode::div_proj_num);
1697 Node* mproj = new ProjNode(divmod, DivModNode::mod_proj_num);
1698 return divmod;
1699 }
1700
1701 //------------------------------match------------------------------------------
1702 // return result(s) along with their RegMask info
1703 Node *DivModINode::match(const ProjNode *proj, const Matcher *match, const RegMask* mask) {
1704 uint ideal_reg = proj->ideal_reg();
1705 RegMask rm;
1706 if (proj->_con == div_proj_num) {
1707 rm = match->divI_proj_mask();
1708 } else {
1709 assert(proj->_con == mod_proj_num, "must be div or mod projection");
1710 rm = match->modI_proj_mask();
1711 }
1712 return new MachProjNode(this, proj->_con, rm, ideal_reg);
1713 }
1714
1715
1716 //------------------------------match------------------------------------------
1717 // return result(s) along with their RegMask info
1718 Node *DivModLNode::match(const ProjNode *proj, const Matcher *match, const RegMask* mask) {
1719 uint ideal_reg = proj->ideal_reg();
1720 RegMask rm;
1721 if (proj->_con == div_proj_num) {
1722 rm = match->divL_proj_mask();
1723 } else {
1724 assert(proj->_con == mod_proj_num, "must be div or mod projection");
1725 rm = match->modL_proj_mask();
1726 }
1727 return new MachProjNode(this, proj->_con, rm, ideal_reg);
1728 }
1729
1730 //------------------------------make------------------------------------------
1731 UDivModINode* UDivModINode::make(Node* div_or_mod) {
1732 Node* n = div_or_mod;
1733 assert(n->Opcode() == Op_UDivI || n->Opcode() == Op_UModI,
1734 "only div or mod input pattern accepted");
1735
1736 UDivModINode* divmod = new UDivModINode(n->in(0), n->in(1), n->in(2));
1737 Node* dproj = new ProjNode(divmod, DivModNode::div_proj_num);
1738 Node* mproj = new ProjNode(divmod, DivModNode::mod_proj_num);
1739 return divmod;
1740 }
1741
1742 //------------------------------make------------------------------------------
1743 UDivModLNode* UDivModLNode::make(Node* div_or_mod) {
1744 Node* n = div_or_mod;
1745 assert(n->Opcode() == Op_UDivL || n->Opcode() == Op_UModL,
1746 "only div or mod input pattern accepted");
1747
1748 UDivModLNode* divmod = new UDivModLNode(n->in(0), n->in(1), n->in(2));
1749 Node* dproj = new ProjNode(divmod, DivModNode::div_proj_num);
1750 Node* mproj = new ProjNode(divmod, DivModNode::mod_proj_num);
1751 return divmod;
1752 }
1753
1754 //------------------------------match------------------------------------------
1755 // return result(s) along with their RegMask info
1756 Node* UDivModINode::match(const ProjNode* proj, const Matcher* match, const RegMask* mask) {
1757 uint ideal_reg = proj->ideal_reg();
1758 RegMask rm;
1759 if (proj->_con == div_proj_num) {
1760 rm = match->divI_proj_mask();
1761 } else {
1762 assert(proj->_con == mod_proj_num, "must be div or mod projection");
1763 rm = match->modI_proj_mask();
1764 }
1765 return new MachProjNode(this, proj->_con, rm, ideal_reg);
1766 }
1767
1768
1769 //------------------------------match------------------------------------------
1770 // return result(s) along with their RegMask info
1771 Node* UDivModLNode::match( const ProjNode* proj, const Matcher* match, const RegMask* mask) {
1772 uint ideal_reg = proj->ideal_reg();
1773 RegMask rm;
1774 if (proj->_con == div_proj_num) {
1775 rm = match->divL_proj_mask();
1776 } else {
1777 assert(proj->_con == mod_proj_num, "must be div or mod projection");
1778 rm = match->modL_proj_mask();
1779 }
1780 return new MachProjNode(this, proj->_con, rm, ideal_reg);
1781 }
|