Repository: dotnet/runtime
File: src/coreclr/jit/treelifeupdater.cpp (C++)

Code before:
{
    assert(m_compiler->GetCurLVEpoch() == epoch);
    // TODO-Cleanup: We shouldn't really be calling this more than once
    if (tree == m_compiler->compCurLifeTree)
    {
        return;
    }

    // Note that after lowering, we can see indirect uses and definitions of tracked variables.
    if (tree->OperIsNonPhiLocal())
    {
        UpdateLifeVar(tree, tree->AsLclVarCommon());
    }
    else if (tree->OperIsIndir() && tree->AsIndir()->Addr()->OperIs(GT_LCL_ADDR))
    {
        UpdateLifeVar(tree, tree->AsIndir()->Addr()->AsLclVarCommon());
    }
    else if (tree->IsCall())
    {
        auto visitDef = [=](GenTreeLclVarCommon* lcl) {
            UpdateLifeVar(tree, lcl);
            return GenTree::VisitResult::Continue;
        };
        tree->VisitLocalDefNodes(m_compiler, visitDef);
    }
    else if (ProcessLclAddrs && tree->OperIs(GT_LCL_ADDR))
    {
        UpdateLifeVar(tree, tree->AsLclVarCommon());
    }
}

//------------------------------------------------------------------------
// UpdateLifeBit: Update a liveness set for a specific local depending on whether it is being born or dying.
//
// Arguments:
//    set - The life set
//    dsc - The local's description
//    isBorn - Whether the local is being born now
//    isDying - Whether the local is dying now
//
template <bool ForCodeGen>
void TreeLifeUpdater<ForCodeGen>::UpdateLifeBit(VARSET_TP& set, LclVarDsc* dsc, bool isBorn, bool isDying)
{
    if (isDying)
    {
        VarSetOps::RemoveElemD(m_compiler, set, dsc->lvVarIndex);
    }
    else if (isBorn)
    {
        VarSetOps::AddElemD(m_compiler, set, dsc->lvVarIndex);
    }

Review comment (suggestion):
Should this be symmetric with the handling above? So that `LCL_ADDR`s are not double-counted (it seems that would be mostly harmless though).

Code after:
{
    assert(m_compiler->GetCurLVEpoch() == epoch);
    // TODO-Cleanup: We shouldn't really be calling this more than once
    if (tree == m_compiler->compCurLifeTree)
    {
        return;
    }

    // Note that after lowering, we can see indirect uses and definitions of tracked variables.
    if (tree->OperIsNonPhiLocal())
    {
        UpdateLifeVar(tree, tree->AsLclVarCommon());
    }
    else if (!GeneralLclAddrHandling && tree->OperIsIndir() && tree->AsIndir()->Addr()->OperIs(GT_LCL_ADDR))
    {
        UpdateLifeVar(tree, tree->AsIndir()->Addr()->AsLclVarCommon());
    }
    else if (tree->IsCall())
    {
        auto visitDef = [=](GenTreeLclVarCommon* lcl) {
            UpdateLifeVar(tree, lcl);
            return GenTree::VisitResult::Continue;
        };
        tree->VisitLocalDefNodes(m_compiler, visitDef);
    }
    else if (GeneralLclAddrHandling && tree->OperIs(GT_LCL_ADDR))
    {
        UpdateLifeVar(tree, tree->AsLclVarCommon());
    }
}

//------------------------------------------------------------------------
// UpdateLifeBit: Update a liveness set for a specific local depending on whether it is being born or dying.
//
// Arguments:
//    set - The life set
//    dsc - The local's description
//    isBorn - Whether the local is being born now
//    isDying - Whether the local is dying now
//
template <bool ForCodeGen>
void TreeLifeUpdater<ForCodeGen>::UpdateLifeBit(VARSET_TP& set, LclVarDsc* dsc, bool isBorn, bool isDying)
{
    if (isDying)
    {
        VarSetOps::RemoveElemD(m_compiler, set, dsc->lvVarIndex);
    }
    else if (isBorn)
    {
        VarSetOps::AddElemD(m_compiler, set, dsc->lvVarIndex);
    }