Example #1
0
// 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();
}