1 /*
2  * Copyright (c) 2014, 2019, 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 #ifndef SHARE_OPTO_CASTNODE_HPP
26 #define SHARE_OPTO_CASTNODE_HPP
27 
28 #include "opto/node.hpp"
29 #include "opto/opcodes.hpp"
30 
31 
32 //------------------------------ConstraintCastNode-----------------------------
33 // cast to a different range
34 class ConstraintCastNode: public TypeNode {
35   protected:
36   // Can this node be removed post CCP or does it carry a required dependency?
37   const bool _carry_dependency;
38   virtual bool cmp( const Node &n ) const;
39   virtual uint size_of() const;
40 
41   public:
ConstraintCastNode(Node * n,const Type * t,bool carry_dependency)42   ConstraintCastNode(Node *n, const Type *t, bool carry_dependency)
43     : TypeNode(t,2), _carry_dependency(carry_dependency) {
44     init_class_id(Class_ConstraintCast);
45     init_req(1, n);
46   }
47   virtual Node* Identity(PhaseGVN* phase);
48   virtual const Type* Value(PhaseGVN* phase) const;
49   virtual Node *Ideal(PhaseGVN *phase, bool can_reshape);
50   virtual int Opcode() const;
51   virtual uint ideal_reg() const = 0;
depends_only_on_test() const52   virtual bool depends_only_on_test() const { return !_carry_dependency; }
carry_dependency() const53   bool carry_dependency() const { return _carry_dependency; }
54   TypeNode* dominating_cast(PhaseGVN* gvn, PhaseTransform* pt) const;
55   static Node* make_cast(int opcode,  Node* c, Node *n, const Type *t, bool carry_dependency);
56   static Node* make(Node* c, Node *n, const Type *t, BasicType bt);
operates_on(BasicType bt,bool signed_int) const57   virtual bool operates_on(BasicType bt, bool signed_int) const {
58     assert(bt == T_INT || bt == T_LONG, "unsupported");
59     return false;
60   }
61 
62 #ifndef PRODUCT
63   virtual void dump_spec(outputStream *st) const;
64 #endif
65 };
66 
67 //------------------------------CastIINode-------------------------------------
68 // cast integer to integer (different range)
69 class CastIINode: public ConstraintCastNode {
70   protected:
71   // Is this node dependent on a range check?
72   const bool _range_check_dependency;
73   virtual bool cmp(const Node &n) const;
74   virtual uint size_of() const;
75 
76   public:
CastIINode(Node * n,const Type * t,bool carry_dependency=false,bool range_check_dependency=false)77   CastIINode(Node* n, const Type* t, bool carry_dependency = false, bool range_check_dependency = false)
78     : ConstraintCastNode(n, t, carry_dependency), _range_check_dependency(range_check_dependency) {
79     init_class_id(Class_CastII);
80   }
81   virtual int Opcode() const;
ideal_reg() const82   virtual uint ideal_reg() const { return Op_RegI; }
83   virtual Node* Identity(PhaseGVN* phase);
84   virtual const Type* Value(PhaseGVN* phase) const;
85   virtual Node *Ideal(PhaseGVN *phase, bool can_reshape);
has_range_check()86   const bool has_range_check() {
87 #ifdef _LP64
88     return _range_check_dependency;
89 #else
90     assert(!_range_check_dependency, "Should not have range check dependency");
91     return false;
92 #endif
93   }
operates_on(BasicType bt,bool signed_int) const94   virtual bool operates_on(BasicType bt, bool signed_int) const {
95     assert(bt == T_INT || bt == T_LONG, "unsupported");
96     return bt == T_INT;
97   }
98 
99 #ifndef PRODUCT
100   virtual void dump_spec(outputStream* st) const;
101 #endif
102 };
103 
104 class CastLLNode: public ConstraintCastNode {
105 public:
CastLLNode(Node * n,const Type * t,bool carry_dependency=false)106   CastLLNode(Node* n, const Type* t, bool carry_dependency = false)
107           : ConstraintCastNode(n, t, carry_dependency){
108     init_class_id(Class_CastLL);
109   }
operates_on(BasicType bt,bool signed_int) const110   virtual bool operates_on(BasicType bt, bool signed_int) const {
111     assert(bt == T_INT || bt == T_LONG, "unsupported");
112     return bt == T_LONG;
113   }
114   virtual int Opcode() const;
ideal_reg() const115   virtual uint ideal_reg() const { return Op_RegL; }
116 };
117 
118 //------------------------------CastPPNode-------------------------------------
119 // cast pointer to pointer (different type)
120 class CastPPNode: public ConstraintCastNode {
121   public:
CastPPNode(Node * n,const Type * t,bool carry_dependency=false)122   CastPPNode (Node *n, const Type *t, bool carry_dependency = false)
123     : ConstraintCastNode(n, t, carry_dependency) {
124   }
125   virtual int Opcode() const;
ideal_reg() const126   virtual uint ideal_reg() const { return Op_RegP; }
127 };
128 
129 //------------------------------CheckCastPPNode--------------------------------
130 // for _checkcast, cast pointer to pointer (different type), without JOIN,
131 class CheckCastPPNode: public ConstraintCastNode {
132   public:
CheckCastPPNode(Node * c,Node * n,const Type * t,bool carry_dependency=false)133   CheckCastPPNode(Node *c, Node *n, const Type *t, bool carry_dependency = false)
134     : ConstraintCastNode(n, t, carry_dependency) {
135     init_class_id(Class_CheckCastPP);
136     init_req(0, c);
137   }
138 
139   virtual Node* Identity(PhaseGVN* phase);
140   virtual const Type* Value(PhaseGVN* phase) const;
141   virtual int   Opcode() const;
ideal_reg() const142   virtual uint  ideal_reg() const { return Op_RegP; }
depends_only_on_test() const143   bool depends_only_on_test() const { return !type()->isa_rawptr() && ConstraintCastNode::depends_only_on_test(); }
144  };
145 
146 
147 //------------------------------CastX2PNode-------------------------------------
148 // convert a machine-pointer-sized integer to a raw pointer
149 class CastX2PNode : public Node {
150   public:
CastX2PNode(Node * n)151   CastX2PNode( Node *n ) : Node(NULL, n) {}
152   virtual int Opcode() const;
153   virtual const Type* Value(PhaseGVN* phase) const;
154   virtual Node *Ideal(PhaseGVN *phase, bool can_reshape);
155   virtual Node* Identity(PhaseGVN* phase);
ideal_reg() const156   virtual uint ideal_reg() const { return Op_RegP; }
bottom_type() const157   virtual const Type *bottom_type() const { return TypeRawPtr::BOTTOM; }
158 };
159 
160 //------------------------------CastP2XNode-------------------------------------
161 // Used in both 32-bit and 64-bit land.
162 // Used for card-marks and unsafe pointer math.
163 class CastP2XNode : public Node {
164   public:
CastP2XNode(Node * ctrl,Node * n)165   CastP2XNode( Node *ctrl, Node *n ) : Node(ctrl, n) {}
166   virtual int Opcode() const;
167   virtual const Type* Value(PhaseGVN* phase) const;
168   virtual Node *Ideal(PhaseGVN *phase, bool can_reshape);
169   virtual Node* Identity(PhaseGVN* phase);
ideal_reg() const170   virtual uint ideal_reg() const { return Op_RegX; }
bottom_type() const171   virtual const Type *bottom_type() const { return TypeX_X; }
172   // Return false to keep node from moving away from an associated card mark.
depends_only_on_test() const173   virtual bool depends_only_on_test() const { return false; }
174 };
175 
176 
177 
178 #endif // SHARE_OPTO_CASTNODE_HPP
179