Add more iterators to JIT (#52515)
authorBruce Forstall <brucefo@microsoft.com>
Mon, 7 Jun 2021 23:16:51 +0000 (16:16 -0700)
committerGitHub <noreply@github.com>
Mon, 7 Jun 2021 23:16:51 +0000 (16:16 -0700)
commit5788ea0d7a081dc2a821d5dd5a5a0dcdf1e017fb
treebad4a66b80ee48c858c1bbea57d0e822fa5159c4
parentd173ccaf29e4d6aca217951e88abf29fa8f18461
Add more iterators to JIT (#52515)

Add more iterators compatible with range-based `for` syntax for various data structures. These iterators all assume (and some check) that the underlying data structures determining the iteration are not changed during the iteration. For example, don't use these to iterate over the predecessor edges if you are changing the order or contents of the predecessor edge list.

- BasicBlock: iterate over all blocks in the function, a subset starting not at the first block, or a specified range of blocks. Removed uses of the `foreach_block` macro. E.g.:
```
for (BasicBlock* const block : Blocks()) // all blocks in function
for (BasicBlock* const block : BasicBlockSimpleList(fgFirstBB->bbNext)) // all blocks starting at fgFirstBB->bbNext
for (BasicBlock* const testBlock : BasicBlockRangeList(firstNonLoopBlock, lastNonLoopBlock)) // all blocks in range (inclusive)
```

- block predecessors: iterate over all predecessor edges, or all predecessor blocks, e.g.:
```
for (flowList* const edge : block->PredEdges())
for (BasicBlock* const predBlock : block->PredBlocks())
```

- block successors: iterate over all block successors using the `NumSucc()/GetSucc()`, or `NumSucc(Compiler*)/GetSucc(Compiler*)` pairs, e.g.:
```
for (BasicBlock* const succ : Succs())
for (BasicBlock* const succ : Succs(compiler))
```
Note that there already exists the "AllSuccessorsIter" which iterates over block successors including possible EH successors, e.g.:
```
for (BasicBlock* succ : block->GetAllSuccs(m_pCompiler))
```

- switch targets, (namely, the successors of `BBJ_SWITCH` blocks), e.g.:
```
for (BasicBlock* const bTarget : block->SwitchTargets())
```

- loops blocks: iterate over all the blocks in a loop, e.g.:
```
for (BasicBlock* const blk : optLoopTable[loopInd].LoopBlocks())
```

- Statements: added an iterator shortcut for the non-phi statements, e.g.:
```
for (Statement* const stmt : block->NonPhiStatements())
```
Note that there already exists an iterator over all statements, e.g.:
```
for (Statement* const stmt : block->Statements())
```

- EH clauses, e.g.:
```
for (EHblkDsc* const HBtab : EHClauses(this))
```

- GenTree in linear order (but not LIR, which already has an iterator), namely, using the `gtNext` links, e.g.:
```
for (GenTree* const call : stmt->TreeList())
```

This is a no-diff change.
45 files changed:
src/coreclr/jit/assertionprop.cpp
src/coreclr/jit/block.cpp
src/coreclr/jit/block.h
src/coreclr/jit/codegencommon.cpp
src/coreclr/jit/compiler.cpp
src/coreclr/jit/compiler.h
src/coreclr/jit/compiler.hpp
src/coreclr/jit/copyprop.cpp
src/coreclr/jit/cpp.hint
src/coreclr/jit/earlyprop.cpp
src/coreclr/jit/fgbasic.cpp
src/coreclr/jit/fgdiagnostic.cpp
src/coreclr/jit/fgehopt.cpp
src/coreclr/jit/fgflow.cpp
src/coreclr/jit/fginline.cpp
src/coreclr/jit/fgopt.cpp
src/coreclr/jit/fgprofile.cpp
src/coreclr/jit/flowgraph.cpp
src/coreclr/jit/gcencode.cpp
src/coreclr/jit/gentree.cpp
src/coreclr/jit/gentree.h
src/coreclr/jit/gschecks.cpp
src/coreclr/jit/importer.cpp
src/coreclr/jit/indirectcalltransformer.cpp
src/coreclr/jit/jiteh.cpp
src/coreclr/jit/lclmorph.cpp
src/coreclr/jit/lclvars.cpp
src/coreclr/jit/lir.cpp
src/coreclr/jit/lir.h
src/coreclr/jit/liveness.cpp
src/coreclr/jit/loopcloning.cpp
src/coreclr/jit/lower.cpp
src/coreclr/jit/lsra.cpp
src/coreclr/jit/lsrabuild.cpp
src/coreclr/jit/morph.cpp
src/coreclr/jit/objectalloc.cpp
src/coreclr/jit/optcse.cpp
src/coreclr/jit/optimizer.cpp
src/coreclr/jit/patchpoint.cpp
src/coreclr/jit/rangecheck.cpp
src/coreclr/jit/rationalize.cpp
src/coreclr/jit/redundantbranchopts.cpp
src/coreclr/jit/ssabuilder.cpp
src/coreclr/jit/stacklevelsetter.cpp
src/coreclr/jit/valuenum.cpp