2069 if (nstate == Visit) { |
2068 if (nstate == Visit) { |
2070 mstack.set_state(Post_Visit); |
2069 mstack.set_state(Post_Visit); |
2071 set_visited(n); // Flag as visited now |
2070 set_visited(n); // Flag as visited now |
2072 bool mem_op = false; |
2071 bool mem_op = false; |
2073 int mem_addr_idx = MemNode::Address; |
2072 int mem_addr_idx = MemNode::Address; |
2074 |
2073 bool gc_handled = BarrierSet::barrier_set()->barrier_set_c2()->matcher_find_shared_visit(this, mstack, n, nop, mem_op, mem_addr_idx); |
2075 switch( nop ) { // Handle some opcodes special |
2074 if (!gc_handled) { |
2076 case Op_Phi: // Treat Phis as shared roots |
2075 if (find_shared_visit(mstack, n, nop, mem_op, mem_addr_idx)) { |
2077 case Op_Parm: |
2076 continue; |
2078 case Op_Proj: // All handled specially during matching |
|
2079 case Op_SafePointScalarObject: |
|
2080 set_shared(n); |
|
2081 set_dontcare(n); |
|
2082 break; |
|
2083 case Op_If: |
|
2084 case Op_CountedLoopEnd: |
|
2085 mstack.set_state(Alt_Post_Visit); // Alternative way |
|
2086 // Convert (If (Bool (CmpX A B))) into (If (Bool) (CmpX A B)). Helps |
|
2087 // with matching cmp/branch in 1 instruction. The Matcher needs the |
|
2088 // Bool and CmpX side-by-side, because it can only get at constants |
|
2089 // that are at the leaves of Match trees, and the Bool's condition acts |
|
2090 // as a constant here. |
|
2091 mstack.push(n->in(1), Visit); // Clone the Bool |
|
2092 mstack.push(n->in(0), Pre_Visit); // Visit control input |
|
2093 continue; // while (mstack.is_nonempty()) |
|
2094 case Op_ConvI2D: // These forms efficiently match with a prior |
|
2095 case Op_ConvI2F: // Load but not a following Store |
|
2096 if( n->in(1)->is_Load() && // Prior load |
|
2097 n->outcnt() == 1 && // Not already shared |
|
2098 n->unique_out()->is_Store() ) // Following store |
|
2099 set_shared(n); // Force it to be a root |
|
2100 break; |
|
2101 case Op_ReverseBytesI: |
|
2102 case Op_ReverseBytesL: |
|
2103 if( n->in(1)->is_Load() && // Prior load |
|
2104 n->outcnt() == 1 ) // Not already shared |
|
2105 set_shared(n); // Force it to be a root |
|
2106 break; |
|
2107 case Op_BoxLock: // Cant match until we get stack-regs in ADLC |
|
2108 case Op_IfFalse: |
|
2109 case Op_IfTrue: |
|
2110 case Op_MachProj: |
|
2111 case Op_MergeMem: |
|
2112 case Op_Catch: |
|
2113 case Op_CatchProj: |
|
2114 case Op_CProj: |
|
2115 case Op_JumpProj: |
|
2116 case Op_JProj: |
|
2117 case Op_NeverBranch: |
|
2118 set_dontcare(n); |
|
2119 break; |
|
2120 case Op_Jump: |
|
2121 mstack.push(n->in(1), Pre_Visit); // Switch Value (could be shared) |
|
2122 mstack.push(n->in(0), Pre_Visit); // Visit Control input |
|
2123 continue; // while (mstack.is_nonempty()) |
|
2124 case Op_StrComp: |
|
2125 case Op_StrEquals: |
|
2126 case Op_StrIndexOf: |
|
2127 case Op_StrIndexOfChar: |
|
2128 case Op_AryEq: |
|
2129 case Op_HasNegatives: |
|
2130 case Op_StrInflatedCopy: |
|
2131 case Op_StrCompressedCopy: |
|
2132 case Op_EncodeISOArray: |
|
2133 case Op_FmaD: |
|
2134 case Op_FmaF: |
|
2135 case Op_FmaVD: |
|
2136 case Op_FmaVF: |
|
2137 set_shared(n); // Force result into register (it will be anyways) |
|
2138 break; |
|
2139 case Op_ConP: { // Convert pointers above the centerline to NUL |
|
2140 TypeNode *tn = n->as_Type(); // Constants derive from type nodes |
|
2141 const TypePtr* tp = tn->type()->is_ptr(); |
|
2142 if (tp->_ptr == TypePtr::AnyNull) { |
|
2143 tn->set_type(TypePtr::NULL_PTR); |
|
2144 } |
2077 } |
2145 break; |
2078 } |
2146 } |
|
2147 case Op_ConN: { // Convert narrow pointers above the centerline to NUL |
|
2148 TypeNode *tn = n->as_Type(); // Constants derive from type nodes |
|
2149 const TypePtr* tp = tn->type()->make_ptr(); |
|
2150 if (tp && tp->_ptr == TypePtr::AnyNull) { |
|
2151 tn->set_type(TypeNarrowOop::NULL_PTR); |
|
2152 } |
|
2153 break; |
|
2154 } |
|
2155 case Op_Binary: // These are introduced in the Post_Visit state. |
|
2156 ShouldNotReachHere(); |
|
2157 break; |
|
2158 case Op_ClearArray: |
|
2159 case Op_SafePoint: |
|
2160 mem_op = true; |
|
2161 break; |
|
2162 #if INCLUDE_ZGC |
|
2163 case Op_CallLeaf: |
|
2164 if (UseZGC) { |
|
2165 if (n->as_Call()->entry_point() == ZBarrierSetRuntime::load_barrier_on_oop_field_preloaded_addr() || |
|
2166 n->as_Call()->entry_point() == ZBarrierSetRuntime::load_barrier_on_weak_oop_field_preloaded_addr()) { |
|
2167 mem_op = true; |
|
2168 mem_addr_idx = TypeFunc::Parms+1; |
|
2169 } |
|
2170 break; |
|
2171 } |
|
2172 #endif |
|
2173 default: |
|
2174 if( n->is_Store() ) { |
|
2175 // Do match stores, despite no ideal reg |
|
2176 mem_op = true; |
|
2177 break; |
|
2178 } |
|
2179 if( n->is_Mem() ) { // Loads and LoadStores |
|
2180 mem_op = true; |
|
2181 // Loads must be root of match tree due to prior load conflict |
|
2182 if( C->subsume_loads() == false ) |
|
2183 set_shared(n); |
|
2184 } |
|
2185 // Fall into default case |
|
2186 if( !n->ideal_reg() ) |
|
2187 set_dontcare(n); // Unmatchable Nodes |
|
2188 } // end_switch |
|
2189 |
|
2190 for(int i = n->req() - 1; i >= 0; --i) { // For my children |
2079 for(int i = n->req() - 1; i >= 0; --i) { // For my children |
2191 Node *m = n->in(i); // Get ith input |
2080 Node *m = n->in(i); // Get ith input |
2192 if (m == NULL) continue; // Ignore NULLs |
2081 if (m == NULL) continue; // Ignore NULLs |
2193 uint mop = m->Opcode(); |
2082 uint mop = m->Opcode(); |
2194 |
2083 |
2250 } |
2139 } |
2251 else if (nstate == Post_Visit) { |
2140 else if (nstate == Post_Visit) { |
2252 mstack.pop(); // Remove node from stack |
2141 mstack.pop(); // Remove node from stack |
2253 |
2142 |
2254 // Now hack a few special opcodes |
2143 // Now hack a few special opcodes |
2255 switch( n->Opcode() ) { // Handle some opcodes special |
2144 uint opcode = n->Opcode(); |
2256 case Op_StorePConditional: |
2145 bool gc_handled = BarrierSet::barrier_set()->barrier_set_c2()->matcher_find_shared_post_visit(this, n, opcode); |
2257 case Op_StoreIConditional: |
2146 if (!gc_handled) { |
2258 case Op_StoreLConditional: |
2147 find_shared_post_visit(n, opcode); |
2259 case Op_CompareAndExchangeB: |
|
2260 case Op_CompareAndExchangeS: |
|
2261 case Op_CompareAndExchangeI: |
|
2262 case Op_CompareAndExchangeL: |
|
2263 case Op_CompareAndExchangeP: |
|
2264 case Op_CompareAndExchangeN: |
|
2265 case Op_WeakCompareAndSwapB: |
|
2266 case Op_WeakCompareAndSwapS: |
|
2267 case Op_WeakCompareAndSwapI: |
|
2268 case Op_WeakCompareAndSwapL: |
|
2269 case Op_WeakCompareAndSwapP: |
|
2270 case Op_WeakCompareAndSwapN: |
|
2271 case Op_CompareAndSwapB: |
|
2272 case Op_CompareAndSwapS: |
|
2273 case Op_CompareAndSwapI: |
|
2274 case Op_CompareAndSwapL: |
|
2275 case Op_CompareAndSwapP: |
|
2276 case Op_CompareAndSwapN: { // Convert trinary to binary-tree |
|
2277 Node *newval = n->in(MemNode::ValueIn ); |
|
2278 Node *oldval = n->in(LoadStoreConditionalNode::ExpectedIn); |
|
2279 Node *pair = new BinaryNode( oldval, newval ); |
|
2280 n->set_req(MemNode::ValueIn,pair); |
|
2281 n->del_req(LoadStoreConditionalNode::ExpectedIn); |
|
2282 break; |
|
2283 } |
|
2284 case Op_CMoveD: // Convert trinary to binary-tree |
|
2285 case Op_CMoveF: |
|
2286 case Op_CMoveI: |
|
2287 case Op_CMoveL: |
|
2288 case Op_CMoveN: |
|
2289 case Op_CMoveP: |
|
2290 case Op_CMoveVF: |
|
2291 case Op_CMoveVD: { |
|
2292 // Restructure into a binary tree for Matching. It's possible that |
|
2293 // we could move this code up next to the graph reshaping for IfNodes |
|
2294 // or vice-versa, but I do not want to debug this for Ladybird. |
|
2295 // 10/2/2000 CNC. |
|
2296 Node *pair1 = new BinaryNode(n->in(1),n->in(1)->in(1)); |
|
2297 n->set_req(1,pair1); |
|
2298 Node *pair2 = new BinaryNode(n->in(2),n->in(3)); |
|
2299 n->set_req(2,pair2); |
|
2300 n->del_req(3); |
|
2301 break; |
|
2302 } |
|
2303 case Op_LoopLimit: { |
|
2304 Node *pair1 = new BinaryNode(n->in(1),n->in(2)); |
|
2305 n->set_req(1,pair1); |
|
2306 n->set_req(2,n->in(3)); |
|
2307 n->del_req(3); |
|
2308 break; |
|
2309 } |
|
2310 case Op_StrEquals: |
|
2311 case Op_StrIndexOfChar: { |
|
2312 Node *pair1 = new BinaryNode(n->in(2),n->in(3)); |
|
2313 n->set_req(2,pair1); |
|
2314 n->set_req(3,n->in(4)); |
|
2315 n->del_req(4); |
|
2316 break; |
|
2317 } |
|
2318 case Op_StrComp: |
|
2319 case Op_StrIndexOf: { |
|
2320 Node *pair1 = new BinaryNode(n->in(2),n->in(3)); |
|
2321 n->set_req(2,pair1); |
|
2322 Node *pair2 = new BinaryNode(n->in(4),n->in(5)); |
|
2323 n->set_req(3,pair2); |
|
2324 n->del_req(5); |
|
2325 n->del_req(4); |
|
2326 break; |
|
2327 } |
|
2328 case Op_StrCompressedCopy: |
|
2329 case Op_StrInflatedCopy: |
|
2330 case Op_EncodeISOArray: { |
|
2331 // Restructure into a binary tree for Matching. |
|
2332 Node* pair = new BinaryNode(n->in(3), n->in(4)); |
|
2333 n->set_req(3, pair); |
|
2334 n->del_req(4); |
|
2335 break; |
|
2336 } |
|
2337 case Op_FmaD: |
|
2338 case Op_FmaF: |
|
2339 case Op_FmaVD: |
|
2340 case Op_FmaVF: { |
|
2341 // Restructure into a binary tree for Matching. |
|
2342 Node* pair = new BinaryNode(n->in(1), n->in(2)); |
|
2343 n->set_req(2, pair); |
|
2344 n->set_req(1, n->in(3)); |
|
2345 n->del_req(3); |
|
2346 break; |
|
2347 } |
|
2348 default: |
|
2349 break; |
|
2350 } |
2148 } |
2351 } |
2149 } |
2352 else { |
2150 else { |
2353 ShouldNotReachHere(); |
2151 ShouldNotReachHere(); |
2354 } |
2152 } |
2355 } // end of while (mstack.is_nonempty()) |
2153 } // end of while (mstack.is_nonempty()) |
|
2154 } |
|
2155 |
|
2156 bool Matcher::find_shared_visit(MStack& mstack, Node* n, uint opcode, bool& mem_op, int& mem_addr_idx) { |
|
2157 switch(opcode) { // Handle some opcodes special |
|
2158 case Op_Phi: // Treat Phis as shared roots |
|
2159 case Op_Parm: |
|
2160 case Op_Proj: // All handled specially during matching |
|
2161 case Op_SafePointScalarObject: |
|
2162 set_shared(n); |
|
2163 set_dontcare(n); |
|
2164 break; |
|
2165 case Op_If: |
|
2166 case Op_CountedLoopEnd: |
|
2167 mstack.set_state(Alt_Post_Visit); // Alternative way |
|
2168 // Convert (If (Bool (CmpX A B))) into (If (Bool) (CmpX A B)). Helps |
|
2169 // with matching cmp/branch in 1 instruction. The Matcher needs the |
|
2170 // Bool and CmpX side-by-side, because it can only get at constants |
|
2171 // that are at the leaves of Match trees, and the Bool's condition acts |
|
2172 // as a constant here. |
|
2173 mstack.push(n->in(1), Visit); // Clone the Bool |
|
2174 mstack.push(n->in(0), Pre_Visit); // Visit control input |
|
2175 return true; // while (mstack.is_nonempty()) |
|
2176 case Op_ConvI2D: // These forms efficiently match with a prior |
|
2177 case Op_ConvI2F: // Load but not a following Store |
|
2178 if( n->in(1)->is_Load() && // Prior load |
|
2179 n->outcnt() == 1 && // Not already shared |
|
2180 n->unique_out()->is_Store() ) // Following store |
|
2181 set_shared(n); // Force it to be a root |
|
2182 break; |
|
2183 case Op_ReverseBytesI: |
|
2184 case Op_ReverseBytesL: |
|
2185 if( n->in(1)->is_Load() && // Prior load |
|
2186 n->outcnt() == 1 ) // Not already shared |
|
2187 set_shared(n); // Force it to be a root |
|
2188 break; |
|
2189 case Op_BoxLock: // Cant match until we get stack-regs in ADLC |
|
2190 case Op_IfFalse: |
|
2191 case Op_IfTrue: |
|
2192 case Op_MachProj: |
|
2193 case Op_MergeMem: |
|
2194 case Op_Catch: |
|
2195 case Op_CatchProj: |
|
2196 case Op_CProj: |
|
2197 case Op_JumpProj: |
|
2198 case Op_JProj: |
|
2199 case Op_NeverBranch: |
|
2200 set_dontcare(n); |
|
2201 break; |
|
2202 case Op_Jump: |
|
2203 mstack.push(n->in(1), Pre_Visit); // Switch Value (could be shared) |
|
2204 mstack.push(n->in(0), Pre_Visit); // Visit Control input |
|
2205 return true; // while (mstack.is_nonempty()) |
|
2206 case Op_StrComp: |
|
2207 case Op_StrEquals: |
|
2208 case Op_StrIndexOf: |
|
2209 case Op_StrIndexOfChar: |
|
2210 case Op_AryEq: |
|
2211 case Op_HasNegatives: |
|
2212 case Op_StrInflatedCopy: |
|
2213 case Op_StrCompressedCopy: |
|
2214 case Op_EncodeISOArray: |
|
2215 case Op_FmaD: |
|
2216 case Op_FmaF: |
|
2217 case Op_FmaVD: |
|
2218 case Op_FmaVF: |
|
2219 set_shared(n); // Force result into register (it will be anyways) |
|
2220 break; |
|
2221 case Op_ConP: { // Convert pointers above the centerline to NUL |
|
2222 TypeNode *tn = n->as_Type(); // Constants derive from type nodes |
|
2223 const TypePtr* tp = tn->type()->is_ptr(); |
|
2224 if (tp->_ptr == TypePtr::AnyNull) { |
|
2225 tn->set_type(TypePtr::NULL_PTR); |
|
2226 } |
|
2227 break; |
|
2228 } |
|
2229 case Op_ConN: { // Convert narrow pointers above the centerline to NUL |
|
2230 TypeNode *tn = n->as_Type(); // Constants derive from type nodes |
|
2231 const TypePtr* tp = tn->type()->make_ptr(); |
|
2232 if (tp && tp->_ptr == TypePtr::AnyNull) { |
|
2233 tn->set_type(TypeNarrowOop::NULL_PTR); |
|
2234 } |
|
2235 break; |
|
2236 } |
|
2237 case Op_Binary: // These are introduced in the Post_Visit state. |
|
2238 ShouldNotReachHere(); |
|
2239 break; |
|
2240 case Op_ClearArray: |
|
2241 case Op_SafePoint: |
|
2242 mem_op = true; |
|
2243 break; |
|
2244 default: |
|
2245 if( n->is_Store() ) { |
|
2246 // Do match stores, despite no ideal reg |
|
2247 mem_op = true; |
|
2248 break; |
|
2249 } |
|
2250 if( n->is_Mem() ) { // Loads and LoadStores |
|
2251 mem_op = true; |
|
2252 // Loads must be root of match tree due to prior load conflict |
|
2253 if( C->subsume_loads() == false ) |
|
2254 set_shared(n); |
|
2255 } |
|
2256 // Fall into default case |
|
2257 if( !n->ideal_reg() ) |
|
2258 set_dontcare(n); // Unmatchable Nodes |
|
2259 } // end_switch |
|
2260 return false; |
|
2261 } |
|
2262 |
|
2263 void Matcher::find_shared_post_visit(Node* n, uint opcode) { |
|
2264 switch(opcode) { // Handle some opcodes special |
|
2265 case Op_StorePConditional: |
|
2266 case Op_StoreIConditional: |
|
2267 case Op_StoreLConditional: |
|
2268 case Op_CompareAndExchangeB: |
|
2269 case Op_CompareAndExchangeS: |
|
2270 case Op_CompareAndExchangeI: |
|
2271 case Op_CompareAndExchangeL: |
|
2272 case Op_CompareAndExchangeP: |
|
2273 case Op_CompareAndExchangeN: |
|
2274 case Op_WeakCompareAndSwapB: |
|
2275 case Op_WeakCompareAndSwapS: |
|
2276 case Op_WeakCompareAndSwapI: |
|
2277 case Op_WeakCompareAndSwapL: |
|
2278 case Op_WeakCompareAndSwapP: |
|
2279 case Op_WeakCompareAndSwapN: |
|
2280 case Op_CompareAndSwapB: |
|
2281 case Op_CompareAndSwapS: |
|
2282 case Op_CompareAndSwapI: |
|
2283 case Op_CompareAndSwapL: |
|
2284 case Op_CompareAndSwapP: |
|
2285 case Op_CompareAndSwapN: { // Convert trinary to binary-tree |
|
2286 Node* newval = n->in(MemNode::ValueIn); |
|
2287 Node* oldval = n->in(LoadStoreConditionalNode::ExpectedIn); |
|
2288 Node* pair = new BinaryNode(oldval, newval); |
|
2289 n->set_req(MemNode::ValueIn, pair); |
|
2290 n->del_req(LoadStoreConditionalNode::ExpectedIn); |
|
2291 break; |
|
2292 } |
|
2293 case Op_CMoveD: // Convert trinary to binary-tree |
|
2294 case Op_CMoveF: |
|
2295 case Op_CMoveI: |
|
2296 case Op_CMoveL: |
|
2297 case Op_CMoveN: |
|
2298 case Op_CMoveP: |
|
2299 case Op_CMoveVF: |
|
2300 case Op_CMoveVD: { |
|
2301 // Restructure into a binary tree for Matching. It's possible that |
|
2302 // we could move this code up next to the graph reshaping for IfNodes |
|
2303 // or vice-versa, but I do not want to debug this for Ladybird. |
|
2304 // 10/2/2000 CNC. |
|
2305 Node* pair1 = new BinaryNode(n->in(1), n->in(1)->in(1)); |
|
2306 n->set_req(1, pair1); |
|
2307 Node* pair2 = new BinaryNode(n->in(2), n->in(3)); |
|
2308 n->set_req(2, pair2); |
|
2309 n->del_req(3); |
|
2310 break; |
|
2311 } |
|
2312 case Op_LoopLimit: { |
|
2313 Node* pair1 = new BinaryNode(n->in(1), n->in(2)); |
|
2314 n->set_req(1, pair1); |
|
2315 n->set_req(2, n->in(3)); |
|
2316 n->del_req(3); |
|
2317 break; |
|
2318 } |
|
2319 case Op_StrEquals: |
|
2320 case Op_StrIndexOfChar: { |
|
2321 Node* pair1 = new BinaryNode(n->in(2), n->in(3)); |
|
2322 n->set_req(2, pair1); |
|
2323 n->set_req(3, n->in(4)); |
|
2324 n->del_req(4); |
|
2325 break; |
|
2326 } |
|
2327 case Op_StrComp: |
|
2328 case Op_StrIndexOf: { |
|
2329 Node* pair1 = new BinaryNode(n->in(2), n->in(3)); |
|
2330 n->set_req(2, pair1); |
|
2331 Node* pair2 = new BinaryNode(n->in(4),n->in(5)); |
|
2332 n->set_req(3, pair2); |
|
2333 n->del_req(5); |
|
2334 n->del_req(4); |
|
2335 break; |
|
2336 } |
|
2337 case Op_StrCompressedCopy: |
|
2338 case Op_StrInflatedCopy: |
|
2339 case Op_EncodeISOArray: { |
|
2340 // Restructure into a binary tree for Matching. |
|
2341 Node* pair = new BinaryNode(n->in(3), n->in(4)); |
|
2342 n->set_req(3, pair); |
|
2343 n->del_req(4); |
|
2344 break; |
|
2345 } |
|
2346 case Op_FmaD: |
|
2347 case Op_FmaF: |
|
2348 case Op_FmaVD: |
|
2349 case Op_FmaVF: { |
|
2350 // Restructure into a binary tree for Matching. |
|
2351 Node* pair = new BinaryNode(n->in(1), n->in(2)); |
|
2352 n->set_req(2, pair); |
|
2353 n->set_req(1, n->in(3)); |
|
2354 n->del_req(3); |
|
2355 break; |
|
2356 } |
|
2357 default: |
|
2358 break; |
|
2359 } |
2356 } |
2360 } |
2357 |
2361 |
2358 #ifdef ASSERT |
2362 #ifdef ASSERT |
2359 // machine-independent root to machine-dependent root |
2363 // machine-independent root to machine-dependent root |
2360 void Matcher::dump_old2new_map() { |
2364 void Matcher::dump_old2new_map() { |