1 /* 2 * Copyright (c) 2015, 2020, 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_INTRINSICNODE_HPP 26 #define SHARE_OPTO_INTRINSICNODE_HPP 27 28 #include "opto/node.hpp" 29 #include "opto/opcodes.hpp" 30 #include "opto/connode.hpp" 31 32 33 //----------------------PartialSubtypeCheckNode-------------------------------- 34 // The 2nd slow-half of a subtype check. Scan the subklass's 2ndary superklass 35 // array for an instance of the superklass. Set a hidden internal cache on a 36 // hit (cache is checked with exposed code in gen_subtype_check()). Return 37 // not zero for a miss or zero for a hit. 38 class PartialSubtypeCheckNode : public Node { 39 public: PartialSubtypeCheckNode(Node * c,Node * sub,Node * super)40 PartialSubtypeCheckNode(Node* c, Node* sub, Node* super) : Node(c,sub,super) {} 41 virtual int Opcode() const; bottom_type() const42 virtual const Type* bottom_type() const { return TypeRawPtr::BOTTOM; } ideal_reg() const43 virtual uint ideal_reg() const { return Op_RegP; } 44 }; 45 46 //------------------------------StrIntrinsic------------------------------- 47 // Base class for Ideal nodes used in String intrinsic code. 48 class StrIntrinsicNode: public Node { 49 public: 50 // Possible encodings of the parameters passed to the string intrinsic. 51 // 'L' stands for Latin1 and 'U' stands for UTF16. For example, 'LU' means that 52 // the first string is Latin1 encoded and the second string is UTF16 encoded. 53 // 'L' means that the single string is Latin1 encoded 54 typedef enum ArgEncoding { LL, LU, UL, UU, L, U, none } ArgEnc; 55 56 protected: 57 // Encoding of strings. Used to select the right version of the intrinsic. 58 const ArgEncoding _encoding; 59 virtual uint size_of() const; 60 61 public: StrIntrinsicNode(Node * control,Node * char_array_mem,Node * s1,Node * c1,Node * s2,Node * c2,ArgEncoding encoding)62 StrIntrinsicNode(Node* control, Node* char_array_mem, 63 Node* s1, Node* c1, Node* s2, Node* c2, ArgEncoding encoding): 64 Node(control, char_array_mem, s1, c1, s2, c2), _encoding(encoding) { 65 } 66 StrIntrinsicNode(Node * control,Node * char_array_mem,Node * s1,Node * s2,Node * c,ArgEncoding encoding)67 StrIntrinsicNode(Node* control, Node* char_array_mem, 68 Node* s1, Node* s2, Node* c, ArgEncoding encoding): 69 Node(control, char_array_mem, s1, s2, c), _encoding(encoding) { 70 } 71 StrIntrinsicNode(Node * control,Node * char_array_mem,Node * s1,Node * s2,ArgEncoding encoding)72 StrIntrinsicNode(Node* control, Node* char_array_mem, 73 Node* s1, Node* s2, ArgEncoding encoding): 74 Node(control, char_array_mem, s1, s2), _encoding(encoding) { 75 } 76 depends_only_on_test() const77 virtual bool depends_only_on_test() const { return false; } adr_type() const78 virtual const TypePtr* adr_type() const { return TypeAryPtr::BYTES; } 79 virtual uint match_edge(uint idx) const; ideal_reg() const80 virtual uint ideal_reg() const { return Op_RegI; } 81 virtual Node* Ideal(PhaseGVN* phase, bool can_reshape); 82 virtual const Type* Value(PhaseGVN* phase) const; encoding() const83 ArgEncoding encoding() const { return _encoding; } 84 }; 85 86 //------------------------------StrComp------------------------------------- 87 class StrCompNode: public StrIntrinsicNode { 88 public: StrCompNode(Node * control,Node * char_array_mem,Node * s1,Node * c1,Node * s2,Node * c2,ArgEncoding encoding)89 StrCompNode(Node* control, Node* char_array_mem, 90 Node* s1, Node* c1, Node* s2, Node* c2, ArgEncoding encoding): 91 StrIntrinsicNode(control, char_array_mem, s1, c1, s2, c2, encoding) {}; 92 virtual int Opcode() const; bottom_type() const93 virtual const Type* bottom_type() const { return TypeInt::INT; } 94 }; 95 96 //------------------------------StrEquals------------------------------------- 97 class StrEqualsNode: public StrIntrinsicNode { 98 public: StrEqualsNode(Node * control,Node * char_array_mem,Node * s1,Node * s2,Node * c,ArgEncoding encoding)99 StrEqualsNode(Node* control, Node* char_array_mem, 100 Node* s1, Node* s2, Node* c, ArgEncoding encoding): 101 StrIntrinsicNode(control, char_array_mem, s1, s2, c, encoding) {}; 102 virtual int Opcode() const; bottom_type() const103 virtual const Type* bottom_type() const { return TypeInt::BOOL; } 104 }; 105 106 //------------------------------StrIndexOf------------------------------------- 107 class StrIndexOfNode: public StrIntrinsicNode { 108 public: StrIndexOfNode(Node * control,Node * char_array_mem,Node * s1,Node * c1,Node * s2,Node * c2,ArgEncoding encoding)109 StrIndexOfNode(Node* control, Node* char_array_mem, 110 Node* s1, Node* c1, Node* s2, Node* c2, ArgEncoding encoding): 111 StrIntrinsicNode(control, char_array_mem, s1, c1, s2, c2, encoding) {}; 112 virtual int Opcode() const; bottom_type() const113 virtual const Type* bottom_type() const { return TypeInt::INT; } 114 }; 115 116 //------------------------------StrIndexOfChar------------------------------------- 117 class StrIndexOfCharNode: public StrIntrinsicNode { 118 public: StrIndexOfCharNode(Node * control,Node * char_array_mem,Node * s1,Node * c1,Node * c,ArgEncoding encoding)119 StrIndexOfCharNode(Node* control, Node* char_array_mem, 120 Node* s1, Node* c1, Node* c, ArgEncoding encoding): 121 StrIntrinsicNode(control, char_array_mem, s1, c1, c, encoding) {}; 122 virtual int Opcode() const; bottom_type() const123 virtual const Type* bottom_type() const { return TypeInt::INT; } 124 }; 125 126 //--------------------------StrCompressedCopy------------------------------- 127 class StrCompressedCopyNode: public StrIntrinsicNode { 128 public: StrCompressedCopyNode(Node * control,Node * arymem,Node * s1,Node * s2,Node * c)129 StrCompressedCopyNode(Node* control, Node* arymem, 130 Node* s1, Node* s2, Node* c): 131 StrIntrinsicNode(control, arymem, s1, s2, c, none) {}; 132 virtual int Opcode() const; bottom_type() const133 virtual const Type* bottom_type() const { return TypeInt::INT; } adr_type() const134 virtual const TypePtr* adr_type() const { return TypePtr::BOTTOM; } 135 virtual Node* Ideal(PhaseGVN* phase, bool can_reshape); 136 }; 137 138 //--------------------------StrInflatedCopy--------------------------------- 139 class StrInflatedCopyNode: public StrIntrinsicNode { 140 public: StrInflatedCopyNode(Node * control,Node * arymem,Node * s1,Node * s2,Node * c)141 StrInflatedCopyNode(Node* control, Node* arymem, 142 Node* s1, Node* s2, Node* c): 143 StrIntrinsicNode(control, arymem, s1, s2, c, none) {}; 144 virtual int Opcode() const; bottom_type() const145 virtual const Type* bottom_type() const { return Type::MEMORY; } adr_type() const146 virtual const TypePtr* adr_type() const { return TypePtr::BOTTOM; } 147 virtual Node* Ideal(PhaseGVN* phase, bool can_reshape); 148 }; 149 150 //------------------------------AryEq--------------------------------------- 151 class AryEqNode: public StrIntrinsicNode { 152 public: AryEqNode(Node * control,Node * char_array_mem,Node * s1,Node * s2,ArgEncoding encoding)153 AryEqNode(Node* control, Node* char_array_mem, 154 Node* s1, Node* s2, ArgEncoding encoding): 155 StrIntrinsicNode(control, char_array_mem, s1, s2, encoding) {}; 156 virtual int Opcode() const; bottom_type() const157 virtual const Type* bottom_type() const { return TypeInt::BOOL; } 158 }; 159 160 //------------------------------HasNegatives--------------------------------- 161 class HasNegativesNode: public StrIntrinsicNode { 162 public: HasNegativesNode(Node * control,Node * char_array_mem,Node * s1,Node * c1)163 HasNegativesNode(Node* control, Node* char_array_mem, Node* s1, Node* c1): 164 StrIntrinsicNode(control, char_array_mem, s1, c1, none) {}; 165 virtual int Opcode() const; bottom_type() const166 virtual const Type* bottom_type() const { return TypeInt::BOOL; } 167 }; 168 169 170 //------------------------------EncodeISOArray-------------------------------- 171 // encode char[] to byte[] in ISO_8859_1 172 class EncodeISOArrayNode: public Node { 173 public: EncodeISOArrayNode(Node * control,Node * arymem,Node * s1,Node * s2,Node * c)174 EncodeISOArrayNode(Node* control, Node* arymem, Node* s1, Node* s2, Node* c): Node(control, arymem, s1, s2, c) {}; 175 virtual int Opcode() const; depends_only_on_test() const176 virtual bool depends_only_on_test() const { return false; } bottom_type() const177 virtual const Type* bottom_type() const { return TypeInt::INT; } adr_type() const178 virtual const TypePtr* adr_type() const { return TypePtr::BOTTOM; } 179 virtual uint match_edge(uint idx) const; ideal_reg() const180 virtual uint ideal_reg() const { return Op_RegI; } 181 virtual Node* Ideal(PhaseGVN* phase, bool can_reshape); 182 virtual const Type* Value(PhaseGVN* phase) const; 183 }; 184 185 //-------------------------------DigitNode---------------------------------------- 186 class DigitNode : public Node { 187 public: DigitNode(Node * control,Node * in1)188 DigitNode(Node* control, Node *in1) : Node(control, in1) {} 189 virtual int Opcode() const; bottom_type() const190 const Type* bottom_type() const { return TypeInt::BOOL; } ideal_reg() const191 virtual uint ideal_reg() const { return Op_RegI; } 192 }; 193 194 //------------------------------LowerCaseNode------------------------------------ 195 class LowerCaseNode : public Node { 196 public: LowerCaseNode(Node * control,Node * in1)197 LowerCaseNode(Node* control, Node *in1) : Node(control, in1) {} 198 virtual int Opcode() const; bottom_type() const199 const Type* bottom_type() const { return TypeInt::BOOL; } ideal_reg() const200 virtual uint ideal_reg() const { return Op_RegI; } 201 }; 202 203 //------------------------------UpperCaseNode------------------------------------ 204 class UpperCaseNode : public Node { 205 public: UpperCaseNode(Node * control,Node * in1)206 UpperCaseNode(Node* control, Node *in1) : Node(control, in1) {} 207 virtual int Opcode() const; bottom_type() const208 const Type* bottom_type() const { return TypeInt::BOOL; } ideal_reg() const209 virtual uint ideal_reg() const { return Op_RegI; } 210 }; 211 212 //------------------------------WhitespaceCode----------------------------------- 213 class WhitespaceNode : public Node { 214 public: WhitespaceNode(Node * control,Node * in1)215 WhitespaceNode(Node* control, Node *in1) : Node(control, in1) {} 216 virtual int Opcode() const; bottom_type() const217 const Type* bottom_type() const { return TypeInt::BOOL; } ideal_reg() const218 virtual uint ideal_reg() const { return Op_RegI; } 219 }; 220 221 //------------------------------CopySign----------------------------------------- 222 class CopySignDNode : public Node { 223 protected: CopySignDNode(Node * in1,Node * in2,Node * in3)224 CopySignDNode(Node* in1, Node* in2, Node* in3) : Node(0, in1, in2, in3) {} 225 public: 226 static CopySignDNode* make(PhaseGVN& gvn, Node* in1, Node* in2); 227 virtual int Opcode() const; bottom_type() const228 const Type* bottom_type() const { return TypeLong::DOUBLE; } ideal_reg() const229 virtual uint ideal_reg() const { return Op_RegD; } 230 }; 231 232 class CopySignFNode : public Node { 233 public: CopySignFNode(Node * in1,Node * in2)234 CopySignFNode(Node* in1, Node* in2) : Node(0, in1, in2) {} 235 virtual int Opcode() const; bottom_type() const236 const Type* bottom_type() const { return TypeLong::FLOAT; } ideal_reg() const237 virtual uint ideal_reg() const { return Op_RegF; } 238 }; 239 240 //------------------------------Signum------------------------------------------- 241 class SignumDNode : public Node { 242 protected: SignumDNode(Node * in1,Node * in2,Node * in3)243 SignumDNode(Node* in1, Node* in2, Node* in3) : Node(0, in1, in2, in3) {} 244 public: 245 static SignumDNode* make(PhaseGVN& gvn, Node* in); 246 virtual int Opcode() const; bottom_type() const247 virtual const Type* bottom_type() const { return Type::DOUBLE; } ideal_reg() const248 virtual uint ideal_reg() const { return Op_RegD; } 249 }; 250 251 class SignumFNode : public Node { 252 protected: SignumFNode(Node * in1,Node * in2,Node * in3)253 SignumFNode(Node* in1, Node* in2, Node* in3) : Node(0, in1, in2, in3) {} 254 public: 255 static SignumFNode* make(PhaseGVN& gvn, Node* in); 256 virtual int Opcode() const; bottom_type() const257 virtual const Type* bottom_type() const { return Type::FLOAT; } ideal_reg() const258 virtual uint ideal_reg() const { return Op_RegF; } 259 }; 260 261 #endif // SHARE_OPTO_INTRINSICNODE_HPP 262