From 8f1c094b601b27717bf30629e77eef6293479cd6 Mon Sep 17 00:00:00 2001 From: Edgar Luque Date: Sat, 3 Feb 2024 20:14:29 +0100 Subject: [PATCH] compile --- Cargo.lock | 764 +--------------- lib/edlang_codegen_mlir/Cargo.toml | 5 +- lib/edlang_codegen_mlir/src/codegen.rs | 1165 +++++++++--------------- lib/edlang_codegen_mlir/src/context.rs | 91 -- lib/edlang_codegen_mlir/src/ffi.rs | 10 - lib/edlang_codegen_mlir/src/lib.rs | 47 +- lib/edlang_driver/src/lib.rs | 9 +- lib/edlang_ir/src/lib.rs | 27 + lib/edlang_lowering/src/common.rs | 2 +- lib/edlang_lowering/src/lib.rs | 8 +- programs/simple.ed | 7 +- 11 files changed, 493 insertions(+), 1642 deletions(-) delete mode 100644 lib/edlang_codegen_mlir/src/context.rs delete mode 100644 lib/edlang_codegen_mlir/src/ffi.rs diff --git a/Cargo.lock b/Cargo.lock index b19491a77..324b311c7 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -121,73 +121,12 @@ dependencies = [ "rustc-demangle", ] -[[package]] -name = "base64" -version = "0.21.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9d297deb1925b89f2ccc13d7635fa0714f12c87adce1c75356b39ca9b7178567" - [[package]] name = "beef" version = "0.5.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3a8241f3ebb85c056b509d4327ad0358fbbba6ffb340bf388f26350aeda225b1" -[[package]] -name = "bincode" -version = "1.3.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b1f45e9417d87227c7a56d22e471c6206462cba514c7590c09aff4cf6d1ddcad" -dependencies = [ - "serde", -] - -[[package]] -name = "bindgen" -version = "0.66.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f2b84e06fc203107bfbad243f4aba2af864eb7db3b1cf46ea0a023b0b433d2a7" -dependencies = [ - "bitflags 2.4.2", - "cexpr", - "clang-sys", - "lazy_static", - "lazycell", - "log", - "peeking_take_while", - "prettyplease", - "proc-macro2", - "quote", - "regex", - "rustc-hash", - "shlex", - "syn 2.0.48", - "which", -] - -[[package]] -name = "bindgen" -version = "0.68.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "726e4313eb6ec35d2730258ad4e15b547ee75d6afaa1361a922e78e59b7d8078" -dependencies = [ - "bitflags 2.4.2", - "cexpr", - "clang-sys", - "lazy_static", - "lazycell", - "log", - "peeking_take_while", - "prettyplease", - "proc-macro2", - "quote", - "regex", - "rustc-hash", - "shlex", - "syn 2.0.48", - "which", -] - [[package]] name = "bit-set" version = "0.5.3" @@ -230,32 +169,12 @@ dependencies = [ "libc", ] -[[package]] -name = "cexpr" -version = "0.6.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6fac387a98bb7c37292057cffc56d62ecb629900026402633ae9160df93a8766" -dependencies = [ - "nom", -] - [[package]] name = "cfg-if" version = "1.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" -[[package]] -name = "clang-sys" -version = "1.7.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "67523a3b4be3ce1989d607a828d036249522dd9c1c8de7f4dd2dae43a37369d1" -dependencies = [ - "glob", - "libc", - "libloading", -] - [[package]] name = "clap" version = "4.4.18" @@ -276,7 +195,6 @@ dependencies = [ "anstyle", "clap_lex", "strsim", - "terminal_size", ] [[package]] @@ -288,7 +206,7 @@ dependencies = [ "heck", "proc-macro2", "quote", - "syn 2.0.48", + "syn", ] [[package]] @@ -330,26 +248,6 @@ version = "1.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "acbf1af155f9b9ef647e42cdc158db4b64a1b61f743629225fde6f3e0be2a7c7" -[[package]] -name = "comrak" -version = "0.20.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9f18e72341e6cdc7489cffb76f993812a14a906db54dedb020044ccc211dcaae" -dependencies = [ - "clap", - "derive_builder", - "entities", - "memchr", - "once_cell", - "regex", - "shell-words", - "slug", - "syntect", - "typed-arena", - "unicode_categories", - "xdg", -] - [[package]] name = "concolor" version = "0.1.1" @@ -370,124 +268,12 @@ dependencies = [ "windows-sys 0.45.0", ] -[[package]] -name = "convert_case" -version = "0.6.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ec182b0ca2f35d8fc196cf3404988fd8b8c739a4d270ff118a398feb0cbec1ca" -dependencies = [ - "unicode-segmentation", -] - -[[package]] -name = "crc32fast" -version = "1.3.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b540bd8bc810d3885c6ea91e2018302f68baba2129ab3e88f32389ee9370880d" -dependencies = [ - "cfg-if", -] - [[package]] name = "crunchy" version = "0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7a81dae078cea95a014a339291cec439d2f232ebe854a9d672b796c6afafa9b7" -[[package]] -name = "darling" -version = "0.14.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7b750cb3417fd1b327431a470f388520309479ab0bf5e323505daf0290cd3850" -dependencies = [ - "darling_core", - "darling_macro", -] - -[[package]] -name = "darling_core" -version = "0.14.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "109c1ca6e6b7f82cc233a97004ea8ed7ca123a9af07a8230878fcfda9b158bf0" -dependencies = [ - "fnv", - "ident_case", - "proc-macro2", - "quote", - "strsim", - "syn 1.0.109", -] - -[[package]] -name = "darling_macro" -version = "0.14.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a4aab4dbc9f7611d8b55048a3a16d2d010c2c8334e46304b40ac1cc14bf3b48e" -dependencies = [ - "darling_core", - "quote", - "syn 1.0.109", -] - -[[package]] -name = "dashmap" -version = "5.5.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "978747c1d849a7d2ee5e8adc0159961c48fb7e5db2f06af6723b80123bb53856" -dependencies = [ - "cfg-if", - "hashbrown", - "lock_api", - "once_cell", - "parking_lot_core", -] - -[[package]] -name = "deranged" -version = "0.3.11" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b42b6fa04a440b495c8b04d0e71b707c585f83cb9cb28cf8cd0d976c315e31b4" -dependencies = [ - "powerfmt", -] - -[[package]] -name = "derive_builder" -version = "0.12.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8d67778784b508018359cbc8696edb3db78160bab2c2a28ba7f56ef6932997f8" -dependencies = [ - "derive_builder_macro", -] - -[[package]] -name = "derive_builder_core" -version = "0.12.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c11bdc11a0c47bc7d37d582b5285da6849c96681023680b906673c5707af7b0f" -dependencies = [ - "darling", - "proc-macro2", - "quote", - "syn 1.0.109", -] - -[[package]] -name = "derive_builder_macro" -version = "0.12.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ebcda35c7a396850a55ffeac740804b40ffec779b98fffbb1738f4033f0ee79e" -dependencies = [ - "derive_builder_core", - "syn 1.0.109", -] - -[[package]] -name = "deunicode" -version = "1.4.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3ae2a35373c5c74340b79ae6780b498b2b183915ec5dacf263aac5a099bf485a" - [[package]] name = "diff" version = "0.1.13" @@ -544,12 +330,11 @@ version = "0.1.0" dependencies = [ "bumpalo", "cc", - "edlang_ast", + "edlang_ir", "edlang_parser", "edlang_session", + "inkwell", "llvm-sys", - "melior", - "mlir-sys", "tracing", ] @@ -626,12 +411,6 @@ dependencies = [ "log", ] -[[package]] -name = "entities" -version = "1.0.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b5320ae4c3782150d900b79807611a59a99fc9a1d61d686faafc24b93fc8d7ca" - [[package]] name = "equivalent" version = "1.0.1" @@ -658,32 +437,12 @@ dependencies = [ "once_cell", ] -[[package]] -name = "fancy-regex" -version = "0.11.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b95f7c0680e4142284cf8b22c14a476e87d61b004a3a0861872b32ef7ead40a2" -dependencies = [ - "bit-set", - "regex", -] - [[package]] name = "fixedbitset" version = "0.4.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0ce7134b9999ecaf8bcd65542e436736ef32ddca1b3e06094cb6ec5755203b80" -[[package]] -name = "flate2" -version = "1.0.28" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "46303f565772937ffe1d394a4fac6f411c6013172fadde9dcdb1e147a086940e" -dependencies = [ - "crc32fast", - "miniz_oxide", -] - [[package]] name = "fnv" version = "1.0.7" @@ -707,12 +466,6 @@ version = "0.28.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4271d37baee1b8c7e4b708028c57d816cf9d2434acb33a549475f78c181f6253" -[[package]] -name = "glob" -version = "0.3.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d2fabcfbdc87f4758337ca535fb41a6d701b65693ce38287d856d1674551ec9b" - [[package]] name = "hashbrown" version = "0.14.3" @@ -731,21 +484,6 @@ version = "0.3.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5d3d0e0f38255e7fa3cf31335b3a56f05febd18025f4db5ef7a0cfb4f8da651f" -[[package]] -name = "home" -version = "0.5.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e3d1354bf6b7235cb4a0576c2619fd4ed18183f689b12b006a0ee7329eeff9a5" -dependencies = [ - "windows-sys 0.52.0", -] - -[[package]] -name = "ident_case" -version = "1.0.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b9e0384b61958566e926dc50660321d12159025e767c18e043daf26b70104c39" - [[package]] name = "indenter" version = "0.3.3" @@ -762,6 +500,29 @@ dependencies = [ "hashbrown", ] +[[package]] +name = "inkwell" +version = "0.2.0" +source = "git+https://github.com/TheDan64/inkwell?rev=0cdaa34bd612464f310b3fdefa00a75d1324687d#0cdaa34bd612464f310b3fdefa00a75d1324687d" +dependencies = [ + "either", + "inkwell_internals", + "libc", + "llvm-sys", + "once_cell", + "thiserror", +] + +[[package]] +name = "inkwell_internals" +version = "0.8.0" +source = "git+https://github.com/TheDan64/inkwell?rev=0cdaa34bd612464f310b3fdefa00a75d1324687d#0cdaa34bd612464f310b3fdefa00a75d1324687d" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + [[package]] name = "is-terminal" version = "0.4.10" @@ -791,12 +552,6 @@ dependencies = [ "either", ] -[[package]] -name = "itoa" -version = "1.0.10" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b1a46d1a171d865aa5f83f92695765caa047a9b4cbae2cbf37dbd613a793fd4c" - [[package]] name = "lalrpop" version = "0.20.0" @@ -835,28 +590,12 @@ version = "1.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646" -[[package]] -name = "lazycell" -version = "1.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "830d08ce1d1d941e6b30645f1a0eb5643013d835ce3779a5fc208261dbe10f55" - [[package]] name = "libc" version = "0.2.152" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "13e3bf6590cbc649f4d1a3eefc9d5d6eb746f5200ffb04e5e142700b8faa56e7" -[[package]] -name = "libloading" -version = "0.8.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c571b676ddfc9a8c12f1f3d3085a7b163966a8fd8098a90640953ce5f6170161" -dependencies = [ - "cfg-if", - "windows-sys 0.48.0", -] - [[package]] name = "libredox" version = "0.0.1" @@ -868,21 +607,6 @@ dependencies = [ "redox_syscall", ] -[[package]] -name = "line-wrap" -version = "0.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f30344350a2a51da54c1d53be93fade8a237e545dbcc4bdbe635413f2117cab9" -dependencies = [ - "safemem", -] - -[[package]] -name = "linked-hash-map" -version = "0.5.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0717cef1bc8b636c6e1c1bbdefc09e6322da8a9321966e8928ef80d20f7f770f" - [[package]] name = "linux-raw-sys" version = "0.4.13" @@ -939,7 +663,7 @@ dependencies = [ "proc-macro2", "quote", "regex-syntax 0.6.29", - "syn 2.0.48", + "syn", ] [[package]] @@ -960,47 +684,12 @@ dependencies = [ "regex-automata 0.1.10", ] -[[package]] -name = "melior" -version = "0.15.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "878012ddccd6fdd099a4d98cebdecbaed9bc5eb325d0778ab9d4f4a52c67c18e" -dependencies = [ - "dashmap", - "melior-macro", - "mlir-sys", - "once_cell", -] - -[[package]] -name = "melior-macro" -version = "0.9.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ac9339fd6934926500d5a5f378bb5cda44efe33c74e4c300f083bf89b1544005" -dependencies = [ - "comrak", - "convert_case", - "once_cell", - "proc-macro2", - "quote", - "regex", - "syn 2.0.48", - "tblgen", - "unindent", -] - [[package]] name = "memchr" version = "2.7.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "523dc4f511e55ab87b694dc30d0f820d60906ef06413f93d4d7a1385599cc149" -[[package]] -name = "minimal-lexical" -version = "0.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "68354c5c6bd36d73ff3feceb05efa59b6acb7626617f4962be322a825e61f79a" - [[package]] name = "miniz_oxide" version = "0.7.1" @@ -1010,31 +699,12 @@ dependencies = [ "adler", ] -[[package]] -name = "mlir-sys" -version = "0.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d5e19a5391ed2759fd9060f538330b9b89191e7b13503d7499a4f9580af6699a" -dependencies = [ - "bindgen 0.68.1", -] - [[package]] name = "new_debug_unreachable" version = "1.0.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e4a24736216ec316047a1fc4252e27dabb04218aa4a3f37c6e7ddbf1f9782b54" -[[package]] -name = "nom" -version = "7.1.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d273983c5a657a70a3e8f2a01329822f3b8c8172b73826411a55751e404a0a4a" -dependencies = [ - "memchr", - "minimal-lexical", -] - [[package]] name = "nu-ansi-term" version = "0.46.0" @@ -1060,28 +730,6 @@ version = "1.19.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3fdb12b2476b595f9358c5161aa467c2438859caa136dec86c26fdd2efe17b92" -[[package]] -name = "onig" -version = "6.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8c4b31c8722ad9171c6d77d3557db078cab2bd50afcc9d09c8b315c59df8ca4f" -dependencies = [ - "bitflags 1.3.2", - "libc", - "once_cell", - "onig_sys", -] - -[[package]] -name = "onig_sys" -version = "69.8.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7b829e3d7e9cc74c7e315ee8edb185bf4190da5acde74afd7fc59c35b1f086e7" -dependencies = [ - "cc", - "pkg-config", -] - [[package]] name = "overload" version = "0.1.1" @@ -1117,18 +765,6 @@ dependencies = [ "windows-targets 0.48.5", ] -[[package]] -name = "paste" -version = "1.0.14" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "de3145af08024dea9fa9914f381a17b8fc6034dfb00f3a84013f7ff43f29ed4c" - -[[package]] -name = "peeking_take_while" -version = "0.1.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "19b17cddbe7ec3f8bc800887bab5e717348c95ea2ca0b1bf0837fb964dc67099" - [[package]] name = "petgraph" version = "0.6.4" @@ -1160,48 +796,12 @@ version = "0.2.13" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8afb450f006bf6385ca15ef45d71d2288452bc3683ce2e2cacc0d18e4be60b58" -[[package]] -name = "pkg-config" -version = "0.3.29" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2900ede94e305130c13ddd391e0ab7cbaeb783945ae07a279c268cb05109c6cb" - -[[package]] -name = "plist" -version = "1.6.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e5699cc8a63d1aa2b1ee8e12b9ad70ac790d65788cd36101fa37f87ea46c4cef" -dependencies = [ - "base64", - "indexmap", - "line-wrap", - "quick-xml", - "serde", - "time", -] - -[[package]] -name = "powerfmt" -version = "0.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "439ee305def115ba05938db6eb1644ff94165c5ab5e9420d1c1bcedbba909391" - [[package]] name = "precomputed-hash" version = "0.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "925383efa346730478fb4838dbe9137d2a47675ad789c546d150a6e1dd4ab31c" -[[package]] -name = "prettyplease" -version = "0.2.16" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a41cf62165e97c7f814d2221421dbb9afcbcdb0a88068e5ea206e19951c2cbb5" -dependencies = [ - "proc-macro2", - "syn 2.0.48", -] - [[package]] name = "proc-macro2" version = "1.0.76" @@ -1211,15 +811,6 @@ dependencies = [ "unicode-ident", ] -[[package]] -name = "quick-xml" -version = "0.31.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1004a344b30a54e2ee58d66a71b32d2db2feb0a31f9a2d302bf0536f15de2a33" -dependencies = [ - "memchr", -] - [[package]] name = "quote" version = "1.0.35" @@ -1311,12 +902,6 @@ version = "0.1.23" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d626bb9dae77e28219937af045c257c28bfd3f69333c512553507f5f9798cb76" -[[package]] -name = "rustc-hash" -version = "1.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "08d43f7aa6b08d49f382cde6a7982047c3426db949b1424bc4b7ec9ae12c6ce2" - [[package]] name = "rustix" version = "0.38.30" @@ -1336,27 +921,6 @@ version = "1.0.14" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7ffc183a10b4478d04cbbbfc96d0873219d962dd5accaff2ffbd4ceb7df837f4" -[[package]] -name = "ryu" -version = "1.0.16" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f98d2aa92eebf49b69786be48e4477826b256916e84a57ff2a4f21923b48eb4c" - -[[package]] -name = "safemem" -version = "0.3.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ef703b7cb59335eae2eb93ceb664c0eb7ea6bf567079d843e09420219668e072" - -[[package]] -name = "same-file" -version = "1.0.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "93fc1dc3aaa9bfed95e02e6eadabb4baf7e3078b0bd1b4d7b6b0b68378900502" -dependencies = [ - "winapi-util", -] - [[package]] name = "scopeguard" version = "1.2.0" @@ -1369,37 +933,6 @@ version = "1.0.21" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b97ed7a9823b74f99c7742f5336af7be5ecd3eeafcb1507d1fa93347b1d589b0" -[[package]] -name = "serde" -version = "1.0.195" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "63261df402c67811e9ac6def069e4786148c4563f4b50fd4bf30aa370d626b02" -dependencies = [ - "serde_derive", -] - -[[package]] -name = "serde_derive" -version = "1.0.195" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "46fe8f8603d81ba86327b23a2e9cdf49e1255fb94a4c5f297f6ee0547178ea2c" -dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.48", -] - -[[package]] -name = "serde_json" -version = "1.0.111" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "176e46fa42316f18edd598015a5166857fc835ec732f5215eac6b7bdbf0a84f4" -dependencies = [ - "itoa", - "ryu", - "serde", -] - [[package]] name = "sharded-slab" version = "0.1.7" @@ -1409,34 +942,12 @@ dependencies = [ "lazy_static", ] -[[package]] -name = "shell-words" -version = "1.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "24188a676b6ae68c3b2cb3a01be17fbf7240ce009799bb56d5b1409051e78fde" - -[[package]] -name = "shlex" -version = "1.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a7cee0529a6d40f580e7a5e6c495c8fbfe21b7b52795ed4bb5e62cdf92bc6380" - [[package]] name = "siphasher" version = "0.3.11" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "38b58827f4464d87d377d175e90bf58eb00fd8716ff0a62f80356b5e61555d0d" -[[package]] -name = "slug" -version = "0.1.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3bd94acec9c8da640005f8e135a39fc0372e74535e6b368b7a04b875f784c8c4" -dependencies = [ - "deunicode", - "wasm-bindgen", -] - [[package]] name = "smallvec" version = "1.13.1" @@ -1462,17 +973,6 @@ version = "0.10.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "73473c0e59e6d5812c5dfe2a064a6444949f089e20eec9a2e5506596494e4623" -[[package]] -name = "syn" -version = "1.0.109" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "72b64191b275b66ffe2469e8af2c1cfe3bafa67b529ead792a6d0160888b4237" -dependencies = [ - "proc-macro2", - "quote", - "unicode-ident", -] - [[package]] name = "syn" version = "2.0.48" @@ -1484,40 +984,6 @@ dependencies = [ "unicode-ident", ] -[[package]] -name = "syntect" -version = "5.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e02b4b303bf8d08bfeb0445cba5068a3d306b6baece1d5582171a9bf49188f91" -dependencies = [ - "bincode", - "bitflags 1.3.2", - "fancy-regex", - "flate2", - "fnv", - "once_cell", - "onig", - "plist", - "regex-syntax 0.7.5", - "serde", - "serde_json", - "thiserror", - "walkdir", - "yaml-rust", -] - -[[package]] -name = "tblgen" -version = "0.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3d19c09266feb8b16718d1183044d14703a0b4b59e55ce8beb4d6e21dd066b1b" -dependencies = [ - "bindgen 0.66.1", - "cc", - "paste", - "thiserror", -] - [[package]] name = "term" version = "0.7.0" @@ -1529,16 +995,6 @@ dependencies = [ "winapi", ] -[[package]] -name = "terminal_size" -version = "0.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "21bebf2b7c9e0a515f6e0f8c51dc0f8e4696391e6f1ff30379559f8365fb0df7" -dependencies = [ - "rustix", - "windows-sys 0.48.0", -] - [[package]] name = "thiserror" version = "1.0.56" @@ -1556,7 +1012,7 @@ checksum = "fa0faa943b50f3db30a20aa7e265dbc66076993efed8463e8de414e5d06d3471" dependencies = [ "proc-macro2", "quote", - "syn 2.0.48", + "syn", ] [[package]] @@ -1569,35 +1025,6 @@ dependencies = [ "once_cell", ] -[[package]] -name = "time" -version = "0.3.31" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f657ba42c3f86e7680e53c8cd3af8abbe56b5491790b46e22e19c0d57463583e" -dependencies = [ - "deranged", - "itoa", - "powerfmt", - "serde", - "time-core", - "time-macros", -] - -[[package]] -name = "time-core" -version = "0.1.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ef927ca75afb808a4d64dd374f00a2adf8d0fcff8e7b184af886c3c87ec4a3f3" - -[[package]] -name = "time-macros" -version = "0.2.16" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "26197e33420244aeb70c3e8c78376ca46571bc4e701e4791c2cd9f57dcb3a43f" -dependencies = [ - "time-core", -] - [[package]] name = "tiny-keccak" version = "2.0.2" @@ -1626,7 +1053,7 @@ checksum = "34704c8d6ebcbc939824180af020566b01a7c01f80641264eba0999f6c2b6be7" dependencies = [ "proc-macro2", "quote", - "syn 2.0.48", + "syn", ] [[package]] @@ -1678,24 +1105,12 @@ dependencies = [ "tracing-log", ] -[[package]] -name = "typed-arena" -version = "2.0.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6af6ae20167a9ece4bcb41af5b80f8a1f1df981f6391189ce00fd257af04126a" - [[package]] name = "unicode-ident" version = "1.0.12" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3354b9ac3fae1ff6755cb6db53683adb661634f67557942dea4facebec0fee4b" -[[package]] -name = "unicode-segmentation" -version = "1.10.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1dd624098567895118886609431a7c3b8f516e41d30e0643f03d94592a147e36" - [[package]] name = "unicode-width" version = "0.1.11" @@ -1708,18 +1123,6 @@ version = "0.2.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f962df74c8c05a667b5ee8bcf162993134c104e96440b663c8daa176dc772d8c" -[[package]] -name = "unicode_categories" -version = "0.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "39ec24b3121d976906ece63c9daad25b85969647682eee313cb5779fdd69e14e" - -[[package]] -name = "unindent" -version = "0.2.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c7de7d73e1754487cb58364ee906a499937a0dfabd86bcb980fa99ec8c8fa2ce" - [[package]] name = "utf8parse" version = "0.2.1" @@ -1732,88 +1135,12 @@ version = "0.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "830b7e5d4d90034032940e4ace0d9a9a057e7a45cd94e6c007832e39edb82f6d" -[[package]] -name = "walkdir" -version = "2.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d71d857dc86794ca4c280d616f7da00d2dbfd8cd788846559a6813e6aa4b54ee" -dependencies = [ - "same-file", - "winapi-util", -] - [[package]] name = "wasi" version = "0.11.0+wasi-snapshot-preview1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423" -[[package]] -name = "wasm-bindgen" -version = "0.2.90" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b1223296a201415c7fad14792dbefaace9bd52b62d33453ade1c5b5f07555406" -dependencies = [ - "cfg-if", - "wasm-bindgen-macro", -] - -[[package]] -name = "wasm-bindgen-backend" -version = "0.2.90" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fcdc935b63408d58a32f8cc9738a0bffd8f05cc7c002086c6ef20b7312ad9dcd" -dependencies = [ - "bumpalo", - "log", - "once_cell", - "proc-macro2", - "quote", - "syn 2.0.48", - "wasm-bindgen-shared", -] - -[[package]] -name = "wasm-bindgen-macro" -version = "0.2.90" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3e4c238561b2d428924c49815533a8b9121c664599558a5d9ec51f8a1740a999" -dependencies = [ - "quote", - "wasm-bindgen-macro-support", -] - -[[package]] -name = "wasm-bindgen-macro-support" -version = "0.2.90" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bae1abb6806dc1ad9e560ed242107c0f6c84335f1749dd4e8ddb012ebd5e25a7" -dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.48", - "wasm-bindgen-backend", - "wasm-bindgen-shared", -] - -[[package]] -name = "wasm-bindgen-shared" -version = "0.2.90" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4d91413b1c31d7539ba5ef2451af3f0b833a005eb27a631cec32bc0635a8602b" - -[[package]] -name = "which" -version = "4.4.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "87ba24419a2078cd2b0f2ede2691b6c66d8e47836da3b6db8265ebad47afbfc7" -dependencies = [ - "either", - "home", - "once_cell", - "rustix", -] - [[package]] name = "winapi" version = "0.3.9" @@ -1830,15 +1157,6 @@ version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" -[[package]] -name = "winapi-util" -version = "0.1.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f29e6f9198ba0d26b4c9f07dbe6f9ed633e1f3d5b8b414090084349e46a52596" -dependencies = [ - "winapi", -] - [[package]] name = "winapi-x86_64-pc-windows-gnu" version = "0.4.0" @@ -1854,15 +1172,6 @@ dependencies = [ "windows-targets 0.42.2", ] -[[package]] -name = "windows-sys" -version = "0.48.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "677d2418bec65e3338edb076e806bc1ec15693c5d0104683f2efe857f61056a9" -dependencies = [ - "windows-targets 0.48.5", -] - [[package]] name = "windows-sys" version = "0.52.0" @@ -2043,21 +1352,6 @@ version = "0.52.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "dff9641d1cd4be8d1a070daf9e3773c5f67e78b4d9d42263020c057706765c04" -[[package]] -name = "xdg" -version = "2.5.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "213b7324336b53d2414b2db8537e56544d981803139155afa84f76eeebb7a546" - -[[package]] -name = "yaml-rust" -version = "0.4.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "56c1936c4cc7a1c9ab21a1ebb602eb942ba868cbd44a99cb7cdc5892335e1c85" -dependencies = [ - "linked-hash-map", -] - [[package]] name = "yansi" version = "0.5.1" diff --git a/lib/edlang_codegen_mlir/Cargo.toml b/lib/edlang_codegen_mlir/Cargo.toml index 360396258..d0ef97099 100644 --- a/lib/edlang_codegen_mlir/Cargo.toml +++ b/lib/edlang_codegen_mlir/Cargo.toml @@ -12,12 +12,11 @@ categories = ["compilers"] [dependencies] bumpalo = { version = "3.14.0", features = ["std"] } -edlang_ast = { version = "0.1.0", path = "../edlang_ast" } +edlang_ir = { version = "0.1.0", path = "../edlang_ir" } edlang_parser = { version = "0.1.0", path = "../edlang_parser" } edlang_session = { version = "0.1.0", path = "../edlang_session" } llvm-sys = "170.0.1" -melior = { version = "0.15.2", features = ["ods-dialects"] } -mlir-sys = "0.2.1" +inkwell = { git = "https://github.com/TheDan64/inkwell", rev = "0cdaa34bd612464f310b3fdefa00a75d1324687d", features = ["llvm17-0"] } tracing = { workspace = true } [build-dependencies] diff --git a/lib/edlang_codegen_mlir/src/codegen.rs b/lib/edlang_codegen_mlir/src/codegen.rs index 4aca2c7cc..7f389e593 100644 --- a/lib/edlang_codegen_mlir/src/codegen.rs +++ b/lib/edlang_codegen_mlir/src/codegen.rs @@ -1,789 +1,440 @@ -use std::{collections::HashMap, error::Error}; +use std::{collections::HashMap, error::Error, path::PathBuf}; -use bumpalo::Bump; -use edlang_ast::{ - ArithOp, AssignStmt, BinaryOp, CmpOp, Constant, Expression, FnCallExpr, Function, IfStmt, - LetStmt, LogicOp, Module, ModuleStatement, ReturnStmt, Statement, Struct, ValueExpr, -}; +use edlang_ir as ir; +use edlang_ir::DefId; use edlang_session::Session; -use melior::{ - dialect::{ - arith::{self, CmpiPredicate}, - cf, func, memref, - }, - ir::{ - attribute::{FlatSymbolRefAttribute, IntegerAttribute, StringAttribute, TypeAttribute}, - r#type::{FunctionType, IntegerType, MemRefType}, - Attribute, Block, BlockRef, Location, Module as MeliorModule, Region, Type, Value, - ValueLike, - }, - Context as MeliorContext, +use inkwell::{ + builder::{Builder, BuilderError}, + context::Context, + debug_info::{DICompileUnit, DebugInfoBuilder}, + module::Module, + targets::{InitializationConfig, Target, TargetData, TargetMachine, TargetTriple}, + types::{AnyType, BasicMetadataTypeEnum, BasicType}, + values::{AnyValue, AnyValueEnum, BasicValue, BasicValueEnum}, }; +use ir::ValueTree; +use tracing::info; -#[derive(Debug, Clone)] -pub struct LocalVar<'ctx, 'parent: 'ctx> { - pub ast_type: edlang_ast::Type, - // If it's none its on a register, otherwise allocated on the stack. - pub is_alloca: bool, - pub value: Value<'ctx, 'parent>, +#[derive(Debug, Clone, Copy)] +struct CompileCtx<'a> { + context: &'a Context, + session: &'a Session, + modules: &'a HashMap, + symbols: &'a HashMap, } -impl<'ctx, 'parent> LocalVar<'ctx, 'parent> { - pub fn param(value: Value<'ctx, 'parent>, ast_type: edlang_ast::Type) -> Self { - Self { - value, - ast_type, - is_alloca: false, - } - } - - pub fn alloca(value: Value<'ctx, 'parent>, ast_type: edlang_ast::Type) -> Self { - Self { - value, - ast_type, - is_alloca: true, - } - } +struct ModuleCompileCtx<'ctx, 'm> { + ctx: CompileCtx<'ctx>, + builder: &'m Builder<'ctx>, + module: Module<'m>, + di_builder: DebugInfoBuilder<'ctx>, + di_unit: DICompileUnit<'ctx>, + target_data: TargetData, } -#[derive(Debug, Clone, Default)] -struct ScopeContext<'ctx, 'parent: 'ctx> { - pub locals: HashMap>, - pub functions: HashMap, - pub structs: HashMap, - pub constants: HashMap, - pub function: Option<&'parent edlang_ast::Function>, -} - -impl<'ctx, 'parent: 'ctx> ScopeContext<'ctx, 'parent> { - fn is_type_signed(&self, type_info: &edlang_ast::Type) -> bool { - let signed = ["i8", "i16", "i32", "i64", "i128"]; - signed.contains(&type_info.name.name.as_str()) - } - - fn is_float(&self, type_info: &edlang_ast::Type) -> bool { - let signed = ["f32", "f64"]; - signed.contains(&type_info.name.name.as_str()) - } -} - -struct BlockHelper<'ctx, 'this: 'ctx> { - region: &'this Region<'ctx>, - blocks_arena: &'this Bump, -} - -impl<'ctx, 'this: 'ctx> BlockHelper<'ctx, 'this> { - pub fn append_block(&self, block: Block<'ctx>) -> &'this BlockRef<'ctx, 'this> { - let block = self.region.append_block(block); - - let block_ref: &'this mut BlockRef<'ctx, 'this> = self.blocks_arena.alloc(block); - block_ref - } -} - -impl<'ctx, 'parent: 'ctx> ScopeContext<'ctx, 'parent> { - fn resolve_type_name( - &self, - context: &'ctx MeliorContext, - name: &str, - ) -> Result, Box> { - Ok(match name { - "u128" | "i128" => IntegerType::new(context, 128).into(), - "u64" | "i64" => IntegerType::new(context, 64).into(), - "u32" | "i32" => IntegerType::new(context, 32).into(), - "u16" | "i16" => IntegerType::new(context, 16).into(), - "u8" | "i8" => IntegerType::new(context, 8).into(), - "f32" => Type::float32(context), - "f64" => Type::float64(context), - "bool" => IntegerType::new(context, 1).into(), - _ => todo!("custom type lookup"), - }) - } - - fn resolve_type( - &self, - context: &'ctx MeliorContext, - r#type: &edlang_ast::Type, - ) -> Result, Box> { - self.resolve_type_name(context, &r#type.name.name) - } -} - -pub fn compile_module( +pub fn compile( session: &Session, - context: &MeliorContext, - mlir_module: &MeliorModule, - module: &Module, -) -> Result<(), Box> { - let mut scope_ctx: ScopeContext = Default::default(); - let block = mlir_module.body(); + modules: &HashMap, + symbols: &HashMap, +) -> Result> { + let context = Context::create(); + let builder = context.create_builder(); - // Save types - for statement in &module.contents { - match statement { - ModuleStatement::Function(info) => { - scope_ctx.functions.insert(info.name.name.clone(), info); - } - ModuleStatement::Constant(info) => { - scope_ctx.constants.insert(info.name.name.clone(), info); - } - ModuleStatement::Struct(info) => { - scope_ctx.structs.insert(info.name.name.clone(), info); - } - ModuleStatement::Module(_) => todo!(), - } - } - - for statement in &module.contents { - match statement { - ModuleStatement::Function(info) => { - compile_function_def(session, context, &scope_ctx, &block, info)?; - } - ModuleStatement::Constant(_) => todo!(), - ModuleStatement::Struct(_) => todo!(), - ModuleStatement::Module(_) => todo!(), - } - } - - tracing::debug!("compiled module"); - - Ok(()) -} - -fn get_location<'c>(context: &'c MeliorContext, session: &Session, offset: usize) -> Location<'c> { - let (_, line, col) = session.source.get_offset_line(offset).unwrap(); - Location::new( - context, - &session.file_path.display().to_string(), - line + 1, - col + 1, - ) -} - -fn get_di_file<'c>(context: &'c MeliorContext, session: &Session) -> Attribute<'c> { - Attribute::parse( - context, - &format!(r#"#llvm.di_file<"{}">"#, session.file_path.display()), - ) - .unwrap() -} - -fn get_di<'c>(context: &'c MeliorContext, session: &Session) -> Attribute<'c> { - Attribute::parse( - context, - &format!(r#"#llvm.di_file<"{}">"#, session.file_path.display()), - ) - .unwrap() -} - -fn compile_function_def<'ctx, 'parent>( - session: &Session, - context: &'ctx MeliorContext, - scope_ctx: &ScopeContext<'ctx, 'parent>, - block: &'parent Block<'ctx>, - info: &Function, -) -> Result<(), Box> { - tracing::debug!("compiling function: {}", info.name.name); - let region = Region::new(); - - let location = get_location(context, session, info.name.span.lo); - - let mut args = Vec::with_capacity(info.params.len()); - let mut fn_args_types = Vec::with_capacity(info.params.len()); - - for param in &info.params { - let param_type = scope_ctx.resolve_type(context, ¶m.arg_type)?; - let loc = get_location(context, session, param.name.span.lo); - // let loc = Location::name(context, ¶m.name.name, loc); - args.push((param_type, loc)); - fn_args_types.push(param_type); - } - - let return_type = if let Some(return_type) = &info.return_type { - vec![scope_ctx.resolve_type(context, return_type)?] - } else { - vec![] + let ctx = CompileCtx { + context: &context, + session, + modules, + symbols, }; - let func_type = - TypeAttribute::new(FunctionType::new(context, &fn_args_types, &return_type).into()); + let mut llvm_modules = Vec::new(); - let blocks_arena = Bump::new(); - { - let helper = BlockHelper { - region: ®ion, - blocks_arena: &blocks_arena, + Target::initialize_native(&InitializationConfig::default())?; + let triple = TargetMachine::get_default_triple(); + let cpu_features = TargetMachine::get_host_cpu_features(); + let cpu_name = TargetMachine::get_host_cpu_name(); + let target = Target::from_triple(&triple)?; + let machine = target + .create_target_machine( + &triple, + cpu_name.to_str()?, + cpu_features.to_str()?, + inkwell::OptimizationLevel::Aggressive, + inkwell::targets::RelocMode::Default, + inkwell::targets::CodeModel::Default, + ) + .unwrap(); + + let filename = session.file_path.file_name().unwrap().to_string_lossy(); + let dir = session.file_path.parent().unwrap().to_string_lossy(); + for (id, module) in modules.iter() { + let name = ctx.symbols.get(id).unwrap(); + let llvm_module = context.create_module(name); + llvm_module.set_source_file_name(&filename); + llvm_module.set_triple(&triple); + let (di_builder, di_unit) = llvm_module.create_debug_info_builder( + true, + inkwell::debug_info::DWARFSourceLanguage::Rust, + &filename, + &dir, + "edlang", + true, + "", // compiler flags + 1, + "", // split name + inkwell::debug_info::DWARFEmissionKind::Full, + module.module_id.module_id.try_into().unwrap(), // compile unit id? + false, + false, + "", + "edlang-sdk", + ); + + let module_ctx = ModuleCompileCtx { + ctx, + module: llvm_module, + di_builder, + di_unit, + builder: &builder, + target_data: machine.get_target_data(), }; - let fn_block = helper.append_block(Block::new(&args)); - let mut scope_ctx = scope_ctx.clone(); - scope_ctx.function = Some(info); - // Push arguments into locals - for (i, param) in info.params.iter().enumerate() { - scope_ctx.locals.insert( - param.name.name.clone(), - LocalVar::param(fn_block.argument(i)?.into(), param.arg_type.clone()), - ); - } + compile_module(&module_ctx, module); - let final_block = compile_block( - session, - context, - &mut scope_ctx, - &helper, - fn_block, - &info.body, + module_ctx.module.verify()?; + + module_ctx + .module + .print_to_file(session.output_file.with_extension("ll"))?; + + machine.write_to_file( + &module_ctx.module, + inkwell::targets::FileType::Assembly, + &session.output_file.with_extension("asm"), )?; - - if final_block.terminator().is_none() { - final_block.append_operation(func::r#return( - &[], - get_location(context, session, info.span.hi), - )); - } - } - - let op = func::func( - context, - StringAttribute::new(context, &info.name.name), - func_type, - region, - &[], - location, - ); - assert!(op.verify()); - - block.append_operation(op); - - Ok(()) -} - -fn compile_block<'ctx, 'parent: 'ctx>( - session: &Session, - context: &'ctx MeliorContext, - scope_ctx: &mut ScopeContext<'ctx, 'parent>, - helper: &BlockHelper<'ctx, 'parent>, - mut block: &'parent BlockRef<'ctx, 'parent>, - info: &'parent edlang_ast::Block, -) -> Result<&'parent BlockRef<'ctx, 'parent>, Box> { - tracing::debug!("compiling block"); - for stmt in &info.body { - match stmt { - Statement::Let(info) => { - compile_let(session, context, scope_ctx, helper, block, info)?; - } - Statement::Assign(info) => { - compile_assign(session, context, scope_ctx, helper, block, info)?; - } - Statement::For(_) => todo!(), - Statement::While(_) => todo!(), - Statement::If(info) => { - block = compile_if_stmt(session, context, scope_ctx, helper, block, info)?; - } - Statement::Return(info) => { - compile_return(session, context, scope_ctx, helper, block, info)?; - } - Statement::FnCall(info) => { - compile_fn_call(session, context, scope_ctx, helper, block, info)?; - } - } - } - - Ok(block) -} - -fn compile_let<'ctx, 'parent: 'ctx>( - session: &Session, - context: &'ctx MeliorContext, - scope_ctx: &mut ScopeContext<'ctx, 'parent>, - helper: &BlockHelper<'ctx, 'parent>, - block: &'parent BlockRef<'ctx, 'parent>, - info: &'parent LetStmt, -) -> Result<(), Box> { - tracing::debug!("compiling let"); - let value = compile_expression( - session, - context, - scope_ctx, - helper, - block, - &info.value, - Some(&info.r#type), - )?; - let location = get_location(context, session, info.name.span.lo); - - let memref_type = MemRefType::new(value.r#type(), &[1], None, None); - - let alloca: Value = block - .append_operation(memref::alloca( - context, - memref_type, - &[], - &[], - None, - location, - )) - .result(0)? - .into(); - let k0 = block - .append_operation(arith::constant( - context, - IntegerAttribute::new(0, Type::index(context)).into(), - location, - )) - .result(0)? - .into(); - block.append_operation(memref::store(value, alloca, &[k0], location)); - - scope_ctx.locals.insert( - info.name.name.clone(), - LocalVar::alloca(alloca, info.r#type.clone()), - ); - - Ok(()) -} - -fn compile_assign<'ctx, 'parent: 'ctx>( - session: &Session, - context: &'ctx MeliorContext, - scope_ctx: &mut ScopeContext<'ctx, 'parent>, - helper: &BlockHelper<'ctx, 'parent>, - block: &'parent BlockRef<'ctx, 'parent>, - info: &AssignStmt, -) -> Result<(), Box> { - tracing::debug!("compiling assign"); - let local = scope_ctx - .locals - .get(&info.name.first.name) - .expect("local should exist") - .clone(); - - assert!(local.is_alloca, "can only mutate local stack variables"); - - let location = get_location(context, session, info.name.first.span.lo); - - let value = compile_expression( - session, - context, - scope_ctx, - helper, - block, - &info.value, - Some(&local.ast_type), - )?; - - let k0 = block - .append_operation(arith::constant( - context, - IntegerAttribute::new(0, Type::index(context)).into(), - location, - )) - .result(0)? - .into(); - block.append_operation(memref::store(value, local.value, &[k0], location)); - Ok(()) -} - -fn compile_return<'ctx, 'parent: 'ctx>( - session: &Session, - context: &'ctx MeliorContext, - scope_ctx: &mut ScopeContext<'ctx, 'parent>, - helper: &BlockHelper<'ctx, 'parent>, - block: &'parent BlockRef<'ctx, 'parent>, - info: &ReturnStmt, -) -> Result<(), Box> { - tracing::debug!("compiling return"); - let location = get_location(context, session, info.span.lo); - - let ret_type = scope_ctx.function.and_then(|x| x.return_type.clone()); - - if let Some(value) = &info.value { - let value = compile_expression( - session, - context, - scope_ctx, - helper, - block, - value, - ret_type.as_ref(), + machine.write_to_file( + &module_ctx.module, + inkwell::targets::FileType::Object, + &session.output_file.with_extension("o"), )?; - block.append_operation(func::r#return(&[value], location)); - } else { - block.append_operation(func::r#return(&[], location)); + // todo link modules together + llvm_modules.push(module_ctx.module); } - Ok(()) + Ok(session.output_file.with_extension("o")) } -fn compile_expression<'ctx, 'parent: 'ctx>( - session: &Session, - context: &'ctx MeliorContext, - scope_ctx: &ScopeContext<'ctx, 'parent>, - helper: &BlockHelper<'ctx, 'parent>, - block: &'parent BlockRef<'ctx, 'parent>, - info: &Expression, - type_hint: Option<&'parent edlang_ast::Type>, -) -> Result, Box> { - tracing::debug!("compiling expression"); - Ok(match info { - Expression::Value(info) => match info { - ValueExpr::Bool { value, span } => block - .append_operation(arith::constant( - context, - IntegerAttribute::new((*value) as i64, IntegerType::new(context, 1).into()) - .into(), - get_location(context, session, span.lo), - )) - .result(0)? - .into(), - ValueExpr::Char { value, span } => block - .append_operation(arith::constant( - context, - IntegerAttribute::new((*value) as i64, IntegerType::new(context, 32).into()) - .into(), - get_location(context, session, span.lo), - )) - .result(0)? - .into(), - ValueExpr::Int { value, span } => { - let type_it = match type_hint.map(|x| scope_ctx.resolve_type(context, x)) { - Some(info) => info, - None => Ok(IntegerType::new(context, 32).into()), - }?; - block - .append_operation(arith::constant( - context, - IntegerAttribute::new((*value) as i64, type_it).into(), - get_location(context, session, span.lo), - )) - .result(0)? - .into() +fn compile_module(ctx: &ModuleCompileCtx, module: &ir::ModuleBody) { + info!("compiling module"); + for (fn_id, func) in module.functions.iter() { + compile_fn_signature(ctx, func); + } + + for (fn_id, func) in module.functions.iter() { + compile_fn(ctx, func).unwrap(); + } +} + +fn compile_fn_signature(ctx: &ModuleCompileCtx, body: &ir::Body) { + let (args, ret_type) = { (body.get_args(), body.ret_type.clone().unwrap()) }; + + let args: Vec = args + .iter() + .map(|x| compile_basic_type(ctx, &x.ty).into()) + .collect(); + let ret_type = compile_basic_type(ctx, &ret_type); + let name = ctx.ctx.symbols.get(&body.def_id).unwrap(); + info!("compiling fn sig: {}", name); + + ctx.module.add_function( + name, + ret_type.fn_type(&args, false), + Some(if body.is_extern { + inkwell::module::Linkage::AvailableExternally + } else if body.is_pub { + inkwell::module::Linkage::External + } else { + inkwell::module::Linkage::Private + }), + ); +} + +fn compile_fn(ctx: &ModuleCompileCtx, body: &ir::Body) -> Result<(), BuilderError> { + let name = ctx.ctx.symbols.get(&body.def_id).unwrap(); + info!("compiling fn body: {}", name); + // let (args, ret_type) = { (body.get_args(), body.ret_type.clone().unwrap()) }; + + let fn_value = ctx.module.get_function(name).unwrap(); + + let block = ctx.ctx.context.append_basic_block(fn_value, "entry"); + ctx.builder.position_at_end(block); + + let mut locals = HashMap::new(); + let mut ret_local = None; + + let mut arg_counter = 0; + + for (index, local) in body.locals.iter().enumerate() { + match local.kind { + ir::LocalKind::Temp => { + let ptr = ctx + .builder + .build_alloca(compile_basic_type(ctx, &local.ty), &index.to_string())?; + locals.insert(index, ptr); } - ValueExpr::Float { value, span } => { - let type_it = match type_hint.map(|x| scope_ctx.resolve_type(context, x)) { - Some(info) => info, - None => Ok(Type::float32(context)), - }?; - block - .append_operation(arith::constant( - context, - Attribute::parse(context, &format!("{value} : {type_it}")).unwrap(), - get_location(context, session, span.lo), - )) - .result(0)? - .into() + ir::LocalKind::Arg => { + let ptr = ctx + .builder + .build_alloca(compile_basic_type(ctx, &local.ty), &index.to_string())?; + ctx.builder + .build_store(ptr, fn_value.get_nth_param(arg_counter).unwrap())?; + arg_counter += 1; + locals.insert(index, ptr); } - ValueExpr::Str { value: _, span: _ } => todo!(), - ValueExpr::Path(path) => { - let local = scope_ctx - .locals - .get(&path.first.name) - .expect("local not found"); - - let location = get_location(context, session, path.first.span.lo); - - if local.is_alloca { - let k0 = block - .append_operation(arith::constant( - context, - IntegerAttribute::new(0, Type::index(context)).into(), - location, - )) - .result(0)? - .into(); - - block - .append_operation(memref::load(local.value, &[k0], location)) - .result(0)? - .into() + ir::LocalKind::ReturnPointer => { + if let ir::TypeKind::Unit = &local.ty.kind { } else { - local.value + ret_local = Some(index); + let ptr = ctx + .builder + .build_alloca(compile_basic_type(ctx, &local.ty), &index.to_string())?; + locals.insert(index, ptr); } } + } + } + + let mut blocks = Vec::with_capacity(body.blocks.len()); + + for (index, _block) in body.blocks.iter().enumerate() { + let llvm_block = ctx + .ctx + .context + .append_basic_block(fn_value, &format!("block_{index}")); + blocks.push(llvm_block); + } + + ctx.builder.build_unconditional_branch(blocks[0])?; + + for (block, llvm_block) in body.blocks.iter().zip(&blocks) { + info!("compiling block"); + ctx.builder.position_at_end(*llvm_block); + for stmt in &block.statements { + info!("compiling stmt"); + match &stmt.kind { + ir::StatementKind::Assign(place, rvalue) => { + match rvalue { + ir::RValue::Use(op) => match op { + ir::Operand::Copy(other_place) => { + // should this just copy the local? + let pointee_ty = + compile_basic_type(ctx, &body.locals[other_place.local].ty); + let value = ctx.builder.build_load( + pointee_ty, + *locals.get(&other_place.local).unwrap(), + "", + )?; + ctx.builder + .build_store(*locals.get(&place.local).unwrap(), value)?; + } + ir::Operand::Move(other_place) => { + let pointee_ty = + compile_basic_type(ctx, &body.locals[other_place.local].ty); + let value = ctx.builder.build_load( + pointee_ty, + *locals.get(&other_place.local).unwrap(), + "", + )?; + ctx.builder + .build_store(*locals.get(&place.local).unwrap(), value)?; + } + ir::Operand::Constant(data) => match &data.kind { + ir::ConstKind::Value(val) => { + let value = compile_value(ctx, val, &data.type_info); + ctx.builder + .build_store(*locals.get(&place.local).unwrap(), value)?; + } + ir::ConstKind::ZeroSized => todo!(), + }, + }, + ir::RValue::Ref(_, _) => todo!(), + ir::RValue::BinOp(_, _, _) => todo!(), + ir::RValue::LogicOp(_, _, _) => todo!(), + ir::RValue::UnOp(_, _) => todo!(), + } + } + ir::StatementKind::StorageLive(_) => { + // https://llvm.org/docs/LangRef.html#int-lifestart + } + ir::StatementKind::StorageDead(_) => {} + } + } + + info!("compiling terminator"); + match &block.terminator { + ir::Terminator::Target(id) => { + ctx.builder.build_unconditional_branch(blocks[*id])?; + } + ir::Terminator::Return => match ret_local { + Some(local) => { + let ptr = *locals.get(&local).unwrap(); + let pointee_ty = compile_basic_type(ctx, &body.locals[local].ty); + let value = ctx.builder.build_load(pointee_ty, ptr, "")?; + ctx.builder.build_return(Some(&value))?; + } + None => { + ctx.builder.build_return(None)?; + } + }, + ir::Terminator::Switch => todo!(), + ir::Terminator::Call { + func, + args, + dest, + target, + } => todo!(), + ir::Terminator::Unreachable => todo!(), + } + } + + Ok(()) +} + +fn compile_value<'ctx>( + ctx: &ModuleCompileCtx<'ctx, '_>, + val: &ValueTree, + ty: &ir::TypeInfo, +) -> BasicValueEnum<'ctx> { + let ty = compile_basic_type(ctx, ty); + match val { + ValueTree::Leaf(const_val) => match const_val { + ir::ConstValue::Bool(x) => ty + .into_int_type() + .const_int((*x) as u64, false) + .as_basic_value_enum(), + ir::ConstValue::I8(x) => ty + .into_int_type() + .const_int((*x) as u64, true) + .as_basic_value_enum(), + ir::ConstValue::I16(x) => ty + .into_int_type() + .const_int((*x) as u64, true) + .as_basic_value_enum(), + ir::ConstValue::I32(x) => ty + .into_int_type() + .const_int((*x) as u64, true) + .as_basic_value_enum(), + ir::ConstValue::I64(x) => ty + .into_int_type() + .const_int((*x) as u64, true) + .as_basic_value_enum(), + ir::ConstValue::I128(x) => ty + .into_int_type() + .const_int_from_string(&x.to_string(), inkwell::types::StringRadix::Decimal) + .unwrap() + .as_basic_value_enum(), + ir::ConstValue::U8(x) => ty + .into_int_type() + .const_int((*x) as u64, true) + .as_basic_value_enum(), + ir::ConstValue::U16(x) => ty + .into_int_type() + .const_int((*x) as u64, true) + .as_basic_value_enum(), + ir::ConstValue::U32(x) => ty + .into_int_type() + .const_int((*x) as u64, true) + .as_basic_value_enum(), + ir::ConstValue::U64(x) => ty + .into_int_type() + .const_int((*x) as u64, true) + .as_basic_value_enum(), + ir::ConstValue::U128(x) => ty + .into_int_type() + .const_int((*x) as u64, true) + .as_basic_value_enum(), + ir::ConstValue::F32(x) => ty + .into_float_type() + .const_float((*x) as f64) + .as_basic_value_enum(), + ir::ConstValue::F64(x) => ty.into_float_type().const_float(*x).as_basic_value_enum(), }, - Expression::FnCall(info) => { - compile_fn_call(session, context, scope_ctx, helper, block, info)? + ValueTree::Branch(_) => todo!(), + } +} + +fn compile_type<'a>( + ctx: &'a ModuleCompileCtx, + ty: &ir::TypeInfo, +) -> inkwell::types::AnyTypeEnum<'a> { + // ctx.di_builder.create_basic_type(name, size_in_bits, encoding, flags) + let context = ctx.module.get_context(); + match &ty.kind { + ir::TypeKind::Unit => context.void_type().as_any_type_enum(), + ir::TypeKind::FnDef(def_id, _generic_args) => { + let (args, ret_type) = { + let fn_body = ctx + .ctx + .modules + .get(&def_id.get_module_defid()) + .unwrap() + .functions + .get(def_id) + .unwrap(); + (fn_body.get_args(), fn_body.ret_type.clone().unwrap()) + }; + + let args: Vec = args + .iter() + .map(|x| compile_basic_type(ctx, &x.ty).into()) + .collect(); + let ret_type = compile_basic_type(ctx, &ret_type); + + ret_type.fn_type(&args, false).as_any_type_enum() } - Expression::Unary(_, _) => todo!(), - Expression::Binary(lhs, op, rhs) => { - let lhs = - compile_expression(session, context, scope_ctx, helper, block, lhs, type_hint)?; - let rhs = - compile_expression(session, context, scope_ctx, helper, block, rhs, type_hint)?; + _ => compile_basic_type(ctx, ty).as_any_type_enum(), + } +} - match op { - BinaryOp::Arith(arith_op, span) => { - let location = get_location(context, session, span.lo); - let ast_type_hint = type_hint.expect("type info missing"); - - block.append_operation(if scope_ctx.is_float(ast_type_hint) { - match arith_op { - ArithOp::Add => arith::addf(lhs, rhs, location), - ArithOp::Sub => arith::subf(lhs, rhs, location), - ArithOp::Mul => arith::mulf(lhs, rhs, location), - ArithOp::Div => arith::divf(lhs, rhs, location), - ArithOp::Mod => arith::remf(lhs, rhs, location), - } - } else { - match arith_op { - ArithOp::Add => arith::addi(lhs, rhs, location), - ArithOp::Sub => arith::subi(lhs, rhs, location), - ArithOp::Mul => arith::muli(lhs, rhs, location), - ArithOp::Div => { - if scope_ctx.is_type_signed(ast_type_hint) { - arith::divsi(lhs, rhs, location) - } else { - arith::divui(lhs, rhs, location) - } - } - ArithOp::Mod => { - if scope_ctx.is_type_signed(ast_type_hint) { - arith::remsi(lhs, rhs, location) - } else { - arith::remui(lhs, rhs, location) - } - } - } - }) - } - BinaryOp::Logic(logic_op, span) => { - let location = get_location(context, session, span.lo); - - block.append_operation(match logic_op { - LogicOp::And => { - dbg!(lhs.r#type()); - dbg!(rhs.r#type()); - let const_true = block - .append_operation(arith::constant( - context, - IntegerAttribute::new(1, IntegerType::new(context, 1).into()) - .into(), - location, - )) - .result(0)? - .into(); - let lhs_bool = block - .append_operation(arith::cmpi( - context, - CmpiPredicate::Eq, - lhs, - const_true, - location, - )) - .result(0)? - .into(); - let rhs_bool = block - .append_operation(arith::cmpi( - context, - CmpiPredicate::Eq, - rhs, - const_true, - location, - )) - .result(0)? - .into(); - arith::andi(lhs_bool, rhs_bool, location) - } - LogicOp::Or => { - let const_true = block - .append_operation(arith::constant( - context, - IntegerAttribute::new(1, IntegerType::new(context, 1).into()) - .into(), - location, - )) - .result(0)? - .into(); - let lhs_bool = block - .append_operation(arith::cmpi( - context, - CmpiPredicate::Eq, - lhs, - const_true, - location, - )) - .result(0)? - .into(); - let rhs_bool = block - .append_operation(arith::cmpi( - context, - CmpiPredicate::Eq, - rhs, - const_true, - location, - )) - .result(0)? - .into(); - arith::ori(lhs_bool, rhs_bool, location) - } - }) - } - BinaryOp::Compare(cmp_op, span) => { - let location = get_location(context, session, span.lo); - block.append_operation(match cmp_op { - CmpOp::Eq => arith::cmpi(context, CmpiPredicate::Eq, lhs, rhs, location), - CmpOp::NotEq => arith::cmpi(context, CmpiPredicate::Ne, lhs, rhs, location), - CmpOp::Lt => arith::cmpi(context, CmpiPredicate::Slt, lhs, rhs, location), - CmpOp::LtEq => arith::cmpi(context, CmpiPredicate::Sle, lhs, rhs, location), - CmpOp::Gt => arith::cmpi(context, CmpiPredicate::Sgt, lhs, rhs, location), - CmpOp::GtEq => arith::cmpi(context, CmpiPredicate::Sge, lhs, rhs, location), - }) - } - BinaryOp::Bitwise(_, _) => todo!(), - } - .result(0)? - .into() +fn compile_basic_type<'ctx>( + ctx: &ModuleCompileCtx<'ctx, '_>, + ty: &ir::TypeInfo, +) -> inkwell::types::BasicTypeEnum<'ctx> { + // ctx.di_builder.create_basic_type(name, size_in_bits, encoding, flags) + match &ty.kind { + ir::TypeKind::Unit => panic!(), + ir::TypeKind::Bool => ctx.ctx.context.bool_type().as_basic_type_enum(), + ir::TypeKind::Char => ctx.ctx.context.i32_type().as_basic_type_enum(), + ir::TypeKind::Int(ty) => match ty { + ir::IntTy::I128 => ctx.ctx.context.i128_type().as_basic_type_enum(), + ir::IntTy::I64 => ctx.ctx.context.i64_type().as_basic_type_enum(), + ir::IntTy::I32 => ctx.ctx.context.i32_type().as_basic_type_enum(), + ir::IntTy::I16 => ctx.ctx.context.i16_type().as_basic_type_enum(), + ir::IntTy::I8 => ctx.ctx.context.i8_type().as_basic_type_enum(), + ir::IntTy::Isize => ctx + .ctx + .context + .ptr_sized_int_type(&ctx.target_data, None) + .as_basic_type_enum(), + }, + ir::TypeKind::Uint(ty) => match ty { + ir::UintTy::U128 => ctx.ctx.context.i128_type().as_basic_type_enum(), + ir::UintTy::U64 => ctx.ctx.context.i64_type().as_basic_type_enum(), + ir::UintTy::U32 => ctx.ctx.context.i32_type().as_basic_type_enum(), + ir::UintTy::U16 => ctx.ctx.context.i16_type().as_basic_type_enum(), + ir::UintTy::U8 => ctx.ctx.context.i8_type().as_basic_type_enum(), + ir::UintTy::Usize => ctx + .ctx + .context + .ptr_sized_int_type(&ctx.target_data, None) + .as_basic_type_enum(), + }, + ir::TypeKind::Float(ty) => match ty { + ir::FloatTy::F32 => ctx.ctx.context.f32_type().as_basic_type_enum(), + ir::FloatTy::F64 => ctx.ctx.context.f64_type().as_basic_type_enum(), + }, + ir::TypeKind::FnDef(_def_id, _generic_args) => { + panic!() } - }) -} - -fn compile_fn_call<'ctx, 'parent: 'ctx>( - session: &Session, - context: &'ctx MeliorContext, - scope_ctx: &ScopeContext<'ctx, 'parent>, - _helper: &BlockHelper<'ctx, 'parent>, - block: &'parent BlockRef<'ctx, 'parent>, - info: &FnCallExpr, -) -> Result, Box> { - let mut args = Vec::with_capacity(info.params.len()); - let location = get_location(context, session, info.name.span.lo); - /* - let location_callee = Location::name(context, &info.name.name, location); - let location_caller = Location::name( - context, - &info.name.name, - get_location(context, session, scope_ctx.function.unwrap().span.lo), - ); - */ - let location = Location::call_site( - location, - get_location(context, session, scope_ctx.function.unwrap().span.lo), - ); - - let target_fn = scope_ctx - .functions - .get(&info.name.name) - .expect("function not found"); - - assert_eq!( - info.params.len(), - target_fn.params.len(), - "parameter length doesnt match" - ); - - for (arg, arg_info) in info.params.iter().zip(&target_fn.params) { - let value = compile_expression( - session, - context, - scope_ctx, - _helper, - block, - arg, - Some(&arg_info.arg_type), - )?; - args.push(value); - } - - let return_type = if let Some(ret_type) = &target_fn.return_type { - vec![scope_ctx.resolve_type(context, ret_type)?] - } else { - vec![] - }; - - Ok(block - .append_operation(func::call( - context, - FlatSymbolRefAttribute::new(context, &info.name.name), - &args, - &return_type, - location, - )) - .result(0)? - .into()) -} - -fn compile_if_stmt<'c, 'this: 'c>( - session: &Session, - context: &'c MeliorContext, - scope_ctx: &mut ScopeContext<'c, 'this>, - helper: &BlockHelper<'c, 'this>, - block: &'this BlockRef<'c, 'this>, - info: &'this IfStmt, -) -> Result<&'this BlockRef<'c, 'this>, Box> { - let condition = compile_expression( - session, - context, - scope_ctx, - helper, - block, - &info.condition, - None, - )?; - - let then_successor = helper.append_block(Block::new(&[])); - let else_successor = helper.append_block(Block::new(&[])); - - let location = get_location(context, session, info.span.lo); - - block.append_operation(cf::cond_br( - context, - condition, - then_successor, - else_successor, - &[], - &[], - location, - )); - - let mut then_successor = then_successor; - let mut else_successor = else_successor; - - { - let mut then_scope_ctx = scope_ctx.clone(); - then_successor = compile_block( - session, - context, - &mut then_scope_ctx, - helper, - then_successor, - &info.then_block, - )?; - } - - if let Some(else_block) = info.else_block.as_ref() { - let mut else_scope_ctx = scope_ctx.clone(); - else_successor = compile_block( - session, - context, - &mut else_scope_ctx, - helper, - else_successor, - else_block, - )?; - } - - // both return - if then_successor.terminator().is_some() && else_successor.terminator().is_some() { - return Ok(then_successor); - } - - let final_block = helper.append_block(Block::new(&[])); - - if then_successor.terminator().is_none() { - then_successor.append_operation(cf::br( - final_block, - &[], - get_location(context, session, info.span.hi), - )); - } - - if else_successor.terminator().is_none() { - else_successor.append_operation(cf::br( - final_block, - &[], - get_location(context, session, info.span.hi), - )); - } - - Ok(final_block) + } } diff --git a/lib/edlang_codegen_mlir/src/context.rs b/lib/edlang_codegen_mlir/src/context.rs deleted file mode 100644 index e8c89e3fc..000000000 --- a/lib/edlang_codegen_mlir/src/context.rs +++ /dev/null @@ -1,91 +0,0 @@ -use std::error::Error; - -use edlang_ast::Module; -use edlang_session::Session; -use melior::{ - dialect::DialectRegistry, - ir::{operation::OperationPrintingFlags, Location, Module as MeliorModule}, - pass::{self, PassManager}, - utility::{register_all_dialects, register_all_llvm_translations, register_all_passes}, - Context as MeliorContext, -}; - -#[derive(Debug, Eq, PartialEq)] -pub struct Context { - melior_context: MeliorContext, -} - -impl Default for Context { - fn default() -> Self { - Self::new() - } -} - -impl Context { - pub fn new() -> Self { - let melior_context = initialize_mlir(); - Self { melior_context } - } - - pub fn compile( - &self, - session: &Session, - module: &Module, - ) -> Result> { - let file_path = session.file_path.display().to_string(); - let location = Location::new(&self.melior_context, &file_path, 0, 0); - - let mut melior_module = MeliorModule::new(location); - - super::codegen::compile_module(session, &self.melior_context, &melior_module, module)?; - - assert!(melior_module.as_operation().verify()); - - tracing::debug!( - "MLIR Code before passes:\n{}", - melior_module.as_operation().to_string_with_flags( - OperationPrintingFlags::new().enable_debug_info(true, true) - )? - ); - - // TODO: Add proper error handling. - self.run_pass_manager(&mut melior_module)?; - - tracing::debug!( - "MLIR Code after passes:\n{}", - melior_module.as_operation().to_string_with_flags( - OperationPrintingFlags::new().enable_debug_info(true, true) - )? - ); - - Ok(melior_module) - } - - fn run_pass_manager(&self, module: &mut MeliorModule) -> Result<(), melior::Error> { - let pass_manager = PassManager::new(&self.melior_context); - pass_manager.enable_verifier(true); - pass_manager.add_pass(pass::transform::create_canonicalizer()); - pass_manager.add_pass(pass::conversion::create_scf_to_control_flow()); - pass_manager.add_pass(pass::conversion::create_arith_to_llvm()); - pass_manager.add_pass(pass::conversion::create_control_flow_to_llvm()); - pass_manager.add_pass(pass::conversion::create_func_to_llvm()); - pass_manager.add_pass(pass::conversion::create_index_to_llvm()); - pass_manager.add_pass(pass::conversion::create_finalize_mem_ref_to_llvm()); - pass_manager.add_pass(pass::conversion::create_reconcile_unrealized_casts()); - pass_manager.run(module) - } -} - -/// Initialize an MLIR context. -pub fn initialize_mlir() -> MeliorContext { - let context = MeliorContext::new(); - context.append_dialect_registry(&{ - let registry = DialectRegistry::new(); - register_all_dialects(®istry); - registry - }); - context.load_all_available_dialects(); - register_all_passes(); - register_all_llvm_translations(&context); - context -} diff --git a/lib/edlang_codegen_mlir/src/ffi.rs b/lib/edlang_codegen_mlir/src/ffi.rs deleted file mode 100644 index 8f5117613..000000000 --- a/lib/edlang_codegen_mlir/src/ffi.rs +++ /dev/null @@ -1,10 +0,0 @@ -use llvm_sys::prelude::{LLVMContextRef, LLVMModuleRef}; - -extern "C" { - /// Translate operation that satisfies LLVM dialect module requirements into an LLVM IR module living in the given context. - /// This translates operations from any dilalect that has a registered implementation of LLVMTranslationDialectInterface. - pub fn mlirTranslateModuleToLLVMIR( - module_operation_ptr: mlir_sys::MlirOperation, - llvm_context: LLVMContextRef, - ) -> LLVMModuleRef; -} diff --git a/lib/edlang_codegen_mlir/src/lib.rs b/lib/edlang_codegen_mlir/src/lib.rs index 8e8a42a14..244fba0ee 100644 --- a/lib/edlang_codegen_mlir/src/lib.rs +++ b/lib/edlang_codegen_mlir/src/lib.rs @@ -1,6 +1,8 @@ #![allow(clippy::too_many_arguments)] +use edlang_ir as ir; use std::{ + collections::HashMap, ffi::{CStr, CString}, mem::MaybeUninit, path::PathBuf, @@ -8,9 +10,10 @@ use std::{ sync::OnceLock, }; -use context::Context; -use edlang_ast::Module; use edlang_session::{OptLevel, Session}; +use inkwell::context::Context; +use ir::DefId; +/* use llvm_sys::{ core::{LLVMContextCreate, LLVMContextDispose, LLVMDisposeMessage, LLVMDisposeModule}, target::{ @@ -24,41 +27,26 @@ use llvm_sys::{ LLVMTargetRef, }, }; -use melior::ir::{operation::OperationPrintingFlags, Module as MeliorModule}; - -use crate::ffi::mlirTranslateModuleToLLVMIR; +*/ pub mod codegen; -mod context; -mod ffi; pub mod linker; -pub fn compile_mlir( +pub fn compile( session: &Session, - program: &Module, -) -> Result> { - let context = Context::new(); - let mlir_module = context.compile(session, program)?; - - Ok(mlir_module - .as_operation() - .to_string_with_flags(OperationPrintingFlags::new().enable_debug_info(true, false))?) + modules: &HashMap, + symbols: HashMap, +) -> Result> { + codegen::compile(session, modules, &symbols) } -pub fn compile(session: &Session, program: &Module) -> Result> { - let context = Context::new(); - let mlir_module = context.compile(session, program)?; +// Converts a module to an object. +// The object will be written to the specified target path. +// TODO: error handling +// +// Returns the path to the object.รง - let object_path = compile_to_object(session, &mlir_module)?; - - Ok(object_path) -} - -/// Converts a module to an object. -/// The object will be written to the specified target path. -/// TODO: error handling -/// -/// Returns the path to the object. +/* pub fn compile_to_object( session: &Session, module: &MeliorModule, @@ -175,3 +163,4 @@ pub fn compile_to_object( Ok(target_path) } } +*/ diff --git a/lib/edlang_driver/src/lib.rs b/lib/edlang_driver/src/lib.rs index 8356726c7..ea5c425ab 100644 --- a/lib/edlang_driver/src/lib.rs +++ b/lib/edlang_driver/src/lib.rs @@ -85,19 +85,14 @@ pub fn main() -> Result<(), Box> { return Ok(()); } - let (_symbols, module_irs) = lower_modules(&[module.clone()]); + let (symbols, module_irs) = lower_modules(&[module.clone()]); if args.ir { println!("{:#?}", module_irs); return Ok(()); } - if args.mlir { - println!("{}", edlang_codegen_mlir::compile_mlir(&session, &module)?); - return Ok(()); - } - - let object_path = edlang_codegen_mlir::compile(&session, &module)?; + let object_path = edlang_codegen_mlir::compile(&session, &module_irs, symbols)?; if session.library { link_shared_lib(&object_path, &session.output_file.with_extension("so"))?; diff --git a/lib/edlang_ir/src/lib.rs b/lib/edlang_ir/src/lib.rs index 15e8ddbed..f99ca173c 100644 --- a/lib/edlang_ir/src/lib.rs +++ b/lib/edlang_ir/src/lib.rs @@ -22,6 +22,15 @@ pub struct DefId { pub id: usize, } +impl DefId { + pub fn get_module_defid(&self) -> Self { + Self { + module_id: self.module_id, + id: 0, + } + } +} + #[derive(Debug, Clone)] pub struct Body { pub def_id: DefId, @@ -33,6 +42,24 @@ pub struct Body { pub fn_span: Span, } +impl Body { + pub fn get_args(&self) -> SmallVec<[Local; 4]> { + let mut args = SmallVec::default(); + + for x in &self.locals { + if let LocalKind::Arg = x.kind { + args.push(x.clone()); + } + } + + args + } + + pub fn get_return_local(&self) -> Local { + self.locals[0].clone() + } +} + #[derive(Debug, Clone)] pub struct DebugInfo { pub id: usize, diff --git a/lib/edlang_lowering/src/common.rs b/lib/edlang_lowering/src/common.rs index d92ae30da..4b70caf83 100644 --- a/lib/edlang_lowering/src/common.rs +++ b/lib/edlang_lowering/src/common.rs @@ -12,7 +12,7 @@ impl IdGenerator { pub const fn new(module_id: usize) -> Self { Self { current_id: 0, - module_id: 0, + module_id, } } diff --git a/lib/edlang_lowering/src/lib.rs b/lib/edlang_lowering/src/lib.rs index 985b228c2..196a38b73 100644 --- a/lib/edlang_lowering/src/lib.rs +++ b/lib/edlang_lowering/src/lib.rs @@ -7,7 +7,9 @@ use ir::{ConstData, ConstKind, DefId, Local, Operand, Place, Statement, Terminat mod common; -pub fn lower_modules(modules: &[ast::Module]) -> (HashMap, Vec) { +pub fn lower_modules( + modules: &[ast::Module], +) -> (HashMap, HashMap) { let mut ctx = BuildCtx::default(); for m in modules { @@ -28,14 +30,14 @@ pub fn lower_modules(modules: &[ast::Module]) -> (HashMap, Vec i32 { + pub fn main(argc: i32) -> i32 { let mut x: i32 = 2; x = 4; - let y: i32 = other(2); return x; } - - fn other(a: i32) -> i32 { - return a; - } }