1601 const Type* divisor_type = phase->type(divisor());
1602 if (dividend_type == Type::TOP || divisor_type == Type::TOP) {
1603 return phase->C->top();
1604 }
1605 const Type* constant_result = get_result_if_constant(dividend_type, divisor_type);
1606 if (constant_result != nullptr) {
1607 return make_tuple_of_input_state_and_constant_result(igvn, constant_result);
1608 }
1609 }
1610
1611 return CallLeafPureNode::Ideal(phase, can_reshape);
1612 }
1613
1614 /* Give a tuple node for ::Ideal to return, made of the input state (control to return addr)
1615 * and the given constant result. Idealization of projections will make sure to transparently
1616 * propagate the input state and replace the result by the said constant.
1617 */
1618 TupleNode* ModFloatingNode::make_tuple_of_input_state_and_constant_result(PhaseIterGVN* phase, const Type* con) const {
1619 Node* con_node = phase->makecon(con);
1620 TupleNode* tuple = TupleNode::make(
1621 tf()->range(),
1622 in(TypeFunc::Control),
1623 in(TypeFunc::I_O),
1624 in(TypeFunc::Memory),
1625 in(TypeFunc::FramePtr),
1626 in(TypeFunc::ReturnAdr),
1627 con_node);
1628
1629 return tuple;
1630 }
1631
1632 //=============================================================================
1633
1634 DivModNode::DivModNode( Node *c, Node *dividend, Node *divisor ) : MultiNode(3) {
1635 init_req(0, c);
1636 init_req(1, dividend);
1637 init_req(2, divisor);
1638 }
1639
1640 DivModNode* DivModNode::make(Node* div_or_mod, BasicType bt, bool is_unsigned) {
1641 assert(bt == T_INT || bt == T_LONG, "only int or long input pattern accepted");
1664 DivModINode* divmod = new DivModINode(n->in(0), n->in(1), n->in(2));
1665 Node* dproj = new ProjNode(divmod, DivModNode::div_proj_num);
1666 Node* mproj = new ProjNode(divmod, DivModNode::mod_proj_num);
1667 return divmod;
1668 }
1669
1670 //------------------------------make------------------------------------------
1671 DivModLNode* DivModLNode::make(Node* div_or_mod) {
1672 Node* n = div_or_mod;
1673 assert(n->Opcode() == Op_DivL || n->Opcode() == Op_ModL,
1674 "only div or mod input pattern accepted");
1675
1676 DivModLNode* divmod = new DivModLNode(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 //------------------------------match------------------------------------------
1683 // return result(s) along with their RegMask info
1684 Node *DivModINode::match( const ProjNode *proj, const Matcher *match ) {
1685 uint ideal_reg = proj->ideal_reg();
1686 RegMask rm;
1687 if (proj->_con == div_proj_num) {
1688 rm.assignFrom(match->divI_proj_mask());
1689 } else {
1690 assert(proj->_con == mod_proj_num, "must be div or mod projection");
1691 rm.assignFrom(match->modI_proj_mask());
1692 }
1693 return new MachProjNode(this, proj->_con, rm, ideal_reg);
1694 }
1695
1696
1697 //------------------------------match------------------------------------------
1698 // return result(s) along with their RegMask info
1699 Node *DivModLNode::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.assignFrom(match->divL_proj_mask());
1704 } else {
1705 assert(proj->_con == mod_proj_num, "must be div or mod projection");
1706 rm.assignFrom(match->modL_proj_mask());
1707 }
1708 return new MachProjNode(this, proj->_con, rm, ideal_reg);
1709 }
1710
1711 //------------------------------make------------------------------------------
1712 UDivModINode* UDivModINode::make(Node* div_or_mod) {
1713 Node* n = div_or_mod;
1714 assert(n->Opcode() == Op_UDivI || n->Opcode() == Op_UModI,
1715 "only div or mod input pattern accepted");
1716
1717 UDivModINode* divmod = new UDivModINode(n->in(0), n->in(1), n->in(2));
1718 Node* dproj = new ProjNode(divmod, DivModNode::div_proj_num);
1719 Node* mproj = new ProjNode(divmod, DivModNode::mod_proj_num);
1720 return divmod;
1721 }
1722
1723 //------------------------------make------------------------------------------
1724 UDivModLNode* UDivModLNode::make(Node* div_or_mod) {
1725 Node* n = div_or_mod;
1726 assert(n->Opcode() == Op_UDivL || n->Opcode() == Op_UModL,
1727 "only div or mod input pattern accepted");
1728
1729 UDivModLNode* divmod = new UDivModLNode(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 //------------------------------match------------------------------------------
1736 // return result(s) along with their RegMask info
1737 Node* UDivModINode::match( const ProjNode *proj, const Matcher *match ) {
1738 uint ideal_reg = proj->ideal_reg();
1739 RegMask rm;
1740 if (proj->_con == div_proj_num) {
1741 rm.assignFrom(match->divI_proj_mask());
1742 } else {
1743 assert(proj->_con == mod_proj_num, "must be div or mod projection");
1744 rm.assignFrom(match->modI_proj_mask());
1745 }
1746 return new MachProjNode(this, proj->_con, rm, ideal_reg);
1747 }
1748
1749
1750 //------------------------------match------------------------------------------
1751 // return result(s) along with their RegMask info
1752 Node* UDivModLNode::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.assignFrom(match->divL_proj_mask());
1757 } else {
1758 assert(proj->_con == mod_proj_num, "must be div or mod projection");
1759 rm.assignFrom(match->modL_proj_mask());
1760 }
1761 return new MachProjNode(this, proj->_con, rm, ideal_reg);
1762 }
|
1601 const Type* divisor_type = phase->type(divisor());
1602 if (dividend_type == Type::TOP || divisor_type == Type::TOP) {
1603 return phase->C->top();
1604 }
1605 const Type* constant_result = get_result_if_constant(dividend_type, divisor_type);
1606 if (constant_result != nullptr) {
1607 return make_tuple_of_input_state_and_constant_result(igvn, constant_result);
1608 }
1609 }
1610
1611 return CallLeafPureNode::Ideal(phase, can_reshape);
1612 }
1613
1614 /* Give a tuple node for ::Ideal to return, made of the input state (control to return addr)
1615 * and the given constant result. Idealization of projections will make sure to transparently
1616 * propagate the input state and replace the result by the said constant.
1617 */
1618 TupleNode* ModFloatingNode::make_tuple_of_input_state_and_constant_result(PhaseIterGVN* phase, const Type* con) const {
1619 Node* con_node = phase->makecon(con);
1620 TupleNode* tuple = TupleNode::make(
1621 tf()->range_cc(),
1622 in(TypeFunc::Control),
1623 in(TypeFunc::I_O),
1624 in(TypeFunc::Memory),
1625 in(TypeFunc::FramePtr),
1626 in(TypeFunc::ReturnAdr),
1627 con_node);
1628
1629 return tuple;
1630 }
1631
1632 //=============================================================================
1633
1634 DivModNode::DivModNode( Node *c, Node *dividend, Node *divisor ) : MultiNode(3) {
1635 init_req(0, c);
1636 init_req(1, dividend);
1637 init_req(2, divisor);
1638 }
1639
1640 DivModNode* DivModNode::make(Node* div_or_mod, BasicType bt, bool is_unsigned) {
1641 assert(bt == T_INT || bt == T_LONG, "only int or long input pattern accepted");
1664 DivModINode* divmod = new DivModINode(n->in(0), n->in(1), n->in(2));
1665 Node* dproj = new ProjNode(divmod, DivModNode::div_proj_num);
1666 Node* mproj = new ProjNode(divmod, DivModNode::mod_proj_num);
1667 return divmod;
1668 }
1669
1670 //------------------------------make------------------------------------------
1671 DivModLNode* DivModLNode::make(Node* div_or_mod) {
1672 Node* n = div_or_mod;
1673 assert(n->Opcode() == Op_DivL || n->Opcode() == Op_ModL,
1674 "only div or mod input pattern accepted");
1675
1676 DivModLNode* divmod = new DivModLNode(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 //------------------------------match------------------------------------------
1683 // return result(s) along with their RegMask info
1684 Node *DivModINode::match(const ProjNode *proj, const Matcher *match, const RegMask* mask) {
1685 uint ideal_reg = proj->ideal_reg();
1686 RegMask rm;
1687 if (proj->_con == div_proj_num) {
1688 rm.assignFrom(match->divI_proj_mask());
1689 } else {
1690 assert(proj->_con == mod_proj_num, "must be div or mod projection");
1691 rm.assignFrom(match->modI_proj_mask());
1692 }
1693 return new MachProjNode(this, proj->_con, rm, ideal_reg);
1694 }
1695
1696
1697 //------------------------------match------------------------------------------
1698 // return result(s) along with their RegMask info
1699 Node *DivModLNode::match(const ProjNode *proj, const Matcher *match, const RegMask* mask) {
1700 uint ideal_reg = proj->ideal_reg();
1701 RegMask rm;
1702 if (proj->_con == div_proj_num) {
1703 rm.assignFrom(match->divL_proj_mask());
1704 } else {
1705 assert(proj->_con == mod_proj_num, "must be div or mod projection");
1706 rm.assignFrom(match->modL_proj_mask());
1707 }
1708 return new MachProjNode(this, proj->_con, rm, ideal_reg);
1709 }
1710
1711 //------------------------------make------------------------------------------
1712 UDivModINode* UDivModINode::make(Node* div_or_mod) {
1713 Node* n = div_or_mod;
1714 assert(n->Opcode() == Op_UDivI || n->Opcode() == Op_UModI,
1715 "only div or mod input pattern accepted");
1716
1717 UDivModINode* divmod = new UDivModINode(n->in(0), n->in(1), n->in(2));
1718 Node* dproj = new ProjNode(divmod, DivModNode::div_proj_num);
1719 Node* mproj = new ProjNode(divmod, DivModNode::mod_proj_num);
1720 return divmod;
1721 }
1722
1723 //------------------------------make------------------------------------------
1724 UDivModLNode* UDivModLNode::make(Node* div_or_mod) {
1725 Node* n = div_or_mod;
1726 assert(n->Opcode() == Op_UDivL || n->Opcode() == Op_UModL,
1727 "only div or mod input pattern accepted");
1728
1729 UDivModLNode* divmod = new UDivModLNode(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 //------------------------------match------------------------------------------
1736 // return result(s) along with their RegMask info
1737 Node* UDivModINode::match(const ProjNode* proj, const Matcher* match, const RegMask* mask) {
1738 uint ideal_reg = proj->ideal_reg();
1739 RegMask rm;
1740 if (proj->_con == div_proj_num) {
1741 rm.assignFrom(match->divI_proj_mask());
1742 } else {
1743 assert(proj->_con == mod_proj_num, "must be div or mod projection");
1744 rm.assignFrom(match->modI_proj_mask());
1745 }
1746 return new MachProjNode(this, proj->_con, rm, ideal_reg);
1747 }
1748
1749
1750 //------------------------------match------------------------------------------
1751 // return result(s) along with their RegMask info
1752 Node* UDivModLNode::match( const ProjNode* proj, const Matcher* match, const RegMask* mask) {
1753 uint ideal_reg = proj->ideal_reg();
1754 RegMask rm;
1755 if (proj->_con == div_proj_num) {
1756 rm.assignFrom(match->divL_proj_mask());
1757 } else {
1758 assert(proj->_con == mod_proj_num, "must be div or mod projection");
1759 rm.assignFrom(match->modL_proj_mask());
1760 }
1761 return new MachProjNode(this, proj->_con, rm, ideal_reg);
1762 }
|