@@ -338,97 +338,41 @@ struct GenTree
338338#define GTSTRUCT_0 (fn, en ) \
339339 GenTree##fn* As##fn() \
340340 { \
341- assert (this -> OperIsSimple ()); \
341+ assert (OperIsSimple ()); \
342342 return reinterpret_cast <GenTree##fn*>(this ); \
343343 } \
344- GenTree##fn& As##fn##Ref() \
345- { \
346- return *As##fn (); \
347- } \
348- __declspec (property(get = As##fn##Ref)) GenTree##fn& gt##fn;
349- #define GTSTRUCT_1 (fn, en ) \
350- GenTree##fn* As##fn() \
351- { \
352- assert (this ->gtOper == en); \
353- return reinterpret_cast <GenTree##fn*>(this ); \
354- } \
355- GenTree##fn& As##fn##Ref() \
356- { \
357- return *As##fn (); \
358- } \
359- __declspec (property(get = As##fn##Ref)) GenTree##fn& gt##fn;
360- #define GTSTRUCT_2 (fn, en, en2 ) \
361- GenTree##fn* As##fn() \
344+ const GenTree##fn* As##fn() const \
362345 { \
363- assert (this ->gtOper == en || this ->gtOper == en2); \
364- return reinterpret_cast <GenTree##fn*>(this ); \
365- } \
366- GenTree##fn& As##fn##Ref() \
367- { \
368- return *As##fn (); \
369- } \
370- __declspec (property(get = As##fn##Ref)) GenTree##fn& gt##fn;
371- #define GTSTRUCT_3 (fn, en, en2, en3 ) \
372- GenTree##fn* As##fn() \
373- { \
374- assert (this ->gtOper == en || this ->gtOper == en2 || this ->gtOper == en3); \
375- return reinterpret_cast <GenTree##fn*>(this ); \
376- } \
377- GenTree##fn& As##fn##Ref() \
378- { \
379- return *As##fn (); \
380- } \
381- __declspec (property(get = As##fn##Ref)) GenTree##fn& gt##fn;
382-
383- #define GTSTRUCT_4 (fn, en, en2, en3, en4 ) \
384- GenTree##fn* As##fn() \
385- { \
386- assert (this ->gtOper == en || this ->gtOper == en2 || this ->gtOper == en3 || this ->gtOper == en4); \
387- return reinterpret_cast <GenTree##fn*>(this ); \
346+ assert (OperIsSimple ()); \
347+ return reinterpret_cast <const GenTree##fn*>(this ); \
388348 } \
389349 GenTree##fn& As##fn##Ref() \
390350 { \
391351 return *As##fn (); \
392352 } \
393353 __declspec (property(get = As##fn##Ref)) GenTree##fn& gt##fn;
394354
395- #ifdef DEBUG
396- // VC does not optimize out this loop in retail even though the value it computes is unused
397- // so we need a separate version for non-debug
398355#define GTSTRUCT_N (fn, ...) \
399356 GenTree##fn* As##fn() \
400357 { \
401- genTreeOps validOps[] = {__VA_ARGS__}; \
402- bool found = false ; \
403- for (unsigned i = 0 ; i < ArrLen (validOps); i++) \
404- { \
405- if (this ->gtOper == validOps[i]) \
406- { \
407- found = true ; \
408- break ; \
409- } \
410- } \
411- assert (found); \
358+ assert (OperIs (__VA_ARGS__)); \
412359 return reinterpret_cast <GenTree##fn*>(this ); \
413360 } \
414- GenTree##fn& As##fn##Ref () \
361+ const GenTree##fn* As##fn() const \
415362 { \
416- return *As##fn (); \
417- } \
418- __declspec (property(get = As##fn##Ref)) GenTree##fn& gt##fn;
419- #else
420- #define GTSTRUCT_N (fn, ...) \
421- GenTree##fn* As##fn() \
422- { \
423- return reinterpret_cast <GenTree##fn*>(this ); \
363+ assert (OperIs (__VA_ARGS__)); \
364+ return reinterpret_cast <const GenTree##fn*>(this ); \
424365 } \
425366 GenTree##fn& As##fn##Ref() \
426367 { \
427368 return *As##fn (); \
428369 } \
429370 __declspec (property(get = As##fn##Ref)) GenTree##fn& gt##fn;
430- #endif
431371
372+ #define GTSTRUCT_1 (fn, en ) GTSTRUCT_N(fn, en)
373+ #define GTSTRUCT_2 (fn, en, en2 ) GTSTRUCT_N(fn, en, en2)
374+ #define GTSTRUCT_3 (fn, en, en2, en3 ) GTSTRUCT_N(fn, en, en2, en3)
375+ #define GTSTRUCT_4 (fn, en, en2, en3, en4 ) GTSTRUCT_N(fn, en, en2, en3, en4)
432376#define GTSTRUCT_2_SPECIAL (fn, en, en2 ) GTSTRUCT_2(fn, en, en2)
433377#define GTSTRUCT_3_SPECIAL (fn, en, en2, en3 ) GTSTRUCT_3(fn, en, en2, en3)
434378
@@ -1178,7 +1122,7 @@ struct GenTree
11781122 {
11791123 // ADDR ndoes may only be present in LIR if the location they refer to is not a
11801124 // local, class variable, or IND node.
1181- GenTree* location = const_cast <GenTree*>( this )-> gtGetOp1 ();
1125+ GenTree* location = gtGetOp1 ();
11821126 genTreeOps locationOp = location->OperGet ();
11831127 return !location->IsLocal () && (locationOp != GT_CLS_VAR) && (locationOp != GT_IND);
11841128 }
@@ -1787,15 +1731,15 @@ struct GenTree
17871731
17881732 inline GenTreePtr* pCurrent ();
17891733
1790- inline GenTreePtr gtGetOp1 ();
1734+ inline GenTree* gtGetOp1 () const ;
17911735
17921736 // Directly return op2. Asserts the node is binary. Might return nullptr if the binary node allows
17931737 // a nullptr op2, such as GT_LIST. This is more efficient than gtGetOp2IfPresent() if you know what
17941738 // node type you have.
1795- inline GenTreePtr gtGetOp2 ();
1739+ inline GenTree* gtGetOp2 () const ;
17961740
17971741 // The returned pointer might be nullptr if the node is not binary, or if non-null op2 is not required.
1798- inline GenTreePtr gtGetOp2IfPresent ();
1742+ inline GenTree* gtGetOp2IfPresent () const ;
17991743
18001744 // Given a tree node, if this is a child of that node, return the pointer to the child node so that it
18011745 // can be modified; otherwise, return null.
@@ -5931,10 +5875,8 @@ inline bool GenTree::IsSIMDEqualityOrInequality() const
59315875#ifdef FEATURE_SIMD
59325876 if (gtOper == GT_SIMD)
59335877 {
5934- // Has to cast away const-ness since AsSIMD() method is non-const.
5935- GenTreeSIMD* simdNode = const_cast <GenTree*>(this )->AsSIMD ();
5936- return (simdNode->gtSIMDIntrinsicID == SIMDIntrinsicOpEquality ||
5937- simdNode->gtSIMDIntrinsicID == SIMDIntrinsicOpInEquality);
5878+ SIMDIntrinsicID id = AsSIMD ()->gtSIMDIntrinsicID ;
5879+ return (id == SIMDIntrinsicOpEquality) || (id == SIMDIntrinsicOpInEquality);
59385880 }
59395881#endif
59405882
@@ -6033,9 +5975,9 @@ inline GenTreePtr* GenTree::pCurrent()
60335975 return &(gtOp.gtOp1 );
60345976}
60355977
6036- inline GenTreePtr GenTree::gtGetOp1 ()
5978+ inline GenTree* GenTree::gtGetOp1 () const
60375979{
6038- return gtOp. gtOp1 ;
5980+ return AsOp ()-> gtOp1 ;
60395981}
60405982
60415983#ifdef DEBUG
@@ -6093,23 +6035,23 @@ inline bool GenTree::RequiresNonNullOp2(genTreeOps oper)
60936035}
60946036#endif // DEBUG
60956037
6096- inline GenTreePtr GenTree::gtGetOp2 ()
6038+ inline GenTree* GenTree::gtGetOp2 () const
60976039{
60986040 assert (OperIsBinary ());
60996041
6100- GenTreePtr op2 = gtOp. gtOp2 ;
6042+ GenTree* op2 = AsOp ()-> gtOp2 ;
61016043
61026044 // Only allow null op2 if the node type allows it, e.g. GT_LIST.
61036045 assert ((op2 != nullptr ) || !RequiresNonNullOp2 (gtOper));
61046046
61056047 return op2;
61066048}
61076049
6108- inline GenTreePtr GenTree::gtGetOp2IfPresent ()
6050+ inline GenTree* GenTree::gtGetOp2IfPresent () const
61096051{
61106052 /* gtOp.gtOp2 is only valid for GTK_BINOP nodes. */
61116053
6112- GenTreePtr op2 = OperIsBinary () ? gtOp. gtOp2 : nullptr ;
6054+ GenTree* op2 = OperIsBinary () ? AsOp ()-> gtOp2 : nullptr ;
61136055
61146056 // This documents the genTreeOps for which gtOp.gtOp2 cannot be nullptr.
61156057 // This helps prefix in its analysis of code which calls gtGetOp2()
@@ -6248,8 +6190,7 @@ inline bool GenTree::IsCopyOrReloadOfMultiRegCall() const
62486190{
62496191 if (IsCopyOrReload ())
62506192 {
6251- GenTree* t = const_cast <GenTree*>(this );
6252- return t->gtGetOp1 ()->IsMultiRegCall ();
6193+ return gtGetOp1 ()->IsMultiRegCall ();
62536194 }
62546195
62556196 return false ;
0 commit comments