-
Notifications
You must be signed in to change notification settings - Fork 11
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
This PR is an alternative to #99. This is built on top of #116. With this PR, the following test cases now pass correctly: ```julia # Final block is not a `return`: Need to use `config::SelectiveEvalRecurse` explicitly ex = quote x = 1 yy = 7 @Label loop x += 1 x < 5 || return yy @goto loop end frame = Frame(ModSelective, ex) src = frame.framecode.src edges = CodeEdges(ModSelective, src) config = SelectiveEvalRecurse() isrequired = lines_required(GlobalRef(ModSelective, :x), src, edges, config) selective_eval_fromstart!(config, frame, isrequired, true) @test ModSelective.x == 5 @test !isdefined(ModSelective, :yy) ``` The basic approach is overloading `JuliaInterpreter.step_expr!` and `LoweredCodeUtils.next_or_nothing!` for the new `SelectiveEvalController` type, as described below, to perform correct selective execution. When `SelectiveEvalController` is passed as the `recurse` argument of `selective_eval!`, the selective execution is adjusted as follows: - **Implicit return**: In Julia's IR representation (`CodeInfo`), the final block does not necessarily return and may `goto` another block. And if the `return` statement is not included in the slice in such cases, it is necessary to terminate `selective_eval!` when execution reaches such implicit return statements. `controller.implicit_returns` records the PCs of such return statements, and `selective_eval!` will return when reaching those statements. This is the core part of the fix for the test cases in #99. - **CFG short-cut**: When the successors of a conditional branch are inactive, and it is safe to move the program counter from the conditional branch to the nearest common post-dominator of those successors, this short-cut is taken. This short-cut is not merely an optimization but is actually essential for the correctness of the selective execution. This is because, in `CodeInfo`, even if we simply fall-through dead blocks (i.e., increment the program counter without executing the statements of those blocks), it does not necessarily lead to the nearest common post-dominator block. And now [`lines_required`](@ref) or [`lines_required!`](@ref) will update the `SelectiveEvalController` passed as their argument to be appropriate for the program slice generated. One thing to note is that currently, the `controller` is not be recursed. That said, in Revise, which is the main consumer of LCU, there is no need for recursive selective execution, and so `selective_eval!` does not provide a system for inter-procedural selective evaluation. Accordingly `SelectiveEvalController` does not recurse too, but this can be left as a future extension.
- Loading branch information
Showing
7 changed files
with
161 additions
and
35 deletions.
There are no files selected for viewing
This file contains 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
This file contains 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
This file contains 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
This file contains 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
This file contains 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
This file contains 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
This file contains 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