mirror of
https://github.com/pezkuwichain/revive.git
synced 2026-06-14 21:31:05 +00:00
Compare commits
1 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 2913fbc494 |
Generated
+6
-7
@@ -687,6 +687,7 @@ dependencies = [
|
||||
"regex",
|
||||
"revive-builtins",
|
||||
"revive-common",
|
||||
"revive-extensions",
|
||||
"revive-linker",
|
||||
"revive-stdlib",
|
||||
"semver 1.0.22",
|
||||
@@ -1349,7 +1350,7 @@ dependencies = [
|
||||
[[package]]
|
||||
name = "polkavm"
|
||||
version = "0.9.3"
|
||||
source = "git+https://github.com/xermicus/polkavm.git?branch=master_byteswap#73ab6d953c13de26ab75ed11707aa6d902ba47ea"
|
||||
source = "git+https://github.com/koute/polkavm.git?branch=master_byteswap#8b8050bd58be30c6001925b5b2785bc9c98cca4e"
|
||||
dependencies = [
|
||||
"libc",
|
||||
"log",
|
||||
@@ -1361,7 +1362,7 @@ dependencies = [
|
||||
[[package]]
|
||||
name = "polkavm-assembler"
|
||||
version = "0.9.0"
|
||||
source = "git+https://github.com/xermicus/polkavm.git?branch=master_byteswap#73ab6d953c13de26ab75ed11707aa6d902ba47ea"
|
||||
source = "git+https://github.com/koute/polkavm.git?branch=master_byteswap#8b8050bd58be30c6001925b5b2785bc9c98cca4e"
|
||||
dependencies = [
|
||||
"log",
|
||||
]
|
||||
@@ -1369,7 +1370,7 @@ dependencies = [
|
||||
[[package]]
|
||||
name = "polkavm-common"
|
||||
version = "0.9.0"
|
||||
source = "git+https://github.com/xermicus/polkavm.git?branch=master_byteswap#73ab6d953c13de26ab75ed11707aa6d902ba47ea"
|
||||
source = "git+https://github.com/koute/polkavm.git?branch=master_byteswap#8b8050bd58be30c6001925b5b2785bc9c98cca4e"
|
||||
dependencies = [
|
||||
"log",
|
||||
]
|
||||
@@ -1377,7 +1378,7 @@ dependencies = [
|
||||
[[package]]
|
||||
name = "polkavm-linker"
|
||||
version = "0.9.2"
|
||||
source = "git+https://github.com/xermicus/polkavm.git?branch=master_byteswap#73ab6d953c13de26ab75ed11707aa6d902ba47ea"
|
||||
source = "git+https://github.com/koute/polkavm.git?branch=master_byteswap#8b8050bd58be30c6001925b5b2785bc9c98cca4e"
|
||||
dependencies = [
|
||||
"gimli",
|
||||
"hashbrown 0.14.3",
|
||||
@@ -1391,7 +1392,7 @@ dependencies = [
|
||||
[[package]]
|
||||
name = "polkavm-linux-raw"
|
||||
version = "0.9.0"
|
||||
source = "git+https://github.com/xermicus/polkavm.git?branch=master_byteswap#73ab6d953c13de26ab75ed11707aa6d902ba47ea"
|
||||
source = "git+https://github.com/koute/polkavm.git?branch=master_byteswap#8b8050bd58be30c6001925b5b2785bc9c98cca4e"
|
||||
|
||||
[[package]]
|
||||
name = "ppv-lite86"
|
||||
@@ -1675,8 +1676,6 @@ dependencies = [
|
||||
"polkavm",
|
||||
"revive-differential",
|
||||
"revive-solidity",
|
||||
"serde",
|
||||
"serde_json",
|
||||
"sha1",
|
||||
]
|
||||
|
||||
|
||||
+3
-3
@@ -27,9 +27,9 @@ path-slash = "0.2"
|
||||
rayon = "1.8"
|
||||
structopt = { version = "0.3", default-features = false }
|
||||
rand = "0.8"
|
||||
polkavm-common = { branch = "master_byteswap", git = "https://github.com/xermicus/polkavm.git" }
|
||||
polkavm-linker = { branch = "master_byteswap", git = "https://github.com/xermicus/polkavm.git" }
|
||||
polkavm = { branch = "master_byteswap", git = "https://github.com/xermicus/polkavm.git" }
|
||||
polkavm-common = { branch = "master_byteswap", git = "https://github.com/koute/polkavm.git" }
|
||||
polkavm-linker = { branch = "master_byteswap", git = "https://github.com/koute/polkavm.git" }
|
||||
polkavm = { branch = "master_byteswap", git = "https://github.com/koute/polkavm.git" }
|
||||
alloy-primitives = "0.6"
|
||||
alloy-sol-types = "0.6"
|
||||
env_logger = { version = "0.10.0", default-features = false }
|
||||
|
||||
@@ -38,8 +38,6 @@ bench: install-bin
|
||||
cargo criterion --all --features bench-evm,bench-pvm --message-format=json \
|
||||
| criterion-table > crates/benchmarks/BENCHMARKS.md
|
||||
|
||||
clippy:
|
||||
cargo clippy --all-features --workspace --tests --benches
|
||||
|
||||
clean:
|
||||
cargo clean ; \
|
||||
|
||||
+3
-3
@@ -37,7 +37,7 @@ cd ../compiler-rt
|
||||
mkdir -p build
|
||||
cd build
|
||||
|
||||
CFLAGS="--target=riscv64 -march=rv64em -mabi=lp64e -nostdlib -nodefaultlibs -mcpu=generic-rv64"
|
||||
CFLAGS="--target=riscv32 -march=rv32em -mabi=ilp32e -nostdlib -nodefaultlibs -mcpu=generic-rv32"
|
||||
cmake -G Ninja -DCMAKE_BUILD_TYPE=Release -DCMAKE_INSTALL_PREFIX=$INSTALL_DIR \
|
||||
-DCOMPILER_RT_BUILD_BUILTINS=ON \
|
||||
-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_XRAY=OFF \
|
||||
-DCMAKE_C_COMPILER=$INSTALL_DIR/bin/clang \
|
||||
-DCMAKE_C_COMPILER_TARGET="riscv64" \
|
||||
-DCMAKE_ASM_COMPILER_TARGET="riscv64" \
|
||||
-DCMAKE_C_COMPILER_TARGET="riscv32" \
|
||||
-DCMAKE_ASM_COMPILER_TARGET="riscv32" \
|
||||
-DCMAKE_AR=$INSTALL_DIR/bin/llvm-ar \
|
||||
-DCMAKE_NM=$INSTALL_DIR/bin/llvm-nm \
|
||||
-DCMAKE_RANLIB=$INSTALL_DIR/bin/llvm-ranlib \
|
||||
|
||||
@@ -1,125 +0,0 @@
|
||||
# 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)
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
use std::{env, fs, io::Read, path::Path, process::Command};
|
||||
|
||||
fn main() {
|
||||
let lib = "libclang_rt.builtins-riscv64.a";
|
||||
let lib = "libclang_rt.builtins-riscv32.a";
|
||||
let mut llvm_lib_dir = String::new();
|
||||
|
||||
Command::new("llvm-config")
|
||||
@@ -16,7 +16,7 @@ fn main() {
|
||||
let lib_path = std::path::PathBuf::from(llvm_lib_dir.trim())
|
||||
.join("linux")
|
||||
.join(lib);
|
||||
let archive = fs::read(lib_path).expect("clang builtins for riscv64 not found");
|
||||
let archive = fs::read(lib_path).expect("clang builtins for riscv32 not found");
|
||||
|
||||
let out_dir = env::var_os("OUT_DIR").expect("has OUT_DIR");
|
||||
let archive_path = Path::new(&out_dir).join(lib);
|
||||
|
||||
@@ -9,7 +9,7 @@ pub const BYTE_LENGTH_BYTE: usize = 1;
|
||||
pub const BYTE_LENGTH_X32: usize = 4;
|
||||
|
||||
/// Native stack alignment size in bytes
|
||||
pub const BYTE_LENGTH_STACK_ALIGN: usize = BYTE_LENGTH_X64;
|
||||
pub const BYTE_LENGTH_STACK_ALIGN: usize = 4;
|
||||
|
||||
/// The x86_64 word byte-length.
|
||||
pub const BYTE_LENGTH_X64: usize = 8;
|
||||
|
||||
@@ -1,7 +1,5 @@
|
||||
; target datalayout = "e-m:e-p:32:32-i64:64-n32-S128"
|
||||
; 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"
|
||||
target datalayout = "e-m:e-p:32:32-i64:64-n32-S128"
|
||||
target triple = "riscv32-unknown-unknown-elf"
|
||||
|
||||
define dso_local noundef i256 @__bswap(i256 noundef %0) local_unnamed_addr #0 {
|
||||
%2 = tail call i256 @llvm.bswap.i256(i256 %0)
|
||||
|
||||
@@ -5,7 +5,7 @@ fn compile(source_path: &str, output_path: &str) {
|
||||
.args([
|
||||
"-O3",
|
||||
"-filetype=asm",
|
||||
"-mattr=+zbb,+e",
|
||||
"-mattr=+zbb,+e,+m",
|
||||
source_path,
|
||||
"-o",
|
||||
output_path,
|
||||
|
||||
@@ -18,5 +18,3 @@ era-compiler-llvm-context = { path = "../llvm-context" }
|
||||
|
||||
[dev-dependencies]
|
||||
sha1 = { workspace = true }
|
||||
serde = { workspace = true }
|
||||
serde_json = { workspace = true }
|
||||
|
||||
@@ -1,7 +0,0 @@
|
||||
{
|
||||
"Flipper": 3958,
|
||||
"Baseline": 3551,
|
||||
"Computation": 5912,
|
||||
"Fibonacci": 4909,
|
||||
"ERC20": 1966
|
||||
}
|
||||
@@ -10,8 +10,6 @@ pub struct Contract {
|
||||
|
||||
sol!(contract Baseline { function baseline() public payable; });
|
||||
|
||||
sol!(contract Flipper { function flip() public; });
|
||||
|
||||
sol!(contract Computation {
|
||||
function odd_product(int32 n) public pure returns (int64);
|
||||
function triangle_number(int64 n) public pure returns (int64 sum);
|
||||
@@ -41,32 +39,6 @@ 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 {
|
||||
pub fn baseline() -> Self {
|
||||
let code = include_str!("../contracts/Baseline.sol");
|
||||
@@ -144,77 +116,4 @@ impl Contract {
|
||||
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));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -26,10 +26,11 @@ fn fibonacci() {
|
||||
|
||||
#[test]
|
||||
fn flipper() {
|
||||
let contract = Contract::flipper();
|
||||
let (mut instance, export) = mock_runtime::prepare(&contract.pvm_runtime, None);
|
||||
let code = crate::compile_blob("Flipper", include_str!("../contracts/flipper.sol"));
|
||||
let state = State::new(0xcde4efa9u32.to_be_bytes().to_vec());
|
||||
let (mut instance, export) = mock_runtime::prepare(&code, None);
|
||||
|
||||
let state = crate::mock_runtime::call(State::new(contract.calldata), &mut instance, export);
|
||||
let state = crate::mock_runtime::call(state, &mut instance, export);
|
||||
assert_eq!(state.output.flags, 0);
|
||||
assert_eq!(state.storage[&U256::ZERO], U256::try_from(1).unwrap());
|
||||
|
||||
|
||||
@@ -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 object_path = dir.path().join("out.o");
|
||||
let linker_script_path = dir.path().join("linker.ld");
|
||||
let compiler_rt_path = dir.path().join("libclang_rt.builtins-riscv64.a");
|
||||
let compiler_rt_path = dir.path().join("libclang_rt.builtins-riscv32.a");
|
||||
|
||||
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",
|
||||
dir.path().to_str().expect("should be utf8"),
|
||||
"--library",
|
||||
"clang_rt.builtins-riscv64",
|
||||
"clang_rt.builtins-riscv32",
|
||||
linker_script_path.to_str().expect("should be utf8"),
|
||||
object_path.to_str().expect("should be utf8"),
|
||||
"-o",
|
||||
|
||||
@@ -12,9 +12,6 @@ description = "Shared front end code of the EraVM compilers"
|
||||
[lib]
|
||||
doctest = false
|
||||
|
||||
[features]
|
||||
riscv-zbb = []
|
||||
|
||||
[dependencies]
|
||||
anyhow = { workspace = true }
|
||||
semver = { workspace = true }
|
||||
@@ -36,3 +33,4 @@ pallet-contracts-pvm-llapi = { path = "../pallet-contracts-pvm-llapi" }
|
||||
revive-linker = { path = "../linker" }
|
||||
revive-builtins = { path = "../builtins" }
|
||||
revive-stdlib = { path = "../stdlib" }
|
||||
revive-extensions = { path = "../extensions" }
|
||||
|
||||
@@ -183,24 +183,6 @@ 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.
|
||||
///
|
||||
@@ -212,10 +194,6 @@ impl<'ctx> Function<'ctx> {
|
||||
optimizer: &Optimizer,
|
||||
) {
|
||||
if optimizer.settings().level_middle_end == inkwell::OptimizationLevel::None {
|
||||
Self::remove_attributes(
|
||||
declaration,
|
||||
&[Attribute::OptimizeForSize, Attribute::AlwaysInline],
|
||||
);
|
||||
Self::set_attributes(
|
||||
llvm,
|
||||
declaration,
|
||||
|
||||
@@ -122,6 +122,31 @@ where
|
||||
/// The PolkaVM minimum stack size.
|
||||
const POLKAVM_STACK_SIZE: u32 = 0x4000;
|
||||
|
||||
/// Link in the extensions module.
|
||||
fn link_extensions_module(
|
||||
llvm: &'ctx inkwell::context::Context,
|
||||
module: &inkwell::module::Module<'ctx>,
|
||||
) {
|
||||
module
|
||||
.link_in_module(revive_extensions::module(llvm, "revive_extensions").unwrap())
|
||||
.expect("the extensions module should be linkable");
|
||||
|
||||
let i256_type = llvm.custom_width_int_type(revive_common::BIT_LENGTH_FIELD as u32);
|
||||
let bswap = module.add_function(
|
||||
"__bswap",
|
||||
i256_type.fn_type(&[i256_type.into()], false),
|
||||
Some(inkwell::module::Linkage::External),
|
||||
);
|
||||
bswap.add_attribute(
|
||||
inkwell::attributes::AttributeLoc::Function,
|
||||
llvm.create_enum_attribute(Attribute::AlwaysInline as u32, 0),
|
||||
);
|
||||
bswap.add_attribute(
|
||||
inkwell::attributes::AttributeLoc::Function,
|
||||
llvm.create_enum_attribute(Attribute::WillReturn as u32, 0),
|
||||
);
|
||||
}
|
||||
|
||||
/// Link in the stdlib module.
|
||||
fn link_stdlib_module(
|
||||
llvm: &'ctx inkwell::context::Context,
|
||||
@@ -203,6 +228,7 @@ where
|
||||
debug_config: Option<DebugConfig>,
|
||||
) -> Self {
|
||||
Self::link_stdlib_module(llvm, &module);
|
||||
Self::link_extensions_module(llvm, &module);
|
||||
Self::link_polkavm_guest_module(llvm, &module);
|
||||
Self::set_polkavm_stack_size(llvm, &module, Self::POLKAVM_STACK_SIZE);
|
||||
Self::set_module_flags(llvm, &module);
|
||||
@@ -703,7 +729,7 @@ where
|
||||
.set_alignment(revive_common::BYTE_LENGTH_BYTE as u32)
|
||||
.expect("Alignment is valid");
|
||||
|
||||
Ok(self.build_byte_swap(value))
|
||||
self.build_byte_swap(value)
|
||||
}
|
||||
AddressSpace::TransientStorage => todo!(),
|
||||
AddressSpace::Storage => {
|
||||
@@ -761,13 +787,13 @@ where
|
||||
// TODO check return value
|
||||
|
||||
self.build_load(storage_value_pointer, "storage_value_load")
|
||||
.map(|value| self.build_byte_swap(value))
|
||||
.and_then(|value| self.build_byte_swap(value))
|
||||
}
|
||||
AddressSpace::Code | AddressSpace::HeapAuxiliary => todo!(),
|
||||
AddressSpace::Generic => Ok(self.build_byte_swap(self.build_load(
|
||||
AddressSpace::Generic => self.build_byte_swap(self.build_load(
|
||||
pointer.address_space_cast(self, AddressSpace::Stack, &format!("{}_cast", name))?,
|
||||
name,
|
||||
)?)),
|
||||
)?),
|
||||
AddressSpace::Stack => {
|
||||
let value = self
|
||||
.builder()
|
||||
@@ -811,7 +837,7 @@ where
|
||||
|
||||
let value = value.as_basic_value_enum();
|
||||
let value = match value.get_type().into_int_type().get_bit_width() as usize {
|
||||
revive_common::BIT_LENGTH_FIELD => self.build_byte_swap(value),
|
||||
revive_common::BIT_LENGTH_FIELD => self.build_byte_swap(value)?,
|
||||
revive_common::BIT_LENGTH_BYTE => value,
|
||||
_ => unreachable!("Only word and byte sized values can be stored on EVM heap"),
|
||||
};
|
||||
@@ -834,7 +860,7 @@ where
|
||||
self.build_alloca(storage_key_value.get_type(), "storage_key");
|
||||
|
||||
let storage_value_value = self
|
||||
.build_byte_swap(value.as_basic_value_enum())
|
||||
.build_byte_swap(value.as_basic_value_enum())?
|
||||
.into_int_value();
|
||||
let storage_value_pointer =
|
||||
self.build_alloca(storage_value_value.get_type(), "storage_value");
|
||||
@@ -871,7 +897,7 @@ where
|
||||
AddressSpace::Code | AddressSpace::HeapAuxiliary => {}
|
||||
AddressSpace::Generic => self.build_store(
|
||||
pointer.address_space_cast(self, AddressSpace::Stack, "cast")?,
|
||||
self.build_byte_swap(value.as_basic_value_enum()),
|
||||
self.build_byte_swap(value.as_basic_value_enum())?,
|
||||
)?,
|
||||
AddressSpace::Stack => {
|
||||
let instruction = self.builder.build_store(pointer.value, value).unwrap();
|
||||
@@ -888,9 +914,23 @@ where
|
||||
pub fn build_byte_swap(
|
||||
&self,
|
||||
value: inkwell::values::BasicValueEnum<'ctx>,
|
||||
) -> inkwell::values::BasicValueEnum<'ctx> {
|
||||
self.build_call(self.intrinsics().byte_swap, &[value], "call_byte_swap")
|
||||
.expect("byte_swap should return a value")
|
||||
) -> anyhow::Result<inkwell::values::BasicValueEnum<'ctx>> {
|
||||
//return Ok(self
|
||||
// .build_call(self.intrinsics().byte_swap, &[value], "call_byte_swap")
|
||||
// .expect("__bswap should return a value"));
|
||||
|
||||
let function = self
|
||||
.module()
|
||||
.get_function("__bswap")
|
||||
.expect("should be declared");
|
||||
|
||||
Ok(self
|
||||
.builder()
|
||||
.build_direct_call(function, &[value.into()], "call_byte_swap")?
|
||||
.try_as_basic_value()
|
||||
.left()
|
||||
.expect("__bswap should return a value")
|
||||
.into())
|
||||
}
|
||||
|
||||
///
|
||||
|
||||
@@ -30,7 +30,7 @@ where
|
||||
);
|
||||
context
|
||||
.build_load(offset, "calldata_value")
|
||||
.map(|value| context.build_byte_swap(value))
|
||||
.and_then(|value| context.build_byte_swap(value))
|
||||
}
|
||||
|
||||
///
|
||||
|
||||
@@ -47,5 +47,5 @@ where
|
||||
"call_seal_hash_keccak_256",
|
||||
)?;
|
||||
|
||||
Ok(context.build_byte_swap(context.build_load(output_pointer, "sha3_output")?))
|
||||
context.build_byte_swap(context.build_load(output_pointer, "sha3_output")?)
|
||||
}
|
||||
|
||||
@@ -24,16 +24,10 @@ pub struct TargetMachine {
|
||||
|
||||
impl TargetMachine {
|
||||
/// The LLVM target name.
|
||||
pub const VM_TARGET_NAME: &'static str = "riscv64";
|
||||
pub const VM_TARGET_NAME: &'static str = "riscv32";
|
||||
|
||||
/// The LLVM target triple.
|
||||
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";
|
||||
pub const VM_TARGET_TRIPLE: &'static str = "riscv32-unknown-unknown-elf";
|
||||
|
||||
///
|
||||
/// A shortcut constructor.
|
||||
@@ -45,8 +39,8 @@ impl TargetMachine {
|
||||
.ok_or_else(|| anyhow::anyhow!("LLVM target machine `{}` not found", target.name()))?
|
||||
.create_target_machine(
|
||||
&inkwell::targets::TargetTriple::create(target.triple()),
|
||||
"generic-rv64",
|
||||
Self::VM_FEATURES,
|
||||
"generic-rv32",
|
||||
"+e,+m",
|
||||
optimizer_settings.level_back_end,
|
||||
inkwell::targets::RelocMode::PIC,
|
||||
inkwell::targets::CodeModel::Default,
|
||||
|
||||
@@ -19,7 +19,7 @@ impl Target {
|
||||
///
|
||||
pub fn name(&self) -> &str {
|
||||
match self {
|
||||
Self::PVM => "riscv64",
|
||||
Self::PVM => "riscv32",
|
||||
}
|
||||
}
|
||||
|
||||
@@ -28,7 +28,7 @@ impl Target {
|
||||
///
|
||||
pub fn triple(&self) -> &str {
|
||||
match self {
|
||||
Self::PVM => "riscv64-unknown-unknown-elf",
|
||||
Self::PVM => "riscv32-unknown-unknown-elf",
|
||||
}
|
||||
}
|
||||
|
||||
@@ -47,7 +47,7 @@ impl FromStr for Target {
|
||||
|
||||
fn from_str(string: &str) -> Result<Self, Self::Err> {
|
||||
match string {
|
||||
"riscv64" => Ok(Self::PVM),
|
||||
"riscv32" => Ok(Self::PVM),
|
||||
_ => Err(anyhow::anyhow!(
|
||||
"Unknown target `{}`. Supported targets: {:?}",
|
||||
string,
|
||||
@@ -60,7 +60,7 @@ impl FromStr for Target {
|
||||
impl std::fmt::Display for Target {
|
||||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||
match self {
|
||||
Target::PVM => write!(f, "riscv64"),
|
||||
Target::PVM => write!(f, "riscv32"),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3,11 +3,11 @@ use std::{env, fs, path::Path, process::Command};
|
||||
fn compile(bitcode_path: &str) {
|
||||
let output = Command::new("clang")
|
||||
.args([
|
||||
"--target=riscv64",
|
||||
"--target=riscv32",
|
||||
"-Xclang",
|
||||
"-triple=riscv64-unknown-unknown-elf",
|
||||
"-march=rv64em",
|
||||
"-mabi=lp64e",
|
||||
"-triple=riscv32-unknown-unknown-elf",
|
||||
"-march=rv32em",
|
||||
"-mabi=ilp32e",
|
||||
"-fno-exceptions",
|
||||
"-ffreestanding",
|
||||
"-Wall",
|
||||
|
||||
@@ -28,10 +28,11 @@ where
|
||||
.original
|
||||
.take()
|
||||
.ok_or_else(|| anyhow::anyhow!("{} Verbatim literal is missing", call.location))?;
|
||||
|
||||
anyhow::bail!(
|
||||
"{} Found unknown internal function `{}`",
|
||||
call.location,
|
||||
identifier
|
||||
)
|
||||
match identifier.as_str() {
|
||||
_ => anyhow::bail!(
|
||||
"{} Found unknown internal function `{}`",
|
||||
call.location,
|
||||
identifier
|
||||
),
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user