147 if( t2 == Type::TOP ) return NULL; |
147 if( t2 == Type::TOP ) return NULL; |
148 // Convert "x-c0" into "x+ -c0". |
148 // Convert "x-c0" into "x+ -c0". |
149 if( t2->base() == Type::Int ){ // Might be bottom or top... |
149 if( t2->base() == Type::Int ){ // Might be bottom or top... |
150 const TypeInt *i = t2->is_int(); |
150 const TypeInt *i = t2->is_int(); |
151 if( i->is_con() ) |
151 if( i->is_con() ) |
152 return new (phase->C, 3) AddINode(in1, phase->intcon(-i->get_con())); |
152 return new (phase->C) AddINode(in1, phase->intcon(-i->get_con())); |
153 } |
153 } |
154 |
154 |
155 // Convert "(x+c0) - y" into (x-y) + c0" |
155 // Convert "(x+c0) - y" into (x-y) + c0" |
156 // Do not collapse (x+c0)-y if "+" is a loop increment or |
156 // Do not collapse (x+c0)-y if "+" is a loop increment or |
157 // if "y" is a loop induction variable. |
157 // if "y" is a loop induction variable. |
158 if( op1 == Op_AddI && ok_to_convert(in1, in2) ) { |
158 if( op1 == Op_AddI && ok_to_convert(in1, in2) ) { |
159 const Type *tadd = phase->type( in1->in(2) ); |
159 const Type *tadd = phase->type( in1->in(2) ); |
160 if( tadd->singleton() && tadd != Type::TOP ) { |
160 if( tadd->singleton() && tadd != Type::TOP ) { |
161 Node *sub2 = phase->transform( new (phase->C, 3) SubINode( in1->in(1), in2 )); |
161 Node *sub2 = phase->transform( new (phase->C) SubINode( in1->in(1), in2 )); |
162 return new (phase->C, 3) AddINode( sub2, in1->in(2) ); |
162 return new (phase->C) AddINode( sub2, in1->in(2) ); |
163 } |
163 } |
164 } |
164 } |
165 |
165 |
166 |
166 |
167 // Convert "x - (y+c0)" into "(x-y) - c0" |
167 // Convert "x - (y+c0)" into "(x-y) - c0" |
169 if (op2 == Op_AddI && ok_to_convert(in2, in1)) { |
169 if (op2 == Op_AddI && ok_to_convert(in2, in1)) { |
170 Node* in21 = in2->in(1); |
170 Node* in21 = in2->in(1); |
171 Node* in22 = in2->in(2); |
171 Node* in22 = in2->in(2); |
172 const TypeInt* tcon = phase->type(in22)->isa_int(); |
172 const TypeInt* tcon = phase->type(in22)->isa_int(); |
173 if (tcon != NULL && tcon->is_con()) { |
173 if (tcon != NULL && tcon->is_con()) { |
174 Node* sub2 = phase->transform( new (phase->C, 3) SubINode(in1, in21) ); |
174 Node* sub2 = phase->transform( new (phase->C) SubINode(in1, in21) ); |
175 Node* neg_c0 = phase->intcon(- tcon->get_con()); |
175 Node* neg_c0 = phase->intcon(- tcon->get_con()); |
176 return new (phase->C, 3) AddINode(sub2, neg_c0); |
176 return new (phase->C) AddINode(sub2, neg_c0); |
177 } |
177 } |
178 } |
178 } |
179 |
179 |
180 const Type *t1 = phase->type( in1 ); |
180 const Type *t1 = phase->type( in1 ); |
181 if( t1 == Type::TOP ) return NULL; |
181 if( t1 == Type::TOP ) return NULL; |
189 #endif |
189 #endif |
190 |
190 |
191 // Convert "x - (x+y)" into "-y" |
191 // Convert "x - (x+y)" into "-y" |
192 if( op2 == Op_AddI && |
192 if( op2 == Op_AddI && |
193 phase->eqv( in1, in2->in(1) ) ) |
193 phase->eqv( in1, in2->in(1) ) ) |
194 return new (phase->C, 3) SubINode( phase->intcon(0),in2->in(2)); |
194 return new (phase->C) SubINode( phase->intcon(0),in2->in(2)); |
195 // Convert "(x-y) - x" into "-y" |
195 // Convert "(x-y) - x" into "-y" |
196 if( op1 == Op_SubI && |
196 if( op1 == Op_SubI && |
197 phase->eqv( in1->in(1), in2 ) ) |
197 phase->eqv( in1->in(1), in2 ) ) |
198 return new (phase->C, 3) SubINode( phase->intcon(0),in1->in(2)); |
198 return new (phase->C) SubINode( phase->intcon(0),in1->in(2)); |
199 // Convert "x - (y+x)" into "-y" |
199 // Convert "x - (y+x)" into "-y" |
200 if( op2 == Op_AddI && |
200 if( op2 == Op_AddI && |
201 phase->eqv( in1, in2->in(2) ) ) |
201 phase->eqv( in1, in2->in(2) ) ) |
202 return new (phase->C, 3) SubINode( phase->intcon(0),in2->in(1)); |
202 return new (phase->C) SubINode( phase->intcon(0),in2->in(1)); |
203 |
203 |
204 // Convert "0 - (x-y)" into "y-x" |
204 // Convert "0 - (x-y)" into "y-x" |
205 if( t1 == TypeInt::ZERO && op2 == Op_SubI ) |
205 if( t1 == TypeInt::ZERO && op2 == Op_SubI ) |
206 return new (phase->C, 3) SubINode( in2->in(2), in2->in(1) ); |
206 return new (phase->C) SubINode( in2->in(2), in2->in(1) ); |
207 |
207 |
208 // Convert "0 - (x+con)" into "-con-x" |
208 // Convert "0 - (x+con)" into "-con-x" |
209 jint con; |
209 jint con; |
210 if( t1 == TypeInt::ZERO && op2 == Op_AddI && |
210 if( t1 == TypeInt::ZERO && op2 == Op_AddI && |
211 (con = in2->in(2)->find_int_con(0)) != 0 ) |
211 (con = in2->in(2)->find_int_con(0)) != 0 ) |
212 return new (phase->C, 3) SubINode( phase->intcon(-con), in2->in(1) ); |
212 return new (phase->C) SubINode( phase->intcon(-con), in2->in(1) ); |
213 |
213 |
214 // Convert "(X+A) - (X+B)" into "A - B" |
214 // Convert "(X+A) - (X+B)" into "A - B" |
215 if( op1 == Op_AddI && op2 == Op_AddI && in1->in(1) == in2->in(1) ) |
215 if( op1 == Op_AddI && op2 == Op_AddI && in1->in(1) == in2->in(1) ) |
216 return new (phase->C, 3) SubINode( in1->in(2), in2->in(2) ); |
216 return new (phase->C) SubINode( in1->in(2), in2->in(2) ); |
217 |
217 |
218 // Convert "(A+X) - (B+X)" into "A - B" |
218 // Convert "(A+X) - (B+X)" into "A - B" |
219 if( op1 == Op_AddI && op2 == Op_AddI && in1->in(2) == in2->in(2) ) |
219 if( op1 == Op_AddI && op2 == Op_AddI && in1->in(2) == in2->in(2) ) |
220 return new (phase->C, 3) SubINode( in1->in(1), in2->in(1) ); |
220 return new (phase->C) SubINode( in1->in(1), in2->in(1) ); |
221 |
221 |
222 // Convert "(A+X) - (X+B)" into "A - B" |
222 // Convert "(A+X) - (X+B)" into "A - B" |
223 if( op1 == Op_AddI && op2 == Op_AddI && in1->in(2) == in2->in(1) ) |
223 if( op1 == Op_AddI && op2 == Op_AddI && in1->in(2) == in2->in(1) ) |
224 return new (phase->C, 3) SubINode( in1->in(1), in2->in(2) ); |
224 return new (phase->C) SubINode( in1->in(1), in2->in(2) ); |
225 |
225 |
226 // Convert "(X+A) - (B+X)" into "A - B" |
226 // Convert "(X+A) - (B+X)" into "A - B" |
227 if( op1 == Op_AddI && op2 == Op_AddI && in1->in(1) == in2->in(2) ) |
227 if( op1 == Op_AddI && op2 == Op_AddI && in1->in(1) == in2->in(2) ) |
228 return new (phase->C, 3) SubINode( in1->in(2), in2->in(1) ); |
228 return new (phase->C) SubINode( in1->in(2), in2->in(1) ); |
229 |
229 |
230 // Convert "A-(B-C)" into (A+C)-B", since add is commutative and generally |
230 // Convert "A-(B-C)" into (A+C)-B", since add is commutative and generally |
231 // nicer to optimize than subtract. |
231 // nicer to optimize than subtract. |
232 if( op2 == Op_SubI && in2->outcnt() == 1) { |
232 if( op2 == Op_SubI && in2->outcnt() == 1) { |
233 Node *add1 = phase->transform( new (phase->C, 3) AddINode( in1, in2->in(2) ) ); |
233 Node *add1 = phase->transform( new (phase->C) AddINode( in1, in2->in(2) ) ); |
234 return new (phase->C, 3) SubINode( add1, in2->in(1) ); |
234 return new (phase->C) SubINode( add1, in2->in(1) ); |
235 } |
235 } |
236 |
236 |
237 return NULL; |
237 return NULL; |
238 } |
238 } |
239 |
239 |
276 if( phase->type( in2 ) == Type::TOP ) return NULL; |
276 if( phase->type( in2 ) == Type::TOP ) return NULL; |
277 const TypeLong *i = phase->type( in2 )->isa_long(); |
277 const TypeLong *i = phase->type( in2 )->isa_long(); |
278 // Convert "x-c0" into "x+ -c0". |
278 // Convert "x-c0" into "x+ -c0". |
279 if( i && // Might be bottom or top... |
279 if( i && // Might be bottom or top... |
280 i->is_con() ) |
280 i->is_con() ) |
281 return new (phase->C, 3) AddLNode(in1, phase->longcon(-i->get_con())); |
281 return new (phase->C) AddLNode(in1, phase->longcon(-i->get_con())); |
282 |
282 |
283 // Convert "(x+c0) - y" into (x-y) + c0" |
283 // Convert "(x+c0) - y" into (x-y) + c0" |
284 // Do not collapse (x+c0)-y if "+" is a loop increment or |
284 // Do not collapse (x+c0)-y if "+" is a loop increment or |
285 // if "y" is a loop induction variable. |
285 // if "y" is a loop induction variable. |
286 if( op1 == Op_AddL && ok_to_convert(in1, in2) ) { |
286 if( op1 == Op_AddL && ok_to_convert(in1, in2) ) { |
287 Node *in11 = in1->in(1); |
287 Node *in11 = in1->in(1); |
288 const Type *tadd = phase->type( in1->in(2) ); |
288 const Type *tadd = phase->type( in1->in(2) ); |
289 if( tadd->singleton() && tadd != Type::TOP ) { |
289 if( tadd->singleton() && tadd != Type::TOP ) { |
290 Node *sub2 = phase->transform( new (phase->C, 3) SubLNode( in11, in2 )); |
290 Node *sub2 = phase->transform( new (phase->C) SubLNode( in11, in2 )); |
291 return new (phase->C, 3) AddLNode( sub2, in1->in(2) ); |
291 return new (phase->C) AddLNode( sub2, in1->in(2) ); |
292 } |
292 } |
293 } |
293 } |
294 |
294 |
295 // Convert "x - (y+c0)" into "(x-y) - c0" |
295 // Convert "x - (y+c0)" into "(x-y) - c0" |
296 // Need the same check as in above optimization but reversed. |
296 // Need the same check as in above optimization but reversed. |
297 if (op2 == Op_AddL && ok_to_convert(in2, in1)) { |
297 if (op2 == Op_AddL && ok_to_convert(in2, in1)) { |
298 Node* in21 = in2->in(1); |
298 Node* in21 = in2->in(1); |
299 Node* in22 = in2->in(2); |
299 Node* in22 = in2->in(2); |
300 const TypeLong* tcon = phase->type(in22)->isa_long(); |
300 const TypeLong* tcon = phase->type(in22)->isa_long(); |
301 if (tcon != NULL && tcon->is_con()) { |
301 if (tcon != NULL && tcon->is_con()) { |
302 Node* sub2 = phase->transform( new (phase->C, 3) SubLNode(in1, in21) ); |
302 Node* sub2 = phase->transform( new (phase->C) SubLNode(in1, in21) ); |
303 Node* neg_c0 = phase->longcon(- tcon->get_con()); |
303 Node* neg_c0 = phase->longcon(- tcon->get_con()); |
304 return new (phase->C, 3) AddLNode(sub2, neg_c0); |
304 return new (phase->C) AddLNode(sub2, neg_c0); |
305 } |
305 } |
306 } |
306 } |
307 |
307 |
308 const Type *t1 = phase->type( in1 ); |
308 const Type *t1 = phase->type( in1 ); |
309 if( t1 == Type::TOP ) return NULL; |
309 if( t1 == Type::TOP ) return NULL; |
317 #endif |
317 #endif |
318 |
318 |
319 // Convert "x - (x+y)" into "-y" |
319 // Convert "x - (x+y)" into "-y" |
320 if( op2 == Op_AddL && |
320 if( op2 == Op_AddL && |
321 phase->eqv( in1, in2->in(1) ) ) |
321 phase->eqv( in1, in2->in(1) ) ) |
322 return new (phase->C, 3) SubLNode( phase->makecon(TypeLong::ZERO), in2->in(2)); |
322 return new (phase->C) SubLNode( phase->makecon(TypeLong::ZERO), in2->in(2)); |
323 // Convert "x - (y+x)" into "-y" |
323 // Convert "x - (y+x)" into "-y" |
324 if( op2 == Op_AddL && |
324 if( op2 == Op_AddL && |
325 phase->eqv( in1, in2->in(2) ) ) |
325 phase->eqv( in1, in2->in(2) ) ) |
326 return new (phase->C, 3) SubLNode( phase->makecon(TypeLong::ZERO),in2->in(1)); |
326 return new (phase->C) SubLNode( phase->makecon(TypeLong::ZERO),in2->in(1)); |
327 |
327 |
328 // Convert "0 - (x-y)" into "y-x" |
328 // Convert "0 - (x-y)" into "y-x" |
329 if( phase->type( in1 ) == TypeLong::ZERO && op2 == Op_SubL ) |
329 if( phase->type( in1 ) == TypeLong::ZERO && op2 == Op_SubL ) |
330 return new (phase->C, 3) SubLNode( in2->in(2), in2->in(1) ); |
330 return new (phase->C) SubLNode( in2->in(2), in2->in(1) ); |
331 |
331 |
332 // Convert "(X+A) - (X+B)" into "A - B" |
332 // Convert "(X+A) - (X+B)" into "A - B" |
333 if( op1 == Op_AddL && op2 == Op_AddL && in1->in(1) == in2->in(1) ) |
333 if( op1 == Op_AddL && op2 == Op_AddL && in1->in(1) == in2->in(1) ) |
334 return new (phase->C, 3) SubLNode( in1->in(2), in2->in(2) ); |
334 return new (phase->C) SubLNode( in1->in(2), in2->in(2) ); |
335 |
335 |
336 // Convert "(A+X) - (B+X)" into "A - B" |
336 // Convert "(A+X) - (B+X)" into "A - B" |
337 if( op1 == Op_AddL && op2 == Op_AddL && in1->in(2) == in2->in(2) ) |
337 if( op1 == Op_AddL && op2 == Op_AddL && in1->in(2) == in2->in(2) ) |
338 return new (phase->C, 3) SubLNode( in1->in(1), in2->in(1) ); |
338 return new (phase->C) SubLNode( in1->in(1), in2->in(1) ); |
339 |
339 |
340 // Convert "A-(B-C)" into (A+C)-B" |
340 // Convert "A-(B-C)" into (A+C)-B" |
341 if( op2 == Op_SubL && in2->outcnt() == 1) { |
341 if( op2 == Op_SubL && in2->outcnt() == 1) { |
342 Node *add1 = phase->transform( new (phase->C, 3) AddLNode( in1, in2->in(2) ) ); |
342 Node *add1 = phase->transform( new (phase->C) AddLNode( in1, in2->in(2) ) ); |
343 return new (phase->C, 3) SubLNode( add1, in2->in(1) ); |
343 return new (phase->C) SubLNode( add1, in2->in(1) ); |
344 } |
344 } |
345 |
345 |
346 return NULL; |
346 return NULL; |
347 } |
347 } |
348 |
348 |
405 // Not associative because of boundary conditions (infinity) |
405 // Not associative because of boundary conditions (infinity) |
406 if( IdealizedNumerics && !phase->C->method()->is_strict() ) { |
406 if( IdealizedNumerics && !phase->C->method()->is_strict() ) { |
407 // Convert "x - (x+y)" into "-y" |
407 // Convert "x - (x+y)" into "-y" |
408 if( in(2)->is_Add() && |
408 if( in(2)->is_Add() && |
409 phase->eqv(in(1),in(2)->in(1) ) ) |
409 phase->eqv(in(1),in(2)->in(1) ) ) |
410 return new (phase->C, 3) SubFNode( phase->makecon(TypeF::ZERO),in(2)->in(2)); |
410 return new (phase->C) SubFNode( phase->makecon(TypeF::ZERO),in(2)->in(2)); |
411 } |
411 } |
412 |
412 |
413 // Cannot replace 0.0-X with -X because a 'fsub' bytecode computes |
413 // Cannot replace 0.0-X with -X because a 'fsub' bytecode computes |
414 // 0.0-0.0 as +0.0, while a 'fneg' bytecode computes -0.0. |
414 // 0.0-0.0 as +0.0, while a 'fneg' bytecode computes -0.0. |
415 //if( phase->type(in(1)) == TypeF::ZERO ) |
415 //if( phase->type(in(1)) == TypeF::ZERO ) |
448 // Not associative because of boundary conditions (infinity) |
448 // Not associative because of boundary conditions (infinity) |
449 if( IdealizedNumerics && !phase->C->method()->is_strict() ) { |
449 if( IdealizedNumerics && !phase->C->method()->is_strict() ) { |
450 // Convert "x - (x+y)" into "-y" |
450 // Convert "x - (x+y)" into "-y" |
451 if( in(2)->is_Add() && |
451 if( in(2)->is_Add() && |
452 phase->eqv(in(1),in(2)->in(1) ) ) |
452 phase->eqv(in(1),in(2)->in(1) ) ) |
453 return new (phase->C, 3) SubDNode( phase->makecon(TypeD::ZERO),in(2)->in(2)); |
453 return new (phase->C) SubDNode( phase->makecon(TypeD::ZERO),in(2)->in(2)); |
454 } |
454 } |
455 |
455 |
456 // Cannot replace 0.0-X with -X because a 'dsub' bytecode computes |
456 // Cannot replace 0.0-X with -X because a 'dsub' bytecode computes |
457 // 0.0-0.0 as +0.0, while a 'dneg' bytecode computes -0.0. |
457 // 0.0-0.0 as +0.0, while a 'dneg' bytecode computes -0.0. |
458 //if( phase->type(in(1)) == TypeD::ZERO ) |
458 //if( phase->type(in(1)) == TypeD::ZERO ) |
579 //------------------------------Idealize--------------------------------------- |
579 //------------------------------Idealize--------------------------------------- |
580 Node *CmpINode::Ideal( PhaseGVN *phase, bool can_reshape ) { |
580 Node *CmpINode::Ideal( PhaseGVN *phase, bool can_reshape ) { |
581 if (phase->type(in(2))->higher_equal(TypeInt::ZERO)) { |
581 if (phase->type(in(2))->higher_equal(TypeInt::ZERO)) { |
582 switch (in(1)->Opcode()) { |
582 switch (in(1)->Opcode()) { |
583 case Op_CmpL3: // Collapse a CmpL3/CmpI into a CmpL |
583 case Op_CmpL3: // Collapse a CmpL3/CmpI into a CmpL |
584 return new (phase->C, 3) CmpLNode(in(1)->in(1),in(1)->in(2)); |
584 return new (phase->C) CmpLNode(in(1)->in(1),in(1)->in(2)); |
585 case Op_CmpF3: // Collapse a CmpF3/CmpI into a CmpF |
585 case Op_CmpF3: // Collapse a CmpF3/CmpI into a CmpF |
586 return new (phase->C, 3) CmpFNode(in(1)->in(1),in(1)->in(2)); |
586 return new (phase->C) CmpFNode(in(1)->in(1),in(1)->in(2)); |
587 case Op_CmpD3: // Collapse a CmpD3/CmpI into a CmpD |
587 case Op_CmpD3: // Collapse a CmpD3/CmpI into a CmpD |
588 return new (phase->C, 3) CmpDNode(in(1)->in(1),in(1)->in(2)); |
588 return new (phase->C) CmpDNode(in(1)->in(1),in(1)->in(2)); |
589 //case Op_SubI: |
589 //case Op_SubI: |
590 // If (x - y) cannot overflow, then ((x - y) <?> 0) |
590 // If (x - y) cannot overflow, then ((x - y) <?> 0) |
591 // can be turned into (x <?> y). |
591 // can be turned into (x <?> y). |
592 // This is handled (with more general cases) by Ideal_sub_algebra. |
592 // This is handled (with more general cases) by Ideal_sub_algebra. |
593 } |
593 } |
1083 static Node *clone_cmp( Node *cmp, Node *cmp1, Node *cmp2, PhaseGVN *gvn, BoolTest::mask test ) { |
1083 static Node *clone_cmp( Node *cmp, Node *cmp1, Node *cmp2, PhaseGVN *gvn, BoolTest::mask test ) { |
1084 Node *ncmp = cmp->clone(); |
1084 Node *ncmp = cmp->clone(); |
1085 ncmp->set_req(1,cmp1); |
1085 ncmp->set_req(1,cmp1); |
1086 ncmp->set_req(2,cmp2); |
1086 ncmp->set_req(2,cmp2); |
1087 ncmp = gvn->transform( ncmp ); |
1087 ncmp = gvn->transform( ncmp ); |
1088 return new (gvn->C, 2) BoolNode( ncmp, test ); |
1088 return new (gvn->C) BoolNode( ncmp, test ); |
1089 } |
1089 } |
1090 |
1090 |
1091 //-------------------------------make_predicate-------------------------------- |
1091 //-------------------------------make_predicate-------------------------------- |
1092 Node* BoolNode::make_predicate(Node* test_value, PhaseGVN* phase) { |
1092 Node* BoolNode::make_predicate(Node* test_value, PhaseGVN* phase) { |
1093 if (test_value->is_Con()) return test_value; |
1093 if (test_value->is_Con()) return test_value; |
1104 return phase->transform( bol->negate(phase) ); |
1104 return phase->transform( bol->negate(phase) ); |
1105 } |
1105 } |
1106 // Else fall through. The CMove gets in the way of the test. |
1106 // Else fall through. The CMove gets in the way of the test. |
1107 // It should be the case that make_predicate(bol->as_int_value()) == bol. |
1107 // It should be the case that make_predicate(bol->as_int_value()) == bol. |
1108 } |
1108 } |
1109 Node* cmp = new (C, 3) CmpINode(test_value, phase->intcon(0)); |
1109 Node* cmp = new (C) CmpINode(test_value, phase->intcon(0)); |
1110 cmp = phase->transform(cmp); |
1110 cmp = phase->transform(cmp); |
1111 Node* bol = new (C, 2) BoolNode(cmp, BoolTest::ne); |
1111 Node* bol = new (C) BoolNode(cmp, BoolTest::ne); |
1112 return phase->transform(bol); |
1112 return phase->transform(bol); |
1113 } |
1113 } |
1114 |
1114 |
1115 //--------------------------------as_int_value--------------------------------- |
1115 //--------------------------------as_int_value--------------------------------- |
1116 Node* BoolNode::as_int_value(PhaseGVN* phase) { |
1116 Node* BoolNode::as_int_value(PhaseGVN* phase) { |
1173 j_xor->in(1) != j_xor && // An xor of itself is dead |
1173 j_xor->in(1) != j_xor && // An xor of itself is dead |
1174 phase->type( j_xor->in(1) ) == TypeInt::BOOL && |
1174 phase->type( j_xor->in(1) ) == TypeInt::BOOL && |
1175 phase->type( j_xor->in(2) ) == TypeInt::ONE && |
1175 phase->type( j_xor->in(2) ) == TypeInt::ONE && |
1176 (_test._test == BoolTest::eq || |
1176 (_test._test == BoolTest::eq || |
1177 _test._test == BoolTest::ne) ) { |
1177 _test._test == BoolTest::ne) ) { |
1178 Node *ncmp = phase->transform(new (phase->C, 3) CmpINode(j_xor->in(1),cmp2)); |
1178 Node *ncmp = phase->transform(new (phase->C) CmpINode(j_xor->in(1),cmp2)); |
1179 return new (phase->C, 2) BoolNode( ncmp, _test.negate() ); |
1179 return new (phase->C) BoolNode( ncmp, _test.negate() ); |
1180 } |
1180 } |
1181 |
1181 |
1182 // Change "bool eq/ne (cmp (Conv2B X) 0)" into "bool eq/ne (cmp X 0)". |
1182 // Change "bool eq/ne (cmp (Conv2B X) 0)" into "bool eq/ne (cmp X 0)". |
1183 // This is a standard idiom for branching on a boolean value. |
1183 // This is a standard idiom for branching on a boolean value. |
1184 Node *c2b = cmp1; |
1184 Node *c2b = cmp1; |
1185 if( cmp2_type == TypeInt::ZERO && |
1185 if( cmp2_type == TypeInt::ZERO && |
1186 cmp1_op == Op_Conv2B && |
1186 cmp1_op == Op_Conv2B && |
1187 (_test._test == BoolTest::eq || |
1187 (_test._test == BoolTest::eq || |
1188 _test._test == BoolTest::ne) ) { |
1188 _test._test == BoolTest::ne) ) { |
1189 Node *ncmp = phase->transform(phase->type(c2b->in(1))->isa_int() |
1189 Node *ncmp = phase->transform(phase->type(c2b->in(1))->isa_int() |
1190 ? (Node*)new (phase->C, 3) CmpINode(c2b->in(1),cmp2) |
1190 ? (Node*)new (phase->C) CmpINode(c2b->in(1),cmp2) |
1191 : (Node*)new (phase->C, 3) CmpPNode(c2b->in(1),phase->makecon(TypePtr::NULL_PTR)) |
1191 : (Node*)new (phase->C) CmpPNode(c2b->in(1),phase->makecon(TypePtr::NULL_PTR)) |
1192 ); |
1192 ); |
1193 return new (phase->C, 2) BoolNode( ncmp, _test._test ); |
1193 return new (phase->C) BoolNode( ncmp, _test._test ); |
1194 } |
1194 } |
1195 |
1195 |
1196 // Comparing a SubI against a zero is equal to comparing the SubI |
1196 // Comparing a SubI against a zero is equal to comparing the SubI |
1197 // arguments directly. This only works for eq and ne comparisons |
1197 // arguments directly. This only works for eq and ne comparisons |
1198 // due to possible integer overflow. |
1198 // due to possible integer overflow. |
1199 if ((_test._test == BoolTest::eq || _test._test == BoolTest::ne) && |
1199 if ((_test._test == BoolTest::eq || _test._test == BoolTest::ne) && |
1200 (cop == Op_CmpI) && |
1200 (cop == Op_CmpI) && |
1201 (cmp1->Opcode() == Op_SubI) && |
1201 (cmp1->Opcode() == Op_SubI) && |
1202 ( cmp2_type == TypeInt::ZERO ) ) { |
1202 ( cmp2_type == TypeInt::ZERO ) ) { |
1203 Node *ncmp = phase->transform( new (phase->C, 3) CmpINode(cmp1->in(1),cmp1->in(2))); |
1203 Node *ncmp = phase->transform( new (phase->C) CmpINode(cmp1->in(1),cmp1->in(2))); |
1204 return new (phase->C, 2) BoolNode( ncmp, _test._test ); |
1204 return new (phase->C) BoolNode( ncmp, _test._test ); |
1205 } |
1205 } |
1206 |
1206 |
1207 // Change (-A vs 0) into (A vs 0) by commuting the test. Disallow in the |
1207 // Change (-A vs 0) into (A vs 0) by commuting the test. Disallow in the |
1208 // most general case because negating 0x80000000 does nothing. Needed for |
1208 // most general case because negating 0x80000000 does nothing. Needed for |
1209 // the CmpF3/SubI/CmpI idiom. |
1209 // the CmpF3/SubI/CmpI idiom. |
1210 if( cop == Op_CmpI && |
1210 if( cop == Op_CmpI && |
1211 cmp1->Opcode() == Op_SubI && |
1211 cmp1->Opcode() == Op_SubI && |
1212 cmp2_type == TypeInt::ZERO && |
1212 cmp2_type == TypeInt::ZERO && |
1213 phase->type( cmp1->in(1) ) == TypeInt::ZERO && |
1213 phase->type( cmp1->in(1) ) == TypeInt::ZERO && |
1214 phase->type( cmp1->in(2) )->higher_equal(TypeInt::SYMINT) ) { |
1214 phase->type( cmp1->in(2) )->higher_equal(TypeInt::SYMINT) ) { |
1215 Node *ncmp = phase->transform( new (phase->C, 3) CmpINode(cmp1->in(2),cmp2)); |
1215 Node *ncmp = phase->transform( new (phase->C) CmpINode(cmp1->in(2),cmp2)); |
1216 return new (phase->C, 2) BoolNode( ncmp, _test.commute() ); |
1216 return new (phase->C) BoolNode( ncmp, _test.commute() ); |
1217 } |
1217 } |
1218 |
1218 |
1219 // The transformation below is not valid for either signed or unsigned |
1219 // The transformation below is not valid for either signed or unsigned |
1220 // comparisons due to wraparound concerns at MAX_VALUE and MIN_VALUE. |
1220 // comparisons due to wraparound concerns at MAX_VALUE and MIN_VALUE. |
1221 // This transformation can be resurrected when we are able to |
1221 // This transformation can be resurrected when we are able to |