src/share/vm/opto/compile.cpp
Index Unified diffs Context diffs Sdiffs Wdiffs Patch New Old Previous File Next File 6747051 Sdiff src/share/vm/opto

src/share/vm/opto/compile.cpp

Print this page




2058             break;
2059           }
2060         }
2061         if (nn != NULL) {
2062           // Decode a narrow oop to match address
2063           // [R12 + narrow_oop_reg<<3 + offset]
2064           nn = new (C,  2) DecodeNNode(nn, t);
2065           n->set_req(AddPNode::Base, nn);
2066           n->set_req(AddPNode::Address, nn);
2067           if (addp->outcnt() == 0) {
2068             addp->disconnect_inputs(NULL);
2069           }
2070         }
2071       }
2072     }
2073 #endif
2074     break;
2075   }
2076 
2077 #ifdef _LP64






































2078   case Op_CmpP:
2079     // Do this transformation here to preserve CmpPNode::sub() and
2080     // other TypePtr related Ideal optimizations (for example, ptr nullness).
2081     if (n->in(1)->is_DecodeN() || n->in(2)->is_DecodeN()) {
2082       Node* in1 = n->in(1);
2083       Node* in2 = n->in(2);
2084       if (!in1->is_DecodeN()) {
2085         in2 = in1;
2086         in1 = n->in(2);
2087       }
2088       assert(in1->is_DecodeN(), "sanity");
2089 
2090       Compile* C = Compile::current();
2091       Node* new_in2 = NULL;
2092       if (in2->is_DecodeN()) {
2093         new_in2 = in2->in(1);
2094       } else if (in2->Opcode() == Op_ConP) {
2095         const Type* t = in2->bottom_type();
2096         if (t == TypePtr::NULL_PTR && UseImplicitNullCheckForNarrowOop) {
2097           if (Matcher::clone_shift_expressions) {
2098             // x86, ARM and friends can handle 2 adds in addressing mode.
2099             // Decode a narrow oop and do implicit NULL check in address
2100             // [R12 + narrow_oop_reg<<3 + offset]
2101             new_in2 = ConNode::make(C, TypeNarrowOop::NULL_PTR);
2102           } else {
2103             // Don't replace CmpP(o ,null) if 'o' is used in AddP
2104             // to generate implicit NULL check on Sparc where
2105             // narrow oops can't be used in address.
2106             uint i = 0;
2107             for (; i < in1->outcnt(); i++) {
2108               if (in1->raw_out(i)->is_AddP())
2109                 break;
2110             }
2111             if (i >= in1->outcnt()) {
2112               new_in2 = ConNode::make(C, TypeNarrowOop::NULL_PTR);
2113             }
2114           }
























2115         } else if (t->isa_oopptr()) {
2116           new_in2 = ConNode::make(C, t->make_narrowoop());
2117         }
2118       }
2119       if (new_in2 != NULL) {
2120         Node* cmpN = new (C, 3) CmpNNode(in1->in(1), new_in2);
2121         n->subsume_by( cmpN );
2122         if (in1->outcnt() == 0) {
2123           in1->disconnect_inputs(NULL);
2124         }
2125         if (in2->outcnt() == 0) {
2126           in2->disconnect_inputs(NULL);
2127         }
2128       }
2129     }
2130     break;











































