summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorStefan Weigl-Bosker <stefan@s00.xyz>2026-01-05 12:40:09 -0500
committerStefan Weigl-Bosker <stefan@s00.xyz>2026-01-10 15:37:46 -0500
commitd4b629cc275769c2553db819643849cda2395a17 (patch)
tree6dcc5d0c886945f8b58b4d8fd6c7eea4bb1b194d
downloadcompiler-d4b629cc275769c2553db819643849cda2395a17.tar.gz
init
wip wip, pt2 wip, pt3
-rw-r--r--.bazelrc2
-rw-r--r--.clang-format3
-rw-r--r--.clang-tidy72
-rw-r--r--.gitignore7
-rw-r--r--.pre-commit-config.yaml6
-rw-r--r--BUILD9
-rw-r--r--LICENSE15
-rw-r--r--MODULE.bazel19
-rw-r--r--MODULE.bazel.lock207
-rw-r--r--nix/flake.lock61
-rw-r--r--nix/flake.nix60
-rw-r--r--willow/BUILD.bazel13
-rw-r--r--willow/MODULE.bazel4
-rw-r--r--willow/MODULE.bazel.lock139
-rw-r--r--willow/docs/doxygen/Doxyfile10
-rw-r--r--willow/include/willow/IR/BasicBlock.h98
-rw-r--r--willow/include/willow/IR/Function.h104
-rw-r--r--willow/include/willow/IR/IRBuilder.h20
-rw-r--r--willow/include/willow/IR/Instruction.h61
-rw-r--r--willow/include/willow/IR/Module.h54
-rw-r--r--willow/include/willow/IR/TypeContext.h57
-rw-r--r--willow/include/willow/IR/Types.h108
-rw-r--r--willow/include/willow/IR/Value.h50
-rw-r--r--willow/lib/IR/TypeContext.cpp0
24 files changed, 1179 insertions, 0 deletions
diff --git a/.bazelrc b/.bazelrc
new file mode 100644
index 0000000..9149678
--- /dev/null
+++ b/.bazelrc
@@ -0,0 +1,2 @@
+common --shell_executable=/nix/store/1jzhbwq5rjjaqa75z88ws2b424vh7m53-bash-5.2p32/bin/bash
+build --cxxopt='-std=c++23'
diff --git a/.clang-format b/.clang-format
new file mode 100644
index 0000000..76cc928
--- /dev/null
+++ b/.clang-format
@@ -0,0 +1,3 @@
+BasedOnStyle: LLVM
+AlwaysBreakTemplateDeclarations: Yes
+LineEnding: LF
diff --git a/.clang-tidy b/.clang-tidy
new file mode 100644
index 0000000..c419033
--- /dev/null
+++ b/.clang-tidy
@@ -0,0 +1,72 @@
+InheritParentConfig: true
+Checks: >
+ bugprone-argument-comment,
+ bugprone-assert-side-effect,
+ bugprone-branch-clone,
+ bugprone-copy-constructor-init,
+ bugprone-dangling-handle,
+ bugprone-dynamic-static-initializers,
+ bugprone-macro-parentheses,
+ bugprone-macro-repeated-side-effects,
+ bugprone-misplaced-widening-cast,
+ bugprone-move-forwarding-reference,
+ bugprone-multiple-statement-macro,
+ bugprone-suspicious-semicolon,
+ bugprone-swapped-arguments,
+ bugprone-terminating-continue,
+ bugprone-unused-raii,
+ bugprone-unused-return-value,
+ misc-redundant-expression,
+ misc-static-assert,
+ misc-unused-using-decls,
+ modernize-use-bool-literals,
+ modernize-loop-convert,
+ modernize-make-unique,
+ modernize-raw-string-literal,
+ modernize-use-equals-default,
+ modernize-use-default-member-init,
+ modernize-use-emplace,
+ modernize-use-nullptr,
+ modernize-use-override,
+ modernize-use-using,
+ performance-for-range-copy,
+ performance-implicit-conversion-in-loop,
+ performance-inefficient-algorithm,
+ performance-inefficient-vector-operation,
+ performance-move-const-arg,
+ performance-no-automatic-move,
+ performance-trivially-destructible,
+ performance-unnecessary-copy-initialization,
+ performance-unnecessary-value-param,
+ readability-avoid-const-params-in-decls,
+ readability-const-return-type,
+ readability-container-size-empty,
+ readability-inconsistent-declaration-parameter-name,
+ readability-misleading-indentation,
+ readability-redundant-control-flow,
+ readability-redundant-smartptr-get,
+ readability-simplify-boolean-expr,
+ readability-simplify-subscript-expr,
+ readability-use-anyofallof
+
+
+CheckOptions:
+ - key: readability-identifier-naming.MemberCase
+ value: lower_case
+ - key: readability-identifier-naming.VariableCase
+ value: lower_case
+ - key: readability-identifier-naming.LocalVariableCase
+ value: lower_case
+ - key: readability-identifier-naming.ParameterCase
+ value: lower_case
+ - key: readability-identifier-naming.FunctionCase
+ value: camelBack
+ - key: readability-identifier-naming.ClassCase
+ value: CamelCase
+ - key: readability-identifier-naming.StructCase
+ value: CamelCase
+ - key: readability-identifier-naming.UnionCase
+ value: CamelCase
+ - key: readability-identifier-naming.ConstantCase
+ value: UPPER_CASE
+
diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000..b267e53
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1,7 @@
+# Ignore all bazel-* symlinks. There is no full list since this can change
+# based on the name of the directory bazel is cloned into.
+/bazel-*
+# Ignore outputs generated during Bazel bootstrapping.
+/output/
+user.bazelrc
+/out
diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml
new file mode 100644
index 0000000..2d278e4
--- /dev/null
+++ b/.pre-commit-config.yaml
@@ -0,0 +1,6 @@
+repos:
+ - repo: https://github.com/pre-commit/mirrors-clang-format
+ rev: v17.0.6
+ hooks:
+ - id: clang-format
+ files: "\\.(c|cc|cpp|cxx|h|hh|hpp)$"
diff --git a/BUILD b/BUILD
new file mode 100644
index 0000000..6cbf83c
--- /dev/null
+++ b/BUILD
@@ -0,0 +1,9 @@
+load("@hedron_compile_commands//:refresh_compile_commands.bzl", "refresh_compile_commands")
+
+refresh_compile_commands(
+ name = "refresh_compile_commands",
+
+ targets = {
+ "//willow:willow": "",
+ },
+)
diff --git a/LICENSE b/LICENSE
new file mode 100644
index 0000000..ddc8442
--- /dev/null
+++ b/LICENSE
@@ -0,0 +1,15 @@
+ISC License
+
+Copyright (c) 2026 Stefan Weigl-Bosker <stefan@s00.xyz>
+
+Permission to use, copy, modify, and/or distribute this software for any
+purpose with or without fee is hereby granted, provided that the above
+copyright notice and this permission notice appear in all copies.
+
+THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
+REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
+INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
+LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
+OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+PERFORMANCE OF THIS SOFTWARE.
diff --git a/MODULE.bazel b/MODULE.bazel
new file mode 100644
index 0000000..4e9fd6e
--- /dev/null
+++ b/MODULE.bazel
@@ -0,0 +1,19 @@
+module(
+ name = "compiler",
+ version = "0.0.1",
+)
+
+bazel_dep(name = "rules_cc", version = "0.2.16")
+bazel_dep(name = "hedron_compile_commands", dev_dependency = True)
+git_override(
+ module_name = "hedron_compile_commands",
+ remote = "https://github.com/hedronvision/bazel-compile-commands-extractor.git",
+ commit = "abb61a688167623088f8768cc9264798df6a9d10",
+)
+
+bazel_dep(name = "willow", version = "0.0.1")
+
+local_path_override(
+ module_name = "willow",
+ path = "willow",
+)
diff --git a/MODULE.bazel.lock b/MODULE.bazel.lock
new file mode 100644
index 0000000..aafa0b4
--- /dev/null
+++ b/MODULE.bazel.lock
@@ -0,0 +1,207 @@
+{
+ "lockFileVersion": 24,
+ "registryFileHashes": {
+ "https://bcr.bazel.build/bazel_registry.json": "8a28e4aff06ee60aed2a8c281907fb8bcbf3b753c91fb5a5c57da3215d5b3497",
+ "https://bcr.bazel.build/modules/abseil-cpp/20210324.2/MODULE.bazel": "7cd0312e064fde87c8d1cd79ba06c876bd23630c83466e9500321be55c96ace2",
+ "https://bcr.bazel.build/modules/abseil-cpp/20211102.0/MODULE.bazel": "70390338f7a5106231d20620712f7cccb659cd0e9d073d1991c038eb9fc57589",
+ "https://bcr.bazel.build/modules/abseil-cpp/20230125.1/MODULE.bazel": "89047429cb0207707b2dface14ba7f8df85273d484c2572755be4bab7ce9c3a0",
+ "https://bcr.bazel.build/modules/abseil-cpp/20230802.0.bcr.1/MODULE.bazel": "1c8cec495288dccd14fdae6e3f95f772c1c91857047a098fad772034264cc8cb",
+ "https://bcr.bazel.build/modules/abseil-cpp/20230802.0/MODULE.bazel": "d253ae36a8bd9ee3c5955384096ccb6baf16a1b1e93e858370da0a3b94f77c16",
+ "https://bcr.bazel.build/modules/abseil-cpp/20230802.1/MODULE.bazel": "fa92e2eb41a04df73cdabeec37107316f7e5272650f81d6cc096418fe647b915",
+ "https://bcr.bazel.build/modules/abseil-cpp/20240116.1/MODULE.bazel": "37bcdb4440fbb61df6a1c296ae01b327f19e9bb521f9b8e26ec854b6f97309ed",
+ "https://bcr.bazel.build/modules/abseil-cpp/20240116.1/source.json": "9be551b8d4e3ef76875c0d744b5d6a504a27e3ae67bc6b28f46415fd2d2957da",
+ "https://bcr.bazel.build/modules/bazel_features/1.1.1/MODULE.bazel": "27b8c79ef57efe08efccbd9dd6ef70d61b4798320b8d3c134fd571f78963dbcd",
+ "https://bcr.bazel.build/modules/bazel_features/1.11.0/MODULE.bazel": "f9382337dd5a474c3b7d334c2f83e50b6eaedc284253334cf823044a26de03e8",
+ "https://bcr.bazel.build/modules/bazel_features/1.15.0/MODULE.bazel": "d38ff6e517149dc509406aca0db3ad1efdd890a85e049585b7234d04238e2a4d",
+ "https://bcr.bazel.build/modules/bazel_features/1.17.0/MODULE.bazel": "039de32d21b816b47bd42c778e0454217e9c9caac4a3cf8e15c7231ee3ddee4d",
+ "https://bcr.bazel.build/modules/bazel_features/1.18.0/MODULE.bazel": "1be0ae2557ab3a72a57aeb31b29be347bcdc5d2b1eb1e70f39e3851a7e97041a",
+ "https://bcr.bazel.build/modules/bazel_features/1.19.0/MODULE.bazel": "59adcdf28230d220f0067b1f435b8537dd033bfff8db21335ef9217919c7fb58",
+ "https://bcr.bazel.build/modules/bazel_features/1.28.0/MODULE.bazel": "4b4200e6cbf8fa335b2c3f43e1d6ef3e240319c33d43d60cc0fbd4b87ece299d",
+ "https://bcr.bazel.build/modules/bazel_features/1.30.0/MODULE.bazel": "a14b62d05969a293b80257e72e597c2da7f717e1e69fa8b339703ed6731bec87",
+ "https://bcr.bazel.build/modules/bazel_features/1.30.0/source.json": "b07e17f067fe4f69f90b03b36ef1e08fe0d1f3cac254c1241a1818773e3423bc",
+ "https://bcr.bazel.build/modules/bazel_features/1.4.1/MODULE.bazel": "e45b6bb2350aff3e442ae1111c555e27eac1d915e77775f6fdc4b351b758b5d7",
+ "https://bcr.bazel.build/modules/bazel_features/1.9.1/MODULE.bazel": "8f679097876a9b609ad1f60249c49d68bfab783dd9be012faf9d82547b14815a",
+ "https://bcr.bazel.build/modules/bazel_skylib/1.0.3/MODULE.bazel": "bcb0fd896384802d1ad283b4e4eb4d718eebd8cb820b0a2c3a347fb971afd9d8",
+ "https://bcr.bazel.build/modules/bazel_skylib/1.1.1/MODULE.bazel": "1add3e7d93ff2e6998f9e118022c84d163917d912f5afafb3058e3d2f1545b5e",
+ "https://bcr.bazel.build/modules/bazel_skylib/1.2.0/MODULE.bazel": "44fe84260e454ed94ad326352a698422dbe372b21a1ac9f3eab76eb531223686",
+ "https://bcr.bazel.build/modules/bazel_skylib/1.2.1/MODULE.bazel": "f35baf9da0efe45fa3da1696ae906eea3d615ad41e2e3def4aeb4e8bc0ef9a7a",
+ "https://bcr.bazel.build/modules/bazel_skylib/1.3.0/MODULE.bazel": "20228b92868bf5cfc41bda7afc8a8ba2a543201851de39d990ec957b513579c5",
+ "https://bcr.bazel.build/modules/bazel_skylib/1.4.1/MODULE.bazel": "a0dcb779424be33100dcae821e9e27e4f2901d9dfd5333efe5ac6a8d7ab75e1d",
+ "https://bcr.bazel.build/modules/bazel_skylib/1.4.2/MODULE.bazel": "3bd40978e7a1fac911d5989e6b09d8f64921865a45822d8b09e815eaa726a651",
+ "https://bcr.bazel.build/modules/bazel_skylib/1.5.0/MODULE.bazel": "32880f5e2945ce6a03d1fbd588e9198c0a959bb42297b2cfaf1685b7bc32e138",
+ "https://bcr.bazel.build/modules/bazel_skylib/1.6.1/MODULE.bazel": "8fdee2dbaace6c252131c00e1de4b165dc65af02ea278476187765e1a617b917",
+ "https://bcr.bazel.build/modules/bazel_skylib/1.7.0/MODULE.bazel": "0db596f4563de7938de764cc8deeabec291f55e8ec15299718b93c4423e9796d",
+ "https://bcr.bazel.build/modules/bazel_skylib/1.7.1/MODULE.bazel": "3120d80c5861aa616222ec015332e5f8d3171e062e3e804a2a0253e1be26e59b",
+ "https://bcr.bazel.build/modules/bazel_skylib/1.7.1/source.json": "f121b43eeefc7c29efbd51b83d08631e2347297c95aac9764a701f2a6a2bb953",
+ "https://bcr.bazel.build/modules/buildozer/7.1.2/MODULE.bazel": "2e8dd40ede9c454042645fd8d8d0cd1527966aa5c919de86661e62953cd73d84",
+ "https://bcr.bazel.build/modules/buildozer/7.1.2/source.json": "c9028a501d2db85793a6996205c8de120944f50a0d570438fcae0457a5f9d1f8",
+ "https://bcr.bazel.build/modules/google_benchmark/1.8.2/MODULE.bazel": "a70cf1bba851000ba93b58ae2f6d76490a9feb74192e57ab8e8ff13c34ec50cb",
+ "https://bcr.bazel.build/modules/googletest/1.11.0/MODULE.bazel": "3a83f095183f66345ca86aa13c58b59f9f94a2f81999c093d4eeaa2d262d12f4",
+ "https://bcr.bazel.build/modules/googletest/1.14.0.bcr.1/MODULE.bazel": "22c31a561553727960057361aa33bf20fb2e98584bc4fec007906e27053f80c6",
+ "https://bcr.bazel.build/modules/googletest/1.14.0.bcr.1/source.json": "41e9e129f80d8c8bf103a7acc337b76e54fad1214ac0a7084bf24f4cd924b8b4",
+ "https://bcr.bazel.build/modules/googletest/1.14.0/MODULE.bazel": "cfbcbf3e6eac06ef9d85900f64424708cc08687d1b527f0ef65aa7517af8118f",
+ "https://bcr.bazel.build/modules/jsoncpp/1.9.5/MODULE.bazel": "31271aedc59e815656f5736f282bb7509a97c7ecb43e927ac1a37966e0578075",
+ "https://bcr.bazel.build/modules/jsoncpp/1.9.5/source.json": "4108ee5085dd2885a341c7fab149429db457b3169b86eb081fa245eadf69169d",
+ "https://bcr.bazel.build/modules/libpfm/4.11.0/MODULE.bazel": "45061ff025b301940f1e30d2c16bea596c25b176c8b6b3087e92615adbd52902",
+ "https://bcr.bazel.build/modules/platforms/0.0.10/MODULE.bazel": "8cb8efaf200bdeb2150d93e162c40f388529a25852b332cec879373771e48ed5",
+ "https://bcr.bazel.build/modules/platforms/0.0.11/MODULE.bazel": "0daefc49732e227caa8bfa834d65dc52e8cc18a2faf80df25e8caea151a9413f",
+ "https://bcr.bazel.build/modules/platforms/0.0.11/source.json": "f7e188b79ebedebfe75e9e1d098b8845226c7992b307e28e1496f23112e8fc29",
+ "https://bcr.bazel.build/modules/platforms/0.0.4/MODULE.bazel": "9b328e31ee156f53f3c416a64f8491f7eb731742655a47c9eec4703a71644aee",
+ "https://bcr.bazel.build/modules/platforms/0.0.5/MODULE.bazel": "5733b54ea419d5eaf7997054bb55f6a1d0b5ff8aedf0176fef9eea44f3acda37",
+ "https://bcr.bazel.build/modules/platforms/0.0.6/MODULE.bazel": "ad6eeef431dc52aefd2d77ed20a4b353f8ebf0f4ecdd26a807d2da5aa8cd0615",
+ "https://bcr.bazel.build/modules/platforms/0.0.7/MODULE.bazel": "72fd4a0ede9ee5c021f6a8dd92b503e089f46c227ba2813ff183b71616034814",
+ "https://bcr.bazel.build/modules/platforms/0.0.8/MODULE.bazel": "9f142c03e348f6d263719f5074b21ef3adf0b139ee4c5133e2aa35664da9eb2d",
+ "https://bcr.bazel.build/modules/protobuf/21.7/MODULE.bazel": "a5a29bb89544f9b97edce05642fac225a808b5b7be74038ea3640fae2f8e66a7",
+ "https://bcr.bazel.build/modules/protobuf/27.0/MODULE.bazel": "7873b60be88844a0a1d8f80b9d5d20cfbd8495a689b8763e76c6372998d3f64c",
+ "https://bcr.bazel.build/modules/protobuf/27.1/MODULE.bazel": "703a7b614728bb06647f965264967a8ef1c39e09e8f167b3ca0bb1fd80449c0d",
+ "https://bcr.bazel.build/modules/protobuf/29.0-rc2/MODULE.bazel": "6241d35983510143049943fc0d57937937122baf1b287862f9dc8590fc4c37df",
+ "https://bcr.bazel.build/modules/protobuf/29.0/MODULE.bazel": "319dc8bf4c679ff87e71b1ccfb5a6e90a6dbc4693501d471f48662ac46d04e4e",
+ "https://bcr.bazel.build/modules/protobuf/29.0/source.json": "b857f93c796750eef95f0d61ee378f3420d00ee1dd38627b27193aa482f4f981",
+ "https://bcr.bazel.build/modules/protobuf/3.19.0/MODULE.bazel": "6b5fbb433f760a99a22b18b6850ed5784ef0e9928a72668b66e4d7ccd47db9b0",
+ "https://bcr.bazel.build/modules/pybind11_bazel/2.11.1/MODULE.bazel": "88af1c246226d87e65be78ed49ecd1e6f5e98648558c14ce99176da041dc378e",
+ "https://bcr.bazel.build/modules/pybind11_bazel/2.11.1/source.json": "be4789e951dd5301282729fe3d4938995dc4c1a81c2ff150afc9f1b0504c6022",
+ "https://bcr.bazel.build/modules/re2/2023-09-01/MODULE.bazel": "cb3d511531b16cfc78a225a9e2136007a48cf8a677e4264baeab57fe78a80206",
+ "https://bcr.bazel.build/modules/re2/2023-09-01/source.json": "e044ce89c2883cd957a2969a43e79f7752f9656f6b20050b62f90ede21ec6eb4",
+ "https://bcr.bazel.build/modules/rules_android/0.1.1/MODULE.bazel": "48809ab0091b07ad0182defb787c4c5328bd3a278938415c00a7b69b50c4d3a8",
+ "https://bcr.bazel.build/modules/rules_android/0.1.1/source.json": "e6986b41626ee10bdc864937ffb6d6bf275bb5b9c65120e6137d56e6331f089e",
+ "https://bcr.bazel.build/modules/rules_cc/0.0.1/MODULE.bazel": "cb2aa0747f84c6c3a78dad4e2049c154f08ab9d166b1273835a8174940365647",
+ "https://bcr.bazel.build/modules/rules_cc/0.0.10/MODULE.bazel": "ec1705118f7eaedd6e118508d3d26deba2a4e76476ada7e0e3965211be012002",
+ "https://bcr.bazel.build/modules/rules_cc/0.0.13/MODULE.bazel": "0e8529ed7b323dad0775ff924d2ae5af7640b23553dfcd4d34344c7e7a867191",
+ "https://bcr.bazel.build/modules/rules_cc/0.0.14/MODULE.bazel": "5e343a3aac88b8d7af3b1b6d2093b55c347b8eefc2e7d1442f7a02dc8fea48ac",
+ "https://bcr.bazel.build/modules/rules_cc/0.0.15/MODULE.bazel": "6704c35f7b4a72502ee81f61bf88706b54f06b3cbe5558ac17e2e14666cd5dcc",
+ "https://bcr.bazel.build/modules/rules_cc/0.0.16/MODULE.bazel": "7661303b8fc1b4d7f532e54e9d6565771fea666fbdf839e0a86affcd02defe87",
+ "https://bcr.bazel.build/modules/rules_cc/0.0.2/MODULE.bazel": "6915987c90970493ab97393024c156ea8fb9f3bea953b2f3ec05c34f19b5695c",
+ "https://bcr.bazel.build/modules/rules_cc/0.0.6/MODULE.bazel": "abf360251023dfe3efcef65ab9d56beefa8394d4176dd29529750e1c57eaa33f",
+ "https://bcr.bazel.build/modules/rules_cc/0.0.8/MODULE.bazel": "964c85c82cfeb6f3855e6a07054fdb159aced38e99a5eecf7bce9d53990afa3e",
+ "https://bcr.bazel.build/modules/rules_cc/0.0.9/MODULE.bazel": "836e76439f354b89afe6a911a7adf59a6b2518fafb174483ad78a2a2fde7b1c5",
+ "https://bcr.bazel.build/modules/rules_cc/0.1.1/MODULE.bazel": "2f0222a6f229f0bf44cd711dc13c858dad98c62d52bd51d8fc3a764a83125513",
+ "https://bcr.bazel.build/modules/rules_cc/0.2.16/MODULE.bazel": "9242fa89f950c6ef7702801ab53922e99c69b02310c39fb6e62b2bd30df2a1d4",
+ "https://bcr.bazel.build/modules/rules_cc/0.2.16/source.json": "d03d5cde49376d87e14ec14b666c56075e5e3926930327fd5d0484a1ff2ac1cc",
+ "https://bcr.bazel.build/modules/rules_foreign_cc/0.9.0/MODULE.bazel": "c9e8c682bf75b0e7c704166d79b599f93b72cfca5ad7477df596947891feeef6",
+ "https://bcr.bazel.build/modules/rules_fuzzing/0.5.2/MODULE.bazel": "40c97d1144356f52905566c55811f13b299453a14ac7769dfba2ac38192337a8",
+ "https://bcr.bazel.build/modules/rules_fuzzing/0.5.2/source.json": "c8b1e2c717646f1702290959a3302a178fb639d987ab61d548105019f11e527e",
+ "https://bcr.bazel.build/modules/rules_java/4.0.0/MODULE.bazel": "5a78a7ae82cd1a33cef56dc578c7d2a46ed0dca12643ee45edbb8417899e6f74",
+ "https://bcr.bazel.build/modules/rules_java/5.3.5/MODULE.bazel": "a4ec4f2db570171e3e5eb753276ee4b389bae16b96207e9d3230895c99644b86",
+ "https://bcr.bazel.build/modules/rules_java/6.0.0/MODULE.bazel": "8a43b7df601a7ec1af61d79345c17b31ea1fedc6711fd4abfd013ea612978e39",
+ "https://bcr.bazel.build/modules/rules_java/6.4.0/MODULE.bazel": "e986a9fe25aeaa84ac17ca093ef13a4637f6107375f64667a15999f77db6c8f6",
+ "https://bcr.bazel.build/modules/rules_java/6.5.2/MODULE.bazel": "1d440d262d0e08453fa0c4d8f699ba81609ed0e9a9a0f02cd10b3e7942e61e31",
+ "https://bcr.bazel.build/modules/rules_java/7.10.0/MODULE.bazel": "530c3beb3067e870561739f1144329a21c851ff771cd752a49e06e3dc9c2e71a",
+ "https://bcr.bazel.build/modules/rules_java/7.12.2/MODULE.bazel": "579c505165ee757a4280ef83cda0150eea193eed3bef50b1004ba88b99da6de6",
+ "https://bcr.bazel.build/modules/rules_java/7.2.0/MODULE.bazel": "06c0334c9be61e6cef2c8c84a7800cef502063269a5af25ceb100b192453d4ab",
+ "https://bcr.bazel.build/modules/rules_java/7.3.2/MODULE.bazel": "50dece891cfdf1741ea230d001aa9c14398062f2b7c066470accace78e412bc2",
+ "https://bcr.bazel.build/modules/rules_java/7.6.1/MODULE.bazel": "2f14b7e8a1aa2f67ae92bc69d1ec0fa8d9f827c4e17ff5e5f02e91caa3b2d0fe",
+ "https://bcr.bazel.build/modules/rules_java/8.14.0/MODULE.bazel": "717717ed40cc69994596a45aec6ea78135ea434b8402fb91b009b9151dd65615",
+ "https://bcr.bazel.build/modules/rules_java/8.14.0/source.json": "8a88c4ca9e8759da53cddc88123880565c520503321e2566b4e33d0287a3d4bc",
+ "https://bcr.bazel.build/modules/rules_jvm_external/4.4.2/MODULE.bazel": "a56b85e418c83eb1839819f0b515c431010160383306d13ec21959ac412d2fe7",
+ "https://bcr.bazel.build/modules/rules_jvm_external/5.1/MODULE.bazel": "33f6f999e03183f7d088c9be518a63467dfd0be94a11d0055fe2d210f89aa909",
+ "https://bcr.bazel.build/modules/rules_jvm_external/5.2/MODULE.bazel": "d9351ba35217ad0de03816ef3ed63f89d411349353077348a45348b096615036",
+ "https://bcr.bazel.build/modules/rules_jvm_external/5.3/MODULE.bazel": "bf93870767689637164657731849fb887ad086739bd5d360d90007a581d5527d",
+ "https://bcr.bazel.build/modules/rules_jvm_external/6.1/MODULE.bazel": "75b5fec090dbd46cf9b7d8ea08cf84a0472d92ba3585b476f44c326eda8059c4",
+ "https://bcr.bazel.build/modules/rules_jvm_external/6.3/MODULE.bazel": "c998e060b85f71e00de5ec552019347c8bca255062c990ac02d051bb80a38df0",
+ "https://bcr.bazel.build/modules/rules_jvm_external/6.3/source.json": "6f5f5a5a4419ae4e37c35a5bb0a6ae657ed40b7abc5a5189111b47fcebe43197",
+ "https://bcr.bazel.build/modules/rules_kotlin/1.9.0/MODULE.bazel": "ef85697305025e5a61f395d4eaede272a5393cee479ace6686dba707de804d59",
+ "https://bcr.bazel.build/modules/rules_kotlin/1.9.6/MODULE.bazel": "d269a01a18ee74d0335450b10f62c9ed81f2321d7958a2934e44272fe82dcef3",
+ "https://bcr.bazel.build/modules/rules_kotlin/1.9.6/source.json": "2faa4794364282db7c06600b7e5e34867a564ae91bda7cae7c29c64e9466b7d5",
+ "https://bcr.bazel.build/modules/rules_license/0.0.3/MODULE.bazel": "627e9ab0247f7d1e05736b59dbb1b6871373de5ad31c3011880b4133cafd4bd0",
+ "https://bcr.bazel.build/modules/rules_license/0.0.7/MODULE.bazel": "088fbeb0b6a419005b89cf93fe62d9517c0a2b8bb56af3244af65ecfe37e7d5d",
+ "https://bcr.bazel.build/modules/rules_license/1.0.0/MODULE.bazel": "a7fda60eefdf3d8c827262ba499957e4df06f659330bbe6cdbdb975b768bb65c",
+ "https://bcr.bazel.build/modules/rules_license/1.0.0/source.json": "a52c89e54cc311196e478f8382df91c15f7a2bfdf4c6cd0e2675cc2ff0b56efb",
+ "https://bcr.bazel.build/modules/rules_pkg/0.7.0/MODULE.bazel": "df99f03fc7934a4737122518bb87e667e62d780b610910f0447665a7e2be62dc",
+ "https://bcr.bazel.build/modules/rules_pkg/1.0.1/MODULE.bazel": "5b1df97dbc29623bccdf2b0dcd0f5cb08e2f2c9050aab1092fd39a41e82686ff",
+ "https://bcr.bazel.build/modules/rules_pkg/1.0.1/source.json": "bd82e5d7b9ce2d31e380dd9f50c111d678c3bdaca190cb76b0e1c71b05e1ba8a",
+ "https://bcr.bazel.build/modules/rules_proto/4.0.0/MODULE.bazel": "a7a7b6ce9bee418c1a760b3d84f83a299ad6952f9903c67f19e4edd964894e06",
+ "https://bcr.bazel.build/modules/rules_proto/5.3.0-21.7/MODULE.bazel": "e8dff86b0971688790ae75528fe1813f71809b5afd57facb44dad9e8eca631b7",
+ "https://bcr.bazel.build/modules/rules_proto/6.0.2/MODULE.bazel": "ce916b775a62b90b61888052a416ccdda405212b6aaeb39522f7dc53431a5e73",
+ "https://bcr.bazel.build/modules/rules_proto/7.0.2/MODULE.bazel": "bf81793bd6d2ad89a37a40693e56c61b0ee30f7a7fdbaf3eabbf5f39de47dea2",
+ "https://bcr.bazel.build/modules/rules_proto/7.0.2/source.json": "1e5e7260ae32ef4f2b52fd1d0de8d03b606a44c91b694d2f1afb1d3b28a48ce1",
+ "https://bcr.bazel.build/modules/rules_python/0.10.2/MODULE.bazel": "cc82bc96f2997baa545ab3ce73f196d040ffb8756fd2d66125a530031cd90e5f",
+ "https://bcr.bazel.build/modules/rules_python/0.23.1/MODULE.bazel": "49ffccf0511cb8414de28321f5fcf2a31312b47c40cc21577144b7447f2bf300",
+ "https://bcr.bazel.build/modules/rules_python/0.25.0/MODULE.bazel": "72f1506841c920a1afec76975b35312410eea3aa7b63267436bfb1dd91d2d382",
+ "https://bcr.bazel.build/modules/rules_python/0.28.0/MODULE.bazel": "cba2573d870babc976664a912539b320cbaa7114cd3e8f053c720171cde331ed",
+ "https://bcr.bazel.build/modules/rules_python/0.31.0/MODULE.bazel": "93a43dc47ee570e6ec9f5779b2e64c1476a6ce921c48cc9a1678a91dd5f8fd58",
+ "https://bcr.bazel.build/modules/rules_python/0.4.0/MODULE.bazel": "9208ee05fd48bf09ac60ed269791cf17fb343db56c8226a720fbb1cdf467166c",
+ "https://bcr.bazel.build/modules/rules_python/0.40.0/MODULE.bazel": "9d1a3cd88ed7d8e39583d9ffe56ae8a244f67783ae89b60caafc9f5cf318ada7",
+ "https://bcr.bazel.build/modules/rules_python/0.40.0/source.json": "939d4bd2e3110f27bfb360292986bb79fd8dcefb874358ccd6cdaa7bda029320",
+ "https://bcr.bazel.build/modules/rules_shell/0.2.0/MODULE.bazel": "fda8a652ab3c7d8fee214de05e7a9916d8b28082234e8d2c0094505c5268ed3c",
+ "https://bcr.bazel.build/modules/rules_shell/0.2.0/source.json": "7f27af3c28037d9701487c4744b5448d26537cc66cdef0d8df7ae85411f8de95",
+ "https://bcr.bazel.build/modules/stardoc/0.5.1/MODULE.bazel": "1a05d92974d0c122f5ccf09291442580317cdd859f07a8655f1db9a60374f9f8",
+ "https://bcr.bazel.build/modules/stardoc/0.5.3/MODULE.bazel": "c7f6948dae6999bf0db32c1858ae345f112cacf98f174c7a8bb707e41b974f1c",
+ "https://bcr.bazel.build/modules/stardoc/0.5.6/MODULE.bazel": "c43dabc564990eeab55e25ed61c07a1aadafe9ece96a4efabb3f8bf9063b71ef",
+ "https://bcr.bazel.build/modules/stardoc/0.7.0/MODULE.bazel": "05e3d6d30c099b6770e97da986c53bd31844d7f13d41412480ea265ac9e8079c",
+ "https://bcr.bazel.build/modules/stardoc/0.7.1/MODULE.bazel": "3548faea4ee5dda5580f9af150e79d0f6aea934fc60c1cc50f4efdd9420759e7",
+ "https://bcr.bazel.build/modules/stardoc/0.7.1/source.json": "b6500ffcd7b48cd72c29bb67bcac781e12701cc0d6d55d266a652583cfcdab01",
+ "https://bcr.bazel.build/modules/upb/0.0.0-20220923-a547704/MODULE.bazel": "7298990c00040a0e2f121f6c32544bab27d4452f80d9ce51349b1a28f3005c43",
+ "https://bcr.bazel.build/modules/zlib/1.2.11/MODULE.bazel": "07b389abc85fdbca459b69e2ec656ae5622873af3f845e1c9d80fe179f3effa0",
+ "https://bcr.bazel.build/modules/zlib/1.3.1.bcr.5/MODULE.bazel": "eec517b5bbe5492629466e11dae908d043364302283de25581e3eb944326c4ca",
+ "https://bcr.bazel.build/modules/zlib/1.3.1.bcr.5/source.json": "22bc55c47af97246cfc093d0acf683a7869377de362b5d1c552c2c2e16b7a806",
+ "https://bcr.bazel.build/modules/zlib/1.3.1/MODULE.bazel": "751c9940dcfe869f5f7274e1295422a34623555916eb98c174c1e945594bf198"
+ },
+ "selectedYankedVersions": {},
+ "moduleExtensions": {
+ "@@rules_kotlin+//src/main/starlark/core/repositories:bzlmod_setup.bzl%rules_kotlin_extensions": {
+ "general": {
+ "bzlTransitiveDigest": "rL/34P1aFDq2GqVC2zCFgQ8nTuOC6ziogocpvG50Qz8=",
+ "usagesDigest": "QI2z8ZUR+mqtbwsf2fLqYdJAkPOHdOV+tF2yVAUgRzw=",
+ "recordedFileInputs": {},
+ "recordedDirentsInputs": {},
+ "envVariables": {},
+ "generatedRepoSpecs": {
+ "com_github_jetbrains_kotlin_git": {
+ "repoRuleId": "@@rules_kotlin+//src/main/starlark/core/repositories:compiler.bzl%kotlin_compiler_git_repository",
+ "attributes": {
+ "urls": [
+ "https://github.com/JetBrains/kotlin/releases/download/v1.9.23/kotlin-compiler-1.9.23.zip"
+ ],
+ "sha256": "93137d3aab9afa9b27cb06a824c2324195c6b6f6179d8a8653f440f5bd58be88"
+ }
+ },
+ "com_github_jetbrains_kotlin": {
+ "repoRuleId": "@@rules_kotlin+//src/main/starlark/core/repositories:compiler.bzl%kotlin_capabilities_repository",
+ "attributes": {
+ "git_repository_name": "com_github_jetbrains_kotlin_git",
+ "compiler_version": "1.9.23"
+ }
+ },
+ "com_github_google_ksp": {
+ "repoRuleId": "@@rules_kotlin+//src/main/starlark/core/repositories:ksp.bzl%ksp_compiler_plugin_repository",
+ "attributes": {
+ "urls": [
+ "https://github.com/google/ksp/releases/download/1.9.23-1.0.20/artifacts.zip"
+ ],
+ "sha256": "ee0618755913ef7fd6511288a232e8fad24838b9af6ea73972a76e81053c8c2d",
+ "strip_version": "1.9.23-1.0.20"
+ }
+ },
+ "com_github_pinterest_ktlint": {
+ "repoRuleId": "@@bazel_tools//tools/build_defs/repo:http.bzl%http_file",
+ "attributes": {
+ "sha256": "01b2e0ef893383a50dbeb13970fe7fa3be36ca3e83259e01649945b09d736985",
+ "urls": [
+ "https://github.com/pinterest/ktlint/releases/download/1.3.0/ktlint"
+ ],
+ "executable": true
+ }
+ },
+ "rules_android": {
+ "repoRuleId": "@@bazel_tools//tools/build_defs/repo:http.bzl%http_archive",
+ "attributes": {
+ "sha256": "cd06d15dd8bb59926e4d65f9003bfc20f9da4b2519985c27e190cddc8b7a7806",
+ "strip_prefix": "rules_android-0.1.1",
+ "urls": [
+ "https://github.com/bazelbuild/rules_android/archive/v0.1.1.zip"
+ ]
+ }
+ }
+ },
+ "recordedRepoMappingEntries": [
+ [
+ "rules_kotlin+",
+ "bazel_tools",
+ "bazel_tools"
+ ]
+ ]
+ }
+ }
+ },
+ "facts": {}
+}
diff --git a/nix/flake.lock b/nix/flake.lock
new file mode 100644
index 0000000..5fd6f52
--- /dev/null
+++ b/nix/flake.lock
@@ -0,0 +1,61 @@
+{
+ "nodes": {
+ "flake-utils": {
+ "inputs": {
+ "systems": "systems"
+ },
+ "locked": {
+ "lastModified": 1731533236,
+ "narHash": "sha256-l0KFg5HjrsfsO/JpG+r7fRrqm12kzFHyUHqHCVpMMbI=",
+ "owner": "numtide",
+ "repo": "flake-utils",
+ "rev": "11707dc2f618dd54ca8739b309ec4fc024de578b",
+ "type": "github"
+ },
+ "original": {
+ "owner": "numtide",
+ "repo": "flake-utils",
+ "type": "github"
+ }
+ },
+ "nixpkgs": {
+ "locked": {
+ "lastModified": 1767379071,
+ "narHash": "sha256-EgE0pxsrW9jp9YFMkHL9JMXxcqi/OoumPJYwf+Okucw=",
+ "owner": "NixOS",
+ "repo": "nixpkgs",
+ "rev": "fb7944c166a3b630f177938e478f0378e64ce108",
+ "type": "github"
+ },
+ "original": {
+ "owner": "NixOS",
+ "ref": "nixos-unstable",
+ "repo": "nixpkgs",
+ "type": "github"
+ }
+ },
+ "root": {
+ "inputs": {
+ "flake-utils": "flake-utils",
+ "nixpkgs": "nixpkgs"
+ }
+ },
+ "systems": {
+ "locked": {
+ "lastModified": 1681028828,
+ "narHash": "sha256-Vy1rq5AaRuLzOxct8nz4T6wlgyUR7zLU309k9mBC768=",
+ "owner": "nix-systems",
+ "repo": "default",
+ "rev": "da67096a3b9bf56a91d16901293e51ba5b49a27e",
+ "type": "github"
+ },
+ "original": {
+ "owner": "nix-systems",
+ "repo": "default",
+ "type": "github"
+ }
+ }
+ },
+ "root": "root",
+ "version": 7
+}
diff --git a/nix/flake.nix b/nix/flake.nix
new file mode 100644
index 0000000..240619c
--- /dev/null
+++ b/nix/flake.nix
@@ -0,0 +1,60 @@
+{
+ description = "pedagogical compiler monorepo (bazel + nix + clang + ccache)";
+
+ inputs = {
+ nixpkgs.url = "github:NixOS/nixpkgs/nixos-unstable";
+ flake-utils.url = "github:numtide/flake-utils";
+ };
+
+ outputs =
+ {
+ self,
+ nixpkgs,
+ flake-utils,
+ ...
+ }:
+ flake-utils.lib.eachDefaultSystem (
+ system:
+ let
+ # pkgs = import nixpkgs { inherit system; config.replaceStdenv = {pkgs, ...}: pkgs.clangStdenv; };
+ pkgs = import nixpkgs { inherit system; };
+ # lock = builtins.fromJSON (builtins.readFile ./flake.lock);
+ # spec = lock.nodes.nixpkgs.locked;
+ # nixpkgs = fetchTarball "https://github.com/${spec.owner}/${spec.repo}/archive/${spec.rev}.tar.gz";
+ in
+ {
+ devShells.default = pkgs.mkShell {
+ name = "compiler stuff";
+ packages = with pkgs; [
+ # clang-tools
+ # bazelisk
+ bazel_8
+ bazel-buildtools
+ nix
+ git
+ gcc
+
+ doxygen
+ ccache
+ python3
+
+ ninja
+ clang-tools
+
+ z3
+ gtest
+ pkg-config
+ lit
+
+ buildifier
+ buildozer
+ ];
+ CC = "ccache clang";
+ CXX = "ccache clang++";
+ # LD_LIBRARY_PATH = nixpkgs.lib.makeLibraryPath [ pkgs.libcxx ];
+ NIX_HARDENING_ENABLE = "";
+ };
+ }
+ );
+}
+
diff --git a/willow/BUILD.bazel b/willow/BUILD.bazel
new file mode 100644
index 0000000..8726cbd
--- /dev/null
+++ b/willow/BUILD.bazel
@@ -0,0 +1,13 @@
+cc_library(
+ name = "willow",
+ srcs = [
+ "lib/IR/TypeContext.cpp",
+ ],
+ hdrs = glob([
+ "include/willow/**/*.h",
+ ]),
+ strip_include_prefix = "include",
+ visibility = ["//visibility:public"],
+ deps = [
+ ],
+)
diff --git a/willow/MODULE.bazel b/willow/MODULE.bazel
new file mode 100644
index 0000000..3597596
--- /dev/null
+++ b/willow/MODULE.bazel
@@ -0,0 +1,4 @@
+module(
+ name = "willow",
+ version = "0.0.1",
+)
diff --git a/willow/MODULE.bazel.lock b/willow/MODULE.bazel.lock
new file mode 100644
index 0000000..34d9edb
--- /dev/null
+++ b/willow/MODULE.bazel.lock
@@ -0,0 +1,139 @@
+{
+ "lockFileVersion": 18,
+ "registryFileHashes": {
+ "https://bcr.bazel.build/bazel_registry.json": "8a28e4aff06ee60aed2a8c281907fb8bcbf3b753c91fb5a5c57da3215d5b3497",
+ "https://bcr.bazel.build/modules/abseil-cpp/20210324.2/MODULE.bazel": "7cd0312e064fde87c8d1cd79ba06c876bd23630c83466e9500321be55c96ace2",
+ "https://bcr.bazel.build/modules/abseil-cpp/20211102.0/MODULE.bazel": "70390338f7a5106231d20620712f7cccb659cd0e9d073d1991c038eb9fc57589",
+ "https://bcr.bazel.build/modules/abseil-cpp/20230125.1/MODULE.bazel": "89047429cb0207707b2dface14ba7f8df85273d484c2572755be4bab7ce9c3a0",
+ "https://bcr.bazel.build/modules/abseil-cpp/20230802.0.bcr.1/MODULE.bazel": "1c8cec495288dccd14fdae6e3f95f772c1c91857047a098fad772034264cc8cb",
+ "https://bcr.bazel.build/modules/abseil-cpp/20230802.0/MODULE.bazel": "d253ae36a8bd9ee3c5955384096ccb6baf16a1b1e93e858370da0a3b94f77c16",
+ "https://bcr.bazel.build/modules/abseil-cpp/20230802.1/MODULE.bazel": "fa92e2eb41a04df73cdabeec37107316f7e5272650f81d6cc096418fe647b915",
+ "https://bcr.bazel.build/modules/abseil-cpp/20240116.1/MODULE.bazel": "37bcdb4440fbb61df6a1c296ae01b327f19e9bb521f9b8e26ec854b6f97309ed",
+ "https://bcr.bazel.build/modules/abseil-cpp/20240116.1/source.json": "9be551b8d4e3ef76875c0d744b5d6a504a27e3ae67bc6b28f46415fd2d2957da",
+ "https://bcr.bazel.build/modules/bazel_features/1.1.1/MODULE.bazel": "27b8c79ef57efe08efccbd9dd6ef70d61b4798320b8d3c134fd571f78963dbcd",
+ "https://bcr.bazel.build/modules/bazel_features/1.11.0/MODULE.bazel": "f9382337dd5a474c3b7d334c2f83e50b6eaedc284253334cf823044a26de03e8",
+ "https://bcr.bazel.build/modules/bazel_features/1.15.0/MODULE.bazel": "d38ff6e517149dc509406aca0db3ad1efdd890a85e049585b7234d04238e2a4d",
+ "https://bcr.bazel.build/modules/bazel_features/1.17.0/MODULE.bazel": "039de32d21b816b47bd42c778e0454217e9c9caac4a3cf8e15c7231ee3ddee4d",
+ "https://bcr.bazel.build/modules/bazel_features/1.18.0/MODULE.bazel": "1be0ae2557ab3a72a57aeb31b29be347bcdc5d2b1eb1e70f39e3851a7e97041a",
+ "https://bcr.bazel.build/modules/bazel_features/1.19.0/MODULE.bazel": "59adcdf28230d220f0067b1f435b8537dd033bfff8db21335ef9217919c7fb58",
+ "https://bcr.bazel.build/modules/bazel_features/1.30.0/MODULE.bazel": "a14b62d05969a293b80257e72e597c2da7f717e1e69fa8b339703ed6731bec87",
+ "https://bcr.bazel.build/modules/bazel_features/1.30.0/source.json": "b07e17f067fe4f69f90b03b36ef1e08fe0d1f3cac254c1241a1818773e3423bc",
+ "https://bcr.bazel.build/modules/bazel_features/1.4.1/MODULE.bazel": "e45b6bb2350aff3e442ae1111c555e27eac1d915e77775f6fdc4b351b758b5d7",
+ "https://bcr.bazel.build/modules/bazel_features/1.9.1/MODULE.bazel": "8f679097876a9b609ad1f60249c49d68bfab783dd9be012faf9d82547b14815a",
+ "https://bcr.bazel.build/modules/bazel_skylib/1.0.3/MODULE.bazel": "bcb0fd896384802d1ad283b4e4eb4d718eebd8cb820b0a2c3a347fb971afd9d8",
+ "https://bcr.bazel.build/modules/bazel_skylib/1.1.1/MODULE.bazel": "1add3e7d93ff2e6998f9e118022c84d163917d912f5afafb3058e3d2f1545b5e",
+ "https://bcr.bazel.build/modules/bazel_skylib/1.2.0/MODULE.bazel": "44fe84260e454ed94ad326352a698422dbe372b21a1ac9f3eab76eb531223686",
+ "https://bcr.bazel.build/modules/bazel_skylib/1.2.1/MODULE.bazel": "f35baf9da0efe45fa3da1696ae906eea3d615ad41e2e3def4aeb4e8bc0ef9a7a",
+ "https://bcr.bazel.build/modules/bazel_skylib/1.3.0/MODULE.bazel": "20228b92868bf5cfc41bda7afc8a8ba2a543201851de39d990ec957b513579c5",
+ "https://bcr.bazel.build/modules/bazel_skylib/1.4.1/MODULE.bazel": "a0dcb779424be33100dcae821e9e27e4f2901d9dfd5333efe5ac6a8d7ab75e1d",
+ "https://bcr.bazel.build/modules/bazel_skylib/1.4.2/MODULE.bazel": "3bd40978e7a1fac911d5989e6b09d8f64921865a45822d8b09e815eaa726a651",
+ "https://bcr.bazel.build/modules/bazel_skylib/1.5.0/MODULE.bazel": "32880f5e2945ce6a03d1fbd588e9198c0a959bb42297b2cfaf1685b7bc32e138",
+ "https://bcr.bazel.build/modules/bazel_skylib/1.6.1/MODULE.bazel": "8fdee2dbaace6c252131c00e1de4b165dc65af02ea278476187765e1a617b917",
+ "https://bcr.bazel.build/modules/bazel_skylib/1.7.0/MODULE.bazel": "0db596f4563de7938de764cc8deeabec291f55e8ec15299718b93c4423e9796d",
+ "https://bcr.bazel.build/modules/bazel_skylib/1.7.1/MODULE.bazel": "3120d80c5861aa616222ec015332e5f8d3171e062e3e804a2a0253e1be26e59b",
+ "https://bcr.bazel.build/modules/bazel_skylib/1.7.1/source.json": "f121b43eeefc7c29efbd51b83d08631e2347297c95aac9764a701f2a6a2bb953",
+ "https://bcr.bazel.build/modules/buildozer/7.1.2/MODULE.bazel": "2e8dd40ede9c454042645fd8d8d0cd1527966aa5c919de86661e62953cd73d84",
+ "https://bcr.bazel.build/modules/buildozer/7.1.2/source.json": "c9028a501d2db85793a6996205c8de120944f50a0d570438fcae0457a5f9d1f8",
+ "https://bcr.bazel.build/modules/google_benchmark/1.8.2/MODULE.bazel": "a70cf1bba851000ba93b58ae2f6d76490a9feb74192e57ab8e8ff13c34ec50cb",
+ "https://bcr.bazel.build/modules/googletest/1.11.0/MODULE.bazel": "3a83f095183f66345ca86aa13c58b59f9f94a2f81999c093d4eeaa2d262d12f4",
+ "https://bcr.bazel.build/modules/googletest/1.14.0.bcr.1/MODULE.bazel": "22c31a561553727960057361aa33bf20fb2e98584bc4fec007906e27053f80c6",
+ "https://bcr.bazel.build/modules/googletest/1.14.0.bcr.1/source.json": "41e9e129f80d8c8bf103a7acc337b76e54fad1214ac0a7084bf24f4cd924b8b4",
+ "https://bcr.bazel.build/modules/googletest/1.14.0/MODULE.bazel": "cfbcbf3e6eac06ef9d85900f64424708cc08687d1b527f0ef65aa7517af8118f",
+ "https://bcr.bazel.build/modules/jsoncpp/1.9.5/MODULE.bazel": "31271aedc59e815656f5736f282bb7509a97c7ecb43e927ac1a37966e0578075",
+ "https://bcr.bazel.build/modules/jsoncpp/1.9.5/source.json": "4108ee5085dd2885a341c7fab149429db457b3169b86eb081fa245eadf69169d",
+ "https://bcr.bazel.build/modules/libpfm/4.11.0/MODULE.bazel": "45061ff025b301940f1e30d2c16bea596c25b176c8b6b3087e92615adbd52902",
+ "https://bcr.bazel.build/modules/platforms/0.0.10/MODULE.bazel": "8cb8efaf200bdeb2150d93e162c40f388529a25852b332cec879373771e48ed5",
+ "https://bcr.bazel.build/modules/platforms/0.0.11/MODULE.bazel": "0daefc49732e227caa8bfa834d65dc52e8cc18a2faf80df25e8caea151a9413f",
+ "https://bcr.bazel.build/modules/platforms/0.0.11/source.json": "f7e188b79ebedebfe75e9e1d098b8845226c7992b307e28e1496f23112e8fc29",
+ "https://bcr.bazel.build/modules/platforms/0.0.4/MODULE.bazel": "9b328e31ee156f53f3c416a64f8491f7eb731742655a47c9eec4703a71644aee",
+ "https://bcr.bazel.build/modules/platforms/0.0.5/MODULE.bazel": "5733b54ea419d5eaf7997054bb55f6a1d0b5ff8aedf0176fef9eea44f3acda37",
+ "https://bcr.bazel.build/modules/platforms/0.0.6/MODULE.bazel": "ad6eeef431dc52aefd2d77ed20a4b353f8ebf0f4ecdd26a807d2da5aa8cd0615",
+ "https://bcr.bazel.build/modules/platforms/0.0.7/MODULE.bazel": "72fd4a0ede9ee5c021f6a8dd92b503e089f46c227ba2813ff183b71616034814",
+ "https://bcr.bazel.build/modules/platforms/0.0.8/MODULE.bazel": "9f142c03e348f6d263719f5074b21ef3adf0b139ee4c5133e2aa35664da9eb2d",
+ "https://bcr.bazel.build/modules/protobuf/21.7/MODULE.bazel": "a5a29bb89544f9b97edce05642fac225a808b5b7be74038ea3640fae2f8e66a7",
+ "https://bcr.bazel.build/modules/protobuf/27.0/MODULE.bazel": "7873b60be88844a0a1d8f80b9d5d20cfbd8495a689b8763e76c6372998d3f64c",
+ "https://bcr.bazel.build/modules/protobuf/27.1/MODULE.bazel": "703a7b614728bb06647f965264967a8ef1c39e09e8f167b3ca0bb1fd80449c0d",
+ "https://bcr.bazel.build/modules/protobuf/29.0-rc2/MODULE.bazel": "6241d35983510143049943fc0d57937937122baf1b287862f9dc8590fc4c37df",
+ "https://bcr.bazel.build/modules/protobuf/29.0/MODULE.bazel": "319dc8bf4c679ff87e71b1ccfb5a6e90a6dbc4693501d471f48662ac46d04e4e",
+ "https://bcr.bazel.build/modules/protobuf/29.0/source.json": "b857f93c796750eef95f0d61ee378f3420d00ee1dd38627b27193aa482f4f981",
+ "https://bcr.bazel.build/modules/protobuf/3.19.0/MODULE.bazel": "6b5fbb433f760a99a22b18b6850ed5784ef0e9928a72668b66e4d7ccd47db9b0",
+ "https://bcr.bazel.build/modules/pybind11_bazel/2.11.1/MODULE.bazel": "88af1c246226d87e65be78ed49ecd1e6f5e98648558c14ce99176da041dc378e",
+ "https://bcr.bazel.build/modules/pybind11_bazel/2.11.1/source.json": "be4789e951dd5301282729fe3d4938995dc4c1a81c2ff150afc9f1b0504c6022",
+ "https://bcr.bazel.build/modules/re2/2023-09-01/MODULE.bazel": "cb3d511531b16cfc78a225a9e2136007a48cf8a677e4264baeab57fe78a80206",
+ "https://bcr.bazel.build/modules/re2/2023-09-01/source.json": "e044ce89c2883cd957a2969a43e79f7752f9656f6b20050b62f90ede21ec6eb4",
+ "https://bcr.bazel.build/modules/rules_android/0.1.1/MODULE.bazel": "48809ab0091b07ad0182defb787c4c5328bd3a278938415c00a7b69b50c4d3a8",
+ "https://bcr.bazel.build/modules/rules_android/0.1.1/source.json": "e6986b41626ee10bdc864937ffb6d6bf275bb5b9c65120e6137d56e6331f089e",
+ "https://bcr.bazel.build/modules/rules_cc/0.0.1/MODULE.bazel": "cb2aa0747f84c6c3a78dad4e2049c154f08ab9d166b1273835a8174940365647",
+ "https://bcr.bazel.build/modules/rules_cc/0.0.10/MODULE.bazel": "ec1705118f7eaedd6e118508d3d26deba2a4e76476ada7e0e3965211be012002",
+ "https://bcr.bazel.build/modules/rules_cc/0.0.13/MODULE.bazel": "0e8529ed7b323dad0775ff924d2ae5af7640b23553dfcd4d34344c7e7a867191",
+ "https://bcr.bazel.build/modules/rules_cc/0.0.14/MODULE.bazel": "5e343a3aac88b8d7af3b1b6d2093b55c347b8eefc2e7d1442f7a02dc8fea48ac",
+ "https://bcr.bazel.build/modules/rules_cc/0.0.15/MODULE.bazel": "6704c35f7b4a72502ee81f61bf88706b54f06b3cbe5558ac17e2e14666cd5dcc",
+ "https://bcr.bazel.build/modules/rules_cc/0.0.16/MODULE.bazel": "7661303b8fc1b4d7f532e54e9d6565771fea666fbdf839e0a86affcd02defe87",
+ "https://bcr.bazel.build/modules/rules_cc/0.0.2/MODULE.bazel": "6915987c90970493ab97393024c156ea8fb9f3bea953b2f3ec05c34f19b5695c",
+ "https://bcr.bazel.build/modules/rules_cc/0.0.6/MODULE.bazel": "abf360251023dfe3efcef65ab9d56beefa8394d4176dd29529750e1c57eaa33f",
+ "https://bcr.bazel.build/modules/rules_cc/0.0.8/MODULE.bazel": "964c85c82cfeb6f3855e6a07054fdb159aced38e99a5eecf7bce9d53990afa3e",
+ "https://bcr.bazel.build/modules/rules_cc/0.0.9/MODULE.bazel": "836e76439f354b89afe6a911a7adf59a6b2518fafb174483ad78a2a2fde7b1c5",
+ "https://bcr.bazel.build/modules/rules_cc/0.1.1/MODULE.bazel": "2f0222a6f229f0bf44cd711dc13c858dad98c62d52bd51d8fc3a764a83125513",
+ "https://bcr.bazel.build/modules/rules_cc/0.1.1/source.json": "d61627377bd7dd1da4652063e368d9366fc9a73920bfa396798ad92172cf645c",
+ "https://bcr.bazel.build/modules/rules_foreign_cc/0.9.0/MODULE.bazel": "c9e8c682bf75b0e7c704166d79b599f93b72cfca5ad7477df596947891feeef6",
+ "https://bcr.bazel.build/modules/rules_fuzzing/0.5.2/MODULE.bazel": "40c97d1144356f52905566c55811f13b299453a14ac7769dfba2ac38192337a8",
+ "https://bcr.bazel.build/modules/rules_fuzzing/0.5.2/source.json": "c8b1e2c717646f1702290959a3302a178fb639d987ab61d548105019f11e527e",
+ "https://bcr.bazel.build/modules/rules_java/4.0.0/MODULE.bazel": "5a78a7ae82cd1a33cef56dc578c7d2a46ed0dca12643ee45edbb8417899e6f74",
+ "https://bcr.bazel.build/modules/rules_java/5.3.5/MODULE.bazel": "a4ec4f2db570171e3e5eb753276ee4b389bae16b96207e9d3230895c99644b86",
+ "https://bcr.bazel.build/modules/rules_java/6.0.0/MODULE.bazel": "8a43b7df601a7ec1af61d79345c17b31ea1fedc6711fd4abfd013ea612978e39",
+ "https://bcr.bazel.build/modules/rules_java/6.4.0/MODULE.bazel": "e986a9fe25aeaa84ac17ca093ef13a4637f6107375f64667a15999f77db6c8f6",
+ "https://bcr.bazel.build/modules/rules_java/6.5.2/MODULE.bazel": "1d440d262d0e08453fa0c4d8f699ba81609ed0e9a9a0f02cd10b3e7942e61e31",
+ "https://bcr.bazel.build/modules/rules_java/7.10.0/MODULE.bazel": "530c3beb3067e870561739f1144329a21c851ff771cd752a49e06e3dc9c2e71a",
+ "https://bcr.bazel.build/modules/rules_java/7.12.2/MODULE.bazel": "579c505165ee757a4280ef83cda0150eea193eed3bef50b1004ba88b99da6de6",
+ "https://bcr.bazel.build/modules/rules_java/7.2.0/MODULE.bazel": "06c0334c9be61e6cef2c8c84a7800cef502063269a5af25ceb100b192453d4ab",
+ "https://bcr.bazel.build/modules/rules_java/7.3.2/MODULE.bazel": "50dece891cfdf1741ea230d001aa9c14398062f2b7c066470accace78e412bc2",
+ "https://bcr.bazel.build/modules/rules_java/7.6.1/MODULE.bazel": "2f14b7e8a1aa2f67ae92bc69d1ec0fa8d9f827c4e17ff5e5f02e91caa3b2d0fe",
+ "https://bcr.bazel.build/modules/rules_java/8.14.0/MODULE.bazel": "717717ed40cc69994596a45aec6ea78135ea434b8402fb91b009b9151dd65615",
+ "https://bcr.bazel.build/modules/rules_java/8.14.0/source.json": "8a88c4ca9e8759da53cddc88123880565c520503321e2566b4e33d0287a3d4bc",
+ "https://bcr.bazel.build/modules/rules_jvm_external/4.4.2/MODULE.bazel": "a56b85e418c83eb1839819f0b515c431010160383306d13ec21959ac412d2fe7",
+ "https://bcr.bazel.build/modules/rules_jvm_external/5.1/MODULE.bazel": "33f6f999e03183f7d088c9be518a63467dfd0be94a11d0055fe2d210f89aa909",
+ "https://bcr.bazel.build/modules/rules_jvm_external/5.2/MODULE.bazel": "d9351ba35217ad0de03816ef3ed63f89d411349353077348a45348b096615036",
+ "https://bcr.bazel.build/modules/rules_jvm_external/5.3/MODULE.bazel": "bf93870767689637164657731849fb887ad086739bd5d360d90007a581d5527d",
+ "https://bcr.bazel.build/modules/rules_jvm_external/6.1/MODULE.bazel": "75b5fec090dbd46cf9b7d8ea08cf84a0472d92ba3585b476f44c326eda8059c4",
+ "https://bcr.bazel.build/modules/rules_jvm_external/6.3/MODULE.bazel": "c998e060b85f71e00de5ec552019347c8bca255062c990ac02d051bb80a38df0",
+ "https://bcr.bazel.build/modules/rules_jvm_external/6.3/source.json": "6f5f5a5a4419ae4e37c35a5bb0a6ae657ed40b7abc5a5189111b47fcebe43197",
+ "https://bcr.bazel.build/modules/rules_kotlin/1.9.0/MODULE.bazel": "ef85697305025e5a61f395d4eaede272a5393cee479ace6686dba707de804d59",
+ "https://bcr.bazel.build/modules/rules_kotlin/1.9.6/MODULE.bazel": "d269a01a18ee74d0335450b10f62c9ed81f2321d7958a2934e44272fe82dcef3",
+ "https://bcr.bazel.build/modules/rules_kotlin/1.9.6/source.json": "2faa4794364282db7c06600b7e5e34867a564ae91bda7cae7c29c64e9466b7d5",
+ "https://bcr.bazel.build/modules/rules_license/0.0.3/MODULE.bazel": "627e9ab0247f7d1e05736b59dbb1b6871373de5ad31c3011880b4133cafd4bd0",
+ "https://bcr.bazel.build/modules/rules_license/0.0.7/MODULE.bazel": "088fbeb0b6a419005b89cf93fe62d9517c0a2b8bb56af3244af65ecfe37e7d5d",
+ "https://bcr.bazel.build/modules/rules_license/1.0.0/MODULE.bazel": "a7fda60eefdf3d8c827262ba499957e4df06f659330bbe6cdbdb975b768bb65c",
+ "https://bcr.bazel.build/modules/rules_license/1.0.0/source.json": "a52c89e54cc311196e478f8382df91c15f7a2bfdf4c6cd0e2675cc2ff0b56efb",
+ "https://bcr.bazel.build/modules/rules_pkg/0.7.0/MODULE.bazel": "df99f03fc7934a4737122518bb87e667e62d780b610910f0447665a7e2be62dc",
+ "https://bcr.bazel.build/modules/rules_pkg/1.0.1/MODULE.bazel": "5b1df97dbc29623bccdf2b0dcd0f5cb08e2f2c9050aab1092fd39a41e82686ff",
+ "https://bcr.bazel.build/modules/rules_pkg/1.0.1/source.json": "bd82e5d7b9ce2d31e380dd9f50c111d678c3bdaca190cb76b0e1c71b05e1ba8a",
+ "https://bcr.bazel.build/modules/rules_proto/4.0.0/MODULE.bazel": "a7a7b6ce9bee418c1a760b3d84f83a299ad6952f9903c67f19e4edd964894e06",
+ "https://bcr.bazel.build/modules/rules_proto/5.3.0-21.7/MODULE.bazel": "e8dff86b0971688790ae75528fe1813f71809b5afd57facb44dad9e8eca631b7",
+ "https://bcr.bazel.build/modules/rules_proto/6.0.2/MODULE.bazel": "ce916b775a62b90b61888052a416ccdda405212b6aaeb39522f7dc53431a5e73",
+ "https://bcr.bazel.build/modules/rules_proto/7.0.2/MODULE.bazel": "bf81793bd6d2ad89a37a40693e56c61b0ee30f7a7fdbaf3eabbf5f39de47dea2",
+ "https://bcr.bazel.build/modules/rules_proto/7.0.2/source.json": "1e5e7260ae32ef4f2b52fd1d0de8d03b606a44c91b694d2f1afb1d3b28a48ce1",
+ "https://bcr.bazel.build/modules/rules_python/0.10.2/MODULE.bazel": "cc82bc96f2997baa545ab3ce73f196d040ffb8756fd2d66125a530031cd90e5f",
+ "https://bcr.bazel.build/modules/rules_python/0.23.1/MODULE.bazel": "49ffccf0511cb8414de28321f5fcf2a31312b47c40cc21577144b7447f2bf300",
+ "https://bcr.bazel.build/modules/rules_python/0.25.0/MODULE.bazel": "72f1506841c920a1afec76975b35312410eea3aa7b63267436bfb1dd91d2d382",
+ "https://bcr.bazel.build/modules/rules_python/0.28.0/MODULE.bazel": "cba2573d870babc976664a912539b320cbaa7114cd3e8f053c720171cde331ed",
+ "https://bcr.bazel.build/modules/rules_python/0.31.0/MODULE.bazel": "93a43dc47ee570e6ec9f5779b2e64c1476a6ce921c48cc9a1678a91dd5f8fd58",
+ "https://bcr.bazel.build/modules/rules_python/0.4.0/MODULE.bazel": "9208ee05fd48bf09ac60ed269791cf17fb343db56c8226a720fbb1cdf467166c",
+ "https://bcr.bazel.build/modules/rules_python/0.40.0/MODULE.bazel": "9d1a3cd88ed7d8e39583d9ffe56ae8a244f67783ae89b60caafc9f5cf318ada7",
+ "https://bcr.bazel.build/modules/rules_python/0.40.0/source.json": "939d4bd2e3110f27bfb360292986bb79fd8dcefb874358ccd6cdaa7bda029320",
+ "https://bcr.bazel.build/modules/rules_shell/0.2.0/MODULE.bazel": "fda8a652ab3c7d8fee214de05e7a9916d8b28082234e8d2c0094505c5268ed3c",
+ "https://bcr.bazel.build/modules/rules_shell/0.2.0/source.json": "7f27af3c28037d9701487c4744b5448d26537cc66cdef0d8df7ae85411f8de95",
+ "https://bcr.bazel.build/modules/stardoc/0.5.1/MODULE.bazel": "1a05d92974d0c122f5ccf09291442580317cdd859f07a8655f1db9a60374f9f8",
+ "https://bcr.bazel.build/modules/stardoc/0.5.3/MODULE.bazel": "c7f6948dae6999bf0db32c1858ae345f112cacf98f174c7a8bb707e41b974f1c",
+ "https://bcr.bazel.build/modules/stardoc/0.5.6/MODULE.bazel": "c43dabc564990eeab55e25ed61c07a1aadafe9ece96a4efabb3f8bf9063b71ef",
+ "https://bcr.bazel.build/modules/stardoc/0.7.0/MODULE.bazel": "05e3d6d30c099b6770e97da986c53bd31844d7f13d41412480ea265ac9e8079c",
+ "https://bcr.bazel.build/modules/stardoc/0.7.1/MODULE.bazel": "3548faea4ee5dda5580f9af150e79d0f6aea934fc60c1cc50f4efdd9420759e7",
+ "https://bcr.bazel.build/modules/stardoc/0.7.1/source.json": "b6500ffcd7b48cd72c29bb67bcac781e12701cc0d6d55d266a652583cfcdab01",
+ "https://bcr.bazel.build/modules/upb/0.0.0-20220923-a547704/MODULE.bazel": "7298990c00040a0e2f121f6c32544bab27d4452f80d9ce51349b1a28f3005c43",
+ "https://bcr.bazel.build/modules/zlib/1.2.11/MODULE.bazel": "07b389abc85fdbca459b69e2ec656ae5622873af3f845e1c9d80fe179f3effa0",
+ "https://bcr.bazel.build/modules/zlib/1.3.1.bcr.5/MODULE.bazel": "eec517b5bbe5492629466e11dae908d043364302283de25581e3eb944326c4ca",
+ "https://bcr.bazel.build/modules/zlib/1.3.1.bcr.5/source.json": "22bc55c47af97246cfc093d0acf683a7869377de362b5d1c552c2c2e16b7a806",
+ "https://bcr.bazel.build/modules/zlib/1.3.1/MODULE.bazel": "751c9940dcfe869f5f7274e1295422a34623555916eb98c174c1e945594bf198"
+ },
+ "selectedYankedVersions": {},
+ "moduleExtensions": {}
+}
diff --git a/willow/docs/doxygen/Doxyfile b/willow/docs/doxygen/Doxyfile
new file mode 100644
index 0000000..bcb4641
--- /dev/null
+++ b/willow/docs/doxygen/Doxyfile
@@ -0,0 +1,10 @@
+PROJECT_NAME = "Willow"
+OUTPUT_DIRECTORY = "out/doxygen/willow"
+INPUT = willow/include
+RECURSIVE = YES
+FILE_PATTERNS = *.h
+GENERATE_HTML = YES
+GENERATE_LATEX = NO
+EXTRACT_ALL = YES
+WARN_AS_ERROR = YES
+QUIET = YES
diff --git a/willow/include/willow/IR/BasicBlock.h b/willow/include/willow/IR/BasicBlock.h
new file mode 100644
index 0000000..d783a5b
--- /dev/null
+++ b/willow/include/willow/IR/BasicBlock.h
@@ -0,0 +1,98 @@
+#ifndef WILLOW_IR_BASIC_BLOCK_H
+#define WILLOW_IR_BASIC_BLOCK_H
+
+#include <willow/IR/Instruction.h>
+
+#include <list>
+#include <memory>
+#include <ranges>
+#include <string>
+#include <string_view>
+#include <utility>
+#include <vector>
+
+namespace willow {
+
+class Function;
+
+/// A group of consecutive instructions.
+class BasicBlock {
+ std::string name;
+ Function *parent = nullptr;
+
+ std::list<std::unique_ptr<Instruction>> body;
+
+ std::vector<BasicBlock *> preds;
+ std::vector<BasicBlock *> succs;
+
+public:
+ // ~BasicBlock() = TODO
+ /// Create a basic block with a name and parent function.
+ BasicBlock(std::string name, Function *parent)
+ : name(std::move(name)), parent(parent) {}
+
+ std::string_view getName() const { return name; }
+ void setName(std::string name) { this->name = std::move(name); }
+
+ Function *getParent() const { return parent; }
+ bool hasParent() const { return parent; }
+ void setParent(Function *parent) { this->parent = parent; }
+
+ bool empty() const { return body.empty(); }
+ std::size_t size() { return body.size(); }
+
+ auto getBody() {
+ return body |
+ std::views::transform([](auto &p) -> Instruction & { return *p; });
+ }
+
+ auto getBody() const {
+ return body | std::views::transform(
+ [](auto &p) -> const Instruction & { return *p; });
+ }
+
+ Instruction *trailer();
+ Instruction *leader();
+
+ Instruction *addInstruction(std::unique_ptr<Instruction> inst);
+
+ template <typename... Args>
+ Instruction *emplaceInstruction(Args &&...args) {
+ body.push_back(std::make_unique<Instruction>(std::forward(args)...));
+ return body.back().get();
+ }
+
+ const std::vector<BasicBlock *> &predecessors() const { return preds; }
+ std::vector<BasicBlock *> &predecessors() { return preds; }
+
+ const std::vector<BasicBlock *> &successors() const { return succs; }
+ std::vector<BasicBlock *> &successors() { return succs; }
+
+ void addPredecessor(BasicBlock *pred) { preds.push_back(pred); }
+ void addSuccessor(BasicBlock *succ) { succs.push_back(succ); }
+ // TODO: add/remove preds
+};
+
+Instruction *BasicBlock::trailer() {
+ if (empty())
+ return nullptr;
+ else
+ return body.back().get();
+}
+
+Instruction *BasicBlock::leader() {
+ if (empty())
+ return nullptr;
+ else
+ return body.back().get();
+}
+
+Instruction *BasicBlock::addInstruction(std::unique_ptr<Instruction> inst) {
+ Instruction *p = inst.get();
+ body.push_back(std::move(inst));
+ return p;
+}
+
+} // namespace willow
+
+#endif // WILLOW_IR_BASIC_BLOCK_H
diff --git a/willow/include/willow/IR/Function.h b/willow/include/willow/IR/Function.h
new file mode 100644
index 0000000..97e4029
--- /dev/null
+++ b/willow/include/willow/IR/Function.h
@@ -0,0 +1,104 @@
+#ifndef WILLOW_IR_FUNCTION_H
+#define WILLOW_IR_FUNCTION_H
+
+#include <willow/IR/BasicBlock.h>
+#include <willow/IR/Value.h>
+
+#include <memory>
+#include <ranges>
+#include <string>
+#include <string_view>
+#include <utility>
+#include <vector>
+
+namespace willow {
+
+class Module;
+
+/// Groups basic blocks and the values they define.
+class Function {
+ std::string name;
+ Module *parent = nullptr;
+
+ std::vector<std::unique_ptr<BasicBlock>> blocks;
+ std::vector<std::unique_ptr<Value>> values;
+
+public:
+ /// Create a function with a name and its owning module.
+ /// \param name Function identifier.
+ /// \param parent Owning module.
+ Function(std::string name, Module *parent)
+ : name(std::move(name)), parent(parent) {}
+
+ std::string_view getName() const { return name; }
+ void setName(std::string name) { this->name = std::move(name); }
+
+ /// \return Parent module or nullptr.
+ Module *getParent() { return parent; }
+ const Module *getParent() const { return parent; }
+ void setParent(Module *parent) { this->parent = parent; }
+
+ /// \return Entry block or nullptr.
+ BasicBlock *entryBlock();
+ const BasicBlock *entryBlock() const;
+
+ bool empty() const { return blocks.empty(); }
+ std::size_t numBlocks() const { return blocks.size(); }
+
+ /// \return The blocks that make up this function.
+ auto getBlocks() {
+ return blocks |
+ std::views::transform([](auto &p) -> BasicBlock & { return *p; });
+ }
+
+ auto getBlocks() const {
+ return blocks | std::views::transform(
+ [](auto &p) -> const BasicBlock & { return *p; });
+ }
+
+ /// \return The SSA values that exist in this block.
+ auto getValues() {
+ return blocks |
+ std::views::transform([](auto &p) -> Value & { return *p; });
+ }
+ auto getValues() const {
+ return blocks |
+ std::views::transform([](auto &p) -> const Value & { return *p; });
+ }
+
+ /// Append an existing block, transferring ownership.
+ /// \param block Basic block to append.
+ /// \return Raw pointer to the appended block.
+ BasicBlock *addBlock(std::unique_ptr<BasicBlock> block) {
+ auto p = block.get();
+ blocks.push_back(std::move(block));
+ p->setParent(this);
+ return p;
+ }
+
+ /// Construct a new block in-place and append it.
+ /// \return Raw pointer to the appended block.
+ template <typename... Args>
+ BasicBlock *createBlock(Args &&...args) {
+ blocks.push_back(std::make_unique<BasicBlock>(std::forward<Args>(args)...));
+ return blocks.back().get();
+ }
+};
+
+const BasicBlock *Function::entryBlock() const {
+ if (blocks.empty())
+ return nullptr;
+ else
+ return blocks.front().get();
+}
+
+BasicBlock *Function::entryBlock() {
+ if (blocks.empty())
+ return nullptr;
+ else
+ return blocks.front().get();
+}
+
+} // namespace willow
+
+#endif // WILLOW_IR_FUNCTION_H
diff --git a/willow/include/willow/IR/IRBuilder.h b/willow/include/willow/IR/IRBuilder.h
new file mode 100644
index 0000000..79d3bb3
--- /dev/null
+++ b/willow/include/willow/IR/IRBuilder.h
@@ -0,0 +1,20 @@
+#ifndef WILLOW_IR_IR_BUILDER_H
+#define WILLOW_IR_IR_BUILDER_H
+
+#include <willow/IR/BasicBlock.h>
+#include <willow/IR/Function.h>
+#include <willow/IR/Instruction.h>
+
+namespace willow {
+
+/// Helper for constructing and modifiying IR.
+class IRBuilder {
+ BasicBlock *block = nullptr;
+
+public:
+ explicit IRBuilder(BasicBlock *block) : block(block);
+};
+
+} // namespace willow
+
+#endif // WILLOW_IR_IR_BUILDER_H
diff --git a/willow/include/willow/IR/Instruction.h b/willow/include/willow/IR/Instruction.h
new file mode 100644
index 0000000..c7756bb
--- /dev/null
+++ b/willow/include/willow/IR/Instruction.h
@@ -0,0 +1,61 @@
+#ifndef WILLOW_IR_INSTRUCTION_HPP
+#define WILLOW_IR_INSTRUCTION_HPP
+
+#include <willow/IR/Value.h>
+
+namespace willow {
+
+class Value;
+
+/// Defines an SSA value or control-flow effect.
+class Instruction : Value {
+public:
+ enum class Op {
+ Const,
+
+ Add,
+ Mul,
+ Sub,
+ Div,
+ Mod,
+ Shl,
+ Shr,
+
+ Eq,
+ Lt,
+ Gt,
+ Le,
+ Ge,
+
+ Not,
+ And,
+ Or,
+
+ Jmp,
+ Br,
+ Call,
+ Ret,
+
+ Phi,
+ Alloca
+ };
+
+private:
+ class BasicBlock *parent = nullptr;
+ Op op;
+
+public:
+ /// \param op Opcode for this instruction.
+ /// \param val SSA value defined by this instruction (may be nullptr).
+ Instruction(Op op, Value *val);
+
+ Op getOp() const { return op; }
+
+ const Value *getValue() const { return value; }
+ Value *getValue() { return value; }
+ bool hasValue() const { return value; }
+};
+
+} // namespace willow
+
+#endif // WILLOW_IR_INST_HPP
diff --git a/willow/include/willow/IR/Module.h b/willow/include/willow/IR/Module.h
new file mode 100644
index 0000000..2002a90
--- /dev/null
+++ b/willow/include/willow/IR/Module.h
@@ -0,0 +1,54 @@
+#ifndef WILLOW_IR_MODULE_H
+#define WILLOW_IR_MODULE_H
+
+#include <willow/IR/Function.h>
+
+namespace willow {
+
+/// Represents a compilation unit.
+class Module {
+ std::string name;
+ std::vector<std::unique_ptr<Function>> functions;
+
+public:
+ explicit Module(std::string name) : name(std::move(name)) {}
+
+ /// Moves a Function to this module, transfering ownership.
+ /// \param fn The function to move.
+ /// \return A raw pointer to the function.
+ Function *addFunction(std::unique_ptr<Function> fn);
+
+ template <typename... Args>
+ Function *emplaceFunction(Args &&...args) {
+ functions.push_back(
+ std::make_unique<Function>(std::forward<Args>(args)...));
+ auto *fn = functions.back().get();
+ fn->setParent(this);
+ return fn;
+ }
+
+ std::string_view getName() const { return name; }
+ void setName(std::string name) { this->name = std::move(name); }
+
+ std::size_t numFunctions() const { return functions.size(); }
+
+ auto getFunctions() {
+ return functions |
+ std::views::transform([](auto &p) -> Function & { return *p; });
+ }
+ auto getFunctions() const {
+ return functions | std::views::transform(
+ [](auto &p) -> const Function & { return *p; });
+ }
+};
+
+Function *Module::addFunction(std::unique_ptr<Function> fn) {
+ auto p = fn.get();
+ functions.push_back(std::move(fn));
+ p->setParent(this);
+ return p;
+}
+
+} // namespace willow
+
+#endif // WILLOW_IR_MODULE_H
diff --git a/willow/include/willow/IR/TypeContext.h b/willow/include/willow/IR/TypeContext.h
new file mode 100644
index 0000000..d1323f0
--- /dev/null
+++ b/willow/include/willow/IR/TypeContext.h
@@ -0,0 +1,57 @@
+#ifndef _WILLOW_INCLUDE_TYPE_CONTEXT_H
+#define _WILLOW_INCLUDE_TYPE_CONTEXT_H
+
+#include <willow/IR/Types.h>
+
+#include <memory>
+#include <unordered_map>
+
+namespace willow {
+
+/// Context that owns and uniques type instances.
+class TypeContext {
+public:
+ TypeContext() = default;
+ TypeContext(const TypeContext &) = delete;
+ TypeContext &operator=(const TypeContext &) = delete;
+
+ /// \param width Bit width of the integer type.
+ /// \return Uniqued integer type for the requested width.
+ Type getIntType(std::size_t width);
+
+ /// \param pointee Type of the pointee.
+ /// \param size Size in bits of the pointer representation.
+ /// \return Uniqued pointer type.
+ Type getPtrType(Type pointee, std::size_t size);
+
+ /// \return Uniqued void type.
+ Type getVoidType();
+
+private:
+ std::unordered_map<IntTypeImpl::Key, std::unique_ptr<IntTypeImpl>,
+ IntTypeImpl::Hash>
+ icache;
+ std::unordered_map<PtrTypeImpl::Key, std::unique_ptr<PtrTypeImpl>,
+ PtrTypeImpl::Hash>
+ pcache;
+ std::unique_ptr<VoidTypeImpl> voidty;
+};
+
+Type TypeContext::getIntType(std::size_t width) {
+ auto [it, _] = icache.try_emplace(IntTypeImpl::Key{width});
+
+ return Type(it->second.get());
+}
+
+Type TypeContext::getPtrType(Type pointee, std::size_t size) {
+ auto [it, _] = pcache.try_emplace(
+ PtrTypeImpl::Key{pointee}, std::make_unique<PtrTypeImpl>(pointee, size));
+
+ return Type(it->second.get());
+}
+
+Type TypeContext::getVoidType() { return Type(voidty.get()); }
+
+} // namespace willow
+
+#endif // _WILLOW_INCLUDE_TYPE_CONTEXT_H
diff --git a/willow/include/willow/IR/Types.h b/willow/include/willow/IR/Types.h
new file mode 100644
index 0000000..85f4a67
--- /dev/null
+++ b/willow/include/willow/IR/Types.h
@@ -0,0 +1,108 @@
+#ifndef _WILLOW_IR_TYPES_H
+#define _WILLOW_IR_TYPES_H
+
+#include <cstddef>
+#include <functional>
+#include <ostream>
+
+namespace willow {
+
+/// IDs of all base types.
+enum class TypeID {
+ // Primitive types
+ Void, ///< Void type
+ Label, ///< Label type
+
+ // Parameterized types
+ Int, ///< Integer type of any bit width
+ Function, ///< A Function symbol
+ Ptr, ///< Parameterized pointer type
+ Struct, ///< Aggregate struct type
+ Vector, ///< Vector type
+};
+
+class TypeImpl;
+
+class TypeImpl {
+ friend class TypeContext;
+ TypeID kind;
+ std::size_t num_bits;
+
+protected:
+ explicit TypeImpl(TypeID kind) : kind{kind} {}
+ explicit TypeImpl(TypeID kind, size_t num_bits)
+ : kind{kind}, num_bits{num_bits} {}
+
+public:
+ virtual ~TypeImpl() = default;
+ TypeID getTypeKind() const { return kind; }
+ std::size_t getNumBits() const { return num_bits; }
+};
+
+/// Instances of Type represent uniqued, immutable datatypes.
+///
+/// Internally, Type instances wrap a pointer to a TypeImpl, so they should be
+/// passed by value.
+class Type {
+ friend class TypeContext;
+ TypeImpl *impl;
+
+public:
+ explicit Type(TypeImpl *impl) : impl(impl) {}
+
+ bool operator==(const Type &other) const { return impl == other.impl; }
+ bool operator!=(const Type &other) const { return impl != other.impl; }
+ // Type() : impl(nullptr) {}
+
+ TypeID kind() const { return impl->getTypeKind(); };
+ std::size_t getNumBits() const { return impl->getNumBits(); };
+ TypeImpl *getImpl() const { return this->impl; }
+
+ bool isInt() const { return kind() == TypeID::Int; }
+ bool isPtr() const { return kind() == TypeID::Ptr; }
+ bool isVoid() const { return kind() == TypeID::Void; }
+};
+
+class IntTypeImpl : public TypeImpl {
+public:
+ explicit IntTypeImpl(std::size_t num_bits)
+ : TypeImpl{TypeID::Int, num_bits} {}
+
+ struct Key {
+ std::size_t num_bits;
+ Key(std::size_t w) : num_bits(w) {}
+
+ bool operator==(const Key &k) const { return this->num_bits == k.num_bits; }
+ };
+
+ struct Hash {
+ std::size_t operator()(const Key &k) const noexcept {
+ return std::hash<size_t>{}(k.num_bits);
+ }
+ };
+};
+
+class PtrTypeImpl : public TypeImpl {
+ Type pointee;
+
+public:
+ PtrTypeImpl(Type pointee_type, std::size_t size)
+ : TypeImpl{TypeID::Ptr, size}, pointee{pointee_type.getImpl()} {}
+
+ struct Key {
+ Type pointee;
+ explicit Key(Type pointee) : pointee{pointee} {}
+
+ bool operator==(const Key &k) const { return this->pointee == k.pointee; }
+ };
+
+ struct Hash {
+ std::size_t operator()(const Key &k) const noexcept {
+ return std::hash<TypeImpl *>{}(k.pointee.getImpl());
+ }
+ };
+};
+
+}; // namespace willow
+
+#endif // _WILLOW_IR_TYPES_H
diff --git a/willow/include/willow/IR/Value.h b/willow/include/willow/IR/Value.h
new file mode 100644
index 0000000..a819b53
--- /dev/null
+++ b/willow/include/willow/IR/Value.h
@@ -0,0 +1,50 @@
+#ifndef _WILLOW_IR_VALUE_HPP
+#define _WILLOW_IR_VALUE_HPP
+
+// #include <willow/IR/Instruction.h>
+#include <willow/IR/Types.h>
+
+#include <string>
+#include <string_view>
+#include <vector>
+
+namespace willow {
+
+class Instruction;
+
+enum class ValueType {
+ Result, ///< the identified result of an instruction
+ Parameter, ///< the named parameter to a function
+ Literal, ///< an anonymous typed literal
+};
+
+/// An SSA value that may be used.
+class Value {
+ std::string name;
+ ValueType value_type;
+ Type type;
+
+ // Instructions that use this value
+ std::vector<Instruction *> uses;
+
+public:
+ Value(std::string name, Type type) : name(std::move(name)), type(type) {}
+ explicit Value(Type type) : type(type) {}
+
+ bool hasName() const { return !name.empty(); }
+
+ std::string_view getName() const { return name; }
+ void setName(std::string name) { this->name = std::move(name); }
+
+ Type getType() const { return type; }
+ ValueType getValueType() const { return value_type; }
+
+ bool isVoid() const { return type->is }
+
+ const std::vector<Instruction *> &getUses() const { return uses; }
+ std::vector<Instruction *> &getUses() { return uses; }
+};
+
+} // namespace willow
+
+#endif // _WILLOW_IR_VALUE_HPP
diff --git a/willow/lib/IR/TypeContext.cpp b/willow/lib/IR/TypeContext.cpp
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/willow/lib/IR/TypeContext.cpp