Skip to content

Refine+AInvs: performance improvements (clear_named_theorems, avoid interpretation Arch and interpret Arch) - #1047

Open
Xaphiosis wants to merge 7 commits into
seL4:masterfrom
Xaphiosis:refine_nmc
Open

Refine+AInvs: performance improvements (clear_named_theorems, avoid interpretation Arch and interpret Arch)#1047
Xaphiosis wants to merge 7 commits into
seL4:masterfrom
Xaphiosis:refine_nmc

Conversation

@Xaphiosis

@Xaphiosis Xaphiosis commented Aug 21, 2026

Copy link
Copy Markdown
Member

Please review commit-by-commit. The "big" commits really consist of tiny changes to many files.

Introduce the clear_named_theorems command plus tests/documentation, then use it to get rid of all the named_theorems declarations throughout Refine, in lieu of a single Arch_assms which we re-use every time we want to accumulate Arch interface locale assumptions. Then we export it to a lemma name which we can access directly from outside Arch in order to interpret the interface locale.

This means print_attributes isn't going to be a flood of all the named_theorems.

The name perturbations that named_theorems produced are now gone, so I had to put back the arch prefixes I previously had to remove when I introduced the named_theorems uses in Refine.

A few small cleanups snuck in, and then I managed to remove every single interpret Arch . and interpretation Arch . in Refine.

Then I did the same thing for AInvs. There was more turbulence, but once again, no more interpret Arch . or interpretation Arch . remains.

Benchmarks are in progress (I wrote a tool, Corey is helping me test it), but it's definitely an improvement. E.g. internal isabelle timing reports around 8.5 minutes for RISCV64 Refine vs around 9 before this change (on my fast main machine).

@ryybrr : tagging you since you'll probably want to copy this for InfoFlow at some point; I can assist.

Benchmark

Comparison of current master (f494027) and named_theorems optimisation branch (August 2026). Times are session processing times as reported by Isabelle in seconds, do not confuse them with run_tests times. Benchmark ran on pcr ( i9-12900K) using 8 max threads. Times are average of 5 runs after an initial warm-up.

ARM Time before after improved s % CPU time before after improved s %
AInvs 366 353 13 3.6% 2023 1922 101 5.0%
Refine 761 721 40 5.3% 4235 3929 306 7.2%
CBaseRefine 714 698 16 2.2% 1123 1100 23 2.0%
ARM_HYP Time before after improved s % CPU time before after improved s %
AInvs 540 525 15 2.8% 2482 2351 131 5.3%
Refine 945 871 74 7.8% 5017 4600 417 8.3%
CBaseRefine 1014 968 46 4.5% 1612 1525 87 5.4%
RISCV64 Time before after improved s % CPU time before after improved s %
AInvs 296 295 1 0.3% 1782 1761 21 1.2%
Refine 713 672 41 5.8% 4069 3770 299 7.3%
CBaseRefine 606 591 15 2.5% 945 917 28 3.0%
X64 Time before after improved s % CPU time before after improved s %
AInvs 437 430 7 1.6% 2408 2325 83 3.4%
Refine 1066 895 171 16.0% 5774 4659 1115 19.3%
CBaseRefine 936 918 18 1.9% 1491 1456 35 2.3%
AARCH64 Time before after improved s % CPU time before after improved s %
AInvs 447 425 22 4.9% 2522 2355 167 6.6%
Refine 971 902 69 7.1% 5255 4730 525 10.0%
CBaseRefine 1084 1080 4 0.4% 1790 1687 103 5.8%
Combined Time before after improved s % CPU time before after improved s %
AInvs 2086 2028 58 2.8% 11217 10714 503 4.5%
Refine 4456 4061 395 8.9% 24350 21688 2662 10.9%
CBaseRefine 4354 4255 99 2.3% 6961 6685 276 4.0%

Benchmark Discussion

Overall, this saves 9.2 minutes of real time across the three images, and 57 minutes of CPU time. As expected, the major improvement is Refine, with between 5.8% to 16% real time speedup. AInvs still benefited, with 0.3% to 4.9% speedup, and CBaseRefine got a marginal boost.

Apparently, clearing the pipeline stall during an interpret Arch . when interpreting an interface locale only results in a larger improvement when there is something to shove into the pipes before the next stall. In CBaseRefine which is running with skip proofs on, there isn't a lot. In AInvs, the interpret doesn't take as long, it only really becomes more expensive when we hit Refine. Nonetheless the 0.3% improvement on RISCV64 AInvs is unexpectedly low. Standard deviation on that run is under 1s, so it's not jitter.

Another possibility is that the Refine arch-split is very aggressive, significantly reducing the amount of arch-specific proofs, and so relying on interfaces more.

Allows an existing named_theorems to be cleared and then re-used,
allowing the construction of re-usable theorem accumulators.

Signed-off-by: Rafal Kolanski <rafal.kolanski@proofcraft.systems>
By using clear_named_theorems, we will re-use this dynamic named
theorems set to satisfy Arch interface locale assumptions.

Signed-off-by: Rafal Kolanski <rafal.kolanski@proofcraft.systems>
Clear out uses of `named_theorems *_assms` and adding theorems to these
assms in lieu of clearing + using Arch_assms. Greatly reduces attribute
namespace pollution. Additionally:
* remove all remaining occurrences of `interpret Arch .` in Refine
* export Arch_assms to appropriate lemmas set for use in interpreting
  Arch interface locales
