comparison src/share/vm/opto/matcher.cpp @ 17729:8a8ff6b577ed

8031321: Support Intel bit manipulation instructions Summary: Add support for BMI1 instructions Reviewed-by: kvn, roland
author iveresov
date Wed, 12 Mar 2014 11:24:26 -0700
parents 085b304a1cc5
children 62c54fcc0a35
comparison
equal deleted inserted replaced
17727:cfd4aac53239 17729:8a8ff6b577ed
1905 calling_convention(&sig_bt, &regs, 1, is_outgoing); 1905 calling_convention(&sig_bt, &regs, 1, is_outgoing);
1906 // Return argument 0 register. In the LP64 build pointers 1906 // Return argument 0 register. In the LP64 build pointers
1907 // take 2 registers, but the VM wants only the 'main' name. 1907 // take 2 registers, but the VM wants only the 'main' name.
1908 return OptoReg::as_OptoReg(regs.first()); 1908 return OptoReg::as_OptoReg(regs.first());
1909 } 1909 }
1910
1911 // This function identifies sub-graphs in which a 'load' node is
1912 // input to two different nodes, and such that it can be matched
1913 // with BMI instructions like blsi, blsr, etc.
1914 // Example : for b = -a[i] & a[i] can be matched to blsi r32, m32.
1915 // The graph is (AndL (SubL Con0 LoadL*) LoadL*), where LoadL*
1916 // refers to the same node.
1917 #ifdef X86
1918 // Match the generic fused operations pattern (op1 (op2 Con{ConType} mop) mop)
1919 // This is a temporary solution until we make DAGs expressible in ADL.
1920 template<typename ConType>
1921 class FusedPatternMatcher {
1922 Node* _op1_node;
1923 Node* _mop_node;
1924 int _con_op;
1925
1926 static int match_next(Node* n, int next_op, int next_op_idx) {
1927 if (n->in(1) == NULL || n->in(2) == NULL) {
1928 return -1;
1929 }
1930
1931 if (next_op_idx == -1) { // n is commutative, try rotations
1932 if (n->in(1)->Opcode() == next_op) {
1933 return 1;
1934 } else if (n->in(2)->Opcode() == next_op) {
1935 return 2;
1936 }
1937 } else {
1938 assert(next_op_idx > 0 && next_op_idx <= 2, "Bad argument index");
1939 if (n->in(next_op_idx)->Opcode() == next_op) {
1940 return next_op_idx;
1941 }
1942 }
1943 return -1;
1944 }
1945 public:
1946 FusedPatternMatcher(Node* op1_node, Node *mop_node, int con_op) :
1947 _op1_node(op1_node), _mop_node(mop_node), _con_op(con_op) { }
1948
1949 bool match(int op1, int op1_op2_idx, // op1 and the index of the op1->op2 edge, -1 if op1 is commutative
1950 int op2, int op2_con_idx, // op2 and the index of the op2->con edge, -1 if op2 is commutative
1951 typename ConType::NativeType con_value) {
1952 if (_op1_node->Opcode() != op1) {
1953 return false;
1954 }
1955 if (_mop_node->outcnt() > 2) {
1956 return false;
1957 }
1958 op1_op2_idx = match_next(_op1_node, op2, op1_op2_idx);
1959 if (op1_op2_idx == -1) {
1960 return false;
1961 }
1962 // Memory operation must be the other edge
1963 int op1_mop_idx = (op1_op2_idx & 1) + 1;
1964
1965 // Check that the mop node is really what we want
1966 if (_op1_node->in(op1_mop_idx) == _mop_node) {
1967 Node *op2_node = _op1_node->in(op1_op2_idx);
1968 if (op2_node->outcnt() > 1) {
1969 return false;
1970 }
1971 assert(op2_node->Opcode() == op2, "Should be");
1972 op2_con_idx = match_next(op2_node, _con_op, op2_con_idx);
1973 if (op2_con_idx == -1) {
1974 return false;
1975 }
1976 // Memory operation must be the other edge
1977 int op2_mop_idx = (op2_con_idx & 1) + 1;
1978 // Check that the memory operation is the same node
1979 if (op2_node->in(op2_mop_idx) == _mop_node) {
1980 // Now check the constant
1981 const Type* con_type = op2_node->in(op2_con_idx)->bottom_type();
1982 if (con_type != Type::TOP && ConType::as_self(con_type)->get_con() == con_value) {
1983 return true;
1984 }
1985 }
1986 }
1987 return false;
1988 }
1989 };
1990
1991
1992 bool Matcher::is_bmi_pattern(Node *n, Node *m) {
1993 if (n != NULL && m != NULL) {
1994 if (m->Opcode() == Op_LoadI) {
1995 FusedPatternMatcher<TypeInt> bmii(n, m, Op_ConI);
1996 return bmii.match(Op_AndI, -1, Op_SubI, 1, 0) ||
1997 bmii.match(Op_AndI, -1, Op_AddI, -1, -1) ||
1998 bmii.match(Op_XorI, -1, Op_AddI, -1, -1);
1999 } else if (m->Opcode() == Op_LoadL) {
2000 FusedPatternMatcher<TypeLong> bmil(n, m, Op_ConL);
2001 return bmil.match(Op_AndL, -1, Op_SubL, 1, 0) ||
2002 bmil.match(Op_AndL, -1, Op_AddL, -1, -1) ||
2003 bmil.match(Op_XorL, -1, Op_AddL, -1, -1);
2004 }
2005 }
2006 return false;
2007 }
2008 #endif // X86
1910 2009
1911 // A method-klass-holder may be passed in the inline_cache_reg 2010 // A method-klass-holder may be passed in the inline_cache_reg
1912 // and then expanded into the inline_cache_reg and a method_oop register 2011 // and then expanded into the inline_cache_reg and a method_oop register
1913 // defined in ad_<arch>.cpp 2012 // defined in ad_<arch>.cpp
1914 2013
2061 // they are shared through a DecodeN they may appear 2160 // they are shared through a DecodeN they may appear
2062 // to have a single use so force sharing here. 2161 // to have a single use so force sharing here.
2063 set_shared(m->in(AddPNode::Base)->in(1)); 2162 set_shared(m->in(AddPNode::Base)->in(1));
2064 } 2163 }
2065 2164
2165 // if 'n' and 'm' are part of a graph for BMI instruction, clone this node.
2166 #ifdef X86
2167 if (UseBMI1Instructions && is_bmi_pattern(n, m)) {
2168 mstack.push(m, Visit);
2169 continue;
2170 }
2171 #endif
2172
2066 // Clone addressing expressions as they are "free" in memory access instructions 2173 // Clone addressing expressions as they are "free" in memory access instructions
2067 if( mem_op && i == MemNode::Address && mop == Op_AddP ) { 2174 if( mem_op && i == MemNode::Address && mop == Op_AddP ) {
2068 // Some inputs for address expression are not put on stack 2175 // Some inputs for address expression are not put on stack
2069 // to avoid marking them as shared and forcing them into register 2176 // to avoid marking them as shared and forcing them into register
2070 // if they are used only in address expressions. 2177 // if they are used only in address expressions.