{"id":19212552,"url":"https://github.com/fasterthanlime/openvolt-notes","last_synced_at":"2026-02-27T20:04:50.640Z","repository":{"id":66881741,"uuid":"200275833","full_name":"fasterthanlime/openvolt-notes","owner":"fasterthanlime","description":"Notes from early discussions","archived":false,"fork":false,"pushed_at":"2019-08-02T18:26:13.000Z","size":3,"stargazers_count":2,"open_issues_count":0,"forks_count":0,"subscribers_count":3,"default_branch":"master","last_synced_at":"2025-01-04T17:30:51.600Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":null,"has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/fasterthanlime.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2019-08-02T17:49:18.000Z","updated_at":"2022-10-24T10:35:39.000Z","dependencies_parsed_at":"2023-02-27T21:45:55.693Z","dependency_job_id":null,"html_url":"https://github.com/fasterthanlime/openvolt-notes","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/fasterthanlime%2Fopenvolt-notes","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/fasterthanlime%2Fopenvolt-notes/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/fasterthanlime%2Fopenvolt-notes/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/fasterthanlime%2Fopenvolt-notes/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/fasterthanlime","download_url":"https://codeload.github.com/fasterthanlime/openvolt-notes/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":240286520,"owners_count":19777353,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2024-11-09T13:47:19.841Z","updated_at":"2025-11-13T20:01:54.641Z","avatar_url":"https://github.com/fasterthanlime.png","language":null,"funding_links":[],"categories":[],"sub_categories":[],"readme":"\n## License\n\nMIT is weird outside the US and doesn't cover patents, which means if someone\ncontributes something and changes their mind, then folks can have the code, but\ndon't have the right to use it.\n\nApache-2.0 covers patents, as in: contributors grant the rights to use all the patents\nthe code might be covered by, forever, which is great.\n\nrustc is MIT+Apache-2.0 (along with a lot of crates), seems good.\n\nEU funding for unstarted projects requires EUPL. More flexible if project already started.\n\nMPL (Mozilla Public License) also worth looking into.\n\nMost likely MIT+Apache-2.0 is fine.\n\nCLA (Contributor License Agreement): would let us relicense easily, might be good\nearly on with small team, but probably not something we want in the long term.\n\n## Funding\n\nCrowd funding, grants, corporate sponsorship, different ways to arrive to sustainability.\n\n## Overflow (int)\n\nWe should do it safely, three modes:\n\n  * Trap\n  * Saturate\n  * Overflow\n  \n## Overflow (buffer)\n\nHave a native slice type, do some checking.\n\nBound check instruction different from integer comparison.\n\n## Performance\n\nMain challenge for this is figuring out good data structures.\n\nFocus for this is compilation speed rather than speed of the generated code, because of the usecases:\n\n  * JavaScript (fast startup)\n  * GPU - same problem\n  \nLLVM has a \"sea of pointers\", lots of indirection / bad cache locality, we can just have an array of\nfixed-size instructions (larger instructions like metadata can be stored elsewhere and we can point to it).\n\nThis makes optimization passes take one big array and return another one, copying is very fast compared\nto allocation, have to test how ergonomic this will be in practice.\n\n## Vectorization\n\nHave \"Vector IR\", but do not attempt automatic vectorization, which a) is a complex research area\nand b) has limited results. Easier (much, much easier) to do `vector ➡ scalar` than the reverse.\nSee https://polly.llvm.org/\n\n## SSA\n\nSingle static assignment is good, not sure about Phi nodes, must research various passes and see\nwhen it is really convenient (rather than arrows pointing in the opposite direction).\n\nWe probably want SSA *always*, even when not performing any optimizations, because it is useful for codegen.\n\n## API\n\nAPI stability is a very important thing, this means the text IR but also the C public API, which\nshould never break inside of a major release.\n\nThe Rust public API can change more often (it'll also be safer).\n\nAPI should include:\n\n  * Builder API, to build IR without using text\n  * Serialiation/Deserialization API\n  * Driver API, to actually optimize/codegen\n\n## Register allocation\n\nDifferent heuristics, allow selecting between them through IR annotations, there's cases\nwhen you want high register usage, and cases where you want to leave some available (for\nexample for other threads on (allocated) 256-register architectures (CUDA).\n\n\u003e The idea is that if thread A uses all 256 registers and thread B needs 32, then 32\nregisters need to be saved to stack and restored before resuming thread A. Also, you\nmight think you need 256 registers, but some of them can be moved out of a loop\n(see LICM, Loop Invariant Code Motion).\n\n## Optimizations\n\nPasses to realistically target first:\n\n  * Legalization (e.g. MIPS only has 64-bit integer arithmetic, ARM only has 64-bit \u0026 32-bit, what if we need 16-bit wide types? Masking etc.)\n  * Strength reduction (e.g. SHUFFLE =\u003e BSWAP)\n  * `mem2reg`: Promoting memory to register\n  * `argpromotion`: Promote 'by reference' arguments to scalars\n  \nBut also:\n\n  * `dce` (Dead code elimination)\n  * `always-inline`\n  * `memcpyopt`\n\n## Debug\n\nWe need great tooling at all steps, examples of nice things:\n\n  * Syntax highlighting for IR\n  * Debugging what passes\n  * Diffs before/after DCE (dead code elimination)\n  * Graphs (graphviz), for SSA tree, dependency analysis\n\n## DWARF \u0026 friends\n\nrust's msvc target is fresh, LLVM got Windows calling conventions \u0026 debug info only recently (2017-2018?),\nwe should plan for it, apparently it's hard to get right. (But it is very important)\n\n## Error handling\n\nHave actual (nice) errors, crashes should only be caused by compiler bugs, not API misuse.\n\n## Plugins / modularity\n\nAll of it needs to be modular so that third-party code doesn't *have* to live in a fork\nor in the mainline repository.\n\n## Type system\n\nMakes sense to look at LLVM's, keeping in mind that:\n\n  * `poison` is bad\n  * `undef` is slightly less bad\n  * don't pander to C-like languages, do the safe thing when possible\n\n### Types\n\n  * `void`, `function`,\n  * integers: uN, iN, same instructions for add/sub/mul/div, N in {8, 16, 32, 64}\n  * floating point types\n  * pointers: two types:\n    * one safe (can only take the address of something we know exists, no arithmetic),\n    * one unsafe (everything's allowed)\n    * also have to think about address spaces, they have numbers, that mean different things on target arch\n    * larger discussion about IR target independence\n  * `vector` type (SIMD, with width)\n  * `label` type (because of jump tables)\n  * `metadata` type: more structured than just tuples, maybe at least a hash\n  * `struct`\n  * `opaque` type (not opaque struct), that you can have pointers to, but not values of\n  * `bool` type (not i1) - it's special-cased anyway\n  * `arrays` (fixed size)\n  * `slices` (address + length)\n  \n### Constants\n\n  * `undef` is a value not a type, propagates until we try to optimize or codegen it, then error out\n  * no `zeroinitializer`, make compiler devs be explicit\n  * no poison values, not interested in speculative execution\n  * const operations are important, would be interested in generating runtime instructions for these so you can step through them and figure out why the const result is wrong\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ffasterthanlime%2Fopenvolt-notes","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Ffasterthanlime%2Fopenvolt-notes","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ffasterthanlime%2Fopenvolt-notes/lists"}