1 /*
2 * Copyright (c) 1997, 2017, Oracle and/or its affiliates. All rights reserved.
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * This code is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License version 2 only, as
7 * published by the Free Software Foundation.
8 *
9 * This code is distributed in the hope that it will be useful, but WITHOUT
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
12 * version 2 for more details (a copy is included in the LICENSE file that
13 * accompanied this code).
14 *
15 * You should have received a copy of the GNU General Public License version
16 * 2 along with this work; if not, write to the Free Software Foundation,
17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
18 *
19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
20 * or visit www.oracle.com if you need additional information or have any
21 * questions.
22 *
23 */
24
25 #include "precompiled.hpp"
26 #include "memory/allocation.inline.hpp"
27 #include "opto/addnode.hpp"
28 #include "opto/connode.hpp"
29 #include "opto/convertnode.hpp"
30 #include "opto/memnode.hpp"
31 #include "opto/mulnode.hpp"
32 #include "opto/phaseX.hpp"
33 #include "opto/subnode.hpp"
34
35 // Portions of code courtesy of Clifford Click
36
37
38 //=============================================================================
39 //------------------------------hash-------------------------------------------
40 // Hash function over MulNodes. Needs to be commutative; i.e., I swap
41 // (commute) inputs to MulNodes willy-nilly so the hash function must return
42 // the same value in the presence of edge swapping.
43 uint MulNode::hash() const {
44 return (uintptr_t)in(1) + (uintptr_t)in(2) + Opcode();
45 }
46
47 //------------------------------Identity---------------------------------------
48 // Multiplying a one preserves the other argument
49 Node* MulNode::Identity(PhaseGVN* phase) {
50 register const Type *one = mul_id(); // The multiplicative identity
51 if( phase->type( in(1) )->higher_equal( one ) ) return in(2);
52 if( phase->type( in(2) )->higher_equal( one ) ) return in(1);
53
456 if (t12 && t12->is_con()) { // Shift is by a constant
457 int shift = t12->get_con();
458 shift &= BitsPerJavaInteger - 1; // semantics of Java shifts
459 int mask = max_juint >> shift;
460 if ((mask & con) == mask) // If AND is useless, skip it
461 return in1;
462 }
463 }
464 }
465 return MulNode::Identity(phase);
466 }
467
468 //------------------------------Ideal------------------------------------------
469 Node *AndINode::Ideal(PhaseGVN *phase, bool can_reshape) {
470 // Special case constant AND mask
471 const TypeInt *t2 = phase->type( in(2) )->isa_int();
472 if( !t2 || !t2->is_con() ) return MulNode::Ideal(phase, can_reshape);
473 const int mask = t2->get_con();
474 Node *load = in(1);
475 uint lop = load->Opcode();
476
477 // Masking bits off of a Character? Hi bits are already zero.
478 if( lop == Op_LoadUS &&
479 (mask & 0xFFFF0000) ) // Can we make a smaller mask?
480 return new AndINode(load,phase->intcon(mask&0xFFFF));
481
482 // Masking bits off of a Short? Loading a Character does some masking
483 if (can_reshape &&
484 load->outcnt() == 1 && load->unique_out() == this) {
485 if (lop == Op_LoadS && (mask & 0xFFFF0000) == 0 ) {
486 Node* ldus = load->as_Load()->convert_to_unsigned_load(*phase);
487 ldus = phase->transform(ldus);
488 return new AndINode(ldus, phase->intcon(mask & 0xFFFF));
489 }
490
491 // Masking sign bits off of a Byte? Do an unsigned byte load plus
492 // an and.
493 if (lop == Op_LoadB && (mask & 0xFFFFFF00) == 0) {
494 Node* ldub = load->as_Load()->convert_to_unsigned_load(*phase);
495 ldub = phase->transform(ldub);
|
1 /*
2 * Copyright (c) 1997, 2018, Oracle and/or its affiliates. All rights reserved.
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * This code is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License version 2 only, as
7 * published by the Free Software Foundation.
8 *
9 * This code is distributed in the hope that it will be useful, but WITHOUT
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
12 * version 2 for more details (a copy is included in the LICENSE file that
13 * accompanied this code).
14 *
15 * You should have received a copy of the GNU General Public License version
16 * 2 along with this work; if not, write to the Free Software Foundation,
17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
18 *
19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
20 * or visit www.oracle.com if you need additional information or have any
21 * questions.
22 *
23 */
24
25 #include "precompiled.hpp"
26 #include "memory/allocation.inline.hpp"
27 #include "opto/addnode.hpp"
28 #include "opto/connode.hpp"
29 #include "opto/convertnode.hpp"
30 #include "opto/memnode.hpp"
31 #include "opto/mulnode.hpp"
32 #include "opto/phaseX.hpp"
33 #include "opto/subnode.hpp"
34 #include "utilities/macros.hpp"
35 #if INCLUDE_SHENANDOAHGC
36 #include "gc/shenandoah/c2/shenandoahBarrierSetC2.hpp"
37 #endif
38
39 // Portions of code courtesy of Clifford Click
40
41
42 //=============================================================================
43 //------------------------------hash-------------------------------------------
44 // Hash function over MulNodes. Needs to be commutative; i.e., I swap
45 // (commute) inputs to MulNodes willy-nilly so the hash function must return
46 // the same value in the presence of edge swapping.
47 uint MulNode::hash() const {
48 return (uintptr_t)in(1) + (uintptr_t)in(2) + Opcode();
49 }
50
51 //------------------------------Identity---------------------------------------
52 // Multiplying a one preserves the other argument
53 Node* MulNode::Identity(PhaseGVN* phase) {
54 register const Type *one = mul_id(); // The multiplicative identity
55 if( phase->type( in(1) )->higher_equal( one ) ) return in(2);
56 if( phase->type( in(2) )->higher_equal( one ) ) return in(1);
57
460 if (t12 && t12->is_con()) { // Shift is by a constant
461 int shift = t12->get_con();
462 shift &= BitsPerJavaInteger - 1; // semantics of Java shifts
463 int mask = max_juint >> shift;
464 if ((mask & con) == mask) // If AND is useless, skip it
465 return in1;
466 }
467 }
468 }
469 return MulNode::Identity(phase);
470 }
471
472 //------------------------------Ideal------------------------------------------
473 Node *AndINode::Ideal(PhaseGVN *phase, bool can_reshape) {
474 // Special case constant AND mask
475 const TypeInt *t2 = phase->type( in(2) )->isa_int();
476 if( !t2 || !t2->is_con() ) return MulNode::Ideal(phase, can_reshape);
477 const int mask = t2->get_con();
478 Node *load = in(1);
479 uint lop = load->Opcode();
480
481 #if INCLUDE_SHENANDOAHGC
482 if (UseShenandoahGC && ShenandoahBarrierC2Support::is_gc_state_load(load)) {
483 // Do not touch the load+mask, we would match the whole sequence exactly.
484 // Converting the load to LoadUB/LoadUS would mismatch and waste a register
485 // on the barrier fastpath.
486 return NULL;
487 }
488 #endif
489
490 // Masking bits off of a Character? Hi bits are already zero.
491 if( lop == Op_LoadUS &&
492 (mask & 0xFFFF0000) ) // Can we make a smaller mask?
493 return new AndINode(load,phase->intcon(mask&0xFFFF));
494
495 // Masking bits off of a Short? Loading a Character does some masking
496 if (can_reshape &&
497 load->outcnt() == 1 && load->unique_out() == this) {
498 if (lop == Op_LoadS && (mask & 0xFFFF0000) == 0 ) {
499 Node* ldus = load->as_Load()->convert_to_unsigned_load(*phase);
500 ldus = phase->transform(ldus);
501 return new AndINode(ldus, phase->intcon(mask & 0xFFFF));
502 }
503
504 // Masking sign bits off of a Byte? Do an unsigned byte load plus
505 // an and.
506 if (lop == Op_LoadB && (mask & 0xFFFFFF00) == 0) {
507 Node* ldub = load->as_Load()->convert_to_unsigned_load(*phase);
508 ldub = phase->transform(ldub);
|