Feature/speculative execution#2222
Open
kevinferrare wants to merge 1 commit into
Open
Conversation
a40ca13 to
dd051b6
Compare
Comment on lines
+132
to
+136
| foreach (StaticSuccessor successor in node.StaticSuccessorAddresses) { | ||
| if (!_nodeIndex.PoisonSet.Contains(successor.Address)) { | ||
| worklist.Enqueue(new ExploreItem(successor.Address, node, successor.EdgeType, FollowContinuations: false)); | ||
| } | ||
| } |
Comment on lines
+193
to
+197
| foreach (StaticSuccessor successor in instruction.StaticSuccessorAddresses) { | ||
| if (!_nodeIndex.PoisonSet.Contains(successor.Address)) { | ||
| worklist.Enqueue(new ExploreItem(successor.Address, instruction, successor.EdgeType, followContinuations)); | ||
| } | ||
| } |
Comment on lines
+75
to
+80
| foreach (ICfgNode predecessor in candidate.Predecessors) { | ||
| if (!candidates.Contains(predecessor) && !predecessor.Equals(discardRoot)) { | ||
| queue.Enqueue(candidate); | ||
| break; | ||
| } | ||
| } |
Comment on lines
+87
to
+91
| foreach (ICfgNode successor in node.Successors) { | ||
| if (candidates.Contains(successor)) { | ||
| queue.Enqueue(successor); | ||
| } | ||
| } |
Contributor
There was a problem hiding this comment.
Pull request overview
This PR introduces Speculative CFG Exploration to the CFG-based CPU execution/codegen pipeline: it grows the CFG along statically-known edges (marking nodes as speculative), emits generated-code guards to safely execute speculative regions, and persists speculation “poisoning” across CFG dump/reload. It also adds extensive unit + integration fixtures (ASM + generated-code) to validate end-to-end behavior.
Changes:
- Add speculative provenance (
IsSpeculative) across CFG nodes/blocks, a persistentCfgNodeIndex+ poison set, and speculative exploration/promotion/pruning in the feeder/linker. - Extend CFG reload dump format to persist speculative flags and poisoned addresses; seed external IRQ handler entrypoints as generation roots when speculation is enabled.
- Update CFG code generation to emit
VerifySpeculativeEntryOrFailguards and add comprehensive tests/fixtures for speculative scenarios.
Reviewed changes
Copilot reviewed 82 out of 91 changed files in this pull request and generated 3 comments.
Show a summary per file
| File | Description |
|---|---|
| tests/Spice86.Tests/UI/CfgCpu/CfgCpuViewModelTest.cs | Adapts test harness construction for new feeder parameter. |
| tests/Spice86.Tests/Spice86Creator.cs | Threads speculative exploration flag into test DI configuration. |
| tests/Spice86.Tests/SpeculativeCfgTest.cs | Adds end-to-end speculative exploration/codegen/runtime guard tests. |
| tests/Spice86.Tests/Resources/cpuTests/res/DumpedListing/speculative_smc_guard.txt | New fixture listing for speculative SMC guard scenario. |
| tests/Spice86.Tests/Resources/cpuTests/res/DumpedListing/speculative_mixed_block.txt | New fixture listing for mixed-block guard placement scenario. |
| tests/Spice86.Tests/Resources/cpuTests/res/DumpedListing/speculative_invalid_opcode.txt | New fixture listing for invalid-opcode hard-stop scenario. |
| tests/Spice86.Tests/Resources/cpuTests/res/DumpedListing/speculative_discard.txt | New fixture listing for discard-on-divergence scenario. |
| tests/Spice86.Tests/Resources/cpuTests/res/DumpedListing/speculative_convergence.txt | New fixture listing for convergence-onto-observed scenario. |
| tests/Spice86.Tests/Resources/cpuTests/res/DumpedListing/speculative_closure.txt | New fixture listing for multi-block closure scenario. |
| tests/Spice86.Tests/Resources/cpuTests/res/DumpedListing/speculative_call_entry.txt | New fixture listing for speculative call-entry scenario. |
| tests/Spice86.Tests/Resources/cpuTests/res/DumpedListing/speculative_branch.txt | New fixture listing for basic conditional-branch scenario. |
| tests/Spice86.Tests/Resources/cpuTests/res/DumpedCfgPartitions/speculative_smc_guard.json | New partition dump for speculative fixture. |
| tests/Spice86.Tests/Resources/cpuTests/res/DumpedCfgPartitions/speculative_mixed_block.json | New partition dump for speculative fixture. |
| tests/Spice86.Tests/Resources/cpuTests/res/DumpedCfgPartitions/speculative_invalid_opcode.json | New partition dump for speculative fixture. |
| tests/Spice86.Tests/Resources/cpuTests/res/DumpedCfgPartitions/speculative_discard.json | New partition dump for speculative fixture. |
| tests/Spice86.Tests/Resources/cpuTests/res/DumpedCfgPartitions/speculative_convergence.json | New partition dump for speculative fixture. |
| tests/Spice86.Tests/Resources/cpuTests/res/DumpedCfgPartitions/speculative_closure.json | New partition dump for speculative fixture. |
| tests/Spice86.Tests/Resources/cpuTests/res/DumpedCfgPartitions/speculative_call_entry.json | New partition dump for speculative fixture. |
| tests/Spice86.Tests/Resources/cpuTests/res/DumpedCfgPartitions/speculative_branch.json | New partition dump for speculative fixture. |
| tests/Spice86.Tests/Resources/cpuTests/res/DumpedCfgBlocks/speculative_smc_guard.json | New CFG block dump for speculative fixture. |
| tests/Spice86.Tests/Resources/cpuTests/res/DumpedCfgBlocks/speculative_mixed_block.json | New CFG block dump for speculative fixture. |
| tests/Spice86.Tests/Resources/cpuTests/res/DumpedCfgBlocks/speculative_invalid_opcode.json | New CFG block dump for speculative fixture. |
| tests/Spice86.Tests/Resources/cpuTests/res/DumpedCfgBlocks/speculative_discard.json | New CFG block dump for speculative fixture. |
| tests/Spice86.Tests/Resources/cpuTests/res/DumpedCfgBlocks/speculative_convergence.json | New CFG block dump for speculative fixture. |
| tests/Spice86.Tests/Resources/cpuTests/res/DumpedCfgBlocks/speculative_closure.json | New CFG block dump for speculative fixture. |
| tests/Spice86.Tests/Resources/cpuTests/res/DumpedCfgBlocks/speculative_call_entry.json | New CFG block dump for speculative fixture. |
| tests/Spice86.Tests/Resources/cpuTests/res/DumpedCfgBlocks/speculative_branch.json | New CFG block dump for speculative fixture. |
| tests/Spice86.Tests/Resources/cpuTests/asmsrc/speculative_smc_guard.asm | New ASM fixture for SMC invalidation of speculative runs. |
| tests/Spice86.Tests/Resources/cpuTests/asmsrc/speculative_mixed_block.asm | New ASM fixture for mid-block speculative guard placement. |
| tests/Spice86.Tests/Resources/cpuTests/asmsrc/speculative_invalid_opcode.asm | New ASM fixture for invalid-opcode speculation hard-stop. |
| tests/Spice86.Tests/Resources/cpuTests/asmsrc/speculative_discard.asm | New ASM fixture for guard failure/discard-on-divergence. |
| tests/Spice86.Tests/Resources/cpuTests/asmsrc/speculative_convergence.asm | New ASM fixture for speculative-to-observed convergence. |
| tests/Spice86.Tests/Resources/cpuTests/asmsrc/speculative_closure.asm | New ASM fixture for speculative multi-block loop closure. |
| tests/Spice86.Tests/Resources/cpuTests/asmsrc/speculative_call_entry.asm | New ASM fixture for speculative callee entry exploration. |
| tests/Spice86.Tests/Resources/cpuTests/asmsrc/speculative_branch.asm | New ASM fixture for basic speculative conditional branch. |
| tests/Spice86.Tests/MachineTest.cs | Adds interpreter-oracle coverage for new speculative fixtures. |
| tests/Spice86.Tests/GeneratedCodeRunOptions.cs | Adds option to enable speculative CFG exploration in runner. |
| tests/Spice86.Tests/GeneratedCodeMachineTestRunner.cs | Threads speculative exploration option through discovery + replay. |
| tests/Spice86.Tests/GeneratedCodeMachineTest.cs | Adds generated-code coverage for speculative fixtures. |
| tests/Spice86.Tests/Fixtures/ExecutionContextManagerFactory.cs | Updates feeder construction for new speculative flag parameter. |
| tests/Spice86.Tests/CpuTests/SingleStepTests/SingleStepTestMinimalMachine.cs | Updates CfgCpu ctor callsite for new parameter. |
| tests/Spice86.Tests/CfgCpu/SpeculativeReachabilityPrunerTest.cs | Adds unit tests for speculative sweep/prune mechanics. |
| tests/Spice86.Tests/CfgCpu/SpeculativeLinkerAndPromotionTest.cs | Adds unit tests for selector safety + promotion behavior. |
| tests/Spice86.Tests/CfgCpu/SpeculativeExplorerEdgeWiringTest.cs | Adds unit tests for exploration wiring + known-safe seeding. |
| tests/Spice86.Tests/CfgCpu/SpeculativeBlockIntegrityTest.cs | Adds unit tests for block integrity after pruning/truncation. |
| tests/Spice86.Tests/CfgCpu/InstructionsFeederTest.cs | Updates feeder construction for new signature. |
| tests/Spice86.Tests/CfgCpu/CfgNodeFeederTest.cs | Updates feeder construction for new signature. |
| tests/Spice86.Tests/CfgCpu/CfgGraphReloadTest.cs | Adds reload invariant test for node index registration. |
| src/Spice86/Spice86DependencyInjection.cs | Wires config flag, passes node index to writer, seeds IRQ handlers as roots. |
| src/Spice86.Core/Emulator/StateSerialization/EmulationStateDataWriter.cs | Serializes CFG reload dump with poison set. |
| src/Spice86.Core/Emulator/StateSerialization/CfgReload/CfgReloadNodeInfo.cs | Adds persisted speculative flag per node. |
| src/Spice86.Core/Emulator/StateSerialization/CfgReload/CfgReloadExporter.cs | Exports speculative flag + poisoned addresses. |
| src/Spice86.Core/Emulator/StateSerialization/CfgReload/CfgReloadDump.cs | Adds poisoned addresses field to dump format. |
| src/Spice86.Core/Emulator/StateSerialization/CfgReload/CfgGraphReloader.cs | Restores speculative flags, registers into node index, restores poison set. |
| src/Spice86.Core/Emulator/ReverseEngineer/CSharpOverrideHelper.cs | Adds runtime VerifySpeculativeEntryOrFail guard helper. |
| src/Spice86.Core/Emulator/ReverseEngineer/ControlFlowGraph/CfgBlockGraphExporter.cs | Documents speculative reachability via BFS from wired edges. |
| src/Spice86.Core/Emulator/ReverseEngineer/CfgCodeGeneration/MethodEmitter.cs | Emits speculative guards at block entry / first speculative instruction. |
| src/Spice86.Core/Emulator/ReverseEngineer/CfgCodeGeneration/CSharpAstEmitter.cs | Handles unobserved indirect dispatch at runtime; far-call fallback to override lookup. |
| src/Spice86.Core/Emulator/ReverseEngineer/CfgCodeGeneration/CfgGeneratorContext.cs | Exposes speculation flag for emission decisions. |
| src/Spice86.Core/Emulator/Devices/ExternalInput/DualPic.cs | Adds enumeration of delivered IRQ vector numbers. |
| src/Spice86.Core/Emulator/CPU/CfgCpu/Parser/SpecificParsers/LoopParser.cs | Registers static successor addresses for LOOP forms. |
| src/Spice86.Core/Emulator/CPU/CfgCpu/Parser/SpecificParsers/JmpParser.cs | Registers static successor addresses for JMP immediate forms. |
| src/Spice86.Core/Emulator/CPU/CfgCpu/Parser/SpecificParsers/JcxzParser.cs | Registers static successor addresses for JCXZ/JECXZ. |
| src/Spice86.Core/Emulator/CPU/CfgCpu/Parser/SpecificParsers/JccParser.cs | Registers taken + fallthrough static successors for Jcc. |
| src/Spice86.Core/Emulator/CPU/CfgCpu/Parser/SpecificParsers/CallParser.cs | Registers static successor address for CALL near immediate. |
| src/Spice86.Core/Emulator/CPU/CfgCpu/Parser/InstructionParser.cs | Ensures default fallthrough successor; routes invalid group index to invalid opcode node. |
| src/Spice86.Core/Emulator/CPU/CfgCpu/ParsedInstruction/StaticSuccessor.cs | Introduces typed static successor representation. |
| src/Spice86.Core/Emulator/CPU/CfgCpu/ParsedInstruction/SelfModifying/SelectorNode.cs | Excludes speculative variants from selector dispatch cache. |
| src/Spice86.Core/Emulator/CPU/CfgCpu/ParsedInstruction/CfgInstruction.cs | Adds speculative provenance + static successor address list. |
| src/Spice86.Core/Emulator/CPU/CfgCpu/Linker/NodeLinker.cs | Adds provenance-aware conflict resolution and bidirectional edge removal helpers. |
| src/Spice86.Core/Emulator/CPU/CfgCpu/Feeder/SpeculativeReachabilityPruner.cs | Implements sweep/prune of speculative regions. |
| src/Spice86.Core/Emulator/CPU/CfgCpu/Feeder/SpeculativePromoter.cs | Implements in-place promotion of speculative nodes to observed. |
| src/Spice86.Core/Emulator/CPU/CfgCpu/Feeder/SpeculativeExplorer.cs | Implements speculative exploration and known-safe handler seeding. |
| src/Spice86.Core/Emulator/CPU/CfgCpu/Feeder/InstructionsFeeder.cs | Integrates node index, speculative promotion/mismatch discard, exploration trigger. |
| src/Spice86.Core/Emulator/CPU/CfgCpu/Feeder/CfgNodeIndex.cs | Adds persistent node index + poison set. |
| src/Spice86.Core/Emulator/CPU/CfgCpu/Feeder/CfgNodeFeeder.cs | Integrates speculative pruner/promoter into reconcile path. |
| src/Spice86.Core/Emulator/CPU/CfgCpu/ExecutionContextManager.cs | Adds API to register CFG entrypoints for seeded handlers. |
| src/Spice86.Core/Emulator/CPU/CfgCpu/ControlFlowGraph/ICfgNode.cs | Adds IsSpeculative/SetSpeculative to node interface. |
| src/Spice86.Core/Emulator/CPU/CfgCpu/ControlFlowGraph/CfgNode.cs | Provides default speculation behavior for non-instruction node types. |
| src/Spice86.Core/Emulator/CPU/CfgCpu/ControlFlowGraph/CfgBlock.cs | Tracks speculative counter and exposes CfgBlock.IsSpeculative. |
| src/Spice86.Core/Emulator/CPU/CfgCpu/CfgCpu.cs | Adds ctor parameter for speculative exploration and wires feeder accordingly. |
| src/Spice86.Core/CLI/Configuration.cs | Adds CLI/config flag EnableSpeculativeCfgExploration (default on). |
| SPECULATIVE_CFG_IMPLEMENTATION_PLAN.md | Adds detailed implementation plan doc for the feature. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
Comment on lines
+184
to
188
| } catch (InvalidGroupIndexException) { | ||
| // An undefined GRP reg-field selection (e.g. GRP5 reg=7) is a #UD invalid opcode: route it | ||
| // through the same invalid-node machinery as other invalid opcodes instead of crashing the decode. | ||
| return BuildInvalidInstruction(address, prefixes, opcodeField, new CpuInvalidOpcodeException($"Invalid group index at {address}")); | ||
| } |
Comment on lines
+295
to
+296
| reloaded.Should().NotBeNull(); | ||
| reloaded!.PoisonedAddresses.Should().Contain(poisonedAddr.ToString()); |
Comment on lines
+100
to
+107
| if (_nodeIndex.HasAddress(address)) { | ||
| // Convergence: wire edge to existing node | ||
| CfgInstruction? existing = FirstNodeAtAddress(address); | ||
| if (existing is not null && item.Predecessor is not null) { | ||
| _nodeLinker.Link(item.EdgeType, item.Predecessor, existing); | ||
| } | ||
| continue; | ||
| } |
50fb97d to
bd75bf4
Compare
bd75bf4 to
b85633c
Compare
Comment on lines
+883
to
+889
| foreach (SegmentedAddress handlerAddress in handlerAddresses) { | ||
| CfgInstruction? entryNode = instructionsFeeder.NodeIndex.GetAtAddress(handlerAddress) | ||
| .FirstOrDefault(node => node.ContainingBlock is not null); | ||
| if (entryNode is not null) { | ||
| cfgCpu.ExecutionContextManager.RegisterEntryPoint(entryNode); | ||
| } | ||
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
No description provided.