diff --git a/crates/integration/Cargo.toml b/crates/integration/Cargo.toml index 50d5f55..0b95a1c 100644 --- a/crates/integration/Cargo.toml +++ b/crates/integration/Cargo.toml @@ -18,3 +18,5 @@ era-compiler-llvm-context = { path = "../llvm-context" } [dev-dependencies] sha1 = { workspace = true } +serde = { workspace = true } +serde_json = { workspace = true } diff --git a/crates/integration/codesize.json b/crates/integration/codesize.json new file mode 100644 index 0000000..2c017e8 --- /dev/null +++ b/crates/integration/codesize.json @@ -0,0 +1,5 @@ +{ + "Baseline": 3551, + "Computation": 5912, + "Fibonacci": 4909 +} \ No newline at end of file diff --git a/crates/integration/src/cases.rs b/crates/integration/src/cases.rs index ca95ed7..47ff03b 100644 --- a/crates/integration/src/cases.rs +++ b/crates/integration/src/cases.rs @@ -117,3 +117,52 @@ impl Contract { } } } + +#[cfg(test)] +mod tests { + use serde::{de::Deserialize, Serialize}; + use std::{collections::HashMap, fs::File}; + + use super::Contract; + + #[test] + fn codesize() { + let path = "codesize.json"; + + let existing = File::open(path) + .map(|file| { + HashMap::::deserialize(&mut serde_json::Deserializer::from_reader( + file, + )) + .expect("should be able to deserialze codesize data") + }) + .ok(); + + let sizes = HashMap::from([ + ("Baseline", Contract::baseline().pvm_runtime.len()), + ("Computation", Contract::odd_product(0).pvm_runtime.len()), + ("Fibonacci", Contract::fib_iterative(0).pvm_runtime.len()), + ]); + + for (name, bytes) in sizes.iter() { + let change = existing + .as_ref() + .and_then(|map| map.get(*name)) + .map(|old| { + let new = *bytes as f32; + let old = *old as f32; + let p = (new - old) / new * 100.0; + format!("({p}% change from {old} bytes)") + }) + .unwrap_or_else(String::new); + + println!("{name}: {bytes} bytes {change}"); + } + + sizes + .serialize(&mut serde_json::Serializer::pretty( + File::create(path).unwrap(), + )) + .unwrap_or_else(|err| panic!("can not write codesize data to '{}': {}", path, err)); + } +} diff --git a/crates/llvm-context/Cargo.toml b/crates/llvm-context/Cargo.toml index a740dc2..7abe6b5 100644 --- a/crates/llvm-context/Cargo.toml +++ b/crates/llvm-context/Cargo.toml @@ -12,6 +12,9 @@ description = "Shared front end code of the EraVM compilers" [lib] doctest = false +[features] +riscv-zbb = [] + [dependencies] anyhow = { workspace = true } semver = { workspace = true } diff --git a/crates/llvm-context/src/target_machine/mod.rs b/crates/llvm-context/src/target_machine/mod.rs index 8790a7b..2ed67fb 100644 --- a/crates/llvm-context/src/target_machine/mod.rs +++ b/crates/llvm-context/src/target_machine/mod.rs @@ -29,6 +29,12 @@ impl TargetMachine { /// The LLVM target triple. pub const VM_TARGET_TRIPLE: &'static str = "riscv32-unknown-unknown-elf"; + /// LLVM target features. + #[cfg(feature = "riscv-zbb")] + pub const VM_FEATURES: &'static str = "+zbb,+e,+m"; + #[cfg(not(feature = "riscv-zbb"))] + pub const VM_FEATURES: &'static str = "+e,+m"; + /// /// A shortcut constructor. /// @@ -40,7 +46,7 @@ impl TargetMachine { .create_target_machine( &inkwell::targets::TargetTriple::create(target.triple()), "generic-rv32", - "+e,+m", + Self::VM_FEATURES, optimizer_settings.level_back_end, inkwell::targets::RelocMode::PIC, inkwell::targets::CodeModel::Default,