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