@@ -4309,15 +4309,37 @@ inline bool Compiler::PreciseRefCountsRequired()
43094309 return opts.OptimizationEnabled ();
43104310}
43114311
4312+ template <typename TVisitor>
4313+ GenTree::VisitResult GenTree::VisitOperands (TVisitor visitor)
4314+ {
4315+ return VisitOperandUses ([visitor](GenTree** use) {
4316+ return visitor (*use);
4317+ });
4318+ }
4319+
43124320#define RETURN_IF_ABORT (expr ) \
43134321 do \
43144322 { \
43154323 if (expr == VisitResult::Abort) \
43164324 return VisitResult::Abort; \
43174325 } while (0 )
43184326
4327+ // ------------------------------------------------------------------------
4328+ // VisitOperandUses: Call a functor for each use of a node's operands.
4329+ //
4330+ // Same as "GenTree::VisitOperands", but the TVisitor takes a "GenTree**
4331+ // use" argument instead of "GenTree* operand", allowing for operand
4332+ // modification.
4333+ //
4334+ // Arguments:
4335+ // visitor - The visitor, see "VisitOperands"
4336+ //
4337+ // Return Value:
4338+ // The visit result as returned by the visitor ("Continue" for nodes
4339+ // without operands).
4340+ //
43194341template <typename TVisitor>
4320- GenTree::VisitResult GenTree::VisitOperands (TVisitor visitor)
4342+ GenTree::VisitResult GenTree::VisitOperandUses (TVisitor visitor)
43214343{
43224344 switch (OperGet ())
43234345 {
@@ -4362,7 +4384,7 @@ GenTree::VisitResult GenTree::VisitOperands(TVisitor visitor)
43624384 case GT_GCPOLL:
43634385 return VisitResult::Continue;
43644386
4365- // Unary operators with an optional operand
4387+ // Unary operators with an optional operand
43664388 case GT_FIELD_ADDR:
43674389 case GT_RETURN:
43684390 case GT_RETFILT:
@@ -4372,7 +4394,7 @@ GenTree::VisitResult GenTree::VisitOperands(TVisitor visitor)
43724394 }
43734395 FALLTHROUGH;
43744396
4375- // Standard unary operators
4397+ // Standard unary operators
43764398 case GT_STORE_LCL_VAR:
43774399 case GT_STORE_LCL_FLD:
43784400 case GT_NOT:
@@ -4404,48 +4426,48 @@ GenTree::VisitResult GenTree::VisitOperands(TVisitor visitor)
44044426 case GT_KEEPALIVE:
44054427 case GT_INC_SATURATE:
44064428 case GT_RETURN_SUSPEND:
4407- return visitor (this ->AsUnOp ()->gtOp1 );
4429+ return visitor (& this ->AsUnOp ()->gtOp1 );
44084430
4409- // Variadic nodes
4431+ // Variadic nodes
44104432#if defined(FEATURE_HW_INTRINSICS)
44114433 case GT_HWINTRINSIC:
4412- for (GenTree* operand : this ->AsMultiOp ()->Operands ())
4434+ for (GenTree** use : this ->AsMultiOp ()->UseEdges ())
44134435 {
4414- RETURN_IF_ABORT (visitor (operand ));
4436+ RETURN_IF_ABORT (visitor (use ));
44154437 }
44164438 return VisitResult::Continue;
44174439#endif // defined(FEATURE_HW_INTRINSICS)
44184440
4419- // Special nodes
4441+ // Special nodes
44204442 case GT_PHI:
44214443 for (GenTreePhi::Use& use : AsPhi ()->Uses ())
44224444 {
4423- RETURN_IF_ABORT (visitor (use.GetNode ()));
4445+ RETURN_IF_ABORT (visitor (& use.NodeRef ()));
44244446 }
44254447 return VisitResult::Continue;
44264448
44274449 case GT_FIELD_LIST:
44284450 for (GenTreeFieldList::Use& field : AsFieldList ()->Uses ())
44294451 {
4430- RETURN_IF_ABORT (visitor (field.GetNode ()));
4452+ RETURN_IF_ABORT (visitor (& field.NodeRef ()));
44314453 }
44324454 return VisitResult::Continue;
44334455
44344456 case GT_CMPXCHG:
44354457 {
44364458 GenTreeCmpXchg* const cmpXchg = this ->AsCmpXchg ();
4437- RETURN_IF_ABORT (visitor (cmpXchg->Addr ()));
4438- RETURN_IF_ABORT (visitor (cmpXchg->Data ()));
4439- return visitor (cmpXchg->Comparand ());
4459+ RETURN_IF_ABORT (visitor (& cmpXchg->Addr ()));
4460+ RETURN_IF_ABORT (visitor (& cmpXchg->Data ()));
4461+ return visitor (& cmpXchg->Comparand ());
44404462 }
44414463
44424464 case GT_ARR_ELEM:
44434465 {
44444466 GenTreeArrElem* const arrElem = this ->AsArrElem ();
4445- RETURN_IF_ABORT (visitor (arrElem->gtArrObj ));
4467+ RETURN_IF_ABORT (visitor (& arrElem->gtArrObj ));
44464468 for (unsigned i = 0 ; i < arrElem->gtArrRank ; i++)
44474469 {
4448- RETURN_IF_ABORT (visitor (arrElem->gtArrInds [i]));
4470+ RETURN_IF_ABORT (visitor (& arrElem->gtArrInds [i]));
44494471 }
44504472 return VisitResult::Continue;
44514473 }
@@ -4456,46 +4478,44 @@ GenTree::VisitResult GenTree::VisitOperands(TVisitor visitor)
44564478
44574479 for (CallArg& arg : call->gtArgs .EarlyArgs ())
44584480 {
4459- RETURN_IF_ABORT (visitor (arg.GetEarlyNode ()));
4481+ RETURN_IF_ABORT (visitor (& arg.EarlyNodeRef ()));
44604482 }
44614483
44624484 for (CallArg& arg : call->gtArgs .LateArgs ())
44634485 {
4464- RETURN_IF_ABORT (visitor (arg.GetLateNode ()));
4486+ RETURN_IF_ABORT (visitor (& arg.LateNodeRef ()));
44654487 }
44664488
44674489 if (call->gtCallType == CT_INDIRECT)
44684490 {
4469- RETURN_IF_ABORT (visitor (call->gtCallAddr ));
4491+ RETURN_IF_ABORT (visitor (& call->gtCallAddr ));
44704492 }
44714493 if (call->gtControlExpr != nullptr )
44724494 {
4473- return visitor (call->gtControlExpr );
4495+ return visitor (& call->gtControlExpr );
44744496 }
44754497 return VisitResult::Continue;
44764498 }
44774499
44784500 case GT_SELECT:
44794501 {
44804502 GenTreeConditional* const cond = this ->AsConditional ();
4481- RETURN_IF_ABORT (visitor (cond->gtCond ));
4482- RETURN_IF_ABORT (visitor (cond->gtOp1 ));
4483- return visitor (cond->gtOp2 );
4503+ RETURN_IF_ABORT (visitor (& cond->gtCond ));
4504+ RETURN_IF_ABORT (visitor (& cond->gtOp1 ));
4505+ return visitor (& cond->gtOp2 );
44844506 }
44854507
44864508 // Binary nodes
44874509 default :
44884510 assert (this ->OperIsBinary ());
4489- GenTree* op1 = gtGetOp1 ();
4490- if (op1 != nullptr )
4511+ if (AsOp ()->gtOp1 != nullptr )
44914512 {
4492- RETURN_IF_ABORT (visitor (op1 ));
4513+ RETURN_IF_ABORT (visitor (& AsOp ()-> gtOp1 ));
44934514 }
44944515
4495- GenTree* op2 = gtGetOp2 ();
4496- if (op2 != nullptr )
4516+ if (AsOp ()->gtOp2 != nullptr )
44974517 {
4498- return visitor (op2 );
4518+ return visitor (& AsOp ()-> gtOp2 );
44994519 }
45004520 return VisitResult::Continue;
45014521 }
0 commit comments