Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
PojavLauncherTeam
GitHub Repository: PojavLauncherTeam/mobile
Path: blob/master/src/hotspot/share/opto/addnode.hpp
40930 views
1
/*
2
* Copyright (c) 1997, 2021, 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_ADDNODE_HPP
26
#define SHARE_OPTO_ADDNODE_HPP
27
28
#include "opto/node.hpp"
29
#include "opto/opcodes.hpp"
30
#include "opto/type.hpp"
31
32
// Portions of code courtesy of Clifford Click
33
34
class PhaseTransform;
35
36
//------------------------------AddNode----------------------------------------
37
// Classic Add functionality. This covers all the usual 'add' behaviors for
38
// an algebraic ring. Add-integer, add-float, add-double, and binary-or are
39
// all inherited from this class. The various identity values are supplied
40
// by virtual functions.
41
class AddNode : public Node {
42
virtual uint hash() const;
43
public:
44
AddNode( Node *in1, Node *in2 ) : Node(0,in1,in2) {
45
init_class_id(Class_Add);
46
}
47
48
// Handle algebraic identities here. If we have an identity, return the Node
49
// we are equivalent to. We look for "add of zero" as an identity.
50
virtual Node* Identity(PhaseGVN* phase);
51
52
// We also canonicalize the Node, moving constants to the right input,
53
// and flatten expressions (so that 1+x+2 becomes x+3).
54
virtual Node *Ideal(PhaseGVN *phase, bool can_reshape);
55
56
// Compute a new Type for this node. Basically we just do the pre-check,
57
// then call the virtual add() to set the type.
58
virtual const Type* Value(PhaseGVN* phase) const;
59
60
// Check if this addition involves the additive identity
61
virtual const Type *add_of_identity( const Type *t1, const Type *t2 ) const;
62
63
// Supplied function returns the sum of the inputs.
64
// This also type-checks the inputs for sanity. Guaranteed never to
65
// be passed a TOP or BOTTOM type, these are filtered out by a pre-check.
66
virtual const Type *add_ring( const Type *, const Type * ) const = 0;
67
68
// Supplied function to return the additive identity type
69
virtual const Type *add_id() const = 0;
70
71
// Supplied function to return the additive opcode
72
virtual int max_opcode() const = 0;
73
74
// Supplied function to return the multiplicative opcode
75
virtual int min_opcode() const = 0;
76
77
virtual bool operates_on(BasicType bt, bool signed_int) const {
78
assert(bt == T_INT || bt == T_LONG, "unsupported");
79
return false;
80
}
81
static AddNode* make(Node* in1, Node* in2, BasicType bt);
82
};
83
84
//------------------------------AddINode---------------------------------------
85
// Add 2 integers
86
class AddINode : public AddNode {
87
public:
88
AddINode( Node *in1, Node *in2 ) : AddNode(in1,in2) {}
89
virtual int Opcode() const;
90
virtual const Type *add_ring( const Type *, const Type * ) const;
91
virtual const Type *add_id() const { return TypeInt::ZERO; }
92
virtual const Type *bottom_type() const { return TypeInt::INT; }
93
int max_opcode() const { return Op_MaxI; }
94
int min_opcode() const { return Op_MinI; }
95
virtual Node *Ideal(PhaseGVN *phase, bool can_reshape);
96
virtual Node* Identity(PhaseGVN* phase);
97
virtual bool operates_on(BasicType bt, bool signed_int) const {
98
assert(bt == T_INT || bt == T_LONG, "unsupported");
99
return bt == T_INT;
100
}
101
virtual uint ideal_reg() const { return Op_RegI; }
102
};
103
104
//------------------------------AddLNode---------------------------------------
105
// Add 2 longs
106
class AddLNode : public AddNode {
107
public:
108
AddLNode( Node *in1, Node *in2 ) : AddNode(in1,in2) {}
109
virtual int Opcode() const;
110
virtual const Type *add_ring( const Type *, const Type * ) const;
111
virtual const Type *add_id() const { return TypeLong::ZERO; }
112
virtual const Type *bottom_type() const { return TypeLong::LONG; }
113
int max_opcode() const { return Op_MaxL; }
114
int min_opcode() const { return Op_MinL; }
115
virtual Node *Ideal(PhaseGVN *phase, bool can_reshape);
116
virtual Node* Identity(PhaseGVN* phase);
117
virtual bool operates_on(BasicType bt, bool signed_int) const {
118
assert(bt == T_INT || bt == T_LONG, "unsupported");
119
return bt == T_LONG;
120
}
121
virtual uint ideal_reg() const { return Op_RegL; }
122
};
123
124
//------------------------------AddFNode---------------------------------------
125
// Add 2 floats
126
class AddFNode : public AddNode {
127
public:
128
AddFNode( Node *in1, Node *in2 ) : AddNode(in1,in2) {}
129
virtual int Opcode() const;
130
virtual Node *Ideal(PhaseGVN *phase, bool can_reshape);
131
virtual const Type *add_of_identity( const Type *t1, const Type *t2 ) const;
132
virtual const Type *add_ring( const Type *, const Type * ) const;
133
virtual const Type *add_id() const { return TypeF::ZERO; }
134
virtual const Type *bottom_type() const { return Type::FLOAT; }
135
int max_opcode() const { return Op_MaxF; }
136
int min_opcode() const { return Op_MinF; }
137
virtual Node* Identity(PhaseGVN* phase) { return this; }
138
virtual uint ideal_reg() const { return Op_RegF; }
139
};
140
141
//------------------------------AddDNode---------------------------------------
142
// Add 2 doubles
143
class AddDNode : public AddNode {
144
public:
145
AddDNode( Node *in1, Node *in2 ) : AddNode(in1,in2) {}
146
virtual int Opcode() const;
147
virtual Node *Ideal(PhaseGVN *phase, bool can_reshape);
148
virtual const Type *add_of_identity( const Type *t1, const Type *t2 ) const;
149
virtual const Type *add_ring( const Type *, const Type * ) const;
150
virtual const Type *add_id() const { return TypeD::ZERO; }
151
virtual const Type *bottom_type() const { return Type::DOUBLE; }
152
int max_opcode() const { return Op_MaxD; }
153
int min_opcode() const { return Op_MinD; }
154
virtual Node* Identity(PhaseGVN* phase) { return this; }
155
virtual uint ideal_reg() const { return Op_RegD; }
156
};
157
158
//------------------------------AddPNode---------------------------------------
159
// Add pointer plus integer to get pointer. NOT commutative, really.
160
// So not really an AddNode. Lives here, because people associate it with
161
// an add.
162
class AddPNode : public Node {
163
public:
164
enum { Control, // When is it safe to do this add?
165
Base, // Base oop, for GC purposes
166
Address, // Actually address, derived from base
167
Offset } ; // Offset added to address
168
AddPNode( Node *base, Node *ptr, Node *off ) : Node(0,base,ptr,off) {
169
init_class_id(Class_AddP);
170
}
171
virtual int Opcode() const;
172
virtual Node* Identity(PhaseGVN* phase);
173
virtual Node *Ideal(PhaseGVN *phase, bool can_reshape);
174
virtual const Type* Value(PhaseGVN* phase) const;
175
virtual const Type *bottom_type() const;
176
virtual uint ideal_reg() const { return Op_RegP; }
177
Node *base_node() { assert( req() > Base, "Missing base"); return in(Base); }
178
static Node* Ideal_base_and_offset(Node* ptr, PhaseTransform* phase,
179
// second return value:
180
intptr_t& offset);
181
182
// Collect the AddP offset values into the elements array, giving up
183
// if there are more than length.
184
int unpack_offsets(Node* elements[], int length);
185
186
// Do not match base-ptr edge
187
virtual uint match_edge(uint idx) const;
188
};
189
190
//------------------------------OrINode----------------------------------------
191
// Logically OR 2 integers. Included with the ADD nodes because it inherits
192
// all the behavior of addition on a ring.
193
class OrINode : public AddNode {
194
public:
195
OrINode( Node *in1, Node *in2 ) : AddNode(in1,in2) {}
196
virtual int Opcode() const;
197
virtual const Type *add_ring( const Type *, const Type * ) const;
198
virtual const Type *add_id() const { return TypeInt::ZERO; }
199
virtual const Type *bottom_type() const { return TypeInt::INT; }
200
int max_opcode() const { return Op_MaxI; }
201
int min_opcode() const { return Op_MinI; }
202
virtual Node* Identity(PhaseGVN* phase);
203
virtual uint ideal_reg() const { return Op_RegI; }
204
virtual Node *Ideal(PhaseGVN *phase, bool can_reshape);
205
};
206
207
//------------------------------OrLNode----------------------------------------
208
// Logically OR 2 longs. Included with the ADD nodes because it inherits
209
// all the behavior of addition on a ring.
210
class OrLNode : public AddNode {
211
public:
212
OrLNode( Node *in1, Node *in2 ) : AddNode(in1,in2) {}
213
virtual int Opcode() const;
214
virtual const Type *add_ring( const Type *, const Type * ) const;
215
virtual const Type *add_id() const { return TypeLong::ZERO; }
216
virtual const Type *bottom_type() const { return TypeLong::LONG; }
217
int max_opcode() const { return Op_MaxL; }
218
int min_opcode() const { return Op_MinL; }
219
virtual Node* Identity(PhaseGVN* phase);
220
virtual uint ideal_reg() const { return Op_RegL; }
221
virtual Node *Ideal(PhaseGVN *phase, bool can_reshape);
222
};
223
224
//------------------------------XorINode---------------------------------------
225
// XOR'ing 2 integers
226
class XorINode : public AddNode {
227
public:
228
XorINode( Node *in1, Node *in2 ) : AddNode(in1,in2) {}
229
virtual int Opcode() const;
230
virtual const Type *add_ring( const Type *, const Type * ) const;
231
virtual const Type *add_id() const { return TypeInt::ZERO; }
232
virtual const Type *bottom_type() const { return TypeInt::INT; }
233
int max_opcode() const { return Op_MaxI; }
234
int min_opcode() const { return Op_MinI; }
235
virtual const Type *Value(PhaseGVN *phase) const;
236
virtual uint ideal_reg() const { return Op_RegI; }
237
};
238
239
//------------------------------XorINode---------------------------------------
240
// XOR'ing 2 longs
241
class XorLNode : public AddNode {
242
public:
243
XorLNode( Node *in1, Node *in2 ) : AddNode(in1,in2) {}
244
virtual int Opcode() const;
245
virtual const Type *add_ring( const Type *, const Type * ) const;
246
virtual const Type *add_id() const { return TypeLong::ZERO; }
247
virtual const Type *bottom_type() const { return TypeLong::LONG; }
248
int max_opcode() const { return Op_MaxL; }
249
int min_opcode() const { return Op_MinL; }
250
virtual const Type *Value(PhaseGVN *phase) const;
251
virtual uint ideal_reg() const { return Op_RegL; }
252
};
253
254
//------------------------------MaxNode----------------------------------------
255
// Max (or min) of 2 values. Included with the ADD nodes because it inherits
256
// all the behavior of addition on a ring. Only new thing is that we allow
257
// 2 equal inputs to be equal.
258
class MaxNode : public AddNode {
259
private:
260
static Node* build_min_max(Node* a, Node* b, bool is_max, bool is_unsigned, const Type* t, PhaseGVN& gvn);
261
static Node* build_min_max_diff_with_zero(Node* a, Node* b, bool is_max, const Type* t, PhaseGVN& gvn);
262
263
public:
264
MaxNode( Node *in1, Node *in2 ) : AddNode(in1,in2) {}
265
virtual int Opcode() const = 0;
266
virtual int max_opcode() const = 0;
267
virtual int min_opcode() const = 0;
268
269
static Node* unsigned_max(Node* a, Node* b, const Type* t, PhaseGVN& gvn) {
270
return build_min_max(a, b, true, true, t, gvn);
271
}
272
273
static Node* unsigned_min(Node* a, Node* b, const Type* t, PhaseGVN& gvn) {
274
return build_min_max(a, b, false, true, t, gvn);
275
}
276
277
static Node* signed_max(Node* a, Node* b, const Type* t, PhaseGVN& gvn) {
278
return build_min_max(a, b, true, false, t, gvn);
279
}
280
281
static Node* signed_min(Node* a, Node* b, const Type* t, PhaseGVN& gvn) {
282
return build_min_max(a, b, false, false, t, gvn);
283
}
284
285
// max(a-b, 0)
286
static Node* max_diff_with_zero(Node* a, Node* b, const Type* t, PhaseGVN& gvn) {
287
return build_min_max_diff_with_zero(a, b, true, t, gvn);
288
}
289
290
// min(a-b, 0)
291
static Node* min_diff_with_zero(Node* a, Node* b, const Type* t, PhaseGVN& gvn) {
292
return build_min_max_diff_with_zero(a, b, false, t, gvn);
293
}
294
};
295
296
//------------------------------MaxINode---------------------------------------
297
// Maximum of 2 integers. Included with the ADD nodes because it inherits
298
// all the behavior of addition on a ring.
299
class MaxINode : public MaxNode {
300
public:
301
MaxINode( Node *in1, Node *in2 ) : MaxNode(in1,in2) {}
302
virtual int Opcode() const;
303
virtual const Type *add_ring( const Type *, const Type * ) const;
304
virtual const Type *add_id() const { return TypeInt::make(min_jint); }
305
virtual const Type *bottom_type() const { return TypeInt::INT; }
306
virtual uint ideal_reg() const { return Op_RegI; }
307
int max_opcode() const { return Op_MaxI; }
308
int min_opcode() const { return Op_MinI; }
309
};
310
311
//------------------------------MinINode---------------------------------------
312
// MINimum of 2 integers. Included with the ADD nodes because it inherits
313
// all the behavior of addition on a ring.
314
class MinINode : public MaxNode {
315
public:
316
MinINode( Node *in1, Node *in2 ) : MaxNode(in1,in2) {}
317
virtual int Opcode() const;
318
virtual const Type *add_ring( const Type *, const Type * ) const;
319
virtual const Type *add_id() const { return TypeInt::make(max_jint); }
320
virtual const Type *bottom_type() const { return TypeInt::INT; }
321
virtual uint ideal_reg() const { return Op_RegI; }
322
int max_opcode() const { return Op_MaxI; }
323
int min_opcode() const { return Op_MinI; }
324
virtual Node *Ideal(PhaseGVN *phase, bool can_reshape);
325
};
326
327
//------------------------------MaxLNode---------------------------------------
328
// MAXimum of 2 longs.
329
class MaxLNode : public MaxNode {
330
public:
331
MaxLNode(Node *in1, Node *in2) : MaxNode(in1, in2) {}
332
virtual int Opcode() const;
333
virtual const Type *add_ring(const Type*, const Type*) const { return TypeLong::LONG; }
334
virtual const Type *add_id() const { return TypeLong::make(min_jlong); }
335
virtual const Type *bottom_type() const { return TypeLong::LONG; }
336
virtual uint ideal_reg() const { return Op_RegL; }
337
int max_opcode() const { return Op_MaxL; }
338
int min_opcode() const { return Op_MinL; }
339
};
340
341
//------------------------------MinLNode---------------------------------------
342
// MINimum of 2 longs.
343
class MinLNode : public MaxNode {
344
public:
345
MinLNode(Node *in1, Node *in2) : MaxNode(in1, in2) {}
346
virtual int Opcode() const;
347
virtual const Type *add_ring(const Type*, const Type*) const { return TypeLong::LONG; }
348
virtual const Type *add_id() const { return TypeLong::make(max_jlong); }
349
virtual const Type *bottom_type() const { return TypeLong::LONG; }
350
virtual uint ideal_reg() const { return Op_RegL; }
351
int max_opcode() const { return Op_MaxL; }
352
int min_opcode() const { return Op_MinL; }
353
};
354
355
//------------------------------MaxFNode---------------------------------------
356
// Maximum of 2 floats.
357
class MaxFNode : public MaxNode {
358
public:
359
MaxFNode(Node *in1, Node *in2) : MaxNode(in1, in2) {}
360
virtual int Opcode() const;
361
virtual const Type *add_ring(const Type*, const Type*) const;
362
virtual const Type *add_id() const { return TypeF::NEG_INF; }
363
virtual const Type *bottom_type() const { return Type::FLOAT; }
364
virtual uint ideal_reg() const { return Op_RegF; }
365
int max_opcode() const { return Op_MaxF; }
366
int min_opcode() const { return Op_MinF; }
367
};
368
369
//------------------------------MinFNode---------------------------------------
370
// Minimum of 2 floats.
371
class MinFNode : public MaxNode {
372
public:
373
MinFNode(Node *in1, Node *in2) : MaxNode(in1, in2) {}
374
virtual int Opcode() const;
375
virtual const Type *add_ring(const Type*, const Type*) const;
376
virtual const Type *add_id() const { return TypeF::POS_INF; }
377
virtual const Type *bottom_type() const { return Type::FLOAT; }
378
virtual uint ideal_reg() const { return Op_RegF; }
379
int max_opcode() const { return Op_MaxF; }
380
int min_opcode() const { return Op_MinF; }
381
};
382
383
//------------------------------MaxDNode---------------------------------------
384
// Maximum of 2 doubles.
385
class MaxDNode : public MaxNode {
386
public:
387
MaxDNode(Node *in1, Node *in2) : MaxNode(in1, in2) {}
388
virtual int Opcode() const;
389
virtual const Type *add_ring(const Type*, const Type*) const;
390
virtual const Type *add_id() const { return TypeD::NEG_INF; }
391
virtual const Type *bottom_type() const { return Type::DOUBLE; }
392
virtual uint ideal_reg() const { return Op_RegD; }
393
int max_opcode() const { return Op_MaxD; }
394
int min_opcode() const { return Op_MinD; }
395
};
396
397
//------------------------------MinDNode---------------------------------------
398
// Minimum of 2 doubles.
399
class MinDNode : public MaxNode {
400
public:
401
MinDNode(Node *in1, Node *in2) : MaxNode(in1, in2) {}
402
virtual int Opcode() const;
403
virtual const Type *add_ring(const Type*, const Type*) const;
404
virtual const Type *add_id() const { return TypeD::POS_INF; }
405
virtual const Type *bottom_type() const { return Type::DOUBLE; }
406
virtual uint ideal_reg() const { return Op_RegD; }
407
int max_opcode() const { return Op_MaxD; }
408
int min_opcode() const { return Op_MinD; }
409
};
410
411
#endif // SHARE_OPTO_ADDNODE_HPP
412
413