2131 #endif
2132 
2133   case Op_ModI:
2134     if (UseDivMod) {
2135       // Check if a%b and a/b both exist
2136       Node* d = n->find_similar(Op_DivI);
2137       if (d) {
2138         // Replace them with a fused divmod if supported
2139         Compile* C = Compile::current();
2140         if (Matcher::has_match_rule(Op_DivModI)) {
2141           DivModINode* divmod = DivModINode::make(C, n);
2142           d->subsume_by(divmod->div_proj());
2143           n->subsume_by(divmod->mod_proj());
2144         } else {
2145           // replace a%b with a-((a/b)*b)
2146           Node* mult = new (C, 3) MulINode(d, d->in(2));
2147           Node* sub  = new (C, 3) SubINode(d->in(1), mult);
2148           n->subsume_by( sub );
2149         }
2150       }




2058             break;
2059           }
2060         }
2061         if (nn != NULL) {
2062           // Decode a narrow oop to match address
2063           // [R12 + narrow_oop_reg<<3 + offset]
2064           nn = new (C,  2) DecodeNNode(nn, t);
2065           n->set_req(AddPNode::Base, nn);
2066           n->set_req(AddPNode::Address, nn);
2067           if (addp->outcnt() == 0) {
2068             addp->disconnect_inputs(NULL);
2069           }
2070         }
2071       }
2072     }
2073 #endif
2074     break;
2075   }
2076 
2077 #ifdef _LP64
2078   case Op_CastPP:
2079     if (n->in(1)->is_DecodeN() && UseImplicitNullCheckForNarrowOop) {
2080       Compile* C = Compile::current();
2081       Node* in1 = n->in(1);
2082       const Type* t = n->bottom_type();
2083       Node* new_in1 = in1->clone();
2084       new_in1->as_DecodeN()->set_type(t);
2085 
2086       if (!Matcher::clone_shift_expressions) {
2087         //
2088         // x86, ARM and friends can handle 2 adds in addressing mode
2089         // and Matcher can fold a DecodeN node into address by using
2090         // a narrow oop directly and do implicit NULL check in address:
2091         //
2092         // [R12 + narrow_oop_reg<<3 + offset]
2093         // NullCheck narrow_oop_reg
2094         //
2095         // On other platforms (Sparc) we have to keep new DecodeN node and
2096         // use it to do implicit NULL check in address:
2097         //
2098         // decode_not_null narrow_oop_reg, base_reg
2099         // [base_reg + offset]
2100         // NullCheck base_reg
2101         //
2102         // Pin the new DecodeN node to non-null path on these patforms (Sparc)
2103         // to keep the information to which NULL check the new DecodeN node
2104         // corresponds to use it as value in implicit_null_check().
2105         //
2106         new_in1->set_req(0, n->in(0));
2107       }
2108 
2109       n->subsume_by(new_in1);
2110       if (in1->outcnt() == 0) {
2111         in1->disconnect_inputs(NULL);
2112       }
2113     }
2114     break;
2115 
2116   case Op_CmpP:
2117     // Do this transformation here to preserve CmpPNode::sub() and
2118     // other TypePtr related Ideal optimizations (for example, ptr nullness).
2119     if (n->in(1)->is_DecodeN() || n->in(2)->is_DecodeN()) {
2120       Node* in1 = n->in(1);
2121       Node* in2 = n->in(2);
2122       if (!in1->is_DecodeN()) {
2123         in2 = in1;
2124         in1 = n->in(2);
2125       }
2126       assert(in1->is_DecodeN(), "sanity");
2127 
2128       Compile* C = Compile::current();
2129       Node* new_in2 = NULL;
2130       if (in2->is_DecodeN()) {
2131         new_in2 = in2->in(1);
2132       } else if (in2->Opcode() == Op_ConP) {
2133         const Type* t = in2->bottom_type();
2134         if (t == TypePtr::NULL_PTR && UseImplicitNullCheckForNarrowOop) {




2135           new_in2 = ConNode::make(C, TypeNarrowOop::NULL_PTR);
2136           //
2137           // This transformation together with CastPP transformation above
2138           // will generated code for implicit NULL checks for compressed oops.
2139           //
2140           // The original code after Optimize()
2141           //
2142           //    LoadN memory, narrow_oop_reg
2143           //    decode narrow_oop_reg, base_reg
2144           //    CmpP base_reg, NULL
2145           //    CastPP base_reg // NotNull
2146           //    Load [base_reg + offset], val_reg
2147           //
2148           // after these transformations will be 
2149           //
2150           //    LoadN memory, narrow_oop_reg
2151           //    CmpN narrow_oop_reg, NULL
2152           //    decode_not_null narrow_oop_reg, base_reg
2153           //    Load [base_reg + offset], val_reg
2154           //
2155           // and the uncommon path (== NULL) will use narrow_oop_reg directly
2156           // since narrow oops can be used in debug info now (see the code in
2157           // final_graph_reshaping_walk()).
2158           //
2159           // At the end the code will be matched to 
2160           // on x86:
2161           //
2162           //    Load_narrow_oop memory, narrow_oop_reg
2163           //    Load [R12 + narrow_oop_reg<<3 + offset], val_reg
2164           //    NullCheck narrow_oop_reg
2165           //
2166           // and on sparc:
2167           //
2168           //    Load_narrow_oop memory, narrow_oop_reg
2169           //    decode_not_null narrow_oop_reg, base_reg
2170           //    Load [base_reg + offset], val_reg
2171           //    NullCheck base_reg
2172           //
2173         } else if (t->isa_oopptr()) {
2174           new_in2 = ConNode::make(C, t->make_narrowoop());
2175         }
2176       }
2177       if (new_in2 != NULL) {
2178         Node* cmpN = new (C, 3) CmpNNode(in1->in(1), new_in2);
2179         n->subsume_by( cmpN );
2180         if (in1->outcnt() == 0) {
2181           in1->disconnect_inputs(NULL);
2182         }
2183         if (in2->outcnt() == 0) {
2184           in2->disconnect_inputs(NULL);
2185         }
2186       }
2187     }
2188     break;
2189 
2190   case Op_DecodeN:
2191     assert(!n->in(1)->is_EncodeP(), "should be optimized out");
2192     break;
2193 
2194   case Op_EncodeP: {
2195     Node* in1 = n->in(1);
2196     if (in1->is_DecodeN()) {
2197       n->subsume_by(in1->in(1));
2198     } else if (in1->Opcode() == Op_ConP) {
2199       Compile* C = Compile::current();
2200       const Type* t = in1->bottom_type();
2201       if (t == TypePtr::NULL_PTR) {
2202         n->subsume_by(ConNode::make(C, TypeNarrowOop::NULL_PTR));
2203       } else if (t->isa_oopptr()) {
2204         n->subsume_by(ConNode::make(C, t->make_narrowoop()));
2205       }
2206     }
2207     if (in1->outcnt() == 0) {
2208       in1->disconnect_inputs(NULL);
2209     }
2210     break;
2211   }
2212 
2213   case Op_Phi:
2214     if (n->as_Phi()->bottom_type()->isa_narrowoop()) {
2215       // The EncodeP optimization may create Phi with the same edges
2216       // for all paths. It is not handled well by Register Allocator.
2217       Node* unique_in = n->in(1);
2218       assert(unique_in != NULL, "");
2219       uint cnt = n->req();
2220       for (uint i = 2; i < cnt; i++) {
2221         Node* m = n->in(i);
2222         assert(m != NULL, "");
2223         if (unique_in != m)
2224           unique_in = NULL;
2225       }
2226       if (unique_in != NULL) {
2227         n->subsume_by(unique_in);
2228       }
2229     }
2230     break;
2231 
2232 #endif
2233 
2234   case Op_ModI:
2235     if (UseDivMod) {
2236       // Check if a%b and a/b both exist
2237       Node* d = n->find_similar(Op_DivI);
2238       if (d) {
2239         // Replace them with a fused divmod if supported
2240         Compile* C = Compile::current();
2241         if (Matcher::has_match_rule(Op_DivModI)) {
2242           DivModINode* divmod = DivModINode::make(C, n);
2243           d->subsume_by(divmod->div_proj());
2244           n->subsume_by(divmod->mod_proj());
2245         } else {
2246           // replace a%b with a-((a/b)*b)
2247           Node* mult = new (C, 3) MulINode(d, d->in(2));
2248           Node* sub  = new (C, 3) SubINode(d->in(1), mult);
2249           n->subsume_by( sub );
2250         }
2251       }


src/share/vm/opto/compile.cpp
Index Unified diffs Context diffs Sdiffs Wdiffs Patch New Old Previous File Next File