< prev index next >

src/share/vm/opto/matcher.cpp

Print this page




1910   // Return argument 0 register.  In the LP64 build pointers
1911   // take 2 registers, but the VM wants only the 'main' name.
1912   return OptoReg::as_OptoReg(regs.first());
1913 }
1914 
1915 // This function identifies sub-graphs in which a 'load' node is
1916 // input to two different nodes, and such that it can be matched
1917 // with BMI instructions like blsi, blsr, etc.
1918 // Example : for b = -a[i] & a[i] can be matched to blsi r32, m32.
1919 // The graph is (AndL (SubL Con0 LoadL*) LoadL*), where LoadL*
1920 // refers to the same node.
1921 #ifdef X86
1922 // Match the generic fused operations pattern (op1 (op2 Con{ConType} mop) mop)
1923 // This is a temporary solution until we make DAGs expressible in ADL.
1924 template<typename ConType>
1925 class FusedPatternMatcher {
1926   Node* _op1_node;
1927   Node* _mop_node;
1928   int _con_op;
1929 
1930   static int match_next(Node* n, int next_op, int next_op_idx) {
1931     if (n->in(1) == NULL || n->in(2) == NULL) {
1932       return -1;
1933     }
1934 
1935     if (next_op_idx == -1) { // n is commutative, try rotations
1936       if (n->in(1)->Opcode() == next_op) {
1937         return 1;
1938       } else if (n->in(2)->Opcode() == next_op) {
1939         return 2;
1940       }
1941     } else {
1942       assert(next_op_idx > 0 && next_op_idx <= 2, "Bad argument index");
1943       if (n->in(next_op_idx)->Opcode() == next_op) {
1944         return next_op_idx;
1945       }
1946     }
1947     return -1;
1948   }
1949 public:
1950   FusedPatternMatcher(Node* op1_node, Node *mop_node, int con_op) :
1951     _op1_node(op1_node), _mop_node(mop_node), _con_op(con_op) { }
1952 
1953   bool match(int op1, int op1_op2_idx,  // op1 and the index of the op1->op2 edge, -1 if op1 is commutative
1954              int op2, int op2_con_idx,  // op2 and the index of the op2->con edge, -1 if op2 is commutative
1955              typename ConType::NativeType con_value) {
1956     if (_op1_node->Opcode() != op1) {
1957       return false;
1958     }
1959     if (_mop_node->outcnt() > 2) {
1960       return false;
1961     }
1962     op1_op2_idx = match_next(_op1_node, op2, op1_op2_idx);
1963     if (op1_op2_idx == -1) {
1964       return false;
1965     }
1966     // Memory operation must be the other edge
1967     int op1_mop_idx = (op1_op2_idx & 1) + 1;
1968 
1969     // Check that the mop node is really what we want
1970     if (_op1_node->in(op1_mop_idx) == _mop_node) {
1971       Node *op2_node = _op1_node->in(op1_op2_idx);
1972       if (op2_node->outcnt() > 1) {
1973         return false;
1974       }




1910   // Return argument 0 register.  In the LP64 build pointers
1911   // take 2 registers, but the VM wants only the 'main' name.
1912   return OptoReg::as_OptoReg(regs.first());
1913 }
1914 
1915 // This function identifies sub-graphs in which a 'load' node is
1916 // input to two different nodes, and such that it can be matched
1917 // with BMI instructions like blsi, blsr, etc.
1918 // Example : for b = -a[i] & a[i] can be matched to blsi r32, m32.
1919 // The graph is (AndL (SubL Con0 LoadL*) LoadL*), where LoadL*
1920 // refers to the same node.
1921 #ifdef X86
1922 // Match the generic fused operations pattern (op1 (op2 Con{ConType} mop) mop)
1923 // This is a temporary solution until we make DAGs expressible in ADL.
1924 template<typename ConType>
1925 class FusedPatternMatcher {
1926   Node* _op1_node;
1927   Node* _mop_node;
1928   int _con_op;
1929 
1930   static int match_next(Node* n, uint next_op, int next_op_idx) {
1931     if (n->in(1) == NULL || n->in(2) == NULL) {
1932       return -1;
1933     }
1934 
1935     if (next_op_idx == -1) { // n is commutative, try rotations
1936       if (n->in(1)->Opcode() == next_op) {
1937         return 1;
1938       } else if (n->in(2)->Opcode() == next_op) {
1939         return 2;
1940       }
1941     } else {
1942       assert(next_op_idx > 0 && next_op_idx <= 2, "Bad argument index");
1943       if (n->in(next_op_idx)->Opcode() == next_op) {
1944         return next_op_idx;
1945       }
1946     }
1947     return -1;
1948   }
1949 public:
1950   FusedPatternMatcher(Node* op1_node, Node *mop_node, int con_op) :
1951     _op1_node(op1_node), _mop_node(mop_node), _con_op(con_op) { }
1952 
1953   bool match(uint op1, int op1_op2_idx,  // op1 and the index of the op1->op2 edge, -1 if op1 is commutative
1954              uint op2, int op2_con_idx,  // op2 and the index of the op2->con edge, -1 if op2 is commutative
1955              typename ConType::NativeType con_value) {
1956     if (_op1_node->Opcode() != op1) {
1957       return false;
1958     }
1959     if (_mop_node->outcnt() > 2) {
1960       return false;
1961     }
1962     op1_op2_idx = match_next(_op1_node, op2, op1_op2_idx);
1963     if (op1_op2_idx == -1) {
1964       return false;
1965     }
1966     // Memory operation must be the other edge
1967     int op1_mop_idx = (op1_op2_idx & 1) + 1;
1968 
1969     // Check that the mop node is really what we want
1970     if (_op1_node->in(op1_mop_idx) == _mop_node) {
1971       Node *op2_node = _op1_node->in(op1_op2_idx);
1972       if (op2_node->outcnt() > 1) {
1973         return false;
1974       }


< prev index next >