2028 if (m->Opcode() == Op_LoadI) {
2029 FusedPatternMatcher<TypeInt> bmii(n, m, Op_ConI);
2030 return bmii.match(Op_AndI, -1, Op_SubI, 1, 0) ||
2031 bmii.match(Op_AndI, -1, Op_AddI, -1, -1) ||
2032 bmii.match(Op_XorI, -1, Op_AddI, -1, -1);
2033 } else if (m->Opcode() == Op_LoadL) {
2034 FusedPatternMatcher<TypeLong> bmil(n, m, Op_ConL);
2035 return bmil.match(Op_AndL, -1, Op_SubL, 1, 0) ||
2036 bmil.match(Op_AndL, -1, Op_AddL, -1, -1) ||
2037 bmil.match(Op_XorL, -1, Op_AddL, -1, -1);
2038 }
2039 }
2040 return false;
2041 }
2042 #endif // X86
2043
2044 // A method-klass-holder may be passed in the inline_cache_reg
2045 // and then expanded into the inline_cache_reg and a method_oop register
2046 // defined in ad_<arch>.cpp
2047
2048
2049 //------------------------------find_shared------------------------------------
2050 // Set bits if Node is shared or otherwise a root
2051 void Matcher::find_shared( Node *n ) {
2052 // Allocate stack of size C->unique() * 2 to avoid frequent realloc
2053 MStack mstack(C->live_nodes() * 2);
2054 // Mark nodes as address_visited if they are inputs to an address expression
2055 VectorSet address_visited(Thread::current()->resource_area());
2056 mstack.push(n, Visit); // Don't need to pre-visit root node
2057 while (mstack.is_nonempty()) {
2058 n = mstack.node(); // Leave node on stack
2059 Node_State nstate = mstack.state();
2060 uint nop = n->Opcode();
2061 if (nstate == Pre_Visit) {
2062 if (address_visited.test(n->_idx)) { // Visited in address already?
2063 // Flag as visited and shared now.
2064 set_visited(n);
2065 }
2066 if (is_visited(n)) { // Visited already?
2067 // Node is shared and has no reason to clone. Flag it as shared.
2188 mstack.push(m, Visit);
2189 continue; // for(int i = ...)
2190 }
2191
2192 if( mop == Op_AddP && m->in(AddPNode::Base)->is_DecodeNarrowPtr()) {
2193 // Bases used in addresses must be shared but since
2194 // they are shared through a DecodeN they may appear
2195 // to have a single use so force sharing here.
2196 set_shared(m->in(AddPNode::Base)->in(1));
2197 }
2198
2199 // if 'n' and 'm' are part of a graph for BMI instruction, clone this node.
2200 #ifdef X86
2201 if (UseBMI1Instructions && is_bmi_pattern(n, m)) {
2202 mstack.push(m, Visit);
2203 continue;
2204 }
2205 #endif
2206
2207 // Clone addressing expressions as they are "free" in memory access instructions
2208 if( mem_op && i == MemNode::Address && mop == Op_AddP ) {
2209 // Some inputs for address expression are not put on stack
2210 // to avoid marking them as shared and forcing them into register
2211 // if they are used only in address expressions.
2212 // But they should be marked as shared if there are other uses
2213 // besides address expressions.
2214
2215 Node *off = m->in(AddPNode::Offset);
2216 if( off->is_Con() &&
2217 // When there are other uses besides address expressions
2218 // put it on stack and mark as shared.
2219 !is_visited(m) ) {
2220 address_visited.test_set(m->_idx); // Flag as address_visited
2221 Node *adr = m->in(AddPNode::Address);
2222
2223 // Intel, ARM and friends can handle 2 adds in addressing mode
2224 if( clone_shift_expressions && adr->is_AddP() &&
2225 // AtomicAdd is not an addressing expression.
2226 // Cheap to find it by looking for screwy base.
2227 !adr->in(AddPNode::Base)->is_top() &&
2228 // Are there other uses besides address expressions?
2229 !is_visited(adr) ) {
2230 address_visited.set(adr->_idx); // Flag as address_visited
2231 Node *shift = adr->in(AddPNode::Offset);
2232 // Check for shift by small constant as well
2233 if( shift->Opcode() == Op_LShiftX && shift->in(2)->is_Con() &&
2234 shift->in(2)->get_int() <= 3 &&
2235 // Are there other uses besides address expressions?
2236 !is_visited(shift) ) {
2237 address_visited.set(shift->_idx); // Flag as address_visited
2238 mstack.push(shift->in(2), Visit);
2239 Node *conv = shift->in(1);
2240 #ifdef _LP64
2241 // Allow Matcher to match the rule which bypass
2242 // ConvI2L operation for an array index on LP64
2243 // if the index value is positive.
2244 if( conv->Opcode() == Op_ConvI2L &&
2245 conv->as_Type()->type()->is_long()->_lo >= 0 &&
2246 // Are there other uses besides address expressions?
2247 !is_visited(conv) ) {
2248 address_visited.set(conv->_idx); // Flag as address_visited
2249 mstack.push(conv->in(1), Pre_Visit);
2250 } else
2251 #endif
2252 mstack.push(conv, Pre_Visit);
2253 } else {
2254 mstack.push(shift, Pre_Visit);
2255 }
2256 mstack.push(adr->in(AddPNode::Address), Pre_Visit);
2257 mstack.push(adr->in(AddPNode::Base), Pre_Visit);
2258 } else { // Sparc, Alpha, PPC and friends
2259 mstack.push(adr, Pre_Visit);
2260 }
2261
2262 // Clone X+offset as it also folds into most addressing expressions
2263 mstack.push(off, Visit);
2264 mstack.push(m->in(AddPNode::Base), Pre_Visit);
2265 continue; // for(int i = ...)
2266 } // if( off->is_Con() )
2267 } // if( mem_op &&
2268 mstack.push(m, Pre_Visit);
2269 } // for(int i = ...)
2270 }
2271 else if (nstate == Alt_Post_Visit) {
2272 mstack.pop(); // Remove node from stack
2273 // We cannot remove the Cmp input from the Bool here, as the Bool may be
2274 // shared and all users of the Bool need to move the Cmp in parallel.
2275 // This leaves both the Bool and the If pointing at the Cmp. To
2276 // prevent the Matcher from trying to Match the Cmp along both paths
2277 // BoolNode::match_edge always returns a zero.
2278
2279 // We reorder the Op_If in a pre-order manner, so we can visit without
2280 // accidentally sharing the Cmp (the Bool and the If make 2 users).
2281 n->add_req( n->in(1)->in(1) ); // Add the Cmp next to the Bool
2282 }
2283 else if (nstate == Post_Visit) {
2284 mstack.pop(); // Remove node from stack
2285
|
2028 if (m->Opcode() == Op_LoadI) {
2029 FusedPatternMatcher<TypeInt> bmii(n, m, Op_ConI);
2030 return bmii.match(Op_AndI, -1, Op_SubI, 1, 0) ||
2031 bmii.match(Op_AndI, -1, Op_AddI, -1, -1) ||
2032 bmii.match(Op_XorI, -1, Op_AddI, -1, -1);
2033 } else if (m->Opcode() == Op_LoadL) {
2034 FusedPatternMatcher<TypeLong> bmil(n, m, Op_ConL);
2035 return bmil.match(Op_AndL, -1, Op_SubL, 1, 0) ||
2036 bmil.match(Op_AndL, -1, Op_AddL, -1, -1) ||
2037 bmil.match(Op_XorL, -1, Op_AddL, -1, -1);
2038 }
2039 }
2040 return false;
2041 }
2042 #endif // X86
2043
2044 // A method-klass-holder may be passed in the inline_cache_reg
2045 // and then expanded into the inline_cache_reg and a method_oop register
2046 // defined in ad_<arch>.cpp
2047
2048 // Check for shift by small constant as well
2049 static bool clone_shift(Node* shift, Matcher* matcher, MStack& mstack, VectorSet& address_visited) {
2050 if (shift->Opcode() == Op_LShiftX && shift->in(2)->is_Con() &&
2051 shift->in(2)->get_int() <= 3 &&
2052 // Are there other uses besides address expressions?
2053 !matcher->is_visited(shift)) {
2054 address_visited.set(shift->_idx); // Flag as address_visited
2055 mstack.push(shift->in(2), Visit);
2056 Node *conv = shift->in(1);
2057 #ifdef _LP64
2058 // Allow Matcher to match the rule which bypass
2059 // ConvI2L operation for an array index on LP64
2060 // if the index value is positive.
2061 if (conv->Opcode() == Op_ConvI2L &&
2062 conv->as_Type()->type()->is_long()->_lo >= 0 &&
2063 // Are there other uses besides address expressions?
2064 !matcher->is_visited(conv)) {
2065 address_visited.set(conv->_idx); // Flag as address_visited
2066 mstack.push(conv->in(1), Pre_Visit);
2067 } else
2068 #endif
2069 mstack.push(conv, Pre_Visit);
2070 return true;
2071 }
2072 return false;
2073 }
2074
2075
2076 //------------------------------find_shared------------------------------------
2077 // Set bits if Node is shared or otherwise a root
2078 void Matcher::find_shared( Node *n ) {
2079 // Allocate stack of size C->unique() * 2 to avoid frequent realloc
2080 MStack mstack(C->live_nodes() * 2);
2081 // Mark nodes as address_visited if they are inputs to an address expression
2082 VectorSet address_visited(Thread::current()->resource_area());
2083 mstack.push(n, Visit); // Don't need to pre-visit root node
2084 while (mstack.is_nonempty()) {
2085 n = mstack.node(); // Leave node on stack
2086 Node_State nstate = mstack.state();
2087 uint nop = n->Opcode();
2088 if (nstate == Pre_Visit) {
2089 if (address_visited.test(n->_idx)) { // Visited in address already?
2090 // Flag as visited and shared now.
2091 set_visited(n);
2092 }
2093 if (is_visited(n)) { // Visited already?
2094 // Node is shared and has no reason to clone. Flag it as shared.
2215 mstack.push(m, Visit);
2216 continue; // for(int i = ...)
2217 }
2218
2219 if( mop == Op_AddP && m->in(AddPNode::Base)->is_DecodeNarrowPtr()) {
2220 // Bases used in addresses must be shared but since
2221 // they are shared through a DecodeN they may appear
2222 // to have a single use so force sharing here.
2223 set_shared(m->in(AddPNode::Base)->in(1));
2224 }
2225
2226 // if 'n' and 'm' are part of a graph for BMI instruction, clone this node.
2227 #ifdef X86
2228 if (UseBMI1Instructions && is_bmi_pattern(n, m)) {
2229 mstack.push(m, Visit);
2230 continue;
2231 }
2232 #endif
2233
2234 // Clone addressing expressions as they are "free" in memory access instructions
2235 if (mem_op && i == MemNode::Address && mop == Op_AddP &&
2236 // When there are other uses besides address expressions
2237 // put it on stack and mark as shared.
2238 !is_visited(m)) {
2239 // Some inputs for address expression are not put on stack
2240 // to avoid marking them as shared and forcing them into register
2241 // if they are used only in address expressions.
2242 // But they should be marked as shared if there are other uses
2243 // besides address expressions.
2244
2245 Node *off = m->in(AddPNode::Offset);
2246 if (off->is_Con()) {
2247 address_visited.test_set(m->_idx); // Flag as address_visited
2248 Node *adr = m->in(AddPNode::Address);
2249
2250 // Intel, ARM and friends can handle 2 adds in addressing mode
2251 if( clone_shift_expressions && adr->is_AddP() &&
2252 // AtomicAdd is not an addressing expression.
2253 // Cheap to find it by looking for screwy base.
2254 !adr->in(AddPNode::Base)->is_top() &&
2255 // Are there other uses besides address expressions?
2256 !is_visited(adr) ) {
2257 address_visited.set(adr->_idx); // Flag as address_visited
2258 Node *shift = adr->in(AddPNode::Offset);
2259 if (!clone_shift(shift, this, mstack, address_visited)) {
2260 mstack.push(shift, Pre_Visit);
2261 }
2262 mstack.push(adr->in(AddPNode::Address), Pre_Visit);
2263 mstack.push(adr->in(AddPNode::Base), Pre_Visit);
2264 } else { // Sparc, Alpha, PPC and friends
2265 mstack.push(adr, Pre_Visit);
2266 }
2267
2268 // Clone X+offset as it also folds into most addressing expressions
2269 mstack.push(off, Visit);
2270 mstack.push(m->in(AddPNode::Base), Pre_Visit);
2271 continue; // for(int i = ...)
2272 } else if (clone_shift_expressions &&
2273 clone_shift(off, this, mstack, address_visited)) {
2274 address_visited.test_set(m->_idx); // Flag as address_visited
2275 mstack.push(m->in(AddPNode::Address), Pre_Visit);
2276 mstack.push(m->in(AddPNode::Base), Pre_Visit);
2277 continue;
2278 } // if( off->is_Con() )
2279 } // if( mem_op &&
2280 mstack.push(m, Pre_Visit);
2281 } // for(int i = ...)
2282 }
2283 else if (nstate == Alt_Post_Visit) {
2284 mstack.pop(); // Remove node from stack
2285 // We cannot remove the Cmp input from the Bool here, as the Bool may be
2286 // shared and all users of the Bool need to move the Cmp in parallel.
2287 // This leaves both the Bool and the If pointing at the Cmp. To
2288 // prevent the Matcher from trying to Match the Cmp along both paths
2289 // BoolNode::match_edge always returns a zero.
2290
2291 // We reorder the Op_If in a pre-order manner, so we can visit without
2292 // accidentally sharing the Cmp (the Bool and the If make 2 users).
2293 n->add_req( n->in(1)->in(1) ); // Add the Cmp next to the Bool
2294 }
2295 else if (nstate == Post_Visit) {
2296 mstack.pop(); // Remove node from stack
2297
|