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

Code before:
            //
            for (Compiler::AddCodeDsc* const add : Compiler::AddCodeDscMap::ValueIteration(comp->fgGetAddCodeDscMap()))
            {
                comp->compUsesThrowHelper = true;
                add->acdUsed              = true;
                comp->fgCreateThrowHelperBlockCode(add);
                madeChanges = true;
            }
        }
    }

    // We have added whatever throw helpers are needed, so set this flag
    comp->fgRngChkThrowAdded = true;

    return madeChanges ? PhaseStatus::MODIFIED_EVERYTHING : PhaseStatus::MODIFIED_NOTHING;
}

//------------------------------------------------------------------------
// ProcessBlocks: Process all the blocks if necessary.
//
void StackLevelSetter::ProcessBlocks()
{
#ifndef TARGET_X86
    // Outside x86 we do not need to compute pushed/popped stack slots.
    // However, we do optimize throw-helpers and need to process the blocks for
    // that, but only when optimizing.
    if (!throwHelperBlocksUsed)
    {
        return;
    }
#endif

    for (BasicBlock* const block : comp->Blocks())
    {
        ProcessBlock(block);
    }
}

//------------------------------------------------------------------------
// ProcessBlock: Do stack level and throw helper determinations for one block.
//
// Notes:
//   Block starts and ends with an empty outgoing stack.
//   Nodes in blocks are iterated in the reverse order to memorize GT_PUTARG_STK
//   stack sizes.
//
//   Also note which (if any) throw helper blocks might end up being used by
//   codegen.
//
// Arguments:
//   block - the block to process.

Review comment (refactor):
The comment says throw-helper processing is needed "only when optimizing", but the optimization check has been removed and this will now run whenever `throwHelperBlocksUsed` is true. Update the comment to match the new behavior so readers don't assume this is optimization-only.
```suggestion
    // However, when throw-helper blocks are used we still need to process the
    // blocks for throw-helper-related work.
```

Code after:
            //
            for (Compiler::AddCodeDsc* const add : Compiler::AddCodeDscMap::ValueIteration(comp->fgGetAddCodeDscMap()))
            {
                comp->compUsesThrowHelper = true;
                add->acdUsed              = true;
                comp->fgCreateThrowHelperBlockCode(add);
                madeChanges = true;
            }
        }
    }

    // We have added whatever throw helpers are needed, so set this flag
    comp->fgRngChkThrowAdded = true;

    return madeChanges ? PhaseStatus::MODIFIED_EVERYTHING : PhaseStatus::MODIFIED_NOTHING;
}

//------------------------------------------------------------------------
// ProcessBlocks: Process all the blocks if necessary.
//
void StackLevelSetter::ProcessBlocks()
{
#ifndef TARGET_X86
    // Outside x86 we do not need to compute pushed/popped stack slots.
    // However, if we are using throw helpers, we also need to process the blocks
    // to find where the helpers are needed and create the blocks and calls.
    //
    if (!throwHelperBlocksUsed)
    {
        return;
    }
#endif

    for (BasicBlock* const block : comp->Blocks())
    {
        ProcessBlock(block);
    }
}

//------------------------------------------------------------------------
// ProcessBlock: Do stack level and throw helper determinations for one block.
//
// Notes:
//   Block starts and ends with an empty outgoing stack.
//   Nodes in blocks are iterated in the reverse order to memorize GT_PUTARG_STK
//   stack sizes.
//
//   Also note which (if any) throw helper blocks might end up being used by
//   codegen.
//
// Arguments: