< prev index next >

src/hotspot/share/opto/divnode.cpp

Print this page

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 }
< prev index next >