< prev index next >

src/hotspot/share/opto/divnode.cpp

Print this page

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