Compare commits
8 Commits
c0a2bf2d0c
...
51c4811e7f
Author | SHA1 | Date |
---|---|---|
David Mak | 51c4811e7f | |
Sebastien Bourdeauducq | 2cee760404 | |
Sebastien Bourdeauducq | 230982dc84 | |
occheung | 2bd3f63991 | |
occheung | b53266e9e6 | |
occheung | 86eb22bbf3 | |
occheung | beaa38047d | |
occheung | 705dc4ff1c |
|
@ -26,9 +26,9 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "anstream"
|
||||
version = "0.6.17"
|
||||
version = "0.6.18"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "23a1e53f0f5d86382dafe1cf314783b2044280f406e7e1506368220ad11b1338"
|
||||
checksum = "8acc5369981196006228e28809f761875c0327210a891e941f4c683b3a99529b"
|
||||
dependencies = [
|
||||
"anstyle",
|
||||
"anstyle-parse",
|
||||
|
@ -41,9 +41,9 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "anstyle"
|
||||
version = "1.0.9"
|
||||
version = "1.0.10"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "8365de52b16c035ff4fcafe0092ba9390540e3e352870ac09933bebcaa2c8c56"
|
||||
checksum = "55cc3b69f167a1ef2e161439aa98aed94e6028e5f9a59be9a6ffb47aef1651f9"
|
||||
|
||||
[[package]]
|
||||
name = "anstyle-parse"
|
||||
|
@ -126,9 +126,9 @@ checksum = "1fd0f2584146f6f2ef48085050886acf353beff7305ebd1ae69500e27c67f64b"
|
|||
|
||||
[[package]]
|
||||
name = "cc"
|
||||
version = "1.1.31"
|
||||
version = "1.2.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "c2e7962b54006dcfcc61cb72735f4d89bb97061dd6a7ed882ec6b8ee53714c6f"
|
||||
checksum = "fd9de9f2205d5ef3fd67e685b0df337994ddd4495e2a28d185500d0e1edfea47"
|
||||
dependencies = [
|
||||
"shlex",
|
||||
]
|
||||
|
@ -141,9 +141,9 @@ checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd"
|
|||
|
||||
[[package]]
|
||||
name = "clap"
|
||||
version = "4.5.20"
|
||||
version = "4.5.21"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b97f376d85a664d5837dbae44bf546e6477a679ff6610010f17276f686d867e8"
|
||||
checksum = "fb3b4b9e5a7c7514dfa52869339ee98b3156b0bfb4e8a77c4ff4babb64b1604f"
|
||||
dependencies = [
|
||||
"clap_builder",
|
||||
"clap_derive",
|
||||
|
@ -151,9 +151,9 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "clap_builder"
|
||||
version = "4.5.20"
|
||||
version = "4.5.21"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "19bc80abd44e4bed93ca373a0704ccbd1b710dc5749406201bb018272808dc54"
|
||||
checksum = "b17a95aa67cc7b5ebd32aa5370189aa0d79069ef1c64ce893bd30fb24bff20ec"
|
||||
dependencies = [
|
||||
"anstream",
|
||||
"anstyle",
|
||||
|
@ -170,14 +170,14 @@ dependencies = [
|
|||
"heck 0.5.0",
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.85",
|
||||
"syn 2.0.87",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "clap_lex"
|
||||
version = "0.7.2"
|
||||
version = "0.7.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "1462739cb27611015575c0c11df5df7601141071f07518d56fcc1be504cbec97"
|
||||
checksum = "afb84c814227b90d6895e01398aee0d8033c00e7466aca416fb6a8e0eb19d8a7"
|
||||
|
||||
[[package]]
|
||||
name = "colorchoice"
|
||||
|
@ -199,9 +199,9 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "cpufeatures"
|
||||
version = "0.2.14"
|
||||
version = "0.2.15"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "608697df725056feaccfa42cffdaeeec3fccc4ffc38358ecd19b243e716a78e0"
|
||||
checksum = "0ca741a962e1b0bff6d724a1a0958b686406e853bb14061f218562e1896f95e6"
|
||||
dependencies = [
|
||||
"libc",
|
||||
]
|
||||
|
@ -321,9 +321,9 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "fastrand"
|
||||
version = "2.1.1"
|
||||
version = "2.2.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e8c02a5121d4ea3eb16a80748c74f5549a5665e4c21333c6098f283870fbdea6"
|
||||
checksum = "486f806e73c5707928240ddc295403b1b93c96a02038563881c4a2fd84b81ac4"
|
||||
|
||||
[[package]]
|
||||
name = "fixedbitset"
|
||||
|
@ -387,9 +387,9 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "hashbrown"
|
||||
version = "0.15.0"
|
||||
version = "0.15.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "1e087f84d4f86bf4b218b927129862374b72199ae7d8657835f1e89000eea4fb"
|
||||
checksum = "3a9bfc1af68b1726ea47d3d5109de126281def866b33970e10fbab11b5dafab3"
|
||||
|
||||
[[package]]
|
||||
name = "heck"
|
||||
|
@ -429,7 +429,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
|||
checksum = "707907fe3c25f5424cce2cb7e1cbcafee6bdbe735ca90ef77c29e84591e5b9da"
|
||||
dependencies = [
|
||||
"equivalent",
|
||||
"hashbrown 0.15.0",
|
||||
"hashbrown 0.15.1",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
@ -460,7 +460,7 @@ checksum = "9dd28cfd4cfba665d47d31c08a6ba637eed16770abca2eccbbc3ca831fef1e44"
|
|||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.85",
|
||||
"syn 2.0.87",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
@ -547,9 +547,9 @@ checksum = "bbd2bcb4c963f2ddae06a2efc7e9f3591312473c50c6685e1f298068316e66fe"
|
|||
|
||||
[[package]]
|
||||
name = "libc"
|
||||
version = "0.2.161"
|
||||
version = "0.2.162"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "8e9489c2807c139ffd9c1794f4af0ebe86a828db53ecdc7fea2111d0fed085d1"
|
||||
checksum = "18d287de67fe55fd7e1581fe933d965a5a9477b38e949cfa9f8574ef01506398"
|
||||
|
||||
[[package]]
|
||||
name = "libloading"
|
||||
|
@ -774,7 +774,7 @@ dependencies = [
|
|||
"phf_shared 0.11.2",
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.85",
|
||||
"syn 2.0.87",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
@ -878,7 +878,7 @@ dependencies = [
|
|||
"proc-macro2",
|
||||
"pyo3-macros-backend",
|
||||
"quote",
|
||||
"syn 2.0.85",
|
||||
"syn 2.0.87",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
@ -891,7 +891,7 @@ dependencies = [
|
|||
"proc-macro2",
|
||||
"pyo3-build-config",
|
||||
"quote",
|
||||
"syn 2.0.85",
|
||||
"syn 2.0.87",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
@ -976,9 +976,9 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "regex-automata"
|
||||
version = "0.4.8"
|
||||
version = "0.4.9"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "368758f23274712b504848e9d5a6f010445cc8b87a7cdb4d7cbee666c1288da3"
|
||||
checksum = "809e8dc61f6de73b46c85f4c96486310fe304c434cfa43669d7b40f711150908"
|
||||
dependencies = [
|
||||
"aho-corasick",
|
||||
"memchr",
|
||||
|
@ -1000,9 +1000,9 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "rustix"
|
||||
version = "0.38.38"
|
||||
version = "0.38.40"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "aa260229e6538e52293eeb577aabd09945a09d6d9cc0fc550ed7529056c2e32a"
|
||||
checksum = "99e4ea3e1cdc4b559b8e5650f9c8e5998e3e5c1343b4eaf034565f32318d63c0"
|
||||
dependencies = [
|
||||
"bitflags",
|
||||
"errno",
|
||||
|
@ -1046,22 +1046,22 @@ checksum = "61697e0a1c7e512e84a621326239844a24d8207b4669b41bc18b32ea5cbf988b"
|
|||
|
||||
[[package]]
|
||||
name = "serde"
|
||||
version = "1.0.214"
|
||||
version = "1.0.215"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f55c3193aca71c12ad7890f1785d2b73e1b9f63a0bbc353c08ef26fe03fc56b5"
|
||||
checksum = "6513c1ad0b11a9376da888e3e0baa0077f1aed55c17f50e7b2397136129fb88f"
|
||||
dependencies = [
|
||||
"serde_derive",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "serde_derive"
|
||||
version = "1.0.214"
|
||||
version = "1.0.215"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "de523f781f095e28fa605cdce0f8307e451cc0fd14e2eb4cd2e98a355b147766"
|
||||
checksum = "ad1e866f866923f252f05c889987993144fb74e722403468a4ebd70c3cd756c0"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.85",
|
||||
"syn 2.0.87",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
@ -1168,7 +1168,7 @@ dependencies = [
|
|||
"proc-macro2",
|
||||
"quote",
|
||||
"rustversion",
|
||||
"syn 2.0.85",
|
||||
"syn 2.0.87",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
@ -1184,9 +1184,9 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "syn"
|
||||
version = "2.0.85"
|
||||
version = "2.0.87"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "5023162dfcd14ef8f32034d8bcd4cc5ddc61ef7a247c024a33e24e1f24d21b56"
|
||||
checksum = "25aa4ce346d03a6dcd68dd8b4010bcb74e54e62c90c573f394c46eae99aba32d"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
|
@ -1201,9 +1201,9 @@ checksum = "61c41af27dd6d1e27b1b16b489db798443478cef1f06a660c96db617ba5de3b1"
|
|||
|
||||
[[package]]
|
||||
name = "tempfile"
|
||||
version = "3.13.0"
|
||||
version = "3.14.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f0f2c9fc62d0beef6951ccffd757e241266a2c833136efbe35af6cd2567dca5b"
|
||||
checksum = "28cce251fcbc87fac86a866eeb0d6c2d536fc16d06f184bb61aeae11aa4cee0c"
|
||||
dependencies = [
|
||||
"cfg-if",
|
||||
"fastrand",
|
||||
|
@ -1237,22 +1237,22 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "thiserror"
|
||||
version = "1.0.65"
|
||||
version = "1.0.69"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "5d11abd9594d9b38965ef50805c5e469ca9cc6f197f883f717e0269a3057b3d5"
|
||||
checksum = "b6aaf5339b578ea85b50e080feb250a3e8ae8cfcdff9a461c9ec2904bc923f52"
|
||||
dependencies = [
|
||||
"thiserror-impl",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "thiserror-impl"
|
||||
version = "1.0.65"
|
||||
version = "1.0.69"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ae71770322cbd277e69d762a16c444af02aa0575ac0d174f0b9562d3b37f8602"
|
||||
checksum = "4fee6c4efc90059e10f81e6d42c60a18f76588c3d74cb83a0b242a2b6c7504c1"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.85",
|
||||
"syn 2.0.87",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
@ -1505,5 +1505,5 @@ checksum = "fa4f8080344d4671fb4e831a13ad1e68092748387dfc4f55e356242fae12ce3e"
|
|||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.85",
|
||||
"syn 2.0.87",
|
||||
]
|
||||
|
|
|
@ -2,11 +2,11 @@
|
|||
"nodes": {
|
||||
"nixpkgs": {
|
||||
"locked": {
|
||||
"lastModified": 1727348695,
|
||||
"narHash": "sha256-J+PeFKSDV+pHL7ukkfpVzCOO7mBSrrpJ3svwBFABbhI=",
|
||||
"lastModified": 1731319897,
|
||||
"narHash": "sha256-PbABj4tnbWFMfBp6OcUK5iGy1QY+/Z96ZcLpooIbuEI=",
|
||||
"owner": "NixOS",
|
||||
"repo": "nixpkgs",
|
||||
"rev": "1925c603f17fc89f4c8f6bf6f631a802ad85d784",
|
||||
"rev": "dc460ec76cbff0e66e269457d7b728432263166c",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
|
|
|
@ -990,11 +990,12 @@ fn rpc_codegen_callback_fn<'ctx>(
|
|||
}
|
||||
}
|
||||
|
||||
pub fn attributes_writeback(
|
||||
ctx: &mut CodeGenContext<'_, '_>,
|
||||
pub fn attributes_writeback<'ctx>(
|
||||
ctx: &mut CodeGenContext<'ctx, '_>,
|
||||
generator: &mut dyn CodeGenerator,
|
||||
inner_resolver: &InnerResolver,
|
||||
host_attributes: &PyObject,
|
||||
return_obj: Option<(Type, ValueEnum<'ctx>)>,
|
||||
) -> Result<(), String> {
|
||||
Python::with_gil(|py| -> PyResult<Result<(), String>> {
|
||||
let host_attributes: &PyList = host_attributes.downcast(py)?;
|
||||
|
@ -1004,6 +1005,11 @@ pub fn attributes_writeback(
|
|||
let zero = int32.const_zero();
|
||||
let mut values = Vec::new();
|
||||
let mut scratch_buffer = Vec::new();
|
||||
|
||||
if let Some((ty, obj)) = return_obj {
|
||||
values.push((ty, obj.to_basic_value_enum(ctx, generator, ty).unwrap()));
|
||||
}
|
||||
|
||||
for val in (*globals).values() {
|
||||
let val = val.as_ref(py);
|
||||
let ty = inner_resolver.get_obj_type(
|
||||
|
@ -1082,7 +1088,7 @@ pub fn attributes_writeback(
|
|||
let args: Vec<_> =
|
||||
values.into_iter().map(|(_, val)| (None, ValueEnum::Dynamic(val))).collect();
|
||||
if let Err(e) =
|
||||
rpc_codegen_callback_fn(ctx, None, (&fun, PrimDef::Int32.id()), args, generator, false)
|
||||
rpc_codegen_callback_fn(ctx, None, (&fun, PrimDef::Int32.id()), args, generator, true)
|
||||
{
|
||||
return Ok(Err(e));
|
||||
}
|
||||
|
|
|
@ -2,9 +2,9 @@
|
|||
future_incompatible,
|
||||
let_underscore,
|
||||
nonstandard_style,
|
||||
rust_2024_compatibility,
|
||||
clippy::all
|
||||
)]
|
||||
#![warn(rust_2024_compatibility)]
|
||||
#![warn(clippy::pedantic)]
|
||||
#![allow(
|
||||
unsafe_op_in_unsafe_fn,
|
||||
|
@ -36,13 +36,15 @@ use tempfile::{self, TempDir};
|
|||
|
||||
use nac3core::{
|
||||
codegen::{
|
||||
concrete_type::ConcreteTypeStore, gen_func_impl, irrt::load_irrt, CodeGenLLVMOptions,
|
||||
CodeGenTargetMachineOptions, CodeGenTask, WithCall, WorkerRegistry,
|
||||
concrete_type::ConcreteTypeStore, gen_func_impl, irrt::load_irrt,
|
||||
tracert::TraceRuntimeConfig, CodeGenLLVMOptions,
|
||||
CodeGenTargetMachineOptions, CodeGenTask, CodeGenerator, WithCall,
|
||||
WorkerRegistry,
|
||||
},
|
||||
inkwell::{
|
||||
context::Context,
|
||||
memory_buffer::MemoryBuffer,
|
||||
module::{Linkage, Module},
|
||||
module::{FlagBehavior, Linkage, Module},
|
||||
passes::PassBuilderOptions,
|
||||
support::is_multithreaded,
|
||||
targets::*,
|
||||
|
@ -673,33 +675,12 @@ impl Nac3 {
|
|||
let task = CodeGenTask {
|
||||
subst: Vec::default(),
|
||||
symbol_name: "__modinit__".to_string(),
|
||||
body: instance.body,
|
||||
signature,
|
||||
resolver: resolver.clone(),
|
||||
store,
|
||||
unifier_index: instance.unifier_id,
|
||||
calls: instance.calls,
|
||||
id: 0,
|
||||
};
|
||||
|
||||
let mut store = ConcreteTypeStore::new();
|
||||
let mut cache = HashMap::new();
|
||||
let signature = store.from_signature(
|
||||
&mut composer.unifier,
|
||||
&self.primitive,
|
||||
&fun_signature,
|
||||
&mut cache,
|
||||
);
|
||||
let signature = store.add_cty(signature);
|
||||
let attributes_writeback_task = CodeGenTask {
|
||||
subst: Vec::default(),
|
||||
symbol_name: "attributes_writeback".to_string(),
|
||||
body: Arc::new(Vec::default()),
|
||||
signature,
|
||||
resolver,
|
||||
store,
|
||||
unifier_index: instance.unifier_id,
|
||||
calls: Arc::new(HashMap::default()),
|
||||
calls: instance.calls,
|
||||
id: 0,
|
||||
};
|
||||
|
||||
|
@ -723,19 +704,32 @@ impl Nac3 {
|
|||
.collect();
|
||||
|
||||
let membuffer = membuffers.clone();
|
||||
let mut has_return = false;
|
||||
py.allow_threads(|| {
|
||||
let (registry, handles) =
|
||||
WorkerRegistry::create_workers(threads, top_level.clone(), &self.llvm_options, &f);
|
||||
registry.add_task(task);
|
||||
registry.wait_tasks_complete(handles);
|
||||
let (registry, handles) = WorkerRegistry::create_workers(
|
||||
threads,
|
||||
top_level.clone(),
|
||||
&self.llvm_options,
|
||||
&TraceRuntimeConfig::default(),
|
||||
&f,
|
||||
);
|
||||
|
||||
let mut generator =
|
||||
ArtiqCodeGenerator::new("attributes_writeback".to_string(), size_t, self.time_fns);
|
||||
let mut generator = ArtiqCodeGenerator::new("main".to_string(), size_t, self.time_fns);
|
||||
let context = Context::create();
|
||||
let module = context.create_module("attributes_writeback");
|
||||
let module = context.create_module("main");
|
||||
let target_machine = self.llvm_options.create_target_machine().unwrap();
|
||||
module.set_data_layout(&target_machine.get_target_data().get_data_layout());
|
||||
module.set_triple(&target_machine.get_triple());
|
||||
module.add_basic_value_flag(
|
||||
"Debug Info Version",
|
||||
FlagBehavior::Warning,
|
||||
context.i32_type().const_int(3, false),
|
||||
);
|
||||
module.add_basic_value_flag(
|
||||
"Dwarf Version",
|
||||
FlagBehavior::Warning,
|
||||
context.i32_type().const_int(4, false),
|
||||
);
|
||||
let builder = context.create_builder();
|
||||
let (_, module, _) = gen_func_impl(
|
||||
&context,
|
||||
|
@ -743,9 +737,27 @@ impl Nac3 {
|
|||
®istry,
|
||||
builder,
|
||||
module,
|
||||
attributes_writeback_task,
|
||||
task,
|
||||
|generator, ctx| {
|
||||
attributes_writeback(ctx, generator, inner_resolver.as_ref(), &host_attributes)
|
||||
assert_eq!(instance.body.len(), 1, "toplevel module should have 1 statement");
|
||||
let StmtKind::Expr { value: ref expr, .. } = instance.body[0].node else {
|
||||
unreachable!("toplevel statement must be an expression")
|
||||
};
|
||||
let ExprKind::Call { .. } = expr.node else {
|
||||
unreachable!("toplevel expression must be a function call")
|
||||
};
|
||||
|
||||
let return_obj =
|
||||
generator.gen_expr(ctx, &expr)?.map(|value| (expr.custom.unwrap(), value));
|
||||
has_return = return_obj.is_some();
|
||||
registry.wait_tasks_complete(handles);
|
||||
attributes_writeback(
|
||||
ctx,
|
||||
generator,
|
||||
inner_resolver.as_ref(),
|
||||
&host_attributes,
|
||||
return_obj,
|
||||
)
|
||||
},
|
||||
)
|
||||
.unwrap();
|
||||
|
@ -754,35 +766,23 @@ impl Nac3 {
|
|||
membuffer.lock().push(buffer);
|
||||
});
|
||||
|
||||
embedding_map.setattr("expects_return", has_return).unwrap();
|
||||
|
||||
// Link all modules into `main`.
|
||||
let buffers = membuffers.lock();
|
||||
let main = context
|
||||
.create_module_from_ir(MemoryBuffer::create_from_memory_range(&buffers[0], "main"))
|
||||
.create_module_from_ir(MemoryBuffer::create_from_memory_range(
|
||||
&buffers.last().unwrap(),
|
||||
"main",
|
||||
))
|
||||
.unwrap();
|
||||
for buffer in buffers.iter().skip(1) {
|
||||
for buffer in buffers.iter().rev().skip(1) {
|
||||
let other = context
|
||||
.create_module_from_ir(MemoryBuffer::create_from_memory_range(buffer, "main"))
|
||||
.unwrap();
|
||||
|
||||
main.link_in_module(other).map_err(|err| CompileError::new_err(err.to_string()))?;
|
||||
}
|
||||
let builder = context.create_builder();
|
||||
let modinit_return = main
|
||||
.get_function("__modinit__")
|
||||
.unwrap()
|
||||
.get_last_basic_block()
|
||||
.unwrap()
|
||||
.get_terminator()
|
||||
.unwrap();
|
||||
builder.position_before(&modinit_return);
|
||||
builder
|
||||
.build_call(
|
||||
main.get_function("attributes_writeback").unwrap(),
|
||||
&[],
|
||||
"attributes_writeback",
|
||||
)
|
||||
.unwrap();
|
||||
|
||||
main.link_in_module(irrt).map_err(|err| CompileError::new_err(err.to_string()))?;
|
||||
|
||||
let mut function_iter = main.get_first_function();
|
||||
|
|
|
@ -2,9 +2,9 @@
|
|||
future_incompatible,
|
||||
let_underscore,
|
||||
nonstandard_style,
|
||||
rust_2024_compatibility,
|
||||
clippy::all
|
||||
)]
|
||||
#![warn(rust_2024_compatibility)]
|
||||
#![warn(clippy::pedantic)]
|
||||
#![allow(
|
||||
clippy::missing_errors_doc,
|
||||
|
|
|
@ -6,6 +6,7 @@ edition = "2021"
|
|||
|
||||
[features]
|
||||
no-escape-analysis = []
|
||||
tracing = []
|
||||
|
||||
[dependencies]
|
||||
itertools = "0.13"
|
||||
|
@ -28,4 +29,5 @@ indoc = "2.0"
|
|||
insta = "=1.11.0"
|
||||
|
||||
[build-dependencies]
|
||||
itertools = "0.13"
|
||||
regex = "1.10"
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
use std::ffi::OsStr;
|
||||
use std::{
|
||||
env,
|
||||
fs::File,
|
||||
|
@ -6,14 +7,28 @@ use std::{
|
|||
process::{Command, Stdio},
|
||||
};
|
||||
|
||||
use itertools::Itertools;
|
||||
use regex::Regex;
|
||||
|
||||
fn main() {
|
||||
struct IRRTCompilation<'a> {
|
||||
pub file: &'a str,
|
||||
pub gcc_options: Vec<&'a str>,
|
||||
pub cargo_instructions: Vec<&'a str>,
|
||||
}
|
||||
|
||||
/// Extracts the extension-less filename from a [`Path`].
|
||||
fn path_to_extless_filename(path: &Path) -> &str {
|
||||
path.file_name().map(Path::new).and_then(Path::file_stem).and_then(OsStr::to_str).unwrap()
|
||||
}
|
||||
|
||||
/// Compiles a source C file into LLVM bitcode.
|
||||
fn compile_file_to_ir(compile_opts: &IRRTCompilation) {
|
||||
let out_dir = env::var("OUT_DIR").unwrap();
|
||||
let out_dir = Path::new(&out_dir);
|
||||
let out_path = Path::new(&out_dir);
|
||||
let irrt_dir = Path::new("irrt");
|
||||
|
||||
let irrt_cpp_path = irrt_dir.join("irrt.cpp");
|
||||
let path = Path::new(compile_opts.file);
|
||||
let filename_without_ext = path_to_extless_filename(path);
|
||||
|
||||
/*
|
||||
* HACK: Sadly, clang doesn't let us emit generic LLVM bitcode.
|
||||
|
@ -35,22 +50,22 @@ fn main() {
|
|||
"-",
|
||||
"-I",
|
||||
irrt_dir.to_str().unwrap(),
|
||||
irrt_cpp_path.to_str().unwrap(),
|
||||
];
|
||||
|
||||
// Apply custom flags from IRRTCompilation
|
||||
flags.extend_from_slice(&compile_opts.gcc_options);
|
||||
|
||||
match env::var("PROFILE").as_deref() {
|
||||
Ok("debug") => {
|
||||
flags.push("-O0");
|
||||
flags.push("-DIRRT_DEBUG_ASSERT");
|
||||
}
|
||||
Ok("release") => {
|
||||
flags.push("-O3");
|
||||
}
|
||||
Ok("debug") => flags.extend_from_slice(&["-O0", "-DIRRT_DEBUG_ASSERT"]),
|
||||
Ok("release") => flags.push("-O3"),
|
||||
flavor => panic!("Unknown or missing build flavor {flavor:?}"),
|
||||
}
|
||||
|
||||
// Tell Cargo to rerun if any file under `irrt_dir` (recursive) changes
|
||||
println!("cargo:rerun-if-changed={}", irrt_dir.to_str().unwrap());
|
||||
flags.push(path.to_str().unwrap());
|
||||
|
||||
// Tell Cargo to rerun if the main IRRT source is changed
|
||||
println!("cargo:rerun-if-changed={}", path.to_str().unwrap());
|
||||
compile_opts.cargo_instructions.iter().for_each(|inst| println!("cargo::{inst}"));
|
||||
|
||||
// Compile IRRT and capture the LLVM IR output
|
||||
let output = Command::new("clang-irrt")
|
||||
|
@ -62,8 +77,7 @@ fn main() {
|
|||
})
|
||||
.unwrap();
|
||||
|
||||
// https://github.com/rust-lang/regex/issues/244
|
||||
let output = std::str::from_utf8(&output.stdout).unwrap().replace("\r\n", "\n");
|
||||
let output = std::str::from_utf8(&output.stdout).unwrap();
|
||||
let mut filtered_output = String::with_capacity(output.len());
|
||||
|
||||
// Filter out irrelevant IR
|
||||
|
@ -77,7 +91,7 @@ fn main() {
|
|||
r"(?ms:^define.*?\}$)|(?m:^declare.*?$)|(?m:^%.+?=\s*type\s*\{.+?\}$)|(?m:^@.+?=.+$)",
|
||||
)
|
||||
.unwrap();
|
||||
for f in regex_filter.captures_iter(&output) {
|
||||
for f in regex_filter.captures_iter(output) {
|
||||
assert_eq!(f.len(), 1);
|
||||
filtered_output.push_str(&f[0]);
|
||||
filtered_output.push('\n');
|
||||
|
@ -91,20 +105,47 @@ fn main() {
|
|||
// Doing `DEBUG_DUMP_IRRT=1 cargo build -p nac3core` dumps the LLVM IR generated
|
||||
const DEBUG_DUMP_IRRT: &str = "DEBUG_DUMP_IRRT";
|
||||
println!("cargo:rerun-if-env-changed={DEBUG_DUMP_IRRT}");
|
||||
if env::var(DEBUG_DUMP_IRRT).is_ok() {
|
||||
let mut file = File::create(out_dir.join("irrt.ll")).unwrap();
|
||||
if env::var("DEBUG_DUMP_IRRT").is_ok() {
|
||||
let mut file = File::create(out_path.join(format!("{filename_without_ext}.ll"))).unwrap();
|
||||
file.write_all(output.as_bytes()).unwrap();
|
||||
|
||||
let mut file = File::create(out_dir.join("irrt-filtered.ll")).unwrap();
|
||||
let mut file =
|
||||
File::create(out_path.join(format!("{filename_without_ext}-filtered.ll"))).unwrap();
|
||||
file.write_all(filtered_output.as_bytes()).unwrap();
|
||||
}
|
||||
|
||||
let mut llvm_as = Command::new("llvm-as-irrt")
|
||||
.stdin(Stdio::piped())
|
||||
.arg("-o")
|
||||
.arg(out_dir.join("irrt.bc"))
|
||||
.arg(out_path.join(format!("{filename_without_ext}.bc")))
|
||||
.spawn()
|
||||
.unwrap();
|
||||
llvm_as.stdin.as_mut().unwrap().write_all(filtered_output.as_bytes()).unwrap();
|
||||
assert!(llvm_as.wait().unwrap().success());
|
||||
}
|
||||
|
||||
fn main() {
|
||||
let irrt_compilations: &[IRRTCompilation] = &[
|
||||
IRRTCompilation {
|
||||
file: "irrt/irrt.cpp",
|
||||
gcc_options: Vec::default(),
|
||||
cargo_instructions: vec!["rerun-if-changed=irrt/irrt"],
|
||||
},
|
||||
IRRTCompilation {
|
||||
file: "irrt/tracert.cpp",
|
||||
gcc_options: Vec::default(),
|
||||
cargo_instructions: Vec::default(),
|
||||
},
|
||||
];
|
||||
|
||||
assert!(irrt_compilations
|
||||
.iter()
|
||||
.map(|comp| comp.file)
|
||||
.map(Path::new)
|
||||
.map(path_to_extless_filename)
|
||||
.all_unique());
|
||||
|
||||
for path in irrt_compilations {
|
||||
compile_file_to_ir(path)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,4 @@
|
|||
extern "C" {
|
||||
// stdio.h
|
||||
int printf(const char *format, ...);
|
||||
} // extern "C"
|
|
@ -3108,48 +3108,53 @@ pub fn gen_expr<'ctx, G: CodeGenerator>(
|
|||
};
|
||||
let left = generator.bool_to_i1(ctx, left);
|
||||
let current = ctx.builder.get_insert_block().unwrap().get_parent().unwrap();
|
||||
let a_bb = ctx.ctx.append_basic_block(current, "a");
|
||||
let b_bb = ctx.ctx.append_basic_block(current, "b");
|
||||
let a_begin_bb = ctx.ctx.append_basic_block(current, "a_begin");
|
||||
let a_end_bb = ctx.ctx.append_basic_block(current, "a_end");
|
||||
let b_begin_bb = ctx.ctx.append_basic_block(current, "b_begin");
|
||||
let b_end_bb = ctx.ctx.append_basic_block(current, "b_end");
|
||||
let cont_bb = ctx.ctx.append_basic_block(current, "cont");
|
||||
ctx.builder.build_conditional_branch(left, a_bb, b_bb).unwrap();
|
||||
ctx.builder.build_conditional_branch(left, a_begin_bb, b_begin_bb).unwrap();
|
||||
|
||||
ctx.builder.position_at_end(a_end_bb);
|
||||
ctx.builder.build_unconditional_branch(cont_bb).unwrap();
|
||||
ctx.builder.position_at_end(b_end_bb);
|
||||
ctx.builder.build_unconditional_branch(cont_bb).unwrap();
|
||||
let (a, b) = match op {
|
||||
Boolop::Or => {
|
||||
ctx.builder.position_at_end(a_bb);
|
||||
ctx.builder.position_at_end(a_begin_bb);
|
||||
let a = ctx.ctx.i8_type().const_int(1, false);
|
||||
ctx.builder.build_unconditional_branch(cont_bb).unwrap();
|
||||
ctx.builder.build_unconditional_branch(a_end_bb).unwrap();
|
||||
|
||||
ctx.builder.position_at_end(b_bb);
|
||||
ctx.builder.position_at_end(b_begin_bb);
|
||||
let b = if let Some(v) = generator.gen_expr(ctx, &values[1])? {
|
||||
let b = v
|
||||
.to_basic_value_enum(ctx, generator, values[1].custom.unwrap())?
|
||||
.into_int_value();
|
||||
let b = generator.bool_to_i8(ctx, b);
|
||||
ctx.builder.build_unconditional_branch(cont_bb).unwrap();
|
||||
|
||||
Some(b)
|
||||
} else {
|
||||
None
|
||||
};
|
||||
ctx.builder.build_unconditional_branch(b_end_bb).unwrap();
|
||||
|
||||
(Some(a), b)
|
||||
}
|
||||
Boolop::And => {
|
||||
ctx.builder.position_at_end(a_bb);
|
||||
ctx.builder.position_at_end(a_begin_bb);
|
||||
let a = if let Some(v) = generator.gen_expr(ctx, &values[1])? {
|
||||
let a = v
|
||||
.to_basic_value_enum(ctx, generator, values[1].custom.unwrap())?
|
||||
.into_int_value();
|
||||
let a = generator.bool_to_i8(ctx, a);
|
||||
ctx.builder.build_unconditional_branch(cont_bb).unwrap();
|
||||
|
||||
Some(a)
|
||||
} else {
|
||||
None
|
||||
};
|
||||
ctx.builder.build_unconditional_branch(a_end_bb).unwrap();
|
||||
|
||||
ctx.builder.position_at_end(b_bb);
|
||||
ctx.builder.position_at_end(b_begin_bb);
|
||||
let b = ctx.ctx.i8_type().const_zero();
|
||||
ctx.builder.build_unconditional_branch(cont_bb).unwrap();
|
||||
ctx.builder.build_unconditional_branch(b_end_bb).unwrap();
|
||||
|
||||
(a, Some(b))
|
||||
}
|
||||
|
@ -3159,7 +3164,7 @@ pub fn gen_expr<'ctx, G: CodeGenerator>(
|
|||
match (a, b) {
|
||||
(Some(a), Some(b)) => {
|
||||
let phi = ctx.builder.build_phi(ctx.ctx.i8_type(), "").unwrap();
|
||||
phi.add_incoming(&[(&a, a_bb), (&b, b_bb)]);
|
||||
phi.add_incoming(&[(&a, a_end_bb), (&b, b_end_bb)]);
|
||||
phi.as_basic_value().into()
|
||||
}
|
||||
(Some(a), None) => a.into(),
|
||||
|
|
|
@ -1,8 +1,11 @@
|
|||
use std::iter::once;
|
||||
|
||||
use inkwell::{
|
||||
attributes::{Attribute, AttributeLoc},
|
||||
values::{BasicValueEnum, CallSiteValue, FloatValue, IntValue},
|
||||
values::{BasicValue, BasicValueEnum, CallSiteValue, FloatValue, IntValue},
|
||||
AddressSpace,
|
||||
};
|
||||
use itertools::Either;
|
||||
use itertools::{Either, Itertools};
|
||||
|
||||
use super::CodeGenContext;
|
||||
|
||||
|
@ -20,7 +23,7 @@ use super::CodeGenContext;
|
|||
/// These will be used unless other attributes are specified
|
||||
/// * `$(,$args:ident)*`: Operands of the extern function
|
||||
/// The data type of these operands will be set to `FloatValue`
|
||||
///
|
||||
///
|
||||
macro_rules! generate_extern_fn {
|
||||
("unary", $fn_name:ident, $extern_fn:literal) => {
|
||||
generate_extern_fn!($fn_name, $extern_fn, arg, "mustprogress", "nofree", "nounwind", "willreturn", "writeonly");
|
||||
|
@ -191,3 +194,49 @@ generate_linalg_extern_fn!(call_np_linalg_det, "np_linalg_det", 2);
|
|||
generate_linalg_extern_fn!(call_sp_linalg_lu, "sp_linalg_lu", 3);
|
||||
generate_linalg_extern_fn!(call_sp_linalg_schur, "sp_linalg_schur", 3);
|
||||
generate_linalg_extern_fn!(call_sp_linalg_hessenberg, "sp_linalg_hessenberg", 3);
|
||||
|
||||
/// Invokes the `printf` function.
|
||||
pub fn call_printf<'ctx>(
|
||||
ctx: &CodeGenContext<'ctx, '_>,
|
||||
format: &str,
|
||||
args: &[BasicValueEnum<'ctx>],
|
||||
) -> IntValue<'ctx> {
|
||||
const FN_NAME: &str = "printf";
|
||||
|
||||
let llvm_i8 = ctx.ctx.i8_type();
|
||||
let llvm_i32 = ctx.ctx.i32_type();
|
||||
let llvm_pi8 = llvm_i8.ptr_type(AddressSpace::default());
|
||||
|
||||
let extern_fn = ctx.module.get_function(FN_NAME).unwrap_or_else(|| {
|
||||
let fn_type = llvm_i32.fn_type(&[llvm_pi8.into()], true);
|
||||
let func = ctx.module.add_function(FN_NAME, fn_type, None);
|
||||
for attr in ["nofree", "nounwind"] {
|
||||
func.add_attribute(
|
||||
AttributeLoc::Function,
|
||||
ctx.ctx.create_enum_attribute(Attribute::get_named_enum_kind_id(attr), 0),
|
||||
);
|
||||
}
|
||||
|
||||
func
|
||||
});
|
||||
|
||||
let pformat = ctx
|
||||
.builder
|
||||
.build_global_string_ptr(&format!("{format}\0"), "")
|
||||
.map(|v| v.as_basic_value_enum())
|
||||
.map(BasicValueEnum::into_pointer_value)
|
||||
.unwrap();
|
||||
|
||||
let fn_args = once(&pformat.as_basic_value_enum())
|
||||
.chain(args)
|
||||
.copied()
|
||||
.map(BasicValueEnum::into)
|
||||
.collect_vec();
|
||||
|
||||
ctx.builder
|
||||
.build_call(extern_fn, fn_args.as_slice(), "")
|
||||
.map(CallSiteValue::try_as_basic_value)
|
||||
.map(|v| v.map_left(BasicValueEnum::into_int_value))
|
||||
.map(Either::unwrap_left)
|
||||
.unwrap()
|
||||
}
|
||||
|
|
|
@ -39,6 +39,7 @@ use crate::{
|
|||
use classes::{ListType, NDArrayType, ProxyType, RangeType};
|
||||
use concrete_type::{ConcreteType, ConcreteTypeEnum, ConcreteTypeStore};
|
||||
pub use generator::{CodeGenerator, DefaultCodeGenerator};
|
||||
use tracert::{TraceRuntimeConfig, TraceRuntimeState};
|
||||
|
||||
pub mod builtin_fns;
|
||||
pub mod classes;
|
||||
|
@ -50,6 +51,7 @@ pub mod irrt;
|
|||
pub mod llvm_intrinsics;
|
||||
pub mod numpy;
|
||||
pub mod stmt;
|
||||
pub mod tracert;
|
||||
|
||||
#[cfg(test)]
|
||||
mod test;
|
||||
|
@ -219,6 +221,8 @@ pub struct CodeGenContext<'ctx, 'a> {
|
|||
/// See [`need_sret`].
|
||||
pub need_sret: bool,
|
||||
|
||||
pub tracert_state: Option<TraceRuntimeState>,
|
||||
|
||||
/// The current source location.
|
||||
pub current_loc: Location,
|
||||
}
|
||||
|
@ -266,6 +270,8 @@ pub struct WorkerRegistry {
|
|||
|
||||
/// LLVM-related options for code generation.
|
||||
pub llvm_options: CodeGenLLVMOptions,
|
||||
|
||||
tracert_config: TraceRuntimeConfig,
|
||||
}
|
||||
|
||||
impl WorkerRegistry {
|
||||
|
@ -275,6 +281,7 @@ impl WorkerRegistry {
|
|||
generators: Vec<Box<G>>,
|
||||
top_level_ctx: Arc<TopLevelContext>,
|
||||
llvm_options: &CodeGenLLVMOptions,
|
||||
tracert_config: &TraceRuntimeConfig,
|
||||
f: &Arc<WithCall>,
|
||||
) -> (Arc<WorkerRegistry>, Vec<thread::JoinHandle<()>>) {
|
||||
let (sender, receiver) = unbounded();
|
||||
|
@ -296,6 +303,7 @@ impl WorkerRegistry {
|
|||
wait_condvar,
|
||||
top_level_ctx,
|
||||
llvm_options: llvm_options.clone(),
|
||||
tracert_config: tracert_config.clone(),
|
||||
});
|
||||
|
||||
let mut handles = Vec::new();
|
||||
|
@ -979,6 +987,13 @@ pub fn gen_func_impl<
|
|||
unifier,
|
||||
static_value_store,
|
||||
need_sret: has_sret,
|
||||
tracert_state: if cfg!(feature = "tracing")
|
||||
|| registry.tracert_config.enabled_tags.is_empty()
|
||||
{
|
||||
None
|
||||
} else {
|
||||
Some(TraceRuntimeState::create(registry.tracert_config.clone()))
|
||||
},
|
||||
current_loc: Location::default(),
|
||||
debug_info: (dibuilder, compile_unit, func_scope.as_debug_info_scope()),
|
||||
};
|
||||
|
|
|
@ -18,6 +18,7 @@ use parking_lot::RwLock;
|
|||
use super::{
|
||||
classes::{ListType, NDArrayType, ProxyType, RangeType},
|
||||
concrete_type::ConcreteTypeStore,
|
||||
tracert::TraceRuntimeConfig,
|
||||
CodeGenContext, CodeGenLLVMOptions, CodeGenTargetMachineOptions, CodeGenTask, CodeGenerator,
|
||||
DefaultCodeGenerator, WithCall, WorkerRegistry,
|
||||
};
|
||||
|
@ -245,7 +246,13 @@ fn test_primitives() {
|
|||
opt_level: OptimizationLevel::Default,
|
||||
target: CodeGenTargetMachineOptions::from_host_triple(),
|
||||
};
|
||||
let (registry, handles) = WorkerRegistry::create_workers(threads, top_level, &llvm_options, &f);
|
||||
let (registry, handles) = WorkerRegistry::create_workers(
|
||||
threads,
|
||||
top_level,
|
||||
&llvm_options,
|
||||
&TraceRuntimeConfig::default(),
|
||||
&f,
|
||||
);
|
||||
registry.add_task(task);
|
||||
registry.wait_tasks_complete(handles);
|
||||
}
|
||||
|
@ -438,7 +445,13 @@ fn test_simple_call() {
|
|||
opt_level: OptimizationLevel::Default,
|
||||
target: CodeGenTargetMachineOptions::from_host_triple(),
|
||||
};
|
||||
let (registry, handles) = WorkerRegistry::create_workers(threads, top_level, &llvm_options, &f);
|
||||
let (registry, handles) = WorkerRegistry::create_workers(
|
||||
threads,
|
||||
top_level,
|
||||
&llvm_options,
|
||||
&TraceRuntimeConfig::default(),
|
||||
&f,
|
||||
);
|
||||
registry.add_task(task);
|
||||
registry.wait_tasks_complete(handles);
|
||||
}
|
||||
|
|
|
@ -0,0 +1,110 @@
|
|||
use std::panic::Location;
|
||||
|
||||
use inkwell::context::Context;
|
||||
use inkwell::memory_buffer::MemoryBuffer;
|
||||
use inkwell::module::Module;
|
||||
use inkwell::values::BasicValueEnum;
|
||||
use inkwell::AtomicOrdering;
|
||||
|
||||
use crate::codegen::{extern_fns, CodeGenContext};
|
||||
|
||||
#[derive(Clone, Default, Eq, PartialEq)]
|
||||
pub struct TraceRuntimeConfig {
|
||||
pub enabled_tags: Vec<String>,
|
||||
}
|
||||
|
||||
#[derive(Eq, Clone, PartialEq)]
|
||||
pub struct TraceRuntimeState {
|
||||
config: TraceRuntimeConfig,
|
||||
indent: usize,
|
||||
}
|
||||
|
||||
impl TraceRuntimeState {
|
||||
#[must_use]
|
||||
pub fn create(config: TraceRuntimeConfig) -> TraceRuntimeState {
|
||||
TraceRuntimeState { config, indent: 0 }
|
||||
}
|
||||
}
|
||||
|
||||
#[must_use]
|
||||
pub fn load_tracert<'ctx>(ctx: &'ctx Context, config: &TraceRuntimeConfig) -> Option<Module<'ctx>> {
|
||||
if cfg!(feature = "tracing") && !config.enabled_tags.is_empty() {
|
||||
let bitcode_buf = MemoryBuffer::create_from_memory_range(
|
||||
include_bytes!(concat!(env!("OUT_DIR"), "/tracert.bc")),
|
||||
"tracert_bitcode_buffer",
|
||||
);
|
||||
let module = Module::parse_bitcode_from_buffer(&bitcode_buf, ctx).unwrap();
|
||||
|
||||
return Some(module);
|
||||
}
|
||||
|
||||
None
|
||||
}
|
||||
|
||||
// TODO: Might need to redesign how trace logging should be done
|
||||
|
||||
pub fn trace_log<'ctx>(
|
||||
ctx: &mut CodeGenContext<'ctx, '_>,
|
||||
tag: &'static str,
|
||||
format: &'static str,
|
||||
args: &[BasicValueEnum<'ctx>],
|
||||
) {
|
||||
if ctx.tracert_state.is_none() {
|
||||
return;
|
||||
}
|
||||
|
||||
// TODO: Add indentation
|
||||
let str = format!("[TRACING] {tag} - {format}\n\0");
|
||||
extern_fns::call_printf(ctx, &str, args);
|
||||
}
|
||||
|
||||
#[track_caller]
|
||||
pub fn trace_log_with_location<'ctx>(
|
||||
ctx: &CodeGenContext<'ctx, '_>,
|
||||
tag: &'static str,
|
||||
format: &str,
|
||||
args: &[BasicValueEnum<'ctx>],
|
||||
) {
|
||||
if ctx.tracert_state.is_none() {
|
||||
return;
|
||||
}
|
||||
|
||||
// TODO: Add indentation
|
||||
let caller_loc = Location::caller();
|
||||
let str = format!(
|
||||
"[TRACING] {}:{}:{}: {tag} - {format}\n\0",
|
||||
caller_loc.file(),
|
||||
caller_loc.line(),
|
||||
caller_loc.column()
|
||||
);
|
||||
extern_fns::call_printf(ctx, &str, args);
|
||||
}
|
||||
|
||||
pub fn trace_push_level(ctx: &mut CodeGenContext<'_, '_>) {
|
||||
let Some(tracert_state) = &mut ctx.tracert_state else {
|
||||
return;
|
||||
};
|
||||
|
||||
debug_assert!(tracert_state.indent < usize::MAX);
|
||||
if tracert_state.indent < usize::MAX {
|
||||
tracert_state.indent = tracert_state.indent.saturating_add(1);
|
||||
}
|
||||
}
|
||||
|
||||
pub fn trace_pop_level(ctx: &mut CodeGenContext<'_, '_>) {
|
||||
let Some(tracert_state) = &mut ctx.tracert_state else {
|
||||
return;
|
||||
};
|
||||
|
||||
debug_assert!(tracert_state.indent > 0);
|
||||
if tracert_state.indent > 0 {
|
||||
tracert_state.indent = tracert_state.indent.saturating_sub(1);
|
||||
}
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn mfence(ctx: &mut CodeGenContext<'_, '_>) {
|
||||
if ctx.tracert_state.is_some() {
|
||||
ctx.builder.build_fence(AtomicOrdering::SequentiallyConsistent, 0, "").unwrap();
|
||||
}
|
||||
}
|
|
@ -2,9 +2,9 @@
|
|||
future_incompatible,
|
||||
let_underscore,
|
||||
nonstandard_style,
|
||||
rust_2024_compatibility,
|
||||
clippy::all
|
||||
)]
|
||||
#![warn(rust_2024_compatibility)]
|
||||
#![warn(clippy::pedantic)]
|
||||
#![allow(
|
||||
dead_code,
|
||||
|
|
|
@ -2,9 +2,9 @@
|
|||
future_incompatible,
|
||||
let_underscore,
|
||||
nonstandard_style,
|
||||
rust_2024_compatibility,
|
||||
clippy::all
|
||||
)]
|
||||
#![warn(rust_2024_compatibility)]
|
||||
#![warn(clippy::pedantic)]
|
||||
#![allow(
|
||||
clippy::cast_possible_truncation,
|
||||
|
|
|
@ -19,9 +19,9 @@
|
|||
future_incompatible,
|
||||
let_underscore,
|
||||
nonstandard_style,
|
||||
rust_2024_compatibility,
|
||||
clippy::all
|
||||
)]
|
||||
#![warn(rust_2024_compatibility)]
|
||||
#![warn(clippy::pedantic)]
|
||||
#![allow(
|
||||
clippy::enum_glob_use,
|
||||
|
@ -49,11 +49,11 @@ lalrpop_mod!(
|
|||
future_incompatible,
|
||||
let_underscore,
|
||||
nonstandard_style,
|
||||
rust_2024_compatibility,
|
||||
unused,
|
||||
clippy::all,
|
||||
clippy::pedantic
|
||||
)]
|
||||
#[warn(rust_2024_compatibility)]
|
||||
python
|
||||
);
|
||||
pub mod config_comment_helper;
|
||||
|
|
|
@ -6,6 +6,7 @@ edition = "2021"
|
|||
|
||||
[features]
|
||||
no-escape-analysis = ["nac3core/no-escape-analysis"]
|
||||
tracing = ["nac3core/tracing"]
|
||||
|
||||
[dependencies]
|
||||
parking_lot = "0.12"
|
||||
|
|
|
@ -65,7 +65,7 @@ struct cslice {
|
|||
size_t len;
|
||||
};
|
||||
|
||||
void output_int32_list(struct cslice* slice) {
|
||||
void output_int32_list(const struct cslice* slice) {
|
||||
const int32_t* data = (int32_t*)slice->data;
|
||||
|
||||
putchar('[');
|
||||
|
@ -80,7 +80,7 @@ void output_int32_list(struct cslice* slice) {
|
|||
putchar('\n');
|
||||
}
|
||||
|
||||
void output_str(struct cslice* slice) {
|
||||
void output_str(const struct cslice* slice) {
|
||||
const char* data = (const char*)slice->data;
|
||||
|
||||
for (size_t i = 0; i < slice->len; ++i) {
|
||||
|
@ -88,12 +88,12 @@ void output_str(struct cslice* slice) {
|
|||
}
|
||||
}
|
||||
|
||||
void output_strln(struct cslice* slice) {
|
||||
void output_strln(const struct cslice* slice) {
|
||||
output_str(slice);
|
||||
putchar('\n');
|
||||
}
|
||||
|
||||
uint64_t dbg_stack_address(__attribute__((unused)) struct cslice* slice) {
|
||||
uint64_t dbg_stack_address(__attribute__((unused)) const struct cslice* slice) {
|
||||
int i;
|
||||
void* ptr = (void*)&i;
|
||||
return (uintptr_t)ptr;
|
||||
|
|
|
@ -2,9 +2,9 @@
|
|||
future_incompatible,
|
||||
let_underscore,
|
||||
nonstandard_style,
|
||||
rust_2024_compatibility,
|
||||
clippy::all
|
||||
)]
|
||||
#![warn(rust_2024_compatibility)]
|
||||
#![warn(clippy::pedantic)]
|
||||
#![allow(clippy::too_many_lines, clippy::wildcard_imports)]
|
||||
|
||||
|
@ -21,8 +21,11 @@ use parking_lot::{Mutex, RwLock};
|
|||
|
||||
use nac3core::{
|
||||
codegen::{
|
||||
concrete_type::ConcreteTypeStore, irrt::load_irrt, CodeGenLLVMOptions,
|
||||
CodeGenTargetMachineOptions, CodeGenTask, DefaultCodeGenerator, WithCall, WorkerRegistry,
|
||||
concrete_type::ConcreteTypeStore,
|
||||
irrt::load_irrt,
|
||||
tracert::{load_tracert, TraceRuntimeConfig},
|
||||
CodeGenLLVMOptions, CodeGenTargetMachineOptions, CodeGenTask, DefaultCodeGenerator,
|
||||
WithCall, WorkerRegistry,
|
||||
},
|
||||
inkwell::{
|
||||
memory_buffer::MemoryBuffer, module::Linkage, passes::PassBuilderOptions,
|
||||
|
@ -82,6 +85,9 @@ struct CommandLineArgs {
|
|||
/// Additional target features to enable/disable, specified using the `+`/`-` prefixes.
|
||||
#[arg(long)]
|
||||
target_features: Option<String>,
|
||||
|
||||
#[arg(long)]
|
||||
trace: Vec<String>,
|
||||
}
|
||||
|
||||
fn handle_typevar_definition(
|
||||
|
@ -282,8 +288,16 @@ fn handle_global_var(
|
|||
|
||||
fn main() {
|
||||
let cli = CommandLineArgs::parse();
|
||||
let CommandLineArgs { file_name, threads, opt_level, emit_llvm, triple, mcpu, target_features } =
|
||||
cli;
|
||||
let CommandLineArgs {
|
||||
file_name,
|
||||
threads,
|
||||
opt_level,
|
||||
emit_llvm,
|
||||
triple,
|
||||
mcpu,
|
||||
target_features,
|
||||
trace,
|
||||
} = cli;
|
||||
|
||||
Target::initialize_all(&InitializationConfig::default());
|
||||
|
||||
|
@ -312,6 +326,7 @@ fn main() {
|
|||
// The default behavior for -O<n> where n>3 defaults to O3 for both Clang and GCC
|
||||
_ => OptimizationLevel::Aggressive,
|
||||
};
|
||||
let tracert_config = TraceRuntimeConfig { enabled_tags: trace };
|
||||
|
||||
let target_machine_options = CodeGenTargetMachineOptions {
|
||||
triple,
|
||||
|
@ -356,6 +371,14 @@ fn main() {
|
|||
irrt.write_bitcode_to_path(Path::new("irrt.bc"));
|
||||
}
|
||||
|
||||
// Process tracert
|
||||
let tracert = load_tracert(&context, &tracert_config);
|
||||
if let Some(tracert) = &tracert {
|
||||
if emit_llvm {
|
||||
tracert.write_bitcode_to_path(Path::new("tracert.bc"));
|
||||
}
|
||||
}
|
||||
|
||||
// Process the Python script
|
||||
let parser_result = parser::parse_program(&program, file_name.into()).unwrap();
|
||||
|
||||
|
@ -464,7 +487,8 @@ fn main() {
|
|||
let threads = (0..threads)
|
||||
.map(|i| Box::new(DefaultCodeGenerator::new(format!("module{i}"), size_t)))
|
||||
.collect();
|
||||
let (registry, handles) = WorkerRegistry::create_workers(threads, top_level, &llvm_options, &f);
|
||||
let (registry, handles) =
|
||||
WorkerRegistry::create_workers(threads, top_level, &llvm_options, &tracert_config, &f);
|
||||
registry.add_task(task);
|
||||
registry.wait_tasks_complete(handles);
|
||||
|
||||
|
@ -490,6 +514,9 @@ fn main() {
|
|||
}
|
||||
|
||||
main.link_in_module(irrt).unwrap();
|
||||
if let Some(tracert) = tracert {
|
||||
main.link_in_module(tracert).unwrap();
|
||||
}
|
||||
|
||||
// Private all functions except "run"
|
||||
let mut function_iter = main.get_first_function();
|
||||
|
|
|
@ -2,9 +2,9 @@
|
|||
future_incompatible,
|
||||
let_underscore,
|
||||
nonstandard_style,
|
||||
rust_2024_compatibility,
|
||||
clippy::all
|
||||
)]
|
||||
#![warn(rust_2024_compatibility)]
|
||||
#![warn(clippy::pedantic)]
|
||||
#![allow(clippy::semicolon_if_nothing_returned, clippy::uninlined_format_args)]
|
||||
|
||||
|
|
Loading…
Reference in New Issue