* add some missing (* Arch *) tags
* clean up confused naming of KHeap_R_assms_2
* named_theorems used to perturb naming schemes; now that we don't
  introduce new named_theorems, global.some_def now gets picked up as
  the default again

Use `fact L4V_ARCH.whatever_assms` instead of `fact whatever_assms` when
satisfying locale assumptions. Since `whatever_assms` no longer exists,
we use a `lemmas` statement to exfiltrate the assumptions from the Arch
locale without interpretation, resulting in a performance improvement.

Used the following .sed script for removing named_theorems and relevant
_assms references. Please recombine commands into a single line, the
first is split to satisfy gitlint:

```
/Arch_assms/!s/named_theorems \([A-Z]\w\+\)_assms/
clear_named_theorems Arch_assms (* accumulate assumptions for \1 locale *)/

/Arch_assms/!s/\(\[\)[A-Z]\w\+_assms/\1Arch_assms/
/Arch_assms/!s/[A-Z]\w\+_assms\(\]\)/Arch_assms\1/
```

Used the following sed command to add the specific arch prefix to
`fact whatever_assms`; e.g. for AARCH64 it ends up as
AARCH64.whatever_assms when we do this in proof/refine:

```
sed -i -e '/Arch_assms/!s/fact \([A-Z]\w\+_assms\))?/fact AARCH64.\1)?/' \
AARCH64/*.thy
```

Signed-off-by: Rafal Kolanski <rafal.kolanski@proofcraft.systems>
The ones in LevityCatch did not need exporting, and the ones in
ArchInvsLemmas only needed importing a simp rule or two from Arch.

Signed-off-by: Rafal Kolanski <rafal.kolanski@proofcraft.systems>
Clear out uses of `named_theorems *_assms` and adding theorems to these
assms in lieu of clearing + using Arch_assms. Greatly reduces attribute
namespace pollution. Additionally:
* remove all remaining occurrences of `interpret Arch .` in AInvs
* export Arch_assms to appropriate lemmas set for use in interpreting
  Arch interface locales; for AInvs, this required a bit of creativity
  in places

Please see recent "refine: use Arch_assms in lieu of named_theorems"
commit for the sed scripts and commands used as a base for these
changes.

Signed-off-by: Rafal Kolanski <rafal.kolanski@proofcraft.systems>
For ArchRetype_AI we are still left with the two instances of
`interpretation retype_region_proofs_arch ..` which are slow.

Signed-off-by: Rafal Kolanski <rafal.kolanski@proofcraft.systems>
Due to cleanup of `interpretation Arch .` in AInvs certain facts were
not leaked by default. In this case, vs_lookup_table' did not make it
from retype_region_proofs_arch to retype_region_proofs.

This solves the immediate issue, and doing an arch-based locale
interpretation right after a `interpretation Arch .` does not incur a
slowdown. In the longer term, `interpretation Arch .` is slow, and the
interaction between retype_region_proofs_arch and retype_region_proofs
should be overhauled.

Signed-off-by: Rafal Kolanski <rafal.kolanski@proofcraft.systems>
@Xaphiosis Xaphiosis changed the title Refine: performance improvements (clear_named_theorems, avoid interpretation Arch and interpret Arch) Refine+AInvs: performance improvements (clear_named_theorems, avoid interpretation Arch and interpret Arch) Aug 22, 2026
Going via Local_Theory.declaration does work, even if we have to give it a "morphism" that
doesn't actually contain a morphism. *)
fun alt_proof_map f =
Local_Theory.declaration {syntax = false, pervasive = false, pos = \<^here>} (fn _ => f);

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'd probably replace (fn _ => f) by (K f) as the more usual form in the Isabelle sources.

alt_proof_map is not really the right name, because proof_map is exactly not the thing we're doing. Looking at the code of Local_Theory.declaration, proof_map is just one of multiple primitive steps in there. Basically proof_map is a primitive lifting operation, and declaration does all of the actual context handling of the locale. What we're doing really is a declaration command like a declare (and we're also giving the keyword type thy_decl, which is correct), so maybe local_declare as a name? The morphism is safe to ignore in this case, because we are not referring to any locale fixes or anything like that, so there is nothing to transform.

val _ =
Outer_Syntax.local_theory \<^command_keyword>\<open>clear_named_theorems\<close>
"clear named collection of theorems"
((Parse.name_position) >>

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

(Parse.name_position) -> Parse.name_position

Comment on lines +570 to +571
(* FIXME arch-split: koType_asidpool and koType_pte are somehow [simp] even outside Arch on AARCH64
due to how pre_storable *)

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The sentence is cut off. Due to how pre_storable works?

Comment on lines +575 to +576
instance by intro_classes
(auto simp: AARCH64_H.arch_kernel_object_type.distinct)

@lsf37 lsf37 Aug 23, 2026

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Indent seems slightly off in the second line in GitHub view. The ( should be under the I of intro_classes (globally in this commit). If that's the case already, please ignore.

@lsf37 lsf37 left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Very nice!

So much name space pollution removed, I'm glad you pushed for looking into this.

@Xaphiosis

Copy link
Copy Markdown
Member Author

Updated PR description with benchmark. Will deal with PR comments after weekend.

@lsf37

lsf37 commented Aug 23, 2026

Copy link
Copy Markdown
Member

Those are some pretty nice numbers, X64 is getting a real boost. Not sure why RISCV64 isn't seeing that much improvement, but overall it is an excellent picture.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

arch-split splitting proofs into generic and architecture dependent

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants