Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

roadmap to spec #40

Open
matu3ba opened this issue Aug 8, 2022 · 4 comments
Open

roadmap to spec #40

matu3ba opened this issue Aug 8, 2022 · 4 comments

Comments

@matu3ba
Copy link

matu3ba commented Aug 8, 2022

The Rust project has 3 related attempts to cover the spec

It could help to have something simple and showable for interested contributors, for which 1 sounds most approachable.
I suspect that 2 will be, with the exception of custom linker semantics (if ever introduced) and under assumption that we have exactly 1 compilation step without generated code to be used, relative simple to derive once we have some sort of model for comptime+runtime semantics.
At least, for now, under the assumption that we dont take into account hardware specifics not covered by the current C11 memory model for parallel execution semantics.
This is due to (if you read the linked paper below) optimizations for weak memory have thread-local and global effects (a thread-local optimization can enable a global one and vice versa), so I am very unsure if and how those should be represented in the type system or how to insert safety checks.

So at least from my point of view to prevent the churn of increasing a lot of paper without a lot meaning, it would be nice to start with 1 and provide a list of open semantic questions contributors can toy with and come up with something better.

Any ideas how to proceed with this? Is this the correct place to discuss or should I open an issue on the Zig compiler repo?

The related discussion
Q:
"Do you have already ideas on simplifying cache synchronisation protocol semantics? The C11 model has many severe flaws, which prevent a lot optimizations. You probably know this already, but for other interested readers https://plv.mpi-sws.org/c11comp/"
A: "so far I am not planning on touching that. I hope someone else will solve it and I just need to plug in the solutions... and there is some nice progress .. https://dl.acm.org/doi/pdf/10.1145/3385412.3386010" ("Promising 2.0: Global Optimizations
in Relaxed Memory Concurrency" by Lee et al.)
Source https://www.reddit.com/r/rust/comments/wiwjch/comment/ijfo2k6/?utm_source=share&utm_medium=web2x&context=3

Link to Coq proofs: https://github.com/snu-sf/promising2-coq

Update1: added brief reddit discussio
Update2: added coq proofs

@exxjob
Copy link

exxjob commented Jan 1, 2024

I'd like to highlight that formal verification is non-negotiable for high integrity software. Even though scoping precisely what's to be verified is a premature question, it would be good to figure out how to go about it. I would suggest this be at least in-progress for 1.0 given the inherent benefits and necessity. It will theoretically aid ongoing design research, and nurish specification development, error proofing, future proofing, and trust. If brought up too little too late, this can devolve into debt and effort fragmentation. Direct inspiration can be taken from CompCert, CakeML, potentially Vellvm and others. A handful of verifications could be repurposed. There is also a hypothetical for Zig to integrate proof assistant capabilities eventually, either like ATS or SPARK, but for now that remains a stretch. ziglang/zig#1776, ziglang/zig#5025

@matu3ba
Copy link
Author

matu3ba commented Jan 1, 2024

Status 20240101

Simplified compilation code paths

                     future optimizations
                      ▲─►    ▲─►
                      │ │    │ │
                      │ │    │ │
     1      2      3  │ ▼ 4  │ ▼               5
.zig ─► AST ─► ZIR ─► AIR ─► MIR (per arch)    ─► Machine Code
   ▲    │      │ ▲        6                    7
   │    │      │ │        ─► LLVM IR (builder) ─► Machine Code
   │    │      │ │        8
   │    │      │ │        ─► LLVM IR bc        ─► Machine Code
   │    │      ▼ │           (future)
   ◄────▼    cached files
     9          10

- 0 main => module => src\Compilation.zig update()
- 1 tokenizer.zig (~1.3k LOC) + Parse.zig (~4.1k LOC); result Ast.zig
- 2 AstGen.zig (~13k LOC); result Zir.zig
- 3 Sema.zig (~38.1k LOC); result Air.zig
- 4 x86_64 CodeGen.zig (~16.6k LOC) result Mir.zig
- 5 x86_64 Lower.zig + Emit.zig + bits etc (~4k LOC)
- 6 left out
- 7 left out
- 8 left out
- 9 zig fmt
- 10 per decl caching system

main controls logic via build.zig (Module.zig, Build.zig etc)
More detailed sketch

┌───────────────────┬───────────────────────────────────────────┐
│                   │  future optimizations                     │
│                   │   ▲─►    ▲─►                              │
│                   │   │ │    │ │                              │
│                   │   │ │    │ │              ┌───────────────┐
│     1      2      │3  │ ▼ 4  │ ▼              │5              │
│.zig ─► AST ─► ZIR │─► AIR ─► MIR (per arch)   │─► Machine Code│
│ │ ▲    │      │ ▲ │       6                   │7  (file)      │
│ │ │    │      │ │ │       ─► LLVM IR (builder)│─► Machine Code│
│ │ │    │      │ │ │       8                   │   (file)      │
│ │ │    │      │ │ │       ─► LLVM IR bc       │─► Machine Code│
│ │ │    │      ▼ │ │          (future)         │   (file)      │
│ │ ◄────▼    cached│ files                     └───────────────┘
│ │   9        │ 10 │                             │             │
└─┼────────────┼────┴─────────────────────────────┼─────────────┘
  │   ▼────────┘                                  │
  └►module◄───────────────────────────────────────┘
    job system with - 1+2
                    - 3 (per decl)
                    - 4 (per fn)
                    - linking (per section?, parallelization+semantics not clear yet)
                    - other build tasks (translating zig code to get header info etc)
    with traversal of build graph (DAG) depending on build.zig

Incremental compilation would also include the linker to store and patch
(symbol, section offsets, binary positions) for decl changes for each file
including rerunning all follow-up dependencies of the build DAG.

@matu3ba
Copy link
Author

matu3ba commented Jan 1, 2024

Even though scoping precisely what's to be verified is a premature question

  1. We still have no semantic specification of Zig file semantics with one of the biggest reasons being unclear result location semantics.
  2. Parser would be feasible, AstGen very challenging with 13k LOC, Sema huge work (likely more than 50k once Zig is finished even on ignoring parallel evluation on semantics and incremental semantics [sounds tricky to ignore during during verification]).

Direct inspiration can be taken from CompCert, CakeML, potentially Vellvm and others.

  1. Can you provide some better guidance on which methods are applicable and which not? As example, CakeML is developed within a proof framework, whereas Zig is not. As I understand it, this also applies to Pancake, which sounds to me like the closest corresponding thing we could aim for in/with Zig https://cakeml.org/pancake.

  2. The biggest obstacle to verification is that high level languages and optimizing backends like LLVM would prefer more optimizations, which require high level semantics. However, those are not (yet) tractable enough and lead to ambiguity between platform semantics and portability concerns. This applies to 1. pointer semantics and 2. synchronization semantics. Can you follow me here or do you need more specific examples from Adopt a Zig Memory Model zig#6396?

  3. Can you be more specific what you expect to be shown? My expectation would be to have a formal model that shows Zig's semantics and show that it is sufficiently expressive (complete only works, if one could "patch the target semantics in" but formal models are rarely commutative), consistent and correct regarding hardware models. I do not expect a full verification of the ZIg codebase due to ZIg's scope, only the most relevant IRs and the overall code design.

  4. Something like https://github.com/vellvm/vellvm would be useful, but would mandate a stable enough AIR.

@exxjob
Copy link

exxjob commented Jan 3, 2024

I did say it's a premature matter. What I'm stressing is that long-term this should be emphasized to an extent, especially for major releases of Zig, rather than embrace fallacies like Go, where "implementation as a specification" is meant literally. Past Zig itself, bootstrap and utilities should also be considered.

Indeed not everything is verifiable nor does it have to be. However, lack of formal proof motivates using or creating alternatives, as alluded to before. Some of the examples are probably better used as exhibits in this sense. This is entirely open ended but I can imagine a combination of tools as in F* appropriate in the future, not excluding in context of crypto.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants