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 }
|