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