< prev index next >

src/hotspot/share/opto/divnode.cpp

Print this page

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