Compare commits

...

8 Commits

Author SHA1 Message Date
xermicus ea78e03348 experimentally switch to rv64
Signed-off-by: xermicus <cyrill@parity.io>
2024-04-27 12:46:05 +02:00
xermicus 018d9f39fc measure erc20 code size
Signed-off-by: xermicus <cyrill@parity.io>
2024-04-26 15:51:14 +02:00
xermicus 3d44685168 measure flipper code size
Signed-off-by: xermicus <cyrill@parity.io>
2024-04-26 10:51:41 +02:00
xermicus 44ae9e77d5 clippies
Signed-off-by: xermicus <cyrill@parity.io>
2024-04-26 10:39:56 +02:00
xermicus a85d1ef333 prevent confusing AlwaysInline and NoInline on O0
Signed-off-by: xermicus <cyrill@parity.io>
2024-04-26 10:36:28 +02:00
Cyrill Leutwiler 45d53f2ee4 test for codesizes
Signed-off-by: Cyrill Leutwiler <bigcyrill@hotmail.com>
2024-04-25 17:39:49 +02:00
Cyrill Leutwiler 34c233207e add clippy to Makefile
Signed-off-by: Cyrill Leutwiler <bigcyrill@hotmail.com>
2024-04-25 15:10:02 +02:00
Cyrill Leutwiler ec46b211ab extensive benchmark results
Signed-off-by: Cyrill Leutwiler <bigcyrill@hotmail.com>
2024-04-24 23:19:41 +02:00
19 changed files with 311 additions and 41 deletions
Generated
+7 -5
View File
@@ -1349,7 +1349,7 @@ dependencies = [
[[package]] [[package]]
name = "polkavm" name = "polkavm"
version = "0.9.3" version = "0.9.3"
source = "git+https://github.com/koute/polkavm.git#4ca06cc1b7cb435b2b92e81e30c2eb0e988f563e" source = "git+https://github.com/xermicus/polkavm.git?branch=master_byteswap#73ab6d953c13de26ab75ed11707aa6d902ba47ea"
dependencies = [ dependencies = [
"libc", "libc",
"log", "log",
@@ -1361,7 +1361,7 @@ dependencies = [
[[package]] [[package]]
name = "polkavm-assembler" name = "polkavm-assembler"
version = "0.9.0" version = "0.9.0"
source = "git+https://github.com/koute/polkavm.git#4ca06cc1b7cb435b2b92e81e30c2eb0e988f563e" source = "git+https://github.com/xermicus/polkavm.git?branch=master_byteswap#73ab6d953c13de26ab75ed11707aa6d902ba47ea"
dependencies = [ dependencies = [
"log", "log",
] ]
@@ -1369,7 +1369,7 @@ dependencies = [
[[package]] [[package]]
name = "polkavm-common" name = "polkavm-common"
version = "0.9.0" version = "0.9.0"
source = "git+https://github.com/koute/polkavm.git#4ca06cc1b7cb435b2b92e81e30c2eb0e988f563e" source = "git+https://github.com/xermicus/polkavm.git?branch=master_byteswap#73ab6d953c13de26ab75ed11707aa6d902ba47ea"
dependencies = [ dependencies = [
"log", "log",
] ]
@@ -1377,7 +1377,7 @@ dependencies = [
[[package]] [[package]]
name = "polkavm-linker" name = "polkavm-linker"
version = "0.9.2" version = "0.9.2"
source = "git+https://github.com/koute/polkavm.git#4ca06cc1b7cb435b2b92e81e30c2eb0e988f563e" source = "git+https://github.com/xermicus/polkavm.git?branch=master_byteswap#73ab6d953c13de26ab75ed11707aa6d902ba47ea"
dependencies = [ dependencies = [
"gimli", "gimli",
"hashbrown 0.14.3", "hashbrown 0.14.3",
@@ -1391,7 +1391,7 @@ dependencies = [
[[package]] [[package]]
name = "polkavm-linux-raw" name = "polkavm-linux-raw"
version = "0.9.0" version = "0.9.0"
source = "git+https://github.com/koute/polkavm.git#4ca06cc1b7cb435b2b92e81e30c2eb0e988f563e" source = "git+https://github.com/xermicus/polkavm.git?branch=master_byteswap#73ab6d953c13de26ab75ed11707aa6d902ba47ea"
[[package]] [[package]]
name = "ppv-lite86" name = "ppv-lite86"
@@ -1675,6 +1675,8 @@ dependencies = [
"polkavm", "polkavm",
"revive-differential", "revive-differential",
"revive-solidity", "revive-solidity",
"serde",
"serde_json",
"sha1", "sha1",
] ]
+3 -3
View File
@@ -27,9 +27,9 @@ path-slash = "0.2"
rayon = "1.8" rayon = "1.8"
structopt = { version = "0.3", default-features = false } structopt = { version = "0.3", default-features = false }
rand = "0.8" rand = "0.8"
polkavm-common = { git = "https://github.com/koute/polkavm.git" } polkavm-common = { branch = "master_byteswap", git = "https://github.com/xermicus/polkavm.git" }
polkavm-linker = { git = "https://github.com/koute/polkavm.git" } polkavm-linker = { branch = "master_byteswap", git = "https://github.com/xermicus/polkavm.git" }
polkavm = { git = "https://github.com/koute/polkavm.git" } polkavm = { branch = "master_byteswap", git = "https://github.com/xermicus/polkavm.git" }
alloy-primitives = "0.6" alloy-primitives = "0.6"
alloy-sol-types = "0.6" alloy-sol-types = "0.6"
env_logger = { version = "0.10.0", default-features = false } env_logger = { version = "0.10.0", default-features = false }
+2
View File
@@ -38,6 +38,8 @@ bench: install-bin
cargo criterion --all --features bench-evm,bench-pvm --message-format=json \ cargo criterion --all --features bench-evm,bench-pvm --message-format=json \
| criterion-table > crates/benchmarks/BENCHMARKS.md | criterion-table > crates/benchmarks/BENCHMARKS.md
clippy:
cargo clippy --all-features --workspace --tests --benches
clean: clean:
cargo clean ; \ cargo clean ; \
+3 -3
View File
@@ -37,7 +37,7 @@ cd ../compiler-rt
mkdir -p build mkdir -p build
cd build cd build
CFLAGS="--target=riscv32 -march=rv32em -mabi=ilp32e -nostdlib -nodefaultlibs -mcpu=generic-rv32" CFLAGS="--target=riscv64 -march=rv64em -mabi=lp64e -nostdlib -nodefaultlibs -mcpu=generic-rv64"
cmake -G Ninja -DCMAKE_BUILD_TYPE=Release -DCMAKE_INSTALL_PREFIX=$INSTALL_DIR \ cmake -G Ninja -DCMAKE_BUILD_TYPE=Release -DCMAKE_INSTALL_PREFIX=$INSTALL_DIR \
-DCOMPILER_RT_BUILD_BUILTINS=ON \ -DCOMPILER_RT_BUILD_BUILTINS=ON \
-DCOMPILER_RT_BUILD_LIBFUZZER=OFF \ -DCOMPILER_RT_BUILD_LIBFUZZER=OFF \
@@ -46,8 +46,8 @@ cmake -G Ninja -DCMAKE_BUILD_TYPE=Release -DCMAKE_INSTALL_PREFIX=$INSTALL_DIR \
-DCOMPILER_RT_BUILD_SANITIZERS=OFF \ -DCOMPILER_RT_BUILD_SANITIZERS=OFF \
-DCOMPILER_RT_BUILD_XRAY=OFF \ -DCOMPILER_RT_BUILD_XRAY=OFF \
-DCMAKE_C_COMPILER=$INSTALL_DIR/bin/clang \ -DCMAKE_C_COMPILER=$INSTALL_DIR/bin/clang \
-DCMAKE_C_COMPILER_TARGET="riscv32" \ -DCMAKE_C_COMPILER_TARGET="riscv64" \
-DCMAKE_ASM_COMPILER_TARGET="riscv32" \ -DCMAKE_ASM_COMPILER_TARGET="riscv64" \
-DCMAKE_AR=$INSTALL_DIR/bin/llvm-ar \ -DCMAKE_AR=$INSTALL_DIR/bin/llvm-ar \
-DCMAKE_NM=$INSTALL_DIR/bin/llvm-nm \ -DCMAKE_NM=$INSTALL_DIR/bin/llvm-nm \
-DCMAKE_RANLIB=$INSTALL_DIR/bin/llvm-ranlib \ -DCMAKE_RANLIB=$INSTALL_DIR/bin/llvm-ranlib \
+125
View File
@@ -0,0 +1,125 @@
# Benchmarks
## Table of Contents
- [Benchmark Results](#benchmark-results)
- [Baseline](#baseline)
- [OddProduct](#oddproduct)
- [TriangleNumber](#trianglenumber)
- [FibonacciRecursive](#fibonaccirecursive)
- [FibonacciIterative](#fibonacciiterative)
- [FibonacciBinet](#fibonaccibinet)
- [SHA1](#sha1)
- [PrepareBaseline](#preparebaseline)
- [PrepareOddProduct](#prepareoddproduct)
- [PrepareTriangleNumber](#preparetrianglenumber)
- [PrepareFibonacciRecursive](#preparefibonaccirecursive)
- [PrepareFibonacciIterative](#preparefibonacciiterative)
- [PrepareFibonacciBinet](#preparefibonaccibinet)
- [PrepareSHA1](#preparesha1)
## Benchmark Results
### Baseline
| | `EVM` | `PVMInterpreter` | `PVM` |
|:--------|:--------------------------|:---------------------------------|:--------------------------------- |
| **`0`** | `855.27 ns` (✅ **1.00x**) | `729.35 ns` (✅ **1.17x faster**) | `23.19 us` (❌ *27.12x slower*) |
### OddProduct
| | `EVM` | `PVMInterpreter` | `PVM` |
|:----------------|:------------------------|:-------------------------------|:--------------------------------- |
| **`2000000`** | `1.51 s` (✅ **1.00x**) | `1.11 s` (✅ **1.35x faster**) | `16.91 ms` (🚀 **89.26x faster**) |
| **`4000000`** | `3.12 s` (✅ **1.00x**) | `2.09 s` (✅ **1.49x faster**) | `32.48 ms` (🚀 **96.10x faster**) |
| **`8000000`** | `6.22 s` (✅ **1.00x**) | `4.26 s` (✅ **1.46x faster**) | `65.36 ms` (🚀 **95.23x faster**) |
| **`120000000`** | `90.60 s` (✅ **1.00x**) | `59.54 s` (✅ **1.52x faster**) | `1.02 s` (🚀 **89.00x faster**) |
### TriangleNumber
| | `EVM` | `PVMInterpreter` | `PVM` |
|:----------------|:------------------------|:-------------------------------|:--------------------------------- |
| **`3000000`** | `1.45 s` (✅ **1.00x**) | `1.01 s` (✅ **1.43x faster**) | `20.83 ms` (🚀 **69.67x faster**) |
| **`6000000`** | `2.92 s` (✅ **1.00x**) | `2.08 s` (✅ **1.41x faster**) | `41.97 ms` (🚀 **69.61x faster**) |
| **`12000000`** | `5.88 s` (✅ **1.00x**) | `4.05 s` (✅ **1.45x faster**) | `83.03 ms` (🚀 **70.82x faster**) |
| **`180000000`** | `89.53 s` (✅ **1.00x**) | `59.08 s` (✅ **1.52x faster**) | `1.24 s` (🚀 **72.49x faster**) |
### FibonacciRecursive
| | `EVM` | `PVMInterpreter` | `PVM` |
|:---------|:--------------------------|:---------------------------------|:---------------------------------- |
| **`26`** | `200.07 ms` (✅ **1.00x**) | `478.04 ms` (❌ *2.39x slower*) | `6.93 ms` (🚀 **28.88x faster**) |
| **`30`** | `1.37 s` (✅ **1.00x**) | `3.36 s` (❌ *2.45x slower*) | `45.17 ms` (🚀 **30.30x faster**) |
| **`34`** | `9.83 s` (✅ **1.00x**) | `22.55 s` (❌ *2.29x slower*) | `306.43 ms` (🚀 **32.08x faster**) |
| **`38`** | `66.98 s` (✅ **1.00x**) | `150.55 s` (❌ *2.25x slower*) | `2.22 s` (🚀 **30.21x faster**) |
### FibonacciIterative
| | `EVM` | `PVMInterpreter` | `PVM` |
|:----------------|:--------------------------|:---------------------------------|:--------------------------------- |
| **`256`** | `88.32 us` (✅ **1.00x**) | `294.08 us` (❌ *3.33x slower*) | `42.46 us` (🚀 **2.08x faster**) |
| **`100000`** | `32.88 ms` (✅ **1.00x**) | `121.70 ms` (❌ *3.70x slower*) | `1.73 ms` (🚀 **18.97x faster**) |
| **`1000000`** | `320.59 ms` (✅ **1.00x**) | `1.25 s` (❌ *3.89x slower*) | `15.60 ms` (🚀 **20.55x faster**) |
| **`100000000`** | `33.09 s` (✅ **1.00x**) | `125.08 s` (❌ *3.78x slower*) | `1.49 s` (🚀 **22.18x faster**) |
### FibonacciBinet
| | `EVM` | `PVMInterpreter` | `PVM` |
|:----------|:-------------------------|:---------------------------------|:-------------------------------- |
| **`64`** | `20.15 us` (✅ **1.00x**) | `129.45 us` (❌ *6.42x slower*) | `39.56 us` (❌ *1.96x slower*) |
| **`128`** | `22.97 us` (✅ **1.00x**) | `150.62 us` (❌ *6.56x slower*) | `40.13 us` (❌ *1.75x slower*) |
| **`256`** | `26.20 us` (✅ **1.00x**) | `165.38 us` (❌ *6.31x slower*) | `39.70 us` (❌ *1.52x slower*) |
### SHA1
| | `EVM` | `PVMInterpreter` | `PVM` |
|:----------|:--------------------------|:---------------------------------|:--------------------------------- |
| **`1`** | `216.56 us` (✅ **1.00x**) | `328.90 us` (❌ *1.52x slower*) | `43.54 us` (🚀 **4.97x faster**) |
| **`64`** | `442.13 us` (✅ **1.00x**) | `553.22 us` (❌ *1.25x slower*) | `45.73 us` (🚀 **9.67x faster**) |
| **`512`** | `1.90 ms` (✅ **1.00x**) | `2.27 ms` (❌ *1.19x slower*) | `78.40 us` (🚀 **24.21x faster**) |
### PrepareBaseline
| | `Evm` | `PVMInterpreterCompile` | `PVMInterpreterInstantiate` | `PVMCompile` | `PVMInstantiate` |
|:--------|:--------------------------|:---------------------------------|:-------------------------------------|:----------------------------------|:---------------------------------- |
| **`0`** | `177.34 ns` (✅ **1.00x**) | `10.83 us` (❌ *61.07x slower*) | `1.33 us` (❌ *7.49x slower*) | `33.43 us` (❌ *188.48x slower*) | `69.26 us` (❌ *390.56x slower*) |
### PrepareOddProduct
| | `Evm` | `PVMInterpreterCompile` | `PVMInterpreterInstantiate` | `PVMCompile` | `PVMInstantiate` |
|:--------|:--------------------------|:---------------------------------|:-------------------------------------|:---------------------------------|:---------------------------------- |
| **`0`** | `486.78 ns` (✅ **1.00x**) | `11.43 us` (❌ *23.49x slower*) | `1.35 us` (❌ *2.78x slower*) | `33.95 us` (❌ *69.75x slower*) | `68.19 us` (❌ *140.07x slower*) |
### PrepareTriangleNumber
| | `Evm` | `PVMInterpreterCompile` | `PVMInterpreterInstantiate` | `PVMCompile` | `PVMInstantiate` |
|:--------|:--------------------------|:---------------------------------|:-------------------------------------|:----------------------------------|:---------------------------------- |
| **`0`** | `489.04 ns` (✅ **1.00x**) | `23.99 us` (❌ *49.06x slower*) | `1.33 us` (❌ *2.72x slower*) | `61.40 us` (❌ *125.56x slower*) | `73.01 us` (❌ *149.29x slower*) |
### PrepareFibonacciRecursive
| | `Evm` | `PVMInterpreterCompile` | `PVMInterpreterInstantiate` | `PVMCompile` | `PVMInstantiate` |
|:--------|:--------------------------|:---------------------------------|:-------------------------------------|:----------------------------------|:---------------------------------- |
| **`0`** | `411.19 ns` (✅ **1.00x**) | `22.32 us` (❌ *54.27x slower*) | `1.43 us` (❌ *3.49x slower*) | `54.52 us` (❌ *132.59x slower*) | `68.99 us` (❌ *167.77x slower*) |
### PrepareFibonacciIterative
| | `Evm` | `PVMInterpreterCompile` | `PVMInterpreterInstantiate` | `PVMCompile` | `PVMInstantiate` |
|:--------|:--------------------------|:---------------------------------|:-------------------------------------|:----------------------------------|:---------------------------------- |
| **`0`** | `313.74 ns` (✅ **1.00x**) | `19.15 us` (❌ *61.04x slower*) | `1.39 us` (❌ *4.44x slower*) | `48.30 us` (❌ *153.95x slower*) | `69.20 us` (❌ *220.57x slower*) |
### PrepareFibonacciBinet
| | `Evm` | `PVMInterpreterCompile` | `PVMInterpreterInstantiate` | `PVMCompile` | `PVMInstantiate` |
|:--------|:--------------------------|:---------------------------------|:-------------------------------------|:----------------------------------|:--------------------------------- |
| **`0`** | `700.40 ns` (✅ **1.00x**) | `41.78 us` (❌ *59.65x slower*) | `1.40 us` (❌ *2.00x slower*) | `92.23 us` (❌ *131.69x slower*) | `68.52 us` (❌ *97.83x slower*) |
### PrepareSHA1
| | `Evm` | `PVMInterpreterCompile` | `PVMInterpreterInstantiate` | `PVMCompile` | `PVMInstantiate` |
|:--------|:------------------------|:----------------------------------|:-------------------------------------|:-----------------------------------|:--------------------------------- |
| **`0`** | `1.77 us` (✅ **1.00x**) | `124.24 us` (❌ *70.39x slower*) | `1.33 us` (✅ **1.33x faster**) | `242.14 us` (❌ *137.19x slower*) | `69.28 us` (❌ *39.25x slower*) |
---
Made with [criterion-table](https://github.com/nu11ptr/criterion-table)
+2 -2
View File
@@ -1,7 +1,7 @@
use std::{env, fs, io::Read, path::Path, process::Command}; use std::{env, fs, io::Read, path::Path, process::Command};
fn main() { fn main() {
let lib = "libclang_rt.builtins-riscv32.a"; let lib = "libclang_rt.builtins-riscv64.a";
let mut llvm_lib_dir = String::new(); let mut llvm_lib_dir = String::new();
Command::new("llvm-config") Command::new("llvm-config")
@@ -16,7 +16,7 @@ fn main() {
let lib_path = std::path::PathBuf::from(llvm_lib_dir.trim()) let lib_path = std::path::PathBuf::from(llvm_lib_dir.trim())
.join("linux") .join("linux")
.join(lib); .join(lib);
let archive = fs::read(lib_path).expect("clang builtins for riscv32 not found"); let archive = fs::read(lib_path).expect("clang builtins for riscv64 not found");
let out_dir = env::var_os("OUT_DIR").expect("has OUT_DIR"); let out_dir = env::var_os("OUT_DIR").expect("has OUT_DIR");
let archive_path = Path::new(&out_dir).join(lib); let archive_path = Path::new(&out_dir).join(lib);
+1 -1
View File
@@ -9,7 +9,7 @@ pub const BYTE_LENGTH_BYTE: usize = 1;
pub const BYTE_LENGTH_X32: usize = 4; pub const BYTE_LENGTH_X32: usize = 4;
/// Native stack alignment size in bytes /// Native stack alignment size in bytes
pub const BYTE_LENGTH_STACK_ALIGN: usize = 4; pub const BYTE_LENGTH_STACK_ALIGN: usize = BYTE_LENGTH_X64;
/// The x86_64 word byte-length. /// The x86_64 word byte-length.
pub const BYTE_LENGTH_X64: usize = 8; pub const BYTE_LENGTH_X64: usize = 8;
+4 -2
View File
@@ -1,5 +1,7 @@
target datalayout = "e-m:e-p:32:32-i64:64-n32-S128" ; target datalayout = "e-m:e-p:32:32-i64:64-n32-S128"
target triple = "riscv32-unknown-unknown-elf" ; target triple = "riscv32-unknown-unknown-elf"
target datalayout = "e-m:e-p:64:64-i64:64-i128:128-n32:64-S128"
target triple = "riscv64-unknown-unknown-elf"
define dso_local noundef i256 @__bswap(i256 noundef %0) local_unnamed_addr #0 { define dso_local noundef i256 @__bswap(i256 noundef %0) local_unnamed_addr #0 {
%2 = tail call i256 @llvm.bswap.i256(i256 %0) %2 = tail call i256 @llvm.bswap.i256(i256 %0)
+2
View File
@@ -18,3 +18,5 @@ era-compiler-llvm-context = { path = "../llvm-context" }
[dev-dependencies] [dev-dependencies]
sha1 = { workspace = true } sha1 = { workspace = true }
serde = { workspace = true }
serde_json = { workspace = true }
+7
View File
@@ -0,0 +1,7 @@
{
"Flipper": 3958,
"Baseline": 3551,
"Computation": 5912,
"Fibonacci": 4909,
"ERC20": 1966
}
+101
View File
@@ -10,6 +10,8 @@ pub struct Contract {
sol!(contract Baseline { function baseline() public payable; }); sol!(contract Baseline { function baseline() public payable; });
sol!(contract Flipper { function flip() public; });
sol!(contract Computation { sol!(contract Computation {
function odd_product(int32 n) public pure returns (int64); function odd_product(int32 n) public pure returns (int64);
function triangle_number(int64 n) public pure returns (int64 sum); function triangle_number(int64 n) public pure returns (int64 sum);
@@ -39,6 +41,32 @@ sol!(
} }
); );
sol!(
interface IERC20 {
function totalSupply() external view returns (uint);
function balanceOf(address account) external view returns (uint);
function transfer(address recipient, uint amount) external returns (bool);
function allowance(
address owner,
address spender
) external view returns (uint);
function approve(address spender, uint amount) external returns (bool);
function transferFrom(
address sender,
address recipient,
uint amount
) external returns (bool);
event Transfer(address indexed from, address indexed to, uint value);
event Approval(address indexed owner, address indexed spender, uint value);
}
);
impl Contract { impl Contract {
pub fn baseline() -> Self { pub fn baseline() -> Self {
let code = include_str!("../contracts/Baseline.sol"); let code = include_str!("../contracts/Baseline.sol");
@@ -116,4 +144,77 @@ impl Contract {
calldata: SHA1::sha1Call::new((pre,)).abi_encode(), calldata: SHA1::sha1Call::new((pre,)).abi_encode(),
} }
} }
pub fn flipper() -> Self {
let code = include_str!("../contracts/flipper.sol");
let name = "Flipper";
Self {
evm_runtime: crate::compile_evm_bin_runtime(name, code),
pvm_runtime: crate::compile_blob(name, code),
calldata: Flipper::flipCall::new(()).abi_encode(),
}
}
pub fn erc20() -> Self {
let code = include_str!("../contracts/ERC20.sol");
let name = "ERC20";
Self {
evm_runtime: crate::compile_evm_bin_runtime(name, code),
pvm_runtime: crate::compile_blob(name, code),
calldata: IERC20::totalSupplyCall::new(()).abi_encode(),
}
}
}
#[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::<String, usize>::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()),
("Flipper", Contract::flipper().pvm_runtime.len()),
("Computation", Contract::odd_product(0).pvm_runtime.len()),
("Fibonacci", Contract::fib_iterative(0).pvm_runtime.len()),
("ERC20", Contract::erc20().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_default();
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));
}
} }
+3 -4
View File
@@ -26,11 +26,10 @@ fn fibonacci() {
#[test] #[test]
fn flipper() { fn flipper() {
let code = crate::compile_blob("Flipper", include_str!("../contracts/flipper.sol")); let contract = Contract::flipper();
let state = State::new(0xcde4efa9u32.to_be_bytes().to_vec()); let (mut instance, export) = mock_runtime::prepare(&contract.pvm_runtime, None);
let (mut instance, export) = mock_runtime::prepare(&code, None);
let state = crate::mock_runtime::call(state, &mut instance, export); let state = crate::mock_runtime::call(State::new(contract.calldata), &mut instance, export);
assert_eq!(state.output.flags, 0); assert_eq!(state.output.flags, 0);
assert_eq!(state.storage[&U256::ZERO], U256::try_from(1).unwrap()); assert_eq!(state.storage[&U256::ZERO], U256::try_from(1).unwrap());
+2 -2
View File
@@ -33,7 +33,7 @@ pub fn link<T: AsRef<[u8]>>(input: T) -> anyhow::Result<Vec<u8>> {
let output_path = dir.path().join("out.so"); let output_path = dir.path().join("out.so");
let object_path = dir.path().join("out.o"); let object_path = dir.path().join("out.o");
let linker_script_path = dir.path().join("linker.ld"); let linker_script_path = dir.path().join("linker.ld");
let compiler_rt_path = dir.path().join("libclang_rt.builtins-riscv32.a"); let compiler_rt_path = dir.path().join("libclang_rt.builtins-riscv64.a");
fs::write(&object_path, input).map_err(|msg| anyhow::anyhow!("{msg} {object_path:?}"))?; fs::write(&object_path, input).map_err(|msg| anyhow::anyhow!("{msg} {object_path:?}"))?;
@@ -58,7 +58,7 @@ pub fn link<T: AsRef<[u8]>>(input: T) -> anyhow::Result<Vec<u8>> {
"--library-path", "--library-path",
dir.path().to_str().expect("should be utf8"), dir.path().to_str().expect("should be utf8"),
"--library", "--library",
"clang_rt.builtins-riscv32", "clang_rt.builtins-riscv64",
linker_script_path.to_str().expect("should be utf8"), linker_script_path.to_str().expect("should be utf8"),
object_path.to_str().expect("should be utf8"), object_path.to_str().expect("should be utf8"),
"-o", "-o",
+3
View File
@@ -12,6 +12,9 @@ description = "Shared front end code of the EraVM compilers"
[lib] [lib]
doctest = false doctest = false
[features]
riscv-zbb = []
[dependencies] [dependencies]
anyhow = { workspace = true } anyhow = { workspace = true }
semver = { workspace = true } semver = { workspace = true }
@@ -183,6 +183,24 @@ impl<'ctx> Function<'ctx> {
} }
} }
/// Remove specified attributes existing on the given declaration.
pub fn remove_attributes(declaration: Declaration, attributes: &[Attribute]) {
for attribute in attributes.iter().filter(|attribute| {
declaration
.value
.get_enum_attribute(
inkwell::attributes::AttributeLoc::Function,
**attribute as u32,
)
.is_some()
}) {
declaration.value.remove_enum_attribute(
inkwell::attributes::AttributeLoc::Function,
*attribute as u32,
);
}
}
/// ///
/// Sets the default attributes. /// Sets the default attributes.
/// ///
@@ -194,6 +212,10 @@ impl<'ctx> Function<'ctx> {
optimizer: &Optimizer, optimizer: &Optimizer,
) { ) {
if optimizer.settings().level_middle_end == inkwell::OptimizationLevel::None { if optimizer.settings().level_middle_end == inkwell::OptimizationLevel::None {
Self::remove_attributes(
declaration,
&[Attribute::OptimizeForSize, Attribute::AlwaysInline],
);
Self::set_attributes( Self::set_attributes(
llvm, llvm,
declaration, declaration,
+10 -4
View File
@@ -24,10 +24,16 @@ pub struct TargetMachine {
impl TargetMachine { impl TargetMachine {
/// The LLVM target name. /// The LLVM target name.
pub const VM_TARGET_NAME: &'static str = "riscv32"; pub const VM_TARGET_NAME: &'static str = "riscv64";
/// The LLVM target triple. /// The LLVM target triple.
pub const VM_TARGET_TRIPLE: &'static str = "riscv32-unknown-unknown-elf"; pub const VM_TARGET_TRIPLE: &'static str = "riscv64-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. /// A shortcut constructor.
@@ -39,8 +45,8 @@ impl TargetMachine {
.ok_or_else(|| anyhow::anyhow!("LLVM target machine `{}` not found", target.name()))? .ok_or_else(|| anyhow::anyhow!("LLVM target machine `{}` not found", target.name()))?
.create_target_machine( .create_target_machine(
&inkwell::targets::TargetTriple::create(target.triple()), &inkwell::targets::TargetTriple::create(target.triple()),
"generic-rv32", "generic-rv64",
"+e,+m", Self::VM_FEATURES,
optimizer_settings.level_back_end, optimizer_settings.level_back_end,
inkwell::targets::RelocMode::PIC, inkwell::targets::RelocMode::PIC,
inkwell::targets::CodeModel::Default, inkwell::targets::CodeModel::Default,
@@ -19,7 +19,7 @@ impl Target {
/// ///
pub fn name(&self) -> &str { pub fn name(&self) -> &str {
match self { match self {
Self::PVM => "riscv32", Self::PVM => "riscv64",
} }
} }
@@ -28,7 +28,7 @@ impl Target {
/// ///
pub fn triple(&self) -> &str { pub fn triple(&self) -> &str {
match self { match self {
Self::PVM => "riscv32-unknown-unknown-elf", Self::PVM => "riscv64-unknown-unknown-elf",
} }
} }
@@ -47,7 +47,7 @@ impl FromStr for Target {
fn from_str(string: &str) -> Result<Self, Self::Err> { fn from_str(string: &str) -> Result<Self, Self::Err> {
match string { match string {
"riscv32" => Ok(Self::PVM), "riscv64" => Ok(Self::PVM),
_ => Err(anyhow::anyhow!( _ => Err(anyhow::anyhow!(
"Unknown target `{}`. Supported targets: {:?}", "Unknown target `{}`. Supported targets: {:?}",
string, string,
@@ -60,7 +60,7 @@ impl FromStr for Target {
impl std::fmt::Display for Target { impl std::fmt::Display for Target {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
match self { match self {
Target::PVM => write!(f, "riscv32"), Target::PVM => write!(f, "riscv64"),
} }
} }
} }
+4 -4
View File
@@ -3,11 +3,11 @@ use std::{env, fs, path::Path, process::Command};
fn compile(bitcode_path: &str) { fn compile(bitcode_path: &str) {
let output = Command::new("clang") let output = Command::new("clang")
.args([ .args([
"--target=riscv32", "--target=riscv64",
"-Xclang", "-Xclang",
"-triple=riscv32-unknown-unknown-elf", "-triple=riscv64-unknown-unknown-elf",
"-march=rv32em", "-march=rv64em",
"-mabi=ilp32e", "-mabi=lp64e",
"-fno-exceptions", "-fno-exceptions",
"-ffreestanding", "-ffreestanding",
"-Wall", "-Wall",
@@ -28,11 +28,10 @@ where
.original .original
.take() .take()
.ok_or_else(|| anyhow::anyhow!("{} Verbatim literal is missing", call.location))?; .ok_or_else(|| anyhow::anyhow!("{} Verbatim literal is missing", call.location))?;
match identifier.as_str() {
_ => anyhow::bail!( anyhow::bail!(
"{} Found unknown internal function `{}`", "{} Found unknown internal function `{}`",
call.location, call.location,
identifier identifier
), )
}
} }