Package ghidra.pcode.emu.jit.analysis

# Class JitControlFlowModel

java.lang.Object
ghidra.pcode.emu.jit.analysis.JitControlFlowModel

public class JitControlFlowModel extends Object
The control flow analysis for JIT-accelerated emulation.

This implements the Control Flow Analysis phase of the `JitCompiler`. Some rudimentary analysis is performed during passage decoding — note the `JitControlFlowModel.BlockSplitter` is exported for use in `DecoderForOneStride`. This is necessary to evaluate whether an instruction (especially an inject-instrumented instruction) has fall-through. Without that information, the decoder cannot know whether it has reached the end of its stride. Note that the decoder records all the branches it encounters and includes them as metadata in the passage. Because branches need to record the source and target p-code op, the decoder is well suited. Additionally, it has to compute these anyway, and we'd rather avoid duplicative work by this analyzer.

The decoded passage contains a good deal of information, but the primary inputs at this point are the ordered list of p-code ops and the branches. This model's primary responsibility is to break the passage down into basic blocks at the p-code level. Even though the p-code ops have all been concatenated together when constructing the passage, we know, by definition, that each stride will end with an unconditional branch (or else a synthesized `JitPassage.ExitPcodeOp`. Note also that `JitPassage.getBranches()` only includes the non-fall-through branches, because these are all that are recorded by the decoder. Thus, it is also this model's responsibility to create the fall-through branches. These will occur to represent the "false" case of any conditional branches, and to represent "unconditional fall through."

The algorithm for this is fairly straightforward and has been implemented primarily in `JitControlFlowModel.BlockSplitter`. Most everything else in this class is data management and the types representing the model.

NOTE: It is technically possible for a userop to branch, but this analysis does not consider that. Instead, the emulator will decide how to handle those. Conventionally, I'd rather a userop never perform control flow. Instead, I'd rather see things like `pc = my_control_op(); goto [pc];`.

- ## Nested Class Summary

  Nested Classes
  Modifier and Type
  Class
  Description
  `static final record`
  `JitControlFlowModel.BlockFlow`
  A flow from one block to another
  `static class`
  `JitControlFlowModel.BlockSplitter`
  A class that splits a sequence of ops and associated branches into basic blocks.
  `static class`
  `JitControlFlowModel.JitBlock`
  A basic block of p-code
  `static class`
  `JitControlFlowModel.UnterminatedFlowException`
  An exception thrown when control flow might run off the edge of the passage.

- ## Constructor Summary

  Constructors
  Constructor
  Description
  `JitControlFlowModel(JitAnalysisContext context)`
  Construct the control flow model.

- ## Method Summary

  Modifier and Type
  Method
  Description
  `protected SequencedMap<PcodeOp,JitControlFlowModel.JitBlock>`
  `analyze()`
  Perform the analysis.
  `void`
  `dumpResult()`
  For diagnostics: Dump the results to stderr
  `Collection<JitControlFlowModel.JitBlock>`
  `getBlocks()`
  Get the basic blocks

  ### Methods inherited from class java.lang.Object

  `clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait`

- ## Constructor Details

  - ### JitControlFlowModel

    public JitControlFlowModel(JitAnalysisContext context)
    Construct the control flow model.

    Analysis is performed as part of constructing the model.

    Parameters:
      `context` - the analysis context

- ## Method Details

  - ### analyze

    protected SequencedMap<PcodeOp,JitControlFlowModel.JitBlock> analyze()
    Perform the analysis.
    Returns:
      the resulting blocks, keyed by `JitControlFlowModel.JitBlock.first()`

  - ### getBlocks

    public Collection<JitControlFlowModel.JitBlock> getBlocks()
    Get the basic blocks
    Returns:
      the collection of blocks

  - ### dumpResult

    public void dumpResult()
    For diagnostics: Dump the results to stderr
    See Also:
      - `JitCompiler.Diag.PRINT_CFM`