mirror of
https://github.com/pezkuwichain/revive.git
synced 2026-10-20 18:56:17 +00:00
This PR introduces powerful code size optimizations. This is achieved with an additional IR layer in between Yul and LLVM IR. It works quite well (see below for a comparison) because it captures optimization gains that neither solc nor LLVM can realize. The feature is gated behind `--newyork` or a corresponding standard JSON input setting and **off by default**. ### How it works We implemented an SSA IR modelled after or inspired by the [MLIR SCF dialect](https://mlir.llvm.org/docs/Dialects/SCFDialect/). Yul is translated into this IR and the IR implements mainly the following optimizations: - **Type narrowing**: narrows 256-bit values to I1..I160 where provable (bidirectional + interprocedural), so LLVM emits native 32/64-bit ops instead of software 256-bit arithmetic. - **FMP range proof**: exposes the `mload(0x40) < heap_size` bound to LLVM IPSCCP, eliminating trailing overflow checks on FMP-derived offsets. Single largest code-size contributor. - **Heap analysis**: skips big-endian byte-swaps where native little-endian layout is safe. - **mem_opt / keccak fusion+folding**, **compound outlining** (mapping sload/sstore), **guard narrowing**, **inlining** tuned for PolkaVM, and **exact + fuzzy function dedup**. ### Results The optimizations implemented with the newyork IR bring substantial code size improvements. - Integration contracts: approximately **-20% to -50%** code size. - OpenZeppelin Wizard corpus: around **-47%** code size. This table shows the code size improvements on various OpenZeppelin ERC implementations, taken from their [contracts wizard](https://wizard.openzeppelin.com/), with almost all features enabled. | Contract | Default: (bytes) | With `--newyork`: (bytes) | Reduction | |---|---:|---:|---:| | erc1155 | 59,206 | 30,649 | -48.2% | | erc20 | 81,697 | 42,893 | -47.5% | | erc721 | 92,052 | 49,423 | -46.3% | | oz_gov | 141,861 | 81,159 | -42.8% | | oz_rwa | 77,274 | 37,975 | -50.9% | | oz_simple_erc20 | 29,950 | 16,554 | -44.7% | | oz_stable | 82,117 | 39,032 | -52.5% | | **Total** | **564,157** | **297,685** | **-47.2%** | We believe this to be a reasonably representative dataset and conclude that the newyork IR achieves drastic code size reductions on real world dApp implementations. ### Methodology, security and runtime performance Since the main contributors to these improvements are the FMP range proofs and the type narrowing, we don't expect big runtime performance regressions (it may even benefit runtime performance in some cases). The PR also includes docs (`book/src/developer_guide/newyork_{optimizer,ir}.md`) and many new integration tests, including regression tests for known FMP soundness traps. The PR was authored collaboratively and reviewed extensively by the `revive` maintainers, as well as Claude Opus, Claude Fable, Qwen, Minimax and Deepseek LLMs, over a span of many months. The `newyork` compiler pipeline introduces no new regressions over our integration and differential test suites (containing over 30000 test cases). This was achieved by careful manual reviews and many LLM bughunt loops. Additionally, a final security review by Anthropic's Fable 5 LLM found no remaining soundness issues. Nonetheless, like any brand new software, please consider this an experimental feature upon release. --------- Signed-off-by: xermicus <bigcyrill@hotmail.com> Signed-off-by: xermicus <cyrill@parity.io> Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com> Co-authored-by: neo <me@90f9.org> Co-authored-by: LJ <81748770+elle-j@users.noreply.github.com>
451 lines
14 KiB
Markdown
451 lines
14 KiB
Markdown
# Changelog
|
|
|
|
## Unreleased
|
|
|
|
Supported `polkadot-sdk` rev: `2604.2.0`
|
|
|
|
### Changed
|
|
|
|
- Updated `polkadot-sdk` to `2604.2.0`
|
|
|
|
### Added
|
|
|
|
- Experimental newyork IR optimization pipeline, selectable via the `--newyork` CLI flag or the `settings.polkavm.newyork` standard JSON input field. Off by default. [#519](https://github.com/paritytech/revive/pull/519)
|
|
|
|
## v1.2.0
|
|
|
|
Supported `polkadot-sdk` rev: `2603`
|
|
|
|
### Changed
|
|
|
|
- Updated `LLVM` from `21.1.8` to LLVM `22.1.4`
|
|
|
|
### Added
|
|
|
|
- Support for solc v0.8.35.
|
|
|
|
### Fixed
|
|
|
|
- A constant folding bug causing incorrect translation of a signed remainder edge case. The affected pattern (Solidity % or Yul smod):
|
|
- SREM over the two constant operands `type(int256).min` and `-1`.
|
|
- At least one of the two constants needs folding (i.e. not just `type(int256).min % -1`),
|
|
and is written specifically such that solc doesn't fold but LLVM does, resulting in UB (signed-overflow).
|
|
- Fix `mulmod` returning out-of-range result for large moduli.
|
|
|
|
## v1.1.0
|
|
|
|
Supported `polkadot-sdk` rev: `2603`
|
|
|
|
### Added
|
|
- Support for solc v0.8.34.
|
|
- Inherit `STDERR` in recursive processes, allowing debug logs to be printed to the console [#485](https://github.com/paritytech/revive/pull/485)
|
|
|
|
### Fixed
|
|
|
|
- npm package: The `--bin` CLI flag was not producing bytecode because the `outputSelection` was not updated to explicitly requested it.
|
|
- Yul mode now properly exits when solc reports validation errors (e.g., invalid hex literals), matching `--standard-json` behavior. [#477](https://github.com/paritytech/revive/issues/477)
|
|
- Fixed a bytecode divergence (yet functionally equivalent) between the resolc Linux/macOS builds and the Windows build for Solidity contracts containing a value multiplied by itself (e.g. via explicit squaring or exponentiation), manifesting primarily when using optimization level `-O0`. [#500](https://github.com/paritytech/revive/pull/500)
|
|
- Recursive processes use the current executable by default [#484](https://github.com/paritytech/revive/pull/484)
|
|
- Work around some LLVM indeterminism problem [#500](https://github.com/paritytech/revive/pull/500)
|
|
|
|
### Changed
|
|
|
|
- Updated `LLVM` from `18.1.8` to LLVM `21.1.8`
|
|
- Updated `musl` to `1.2.5`
|
|
- Updated `inkwell` to `0.8.0`
|
|
- Updated `polkavm-*` to `0.31.0`
|
|
- Updated `EMSDK` to `5.0.0`
|
|
- Switched building LLVM for Windows from Visual Studio to MSVC-compatible Clang (clang-cl) and Ninja. [#497](https://github.com/paritytech/revive/pull/497)
|
|
- Append optnone and noinline for -O0 optlevel [#502](https://github.com/paritytech/revive/pull/502)
|
|
|
|
## v1.0.0
|
|
|
|
Supported `polkadot-sdk` rev: `unstable2507`
|
|
|
|
### Changed
|
|
- Removed the `revive-explorer` utility.
|
|
|
|
### Fixed
|
|
- OOB access in `calldataload` and `calldatacopy` should always produce zero values instead of consuming all gas.
|
|
- The superfluous byte swap in `linkersymbol`.
|
|
- Compiling with `--standard-json` now compiles to PolkaVM bytecode _only_ for the contracts explicitly requested in the `outputSelection`, significantly improving compilation time when none or a subset of files requests bytecode. [PR#461](https://github.com/paritytech/revive/pull/461)
|
|
- Compiling with `--standard-json` now outputs _only_ the explicitly requested output (e.g. `evm.assembly`, `evm.bytecode`, `ast`, etc.). [PR#461](https://github.com/paritytech/revive/pull/461)
|
|
```jsonc
|
|
// Example:
|
|
{
|
|
"settings": {
|
|
// ...
|
|
"outputSelection": {
|
|
"path/to/my/file1.sol": {
|
|
// Contracts in this file will generate bytecode.
|
|
// Only these fields of the JSON output selection will be in the `contracts` output.
|
|
"*": ["abi", "evm.methodIdentifiers", "metadata", "evm.bytecode"],
|
|
// Only this field of the JSON output selection will be in the `sources` output.
|
|
"": ["ast"]
|
|
},
|
|
"path/to/my/file2.sol": {
|
|
// No contracts in this file will generate bytecode.
|
|
"*": ["abi", "evm.methodIdentifiers", "metadata"],
|
|
// No `ast` will be in the `sources` output (only the automatically added `id`,
|
|
// similar to solc as this is not a configurable output selection).
|
|
"": []
|
|
},
|
|
}
|
|
}
|
|
}
|
|
```
|
|
|
|
## v0.6.0
|
|
|
|
This is a development pre-release.
|
|
|
|
Supported `polkadot-sdk` rev: `unstable2507`
|
|
|
|
### Added
|
|
- The comprehensive revive compiler book documentation page: https://paritytech.github.io/revive/
|
|
- Support for solc v0.8.33.
|
|
- Support for the `clz` Yul builtin.
|
|
|
|
### Changed
|
|
- Instruct the LLVM backend and linker to `--relax` (may lead to smaller contract code size).
|
|
- Standard JSON mode: Don't forward EVM bytecode related output selections to solc.
|
|
- The supported `polkadot-sdk` release is `unstable2507`.
|
|
- The `INVALID` opcode and OOB memory accesses now consume all remaining gas.
|
|
- Emit the `call_evm` and `delegate_call_evm` syscalls for contract calls.
|
|
- The `revive-runner` can execute arbitrarily large contract blobs.
|
|
- Set the default PolkaVM stack and heap size values to 128KB.
|
|
|
|
### Fixed:
|
|
- The missing `STOP` instruction at the end of `code` blocks.
|
|
- The missing bounds check in the internal sbrk implementation.
|
|
- The call gas is no longer ignored.
|
|
- The `settings.polkavm.memoryConfig` object and its fields are now in camelCase.
|
|
|
|
## v0.5.0
|
|
|
|
This is a development pre-release.
|
|
|
|
Supported `polkadot-sdk` rev: `2509.0.0`
|
|
|
|
### Added
|
|
- Support for `SELFDESTRUCT`.
|
|
|
|
### Changed
|
|
- Emulated EVM heap memory accesses of zero length are never out of bounds.
|
|
- Switched to newer and cheaper storage syscalls (omits reads and writes of `0` values).
|
|
|
|
### Fixed
|
|
- Introduced a workaround avoiding compiler crashes caused by a bug in LLVM affecting `SDIV`.
|
|
- An off-by-one bug affecting `SDIV` overflow semantics.
|
|
|
|
## v0.4.1
|
|
|
|
This is a development pre-release.
|
|
|
|
Supported `polkadot-sdk` rev: `2503.0.1`
|
|
|
|
### Changed
|
|
- The `ast` output is no longer pruned in standard JSON mode (required for foundry).
|
|
- Support `standard_json.output_selection` to also look at per file settings.
|
|
|
|
## v0.4.0
|
|
|
|
This is a development pre-release.
|
|
|
|
Supported `polkadot-sdk` rev: `2503.0.1`
|
|
|
|
### Changed
|
|
- Remove the broken `--llvm-ir` mode.
|
|
- Remove the unused fallback for size optimization setting.
|
|
- Unlinked contract binaries are emitted as raw ELF objects.
|
|
|
|
### Added
|
|
- Line debug information per YUL builtin and for `if` statements.
|
|
- Column numbers in debug information.
|
|
- Support for the YUL optimizer details in the standard json input definition.
|
|
- The `revive-explorer` compiler utility.
|
|
- `revive-yul`: The AST visitor interface.
|
|
- The `--link` deploy time linking mode.
|
|
|
|
### Fixed
|
|
- The debug info source file matches the YUL path in `--debug-output-dir`, allowing tools to display the source line.
|
|
- Incosistent type forwarding in JSON output (empty string vs. null object).
|
|
- The solc automatic import resolution.
|
|
- Compiler panic on missing libraries definition.
|
|
|
|
## v0.3.0
|
|
|
|
This is a development pre-release.
|
|
|
|
Supported `polkadot-sdk` rev: `2503.0.1`
|
|
|
|
### Fixed
|
|
|
|
- llvm-context: Bugfix the SAR YUL builtin translation.
|
|
- runtime-api: Add the missing `memset` builtin.
|
|
- npm package: Bugfix the exports field defined in the `package.json`.
|
|
|
|
|
|
## v0.2.0
|
|
|
|
This is a development pre-release.
|
|
|
|
Supported `polkadot-sdk` rev: `2503.0.1`
|
|
|
|
### Changed
|
|
|
|
- Removed the license printer from the `resolc` binary.
|
|
- EVM bytecode is no longer requested from solc (except in test utils) leading to less compilation work in the pipeline.
|
|
|
|
### Fixed
|
|
|
|
- solc-json-interface: Serializing of any custom key in the JSON input is only skipped if not provided.
|
|
- npm package resolution no longer fails with an 'ERR_PACKAGE_PATH_NOT_EXPORTED' error for packages defining exports fields in the `package.json`.
|
|
|
|
## v0.1.0
|
|
|
|
This is a development pre-release.
|
|
|
|
Supported `polkadot-sdk` rev: `2503.0.1`
|
|
|
|
### Added
|
|
|
|
- Add the PolkaVM heap size, stack size and debug info CLI compiler options to the standard JSON settings. This makes the standard JSON input succint for reproducible builds.
|
|
|
|
### Changed
|
|
|
|
- Supported `polkadot-sdk` version is now `2503.0.1`
|
|
- The `emsdk` version is now `4.0.9`
|
|
|
|
### Fixed
|
|
|
|
## v0.1.0-dev.16
|
|
|
|
This is a development pre-release.
|
|
|
|
Supported `polkadot-sdk` rev:`c29e72a8628835e34deb6aa7db9a78a2e4eabcee`
|
|
|
|
### Added
|
|
|
|
- Move the npm package from paritytech/js-revive, into this repo. The package `@parity/resolc` will be deployed to npm for each release.
|
|
- Support for solc v0.8.30
|
|
|
|
### Changed
|
|
|
|
- By default, heavy size optimizations are applied.
|
|
|
|
### Fixed
|
|
|
|
- @parity/resolc: The solc dependency package is constrained to the latest supported version, preventing breaking the package ever time a new solc package was released.
|
|
- The resolc npm package no longer ignores the optimizer settings
|
|
|
|
## v0.1.0-dev.14
|
|
|
|
This is a development pre-release.
|
|
|
|
Supported `polkadot-sdk` rev:`c29e72a8628835e34deb6aa7db9a78a2e4eabcee`
|
|
|
|
### Added
|
|
|
|
- The `revive-runner` helper utility binary which helps to run contracts locally without a blockchain node.
|
|
- Allow configuration of the EVM heap memory size and stack size via CLI flags and JSON input settings.
|
|
|
|
### Changed
|
|
|
|
- The default PVM stack memory size was increased from 16kb to 32kb.
|
|
|
|
### Fixed
|
|
|
|
- Constructors avoid storing zero sized immutable data on exit.
|
|
|
|
## v0.1.0-dev.13
|
|
|
|
This is a development pre-release.
|
|
|
|
Supported `polkadot-sdk` rev:`c29e72a8628835e34deb6aa7db9a78a2e4eabcee`
|
|
|
|
### Added
|
|
|
|
- Support for solc v0.8.29
|
|
- Decouples the solc JSON-input-output type definitions from the Solidity fronted and expose them via a dedicated crate.
|
|
- `--supported-solc-versions` for `resolc` binary to return a `semver` range of supported `solc` versions.
|
|
- Support for passing LLVM command line options via the prcoess input or providing one or more `--llvm-arg='..'` resolc CLI flag. This allows more fine-grained control over the LLVM backend configuration.
|
|
|
|
### Changed
|
|
|
|
- Storage keys and values are big endian. This was a pre-mature optimization because for the contract itself it this is a no-op and thus not observable. However we should consider the storage layout as part of the contract ABI. The endianness of transient storage values are still kept as-is.
|
|
- Running `resolc` using webkit is no longer supported.
|
|
|
|
### Fixed
|
|
|
|
- A missing byte swap for the create2 salt value.
|
|
|
|
## v0.1.0-dev.12
|
|
|
|
This is a development pre-release.
|
|
|
|
Supported `polkadot-sdk` rev: `21f6f0705e53c15aa2b8a5706b208200447774a9`
|
|
|
|
### Added
|
|
|
|
- Per file output selection for `--standard-json` mode.
|
|
- The `ir` output selection option for `--standard-json` mode.
|
|
|
|
### Changed
|
|
|
|
- Improved code size: Large contracts compile to smaller code blobs when enabling aggressive size optimizations (`-Oz`).
|
|
|
|
### Fixed
|
|
|
|
## v0.1.0-dev.11
|
|
|
|
This is a development pre-release.
|
|
|
|
Supported `polkadot-sdk` rev: `274a781e8ca1a9432c7ec87593bd93214abbff50`
|
|
|
|
### Added
|
|
|
|
### Changed
|
|
|
|
### Fixed
|
|
|
|
- A bug causing incorrect loads from the emulated EVM linear memory.
|
|
- A missing integer truncate after switching to 64bit.
|
|
|
|
## v0.1.0-dev.10
|
|
|
|
This is a development pre-release.
|
|
|
|
Supported `polkadot-sdk` rev: `274a781e8ca1a9432c7ec87593bd93214abbff50`
|
|
|
|
### Added
|
|
|
|
- Support for the `coinbase` opcode.
|
|
- The resolc web JS version.
|
|
|
|
### Changed
|
|
|
|
- Missing the `--overwrite` flag emits an error instead of a warning.
|
|
- The `resolc` executable prints the help by default.
|
|
- Removed support for legacy EVM assembly (EVMLA) translation.
|
|
- integration: identify cached code blobs on source code to fix potential confusions.
|
|
- Setting base, include or allow paths in emscripten is now a hard error.
|
|
- Employ a heuristic to detect `address.transfer` and `address.send` calls.
|
|
If detected, the re-entrant call flag is not set and 0 deposit limit is endowed.
|
|
|
|
### Fixed
|
|
|
|
- Solidity: Add the solc `--libraries` files to sources.
|
|
- A data race in tests.
|
|
- Fix `broken pipe` errors.
|
|
- llvm-builder: Allow warnings.
|
|
- solidity: Fix the custom compiler warning messages.
|
|
|
|
## v0.1.0-dev.9
|
|
|
|
This is a development pre-release.
|
|
|
|
### Added
|
|
|
|
### Changed
|
|
|
|
- Syscalls with more than 6 arguments now pack them into registers.
|
|
|
|
### Fixed
|
|
|
|
- Remove reloading of the resolc.js file (fix issue with relative path in web worker)
|
|
|
|
## v0.1.0-dev.8
|
|
|
|
This is a development pre-release.
|
|
|
|
### Added
|
|
|
|
- The `revive-llvm-builder` crate with the `revive-llvm` helper utility for streamlined management of the LLVM framework dependency.
|
|
- Initial support for running `resolc` in the browser.
|
|
|
|
### Changed
|
|
|
|
- Suported contracts runtime is polkadot-sdk git version `d62a90c8c729acd98c7e9a5cab9803b8b211ffc5`.
|
|
- The minimum supported Rust version is `1.81.0`.
|
|
- Error out early instead of invoking `solc` with invalid base or include path flags.
|
|
|
|
### Fixed
|
|
|
|
- Decouple the LLVM target dependency from the LLVM host dependency.
|
|
- Do not error out if no files and no errors were produced. This aligns resolc closer to solc.
|
|
- Fixes input normalization in the Wasm version.
|
|
|
|
## v0.1.0-dev.7
|
|
|
|
This is a development pre-release.
|
|
|
|
### Added
|
|
|
|
- Implement the `GASPRICE` opcode.
|
|
- Implement the `BASEFEE` opcode.
|
|
- Implement the `GASLIMIT` opcode.
|
|
|
|
### Changed
|
|
|
|
- The `GAS` opcode now returns the remaining `ref_time`.
|
|
- Contracts can now be supplied call data input of arbitrary size.
|
|
- Some syscalls now return the value in a register, slightly improving emitted contract code.
|
|
- Calls forward maximum weight limits instead of 0, anticipating a change in polkadot-sdk where weight limits of 0 no longer interprets as uncapped limit.
|
|
|
|
### Fixed
|
|
|
|
- A linker bug which was preventing certain contracts from linking with the PVM linker.
|
|
- JS: Fix encoding conversion from JS string (UTF-16) to UTF-8.
|
|
- The git commit hash slug is always displayed in the version string.
|
|
|
|
## v0.1.0-dev.6
|
|
|
|
This is a development pre-release.
|
|
|
|
# Added
|
|
|
|
- Implement the `BLOCKHASH` opcode.
|
|
- Implement delegate calls.
|
|
- Implement the `GASPRICE` opcode. Currently hard-coded to return `1`.
|
|
- The ELF shared object contract artifact is dumped into the debug output directory.
|
|
- Initial support for emitting debug info (opt in via the `-g` flag)
|
|
|
|
# Changed
|
|
|
|
- resolc now emits 64bit PolkaVM blobs, reducing contract code size and execution time.
|
|
- The RISC-V bit-manipulation target feature (`zbb`) is enabled.
|
|
|
|
# Fixed
|
|
|
|
- Compilation to Wasm (for usage in node and web browsers)
|
|
|
|
## v0.1.0-dev.5
|
|
|
|
This is development pre-release.
|
|
|
|
# Added
|
|
|
|
- Implement the `CODESIZE` and `EXTCODESIZE` opcodes.
|
|
|
|
# Changed
|
|
|
|
- Include the full revive version in the contract metadata.
|
|
|
|
# Fixed
|
|
|
|
## v0.1.0-dev-4
|
|
|
|
This is development pre-release.
|
|
|
|
# Added
|
|
|
|
- Support the `ORIGIN` opcode.
|
|
|
|
# Changed
|
|
|
|
- Update polkavm to `v0.14.0`.
|
|
- Enable the `a`, `fast-unaligned-access` and `xtheadcondmov` LLVM target features, decreasing the code size for some contracts.
|
|
|
|
# Fixed
|