-
Notifications
You must be signed in to change notification settings - Fork 397
/
Copy pathOMRNode.hpp
2082 lines (1628 loc) · 80.7 KB
/
OMRNode.hpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
/*******************************************************************************
* Copyright (c) 2000, 2018 IBM Corp. and others
*
* This program and the accompanying materials are made available under
* the terms of the Eclipse Public License 2.0 which accompanies this
* distribution and is available at http://eclipse.org/legal/epl-2.0
* or the Apache License, Version 2.0 which accompanies this distribution
* and is available at https://www.apache.org/licenses/LICENSE-2.0.
*
* This Source Code may also be made available under the following Secondary
* Licenses when the conditions for such availability set forth in the
* Eclipse Public License, v. 2.0 are satisfied: GNU General Public License,
* version 2 with the GNU Classpath Exception [1] and GNU General Public
* License, version 2 with the OpenJDK Assembly Exception [2].
*
* [1] https://www.gnu.org/software/classpath/license.html
* [2] http://openjdk.java.net/legal/assembly-exception.html
*
* SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 OR GPL-2.0 WITH Classpath-exception-2.0 OR LicenseRef-GPL-2.0 WITH Assembly-exception
*******************************************************************************/
#ifndef OMR_NODE_INCL
#define OMR_NODE_INCL
/*
* The following #define and typedef must appear before any #includes in this file
*/
#ifndef OMR_NODE_CONNECTOR
#define OMR_NODE_CONNECTOR
namespace OMR { class Node; }
namespace OMR { typedef OMR::Node NodeConnector; }
#endif
#include <limits.h> // for UINT_MAX, USHRT_MAX
#include <stddef.h> // for size_t
#include <stdint.h> // for uint16_t, int32_t, int64_t
#include <string.h> // for memset
#include "codegen/RegisterConstants.hpp" // for TR_GlobalRegisterNumber
#include "cs2/hashtab.h" // for HashTable
#include "env/TRMemory.hpp" // for TR_ArenaAllocator
#include "il/DataTypes.hpp" // for DataTypes, etc
#include "il/ILOpCodes.hpp" // for ILOpCodes
#include "il/ILOps.hpp" // for ILOpCode
#include "il/NodeUnions.hpp" // for UnionedWithChildren
#include "infra/Annotations.hpp" // for OMR_EXTENSIBLE
#include "infra/Assert.hpp" // for TR_ASSERT
#include "infra/Flags.hpp" // for flags32_t
#include "infra/TRlist.hpp" // for TR::list
class TR_BitVector;
class TR_Debug;
class TR_DebugExt;
class TR_NodeKillAliasSetInterface;
class TR_NodeUseAliasSetInterface;
class TR_OpaqueClassBlock;
class TR_OpaqueMethodBlock;
class TR_ResolvedMethod;
namespace TR { class AutomaticSymbol; }
namespace TR { class Block; }
namespace TR { class CodeGenerator; }
namespace TR { class Compilation; }
namespace TR { class LabelSymbol; }
namespace TR { class Node; }
namespace TR { class NodePool; }
namespace TR { class Register; }
namespace TR { class Symbol; }
namespace TR { class SymbolReference; }
namespace TR { class TreeTop; }
namespace TR { class NodeExtension; }
template <class T> class List;
#define NUM_DEFAULT_CHILDREN 2
/// Node counts
///
typedef uint32_t ncount_t;
#define MAX_NODE_COUNT UINT_MAX
/// Node reference counts
///
typedef uint32_t rcount_t;
#define MAX_RCOUNT UINT_MAX
/// Node local indexes
///
typedef uint32_t scount_t;
#define MAX_SCOUNT UINT_MAX
#define SCOUNT_HIGH_BIT 0x80000000
#define NULL_USEDEF_SYMBOL_INDEX 0xFFFF //TODO: should be 0xFFFF until we change the date type of _localIndex in Symbol.hpp
/// Visit counts
///
/// \def MAX_VCOUNT: max # visit counts that can be consumed before
/// risking incorrect behaviour (ie. hard limit)
/// \def HIGH_VISIT_COUNT: recommended max # visit counts between reset operations (ie. soft limit)
/// \def VCOUNT_HEADROOM: max # visit counts that can be safely consumed
/// between HIGH_VISIT_COUNT checks
///
#define MAX_VCOUNT (USHRT_MAX)
#define VCOUNT_HEADROOM (48000)
#define HIGH_VISIT_COUNT (MAX_VCOUNT-VCOUNT_HEADROOM)
typedef uint16_t vcount_t;
#define TR_MAX_CHARS_FOR_HASH 32
#define TR_DECIMAL_HASH 7
typedef enum
{
NoPrefetch = 0,
PrefetchLoad = 1,
PrefetchLoadL1 = 2,
PrefetchLoadL2 = 3,
PrefetchLoadL3 = 4,
PrefetchLoadNonTemporal = 5,
PrefetchStore = 101,
PrefetchStoreConditional = 102,
PrefetchStoreNonTemporal = 103,
ReleaseStore = 501, ///< Retain for Load
ReleaseAll = 502 ///< Release from cache
} PrefetchType;
namespace OMR
{
class OMR_EXTENSIBLE Node
{
// Forward declarations
public:
class ChildIterator;
private:
/// This operator is declared private and not actually defined;
/// this is a C++ convention to avoid accidental assignment between instances of this class
/// Once we have universal C++11 support, should be changed to use "= delete"
Node & operator=(const TR::Node &);
/**
* Protected constructors and helpers
*/
protected:
Node(TR::Node *originatingByteCodeNode, TR::ILOpCodes op, uint16_t numChildren);
Node(TR::Node *from, uint16_t numChildren = 0);
static void copyValidProperties(TR::Node *fromNode, TR::Node *toNode);
static TR::Node *createInternal(TR::Node *originatingByteCodeNode, TR::ILOpCodes op, uint16_t numChildren, TR::Node *originalNode = 0);
/**
* Public constructors and helpers
*/
public:
inline TR::Node * self();
Node();
~Node();
void * operator new(size_t s, TR::NodePool & nodePool);
void * operator new(size_t s, void *ptr) throw();
static TR::Node *copy(TR::Node *);
static TR::Node *copy(TR::Node *, int32_t numChildren);
static TR::Node *recreate(TR::Node *originalNode, TR::ILOpCodes op);
static TR::Node *recreateWithSymRef(TR::Node *originalNode, TR::ILOpCodes op, TR::SymbolReference *newSymRef);
// create methods from everywhere other than the ilGenerator need
// to pass in a TR::Node pointer from which the byte code information will be copied
//
static TR::Node *create(TR::Node *originatingByteCodeNode, TR::ILOpCodes op, uint16_t numChildren = 0);
static TR::Node *create(TR::Node *originatingByteCodeNode, TR::ILOpCodes op, uint16_t numChildren, TR::Node* first);
static TR::Node *create(TR::Node *originatingByteCodeNode, TR::ILOpCodes op, uint16_t numChildren, TR::Node* first, TR::Node* second);
static TR::Node *create(TR::Node *originatingByteCodeNode, TR::ILOpCodes op, uint16_t numChildren, TR::TreeTop * dest);
static TR::Node *create(TR::Node *originatingByteCodeNode, TR::ILOpCodes op, uint16_t numChildren, int32_t intValue, TR::TreeTop * dest = 0);
static TR::Node *createWithSymRef(TR::Node *originatingByteCodeNode, TR::ILOpCodes op, uint16_t numChildren, TR::SymbolReference * symRef);
static TR::Node *createWithSymRef(TR::Node *originatingByteCodeNode, TR::ILOpCodes op, uint16_t numChildren, TR::Node* first, TR::SymbolReference * symRef);
static TR::Node *createOnStack(TR::Node *originatingByteCodeNode, TR::ILOpCodes op, uint16_t numChildren = 0);
static TR::Node *recreateWithoutProperties(TR::Node *originalNode, TR::ILOpCodes op, uint16_t numChildren = 0, TR::SymbolReference * symRef = 0);
static TR::Node *create(TR::ILOpCodes op, uint16_t numChildren = 0);
static TR::Node *create(TR::ILOpCodes op, uint16_t numChildren, TR::TreeTop * dest);
static TR::Node *create(TR::ILOpCodes op, uint16_t numChildren, int32_t intValue, TR::TreeTop * dest = 0);
static TR::Node *createWithSymRef(TR::ILOpCodes op, uint16_t numChildren, TR::Node *first, uintptr_t extraChildren, TR::SymbolReference *symRef);
static TR::Node *createWithSymRef(TR::ILOpCodes op, uint16_t numChildren, TR::Node *first, TR::Node *second, uintptr_t extraChildren, TR::SymbolReference *symRef);
static TR::Node *createWithSymRef(TR::ILOpCodes op, uint16_t numChildren, TR::SymbolReference * symRef);
static TR::Node *createWithSymRef(TR::ILOpCodes op, uint16_t numChildren, TR::SymbolReference * symRef, uintptr_t extraChildrenForFixup);
#if defined(_MSC_VER) || defined(LINUXPPC)
private:
static TR::Node *recreateWithoutSymRef_va_args(TR::Node *originalNode, TR::ILOpCodes op, uint16_t numChildren, uint16_t numChildArgs, va_list &args);
static TR::Node *createWithoutSymRef(TR::ILOpCodes op, uint16_t numChildren, uint16_t numChildArgs, ...);
static TR::Node *recreateWithoutSymRef(TR::Node *originalNode, TR::ILOpCodes op, uint16_t numChildren, uint16_t numChildArgs, ...);
static TR::Node *recreateWithSymRefWithoutProperties(TR::Node *originalNode, TR::ILOpCodes op, uint16_t numChildren, uint16_t numChildArgs, ...);
public:
// only this variadic method is part of the external interface
static TR::Node *createWithSymRef(TR::ILOpCodes op, uint16_t numChildren, uint16_t numChildArgs, ...);
#else // XLC (but not on LINUX PPC) and GCC support the C++11 feature, variadic templates
private:
uint16_t addChildrenAndSymRef(uint16_t lastIndex, TR::SymbolReference *symRef);
uint16_t addChildrenAndSymRef(uint16_t childIndex, TR::Node *child);
template <class...ChildrenAndSymRefType>
uint16_t addChildrenAndSymRef(uint16_t childIndex, TR::Node *child, ChildrenAndSymRefType... childrenAndSymRef);
template <class...ChildrenAndSymRefType>
static TR::Node *recreateWithSymRefWithoutProperties(TR::Node *originalNode, TR::ILOpCodes op, uint16_t numChildren, uint16_t numChildArgs, TR::Node *first, ChildrenAndSymRefType... childrenAndSymRef);
template <class...Children>
static TR::Node *recreateWithoutSymRef(TR::Node *originalNode, TR::ILOpCodes op, uint16_t numChildren, uint16_t numChildArgs, TR::Node *first, Children... children);
template <class...ChildrenAndSymRefType>
static TR::Node *createWithSymRefInternal(TR::ILOpCodes op, uint16_t numChildren, uint16_t numChildArgs, TR::Node *first, ChildrenAndSymRefType... childrenAndSymRef);
template <class...Children>
static TR::Node *createWithoutSymRef(TR::ILOpCodes op, uint16_t numChildren, uint16_t numChildArgs, TR::Node *first, Children... children);
public:
// only this variadic method is part of the external interface
template <class...ChildrenAndSymRefType>
static TR::Node *createWithSymRef(TR::ILOpCodes op, uint16_t numChildren, uint16_t numChildArgs, TR::Node *first, ChildrenAndSymRefType... childrenAndSymRef);
#endif
static TR::Node *create(TR::ILOpCodes op, uint16_t numChildren, TR::Node *first);
static TR::Node *create(TR::ILOpCodes op, uint16_t numChildren, TR::Node *first, TR::Node *second);
static TR::Node *create(TR::ILOpCodes op, uint16_t numChildren, TR::Node *first, TR::Node *second, TR::Node *third);
static TR::Node *create(TR::ILOpCodes op, uint16_t numChildren, TR::Node *first, TR::Node *second, TR::Node *third, TR::Node *fourth);
static TR::Node *create(TR::ILOpCodes op, uint16_t numChildren, TR::Node *first, TR::Node *second, TR::Node *third, TR::Node *fourth, TR::Node *fifth);
static TR::Node *create(TR::ILOpCodes op, uint16_t numChildren, TR::Node *first, TR::Node *second, TR::Node *third, TR::Node *fourth, TR::Node *fifth, TR::Node *sixth);
static TR::Node *create(TR::ILOpCodes op, uint16_t numChildren, TR::Node *first, TR::Node *second, TR::Node *third, TR::Node *fourth, TR::Node *fifth, TR::Node *sixth, TR::Node *seventh);
static TR::Node *create(TR::ILOpCodes op, uint16_t numChildren, TR::Node *first, TR::Node *second, TR::Node *third, TR::Node *fourth, TR::Node *fifth, TR::Node *sixth, TR::Node *seventh, TR::Node *eighth);
static TR::Node *recreateWithoutProperties(TR::Node *originalNode, TR::ILOpCodes op, uint16_t numChildren, TR::Node *first);
static TR::Node *recreateWithoutProperties(TR::Node *originalNode, TR::ILOpCodes op, uint16_t numChildren, TR::Node *first, TR::Node *second);
static TR::Node *recreateWithoutProperties(TR::Node *originalNode, TR::ILOpCodes op, uint16_t numChildren, TR::Node *first, TR::Node *second, TR::Node *third);
static TR::Node *recreateWithoutProperties(TR::Node *originalNode, TR::ILOpCodes op, uint16_t numChildren, TR::Node *first, TR::Node *second, TR::Node *third, TR::Node *fourth);
static TR::Node *recreateWithoutProperties(TR::Node *originalNode, TR::ILOpCodes op, uint16_t numChildren, TR::Node *first, TR::Node *second, TR::Node *third, TR::Node *fourth, TR::Node *fifth);
static TR::Node *recreateWithoutProperties(TR::Node *originalNode, TR::ILOpCodes op, uint16_t numChildren, TR::Node *first, TR::Node *second, TR::Node *third, TR::Node *fourth, TR::Node *fifth, TR::Node *sixth);
static TR::Node *recreateWithoutProperties(TR::Node *originalNode, TR::ILOpCodes op, uint16_t numChildren, TR::Node *first, TR::Node *second, TR::Node *third, TR::Node *fourth, TR::Node *fifth, TR::Node *sixth, TR::Node *seventh);
static TR::Node *recreateWithoutProperties(TR::Node *originalNode, TR::ILOpCodes op, uint16_t numChildren, TR::Node *first, TR::Node *second, TR::Node *third, TR::Node *fourth, TR::Node *fifth, TR::Node *sixth, TR::Node *seventh, TR::Node *eighth);
static TR::Node *recreateWithoutProperties(TR::Node *originalNode, TR::ILOpCodes op, uint16_t numChildren, TR::Node *first, TR::SymbolReference * symRef);
static TR::Node *recreateWithoutProperties(TR::Node *originalNode, TR::ILOpCodes op, uint16_t numChildren, TR::Node *first, TR::Node *second, TR::SymbolReference * symRef);
static TR::Node *recreateWithoutProperties(TR::Node *originalNode, TR::ILOpCodes op, uint16_t numChildren, TR::Node *first, TR::Node *second, TR::Node *third, TR::SymbolReference * symRef);
static TR::Node *recreateWithoutProperties(TR::Node *originalNode, TR::ILOpCodes op, uint16_t numChildren, TR::Node *first, TR::Node *second, TR::Node *third, TR::Node *fourth, TR::SymbolReference * symRef);
static TR::Node *recreateWithoutProperties(TR::Node *originalNode, TR::ILOpCodes op, uint16_t numChildren, TR::Node *first, TR::Node *second, TR::Node *third, TR::Node *fourth, TR::Node *fifth, TR::SymbolReference * symRef);
static TR::Node *recreateWithoutProperties(TR::Node *originalNode, TR::ILOpCodes op, uint16_t numChildren, TR::Node *first, TR::Node *second, TR::Node *third, TR::Node *fourth, TR::Node *fifth, TR::Node *sixth, TR::SymbolReference * symRef);
static TR::Node *recreateWithoutProperties(TR::Node *originalNode, TR::ILOpCodes op, uint16_t numChildren, TR::Node *first, TR::Node *second, TR::Node *third, TR::Node *fourth, TR::Node *fifth, TR::Node *sixth, TR::Node *seventh, TR::SymbolReference * symRef);
static TR::Node *recreateWithoutProperties(TR::Node *originalNode, TR::ILOpCodes op, uint16_t numChildren, TR::Node *first, TR::Node *second, TR::Node *third, TR::Node *fourth, TR::Node *fifth, TR::Node *sixth, TR::Node *seventh, TR::Node *eighth, TR::SymbolReference * symRef);
static TR::Node *createWithRoomForOneMore(TR::ILOpCodes op, uint16_t numChildren, void * symbolRefOrBranchTarget = 0, TR::Node *first = 0, TR::Node *second = 0, TR::Node *third = 0, TR::Node *fourth = 0, TR::Node *fifth = 0);
static TR::Node *createWithRoomForThree(TR::ILOpCodes op, TR::Node *first, TR::Node *second, void * symbolRefOrBranchTarget = 0);
static TR::Node *createWithRoomForFive(TR::ILOpCodes op, TR::Node *first, TR::Node *second, TR::Node *third, TR::Node *fourth, void * symbolRefOrBranchTarget = 0);
static TR::Node *createif(TR::ILOpCodes op, TR::Node *first, TR::Node *second, TR::TreeTop * branchTarget = 0);
static TR::Node *createbranch(TR::ILOpCodes op, TR::Node * first, TR::TreeTop * branchTarget = 0);
static TR::Node *createCase(TR::Node *originatingByteCodeNode, TR::TreeTop *, CASECONST_TYPE = 0);
static TR::Node *createArrayOperation(TR::ILOpCodes arrayOp, TR::Node *first, TR::Node *second, TR::Node * third, TR::Node *fourth = NULL, TR::Node *fifth = NULL);
static TR::Node *createArraycopy();
static TR::Node *createArraycopy(TR::Node *first, TR::Node *second, TR::Node *third);
static TR::Node *createArraycopy(TR::Node *first, TR::Node *second, TR::Node *third, TR::Node *fourth, TR::Node *fifth);
static TR::Node *createLoad(TR::SymbolReference * symRef);
static TR::Node *createLoad(TR::Node *originatingByteCodeNode, TR::SymbolReference *);
static TR::Node *createStore(TR::SymbolReference * symRef, TR::Node * value);
static TR::Node *createStore(TR::SymbolReference * symRef, TR::Node * value, TR::ILOpCodes op);
static TR::Node *createStore(TR::SymbolReference * symRef, TR::Node * value, TR::ILOpCodes op, size_t size);
static TR::Node *createStore(TR::Node *originatingByteCodeNode, TR::SymbolReference * symRef, TR::Node * value);
static TR::Node *createRelative32BitFenceNode(void * relocationAddress);
static TR::Node *createRelative32BitFenceNode(TR::Node *originatingByteCodeNode, void *);
static TR::Node *createAddressNode(TR::Node *originatingByteCodeNode, TR::ILOpCodes op, uintptrj_t address);
static TR::Node *createAddressNode(TR::Node *originatingByteCodeNode, TR::ILOpCodes op, uintptrj_t address, uint8_t precision);
static TR::Node *createAllocationFence(TR::Node *originatingByteCodeNode, TR::Node *fenceNode);
static TR::Node *bconst(TR::Node *originatingByteCodeNode, int8_t val);
static TR::Node *bconst(int8_t val);
static TR::Node *buconst(TR::Node *originatingByteCodeNode, uint8_t val);
static TR::Node *buconst(uint8_t val);
static TR::Node *sconst(TR::Node *originatingByteCodeNode, int16_t val);
static TR::Node *sconst(int16_t val);
static TR::Node *cconst(TR::Node *originatingByteCodeNode, uint16_t val);
static TR::Node *cconst(uint16_t val);
static TR::Node *iconst(TR::Node *originatingByteCodeNode, int32_t val);
static TR::Node *iconst(int32_t val);
static TR::Node *iuconst(TR::Node *originatingByteCodeNode, uint32_t val);
static TR::Node *iuconst(uint32_t val);
static TR::Node *lconst(TR::Node *originatingByteCodeNode, int64_t val);
static TR::Node *lconst(int64_t val);
static TR::Node *luconst(TR::Node *originatingByteCodeNode, uint64_t val);
static TR::Node *luconst(uint64_t val);
static TR::Node *aconst(TR::Node *originatingByteCodeNode, uintptrj_t val);
static TR::Node *aconst(TR::Node *originatingByteCodeNode, uintptrj_t val, uint8_t precision);
static TR::Node *aconst(uintptrj_t val);
static TR::Node *createConstZeroValue(TR::Node *originatingByteCodeNode, TR::DataType dt);
static TR::Node *createConstOne(TR::Node *originatingByteCodeNode, TR::DataType dt);
static TR::Node *createConstDead(TR::Node *originatingByteCodeNode, TR::DataType dt, intptrj_t extraData=0);
static TR::Node *createCompressedRefsAnchor(TR::Node *firstChild);
static TR::Node *createAddConstantToAddress(TR::Node * addr, intptr_t value, TR::Node * parent = NULL);
static TR::Node *createLiteralPoolAddress(TR::Node *node, size_t offset);
static TR::Node *createVectorConst(TR::Node *originatingByteCodeNode, TR::DataType dt);
static TR::Node *createVectorConversion(TR::Node *src, TR::DataType trgType);
/**
* Private constructor helpers
*/
private:
void copyChildren(TR::Node *from, uint16_t numChildren = 0, bool forNodeExtensionOnly = false);
static TR::Node *recreateAndCopyValidPropertiesImpl(TR::Node *originalNode, TR::ILOpCodes op, TR::SymbolReference *newSymRef);
static bool isLegalCallToCreate(TR::ILOpCodes opvalue)
{
TR::ILOpCode opcode; opcode.setOpCodeValue(opvalue);
TR_ASSERT(!opcode.isIf(), "use createif or createbranch on this node\n");
TR_ASSERT(opvalue != TR::arraycopy, "use createArraycopy to create this node");
TR_ASSERT(opvalue != TR::v2v, "use createVectorConversion to create node: %s", opcode.getName());
TR_ASSERT(opvalue != TR::vconst, "use createVectorConst to create node: %s", opcode.getName());
return true;
}
/**
* Public functions
*/
public:
/** @return true if n is one of the children of this node, return false otherwise */
bool hasChild(TR::Node *searchNode);
void addChildren(TR::Node ** extraChildren, uint16_t num);
TR::Node * setValueChild(TR::Node *child);
TR::Node * setAndIncChild(int32_t c, TR::Node * p);
TR::Node * setAndIncValueChild(TR::Node *child);
TR::Node * getValueChild();
TR::Node * getAndDecChild(int32_t c);
TR::Node * duplicateTree(bool duplicateChildren = true);
TR::Node * duplicateTreeForCodeMotion();
TR::Node * duplicateTreeWithCommoning(TR::Allocator allocator);
TR::Node * duplicateTree_DEPRECATED(bool duplicateChildren = true);
bool isUnsafeToDuplicateAndExecuteAgain(int32_t *nodeVisitBudget);
/// uncommonChild changes
/// parent
/// =>this
/// to:
/// parent
/// clone(this)
/// ...
///
void uncommonChild(int32_t childIndex);
/// creates clone, and adjusts reference counts of clone, node and its children
/// as though the node had been uncommoned from its parent.
///
/// returns the uncommoned clone.
///
TR::Node * uncommon();
bool containsNode(TR::Node *searchNode, vcount_t visitCount); // Careful how you use this: it doesn't account for aliasing
/// Does this node have an unresolved symbol reference?
bool hasUnresolvedSymbolReference();
/// Does this node have a volatile symbol reference?
bool mightHaveVolatileSymbolReference();
/// Is this node the 'this' pointer?
bool isThisPointer();
/// Whether this node is high part of a "dual", in DAG representation a dual
/// is a composite operator, made from a high order part and its adjunct operator
/// which is its third child. It returns true if the node has the form:
///
/// highOp
/// firstChild
/// secondChild
/// adjunctOp
/// pairFirstChild
/// pairSecondChild
///
/// and the opcodes for highOp/adjunctOp are lumulh/lmul, luaddh/luadd, or lusubh/lusub.
///
bool isDualHigh();
/// Whether this node is high part of a ternary subtract or addition, like a dual this
/// is a composite operator, made from a high order part and its adjunct operator
/// which is the first child of its third child. It returns true if the node has the form:
///
/// highOp
/// firstChild
/// secondChild
/// computeCC
/// adjunctOp
/// pairFirstChild
/// pairSecondChild
///
/// and the opcodes for highOp/adjunctOp are luaddc/luadd, or lusubb/lusub.
///
bool isTernaryHigh();
/// Whether this node is the high or low part of a "dual", in cyclic representation.
/// ie it represents a composite operator, together with its pair.
/// The node and its pair have each other as its third child, completing the cycle.
/// It returns true if the node has the form:
///
/// node
/// firstChild
/// secondChild
/// pair
/// pairFirstChild
/// pairSecondChild
/// ==> node
///
bool isDualCyclic();
bool isConstZeroBytes();
bool isConstZeroValue();
bool safeToDoRecursiveDecrement();
/// Is this node a GC safe point
bool canGCandReturn();
bool canGCandExcept();
bool canCauseGC();
bool isGCSafePointWithSymRef();
bool dontEliminateStores(bool isForLocalDeadStore = false);
bool isNotCollected();
bool computeIsInternalPointer();
bool computeIsCollectedReference();
bool addressPointsAtObject();
/**
* @brief Answers whether the act of evaluating this node will
* require a register pair (two registers) to hold the
* result.
* @param comp, the TR::Compilation object
* @return true if two registers are required; false otherwise
*/
bool requiresRegisterPair(TR::Compilation *comp);
/// Decide whether it is safe to replace the next reference to this node with
/// a copy of the node, i.e. make sure it is not killed between the first
/// reference and the next reference.
/// The treetop containing the first reference is provided by the caller.
bool isSafeToReplaceNode(TR::TreeTop *curTreeTop);
bool isl2aForCompressedArrayletLeafLoad();
/// Returns true if the node kills the symbol reference
bool mayModifyValue(TR::SymbolReference *);
bool performsVolatileAccess(vcount_t visitCount);
bool uses64BitGPRs();
bool isRematerializable(TR::Node *parent, bool onlyConsiderOpCode);
bool canEvaluate();
bool isDoNotPropagateNode();
bool containsDoNotPropagateNode(vcount_t vc);
bool anchorConstChildren();
bool isFloatToFixedConversion();
bool isZeroExtension();
bool isPureCall();
bool isClassUnloadingConst();
// A common query used by the optimizer
inline bool isSingleRef();
// A common query used by the code generators
inline bool isSingleRefUnevaluated();
TR_YesNoMaybe hasBeenRun();
/// Given a monenter node, return the persistent class identifer that's being synchronized
TR_OpaqueClassBlock * getMonitorClass(TR_ResolvedMethod *);
TR_OpaqueClassBlock * getMonitorClassInNode();
void setMonitorClassInNode(TR_OpaqueClassBlock *);
// Given that this is a NULLCHK node, find the reference that is being checked.
TR::Node * getNullCheckReference();
void setNullCheckReference(TR::Node *refNode);
/// getFirstArgumentIndex returns the child index where the arguments start for a call node.
/// For an indirect call the first child may be the vft.
int32_t getFirstArgumentIndex();
inline int32_t getNumArguments();
inline TR::Node * getArgument(int32_t index);
inline TR::Node * getFirstArgument();
TR::Node * getReturnCode(bool isReason=false);
TR::Node * getReturnReason();
uint32_t getSize();
uint32_t getRoundedSize();
uint32_t getNumberOfSlots();
int32_t getMaxIntegerPrecision();
uint16_t getCaseIndexUpperBound();
/// Find the store node (if any) represented by this node or its child
TR::Node * getStoreNode();
TR::TreeTop * getVirtualCallTreeForGuard();
TR::Node * getVirtualCallNodeForGuard();
TR_OpaqueMethodBlock * getOwningMethod();
inline TR::DataType getType();
// TODO: Sink into J9. Depends on OMR::Compilation::getMethodFromNode
void * getAOTMethod();
/**
* @return the signature of the node's type if applicable.
* @note the signature's storage may have been created on the stack!
*/
const char * getTypeSignature(int32_t &, TR_AllocationKind = stackAlloc);
// 'Value' can change as a result of modification
void notifyChangeToValueOfNode();
void reverseBranch(TR::TreeTop *newDest);
void devirtualizeCall(TR::TreeTop *treeTop);
bool nodeMightKillCondCode();
void gatherAllNodesWhichMightKillCondCode(vcount_t vc, TR::list<TR::Node *> &nodesWhichKillCondCode);
TR::TreeTop * extractTheNullCheck(TR::TreeTop *);
int32_t countNumberOfNodesInSubtree(vcount_t);
/// Which exceptions can this node cause to be thrown?
uint32_t exceptionsRaised();
/// Has the expression represented by this node ever been executed? Could be
/// determined from such evidence as profile-directed feedback for a static
/// compiler, or runtime instrumentation for a dynamic compiler.
///
TR::Node * skipConversions();
TR::Node * createLongIfNeeded();
TR::TreeTop * createStoresForVar(TR::SymbolReference * &nodeRef, TR::TreeTop *insertBefore, bool simpleRef = false);
void printFullSubtree();
const char * getName(TR_Debug *);
bool isReferenceArrayCopy();
bool chkReferenceArrayCopy();
const char * printIsReferenceArrayCopy();
// CS2 Alias Interface:
// implemented in base/AliasSetInterface.hpp right now.
inline TR_NodeUseAliasSetInterface mayUse();
inline TR_NodeKillAliasSetInterface mayKill(bool gcSafe = false);
/** \brief
* Determines whether this node should be sign/zero extended to 32-bit at the point of evaluation (source) by
* checking for the signExtendTo32BitAtSource or zeroExtendTo32BitAtSource flags.
*/
bool isExtendedTo32BitAtSource();
/** \brief
* Determines whether this node should be sign/zero extended to 64-bit at the point of evaluation (source) by
* checking for the signExtendTo64BitAtSource or zeroExtendTo64BitAtSource flags.
*/
bool isExtendedTo64BitAtSource();
/** \brief
* Determines whether this node should be sign extended at the point of evaluation (source) by checking for the
* signExtendTo32BitAtSource or signExtendTo64BitAtSource flags.
*/
bool isSignExtendedAtSource();
/** \brief
* Determines whether this node should be zero extended at the point of evaluation (source) by checking for the
* zeroExtendTo32BitAtSource or zeroExtendTo64BitAtSource flags.
*/
bool isZeroExtendedAtSource();
/** \brief
* Determines whether this node should be sign extended to 32-bits at the point of evaluation (source).
*/
bool isSignExtendedTo32BitAtSource();
/** \brief
* Determines whether this node should be sign extended to 64-bits at the point of evaluation (source).
*/
bool isSignExtendedTo64BitAtSource();
/** \brief
* Marks the load with the signExtendTo32BitAtSource flag.
*
* \param b
* Determines whether the respective flag should be active.
*/
void setSignExtendTo32BitAtSource(bool b);
/** \brief
* Marks the load with the signExtendTo64BitAtSource flag.
*
* \param b
* Determines whether the respective flag should be active.
*/
void setSignExtendTo64BitAtSource(bool b);
const char* printIsSignExtendedTo32BitAtSource();
const char* printIsSignExtendedTo64BitAtSource();
/** \brief
* Determines whether this node should be zero extended to 32-bits at the point of evaluation (source).
*/
bool isZeroExtendedTo32BitAtSource();
/** \brief
* Determines whether this node should be sign extended to 64-bits at the point of evaluation (source).
*/
bool isZeroExtendedTo64BitAtSource();
/** \brief
* Marks the load with the zeroExtendTo32BitAtSource flag.
*
* \param b
* Determines whether the respective flag should be active.
*/
void setZeroExtendTo32BitAtSource(bool b);
/** \brief
* Marks the load with the zeroExtendTo32BitAtSource flag.
*
* \param b
* Determines whether the respective flag should be active.
*/
void setZeroExtendTo64BitAtSource(bool b);
const char* printIsZeroExtendedTo32BitAtSource();
const char* printIsZeroExtendedTo64BitAtSource();
/**
* Node field functions
*/
TR::ILOpCode& getOpCode() { return _opCode; }
TR::ILOpCodes getOpCodeValue() { return _opCode.getOpCodeValue(); }
uint16_t getNumChildren() { return _numChildren; }
uint16_t setNumChildren(uint16_t num) { return ( _numChildren = num); }
ncount_t getGlobalIndex() { return _globalIndex; }
void setGlobalIndex(ncount_t i) { _globalIndex = i; }
flags32_t getFlags() { return _flags; }
void setFlags(flags32_t f);
TR_ByteCodeInfo& getByteCodeInfo() { return _byteCodeInfo; }
void setByteCodeInfo(const TR_ByteCodeInfo &bcInfo);
void copyByteCodeInfo(TR::Node * from);
uint32_t getByteCodeIndex();
void setByteCodeIndex(uint32_t);
int16_t getInlinedSiteIndex();
void setInlinedSiteIndex(int16_t);
TR::Node* setChild(int32_t c, TR::Node * p);
inline TR::Node * getChild(int32_t c);
TR::Node* setFirst(TR::Node * p);
TR::Node* setSecond(TR::Node * p);
inline TR::Node * getFirstChild();
inline TR::Node * getSecondChild();
inline TR::Node * getThirdChild();
inline TR::Node * getLastChild();
void swapChildren();
TR::Node * removeChild(int32_t);
TR::Node * removeLastChild();
void removeAllChildren();
void rotateChildren(int32_t first, int32_t last); ///< @note when finsihed, last child ends up where first child used to be
TR::Node * findChild(TR::ILOpCodes opcode, bool isReversed = false);
int32_t findChildIndex(TR::Node * child);
int32_t countChildren(TR::ILOpCodes opcode);
/// Return an iterator for the children of this node.
inline ChildIterator childIterator(int32_t startIndex=0);
/**
* Node field functions end
*/
/**
* OptAttributes functions
*/
inline vcount_t getVisitCount();
inline vcount_t setVisitCount(vcount_t vc);
inline vcount_t incVisitCount();
void resetVisitCounts(vcount_t t); ///< reset visit counts on this node and all its children
inline rcount_t getReferenceCount();
inline rcount_t setReferenceCount(rcount_t rc);
inline rcount_t incReferenceCount();
inline rcount_t decReferenceCount();
// Decrement the reference count and if it reaches zero decrement the counts of all the children
rcount_t recursivelyDecReferenceCount();
void recursivelyDecReferenceCountFromCodeGen();
inline scount_t getLocalIndex();
inline scount_t setLocalIndex(scount_t li);
inline scount_t incLocalIndex();
inline scount_t decLocalIndex();
inline scount_t getFutureUseCount();
inline scount_t setFutureUseCount(scount_t li);
inline scount_t incFutureUseCount();
inline scount_t decFutureUseCount();
void initializeFutureUseCounts(vcount_t visitCount);
void setIsNotRematerializeable();
bool isRematerializeable();
inline uint16_t getUseDefIndex();
inline uint16_t setUseDefIndex(uint16_t udi);
TR::Register * getRegister();
TR::Register * setRegister(TR::Register *reg);
void * unsetRegister();
int32_t getEvaluationPriority(TR::CodeGenerator *codeGen);
int32_t setEvaluationPriority(int32_t p);
/**
* OptAttributes functions end
*/
/**
* UnionBase functions
*/
// These three methods should be used only if you're sure you can't use one of the other ones.
inline int64_t getConstValue();
inline uint64_t getUnsignedConstValue();
inline void setConstValue(int64_t val);
inline int64_t getLongInt();
inline int64_t setLongInt(int64_t li);
inline int32_t getLongIntLow();
inline int32_t getLongIntHigh();
inline uint64_t getUnsignedLongInt();
inline uint64_t setUnsignedLongInt(uint64_t uli);
inline uint32_t getUnsignedLongIntLow();
inline uint32_t getUnsignedLongIntHigh();
inline int32_t getInt();
inline int32_t setInt(int32_t i);
inline uint32_t getUnsignedInt();
inline uint32_t setUnsignedInt(uint32_t ui);
inline int16_t getShortInt();
inline int16_t setShortInt(int16_t si);
inline uint16_t getUnsignedShortInt();
inline uint16_t setUnsignedShortInt(uint16_t c);
inline int8_t getByte();
inline int8_t setByte(int8_t b);
inline uint8_t getUnsignedByte();
inline uint8_t setUnsignedByte(uint8_t b);
inline float getFloat();
inline float setFloat(float f);
inline uint32_t setFloatBits(uint32_t f);
inline uint32_t getFloatBits();
inline double getDouble();
inline double setDouble(double d);
inline uint64_t getDoubleBits();
inline uint64_t setDoubleBits(uint64_t d);
inline uint64_t getAddress();
inline uint64_t setAddress(uint64_t a);
template <typename T> inline T getConst();
template <typename T> inline T setConst(T t);
template <class T> inline T getIntegerNodeValue();
bool canGet32bitIntegralValue();
int32_t get32bitIntegralValue();
bool canGet64bitIntegralValue();
int64_t get64bitIntegralValue();
void set64bitIntegralValue(int64_t);
uint64_t get64bitIntegralValueAsUnsigned();
TR::Node * getAllocation();
TR::Node * setAllocation(TR::Node * p);
/*
* This function is public to support the TR::UnionedWithChildren::*
* functions that use it extensively. At the moment however, the extension
* interface is limited to Node subclasses, so this function ends up
* being public.
*/
void freeExtensionIfExists();
TR::DataType getArrayCopyElementType();
void setArrayCopyElementType(TR::DataType type);
TR_OpaqueClassBlock * getArrayStoreClassInNode();
void setArrayStoreClassInNode(TR_OpaqueClassBlock *o);
TR_OpaqueClassBlock * getArrayComponentClassInNode();
void setArrayComponentClassInNode(TR_OpaqueClassBlock *c);
struct ArrayStoreCheckInfo
{
TR_OpaqueClassBlock *objectClass;
TR_OpaqueClassBlock *arrayComponentClass;
};
bool hasArrayStoreCheckInfo();
void createArrayStoreCheckInfo();
TR_OpaqueMethodBlock * getMethod();
void setMethod(TR_OpaqueMethodBlock *method);
// Get/set the label symbol associated with a BBStart node
TR::LabelSymbol * getLabel();
TR::LabelSymbol * setLabel(TR::LabelSymbol *lab);
TR_GlobalRegisterNumber getGlobalRegisterNumber();
TR_GlobalRegisterNumber setGlobalRegisterNumber(TR_GlobalRegisterNumber i);
TR_GlobalRegisterNumber getLowGlobalRegisterNumber();
TR_GlobalRegisterNumber setLowGlobalRegisterNumber(TR_GlobalRegisterNumber i);
TR_GlobalRegisterNumber getHighGlobalRegisterNumber();
TR_GlobalRegisterNumber setHighGlobalRegisterNumber(TR_GlobalRegisterNumber i);
size_t getLiteralPoolOffset();
size_t setLiteralPoolOffset(size_t offset, size_t size);
void * getRelocationDestination(uint32_t n);
void * setRelocationDestination(uint32_t n, void * p);
uint32_t getRelocationType();
uint32_t setRelocationType(uint32_t r);
uint32_t getNumRelocations();
uint32_t setNumRelocations(uint32_t n);
CASECONST_TYPE getCaseConstant();
CASECONST_TYPE setCaseConstant(CASECONST_TYPE c);
void * getMonitorInfo();
void * setMonitorInfo(void *info);
TR::ILOpCodes getOverflowCheckOperation();
TR::ILOpCodes setOverflowCheckOperation(TR::ILOpCodes op);
/**
* UnionBase functions end
*/
/**
* UnionPropertyA functions
*/
TR::SymbolReference * getSymbolReference();
TR::SymbolReference * setSymbolReference(TR::SymbolReference * p);
TR::SymbolReference * getRegLoadStoreSymbolReference();
TR::SymbolReference * setRegLoadStoreSymbolReference(TR::SymbolReference * p);
TR::SymbolReference * getSymbolReferenceOfAnyType();
TR::Symbol * getSymbol();
inline TR::TreeTop * getBranchDestination();
inline TR::TreeTop * setBranchDestination(TR::TreeTop * p);
TR::Block * getBlock(bool ignored = false);
TR::Block * setBlock(TR::Block * p);
int32_t getArrayStride();
int32_t setArrayStride(int32_t s);
TR::AutomaticSymbol * getPinningArrayPointer();
TR::AutomaticSymbol * setPinningArrayPointer(TR::AutomaticSymbol *s);
inline TR::DataType getDataType();
inline TR::DataType setDataType(TR::DataType dt);
TR::DataType computeDataType();
/**
* UnionPropertyA functions end
*/
/**
* Node flag functions
*/
bool isZero();
void setIsZero(bool v);
const char * printIsZero();
bool isNonZero();
void setIsNonZero(bool v);
const char * printIsNonZero();
bool isNull();
void setIsNull(bool v);
bool isNonNull();
void setIsNonNull(bool v);
bool pointsToNull();
void setPointsToNull(bool v);
bool chkPointsToNull();
const char * printPointsToNull();
bool pointsToNonNull();
void setPointsToNonNull(bool v);
bool chkPointsToNonNull();
const char * printPointsToNonNull();
// Only used during local analysis
bool containsCall();
void setContainsCall(bool v);
// Value is in a global register which cannot be used on an 8 bit instruction
bool isInvalid8BitGlobalRegister();
void setIsInvalid8BitGlobalRegister(bool v);
const char * printIsInvalid8BitGlobalRegister();
// 390 zGryphon Highword register GRA
bool getIsHPREligible() { return _flags.testAny(isHPREligible); }
void setIsHPREligible() { _flags.set(isHPREligible); }
void resetIsHPREligible() { _flags.reset(isHPREligible); }
const char * printIsHPREligible();
bool isEligibleForHighWordOpcode();
// Result of this node is being stored into the same location as its left child
bool isDirectMemoryUpdate();
void setDirectMemoryUpdate(bool v);
const char * printIsDirectMemoryUpdate();
// Used prior to codegen phase
bool isProfilingCode();
void setIsProfilingCode();
const char * printIsProfilingCode();
// Used only during codegen phase
bool hasBeenVisitedForHints();
void setHasBeenVisitedForHints(bool v=true);