// Given a lclvar use, try to find the lclvar's defining assignment and its containing block. GenTreeOp* RangeCheck::GetSsaDefAsg(GenTreeLclVarCommon* lclUse, BasicBlock** asgBlock) { unsigned ssaNum = lclUse->GetSsaNum(); if (ssaNum == SsaConfig::RESERVED_SSA_NUM) { return nullptr; } LclSsaVarDsc* ssaData = m_pCompiler->lvaTable[lclUse->GetLclNum()].GetPerSsaData(ssaNum); GenTree* lclDef = ssaData->m_defLoc.m_tree; if (lclDef == nullptr) { return nullptr; } // We have the def node but we also need the assignment node to get its source. // gtGetParent can be used to get the assignment node but it's rather expensive // and not strictly necessary here, there shouldn't be any other node between // the assignment node and its destination node. GenTree* asg = lclDef->gtNext; if (!asg->OperIs(GT_ASG) || (asg->gtGetOp1() != lclDef)) { return nullptr; } #ifdef DEBUG Location* loc = GetDef(lclUse); assert(loc->parent == asg); assert(loc->block == ssaData->m_defLoc.m_blk); #endif *asgBlock = ssaData->m_defLoc.m_blk; return asg->AsOp(); }