mirror of
https://github.com/pezkuwichain/revive.git
synced 2026-10-20 18:56:17 +00:00
Improve compilation time in standard JSON mode and honor requested output (#461)
# Description
Compilation times for resolc were significantly slower than solc when:
* Multiple files were included in the JSON input file via
`--standard-json`
* And none of the files requested code generation
* (If only a subset of files requested code generation, both resolc and
solc were very slow)
Reason:
* Resolc unconditionally generated bytecode for all contracts, even if
not requested.
* When compiling to PolkaVM bytecode, we need to pass additional flags
(e.g. `irOptimized`) to solc. If these flags were not explicitly
requested, resolc also added these to the requested output since PolkaVM
bytecode was always generated.
## Breaking Changes
The following changes are breaking, but fix the semantics to match its
intended behavior:
* Compiling with `--standard-json` now compiles to PolkaVM bytecode
***only*** for the contracts explicitly requested in the
`outputSelection`.
* Compiling with `--standard-json` now outputs ***only*** the explicitly
requested output (e.g. `evm.assembly`, `evm.bytecode`, `ast`, etc.).
```jsonc
// Example:
{
"settings": {
// ...
"outputSelection": {
"src/common/GasService.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"]
},
"src/common/Gateway.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).
"": []
},
}
}
}
```
## Performance Improvements
When e.g. the standard JSON input file includes multiple files and
requests output for every contract as per this setting:
```jsonc
{
"settings": {
// ...
"optimizer": { "enabled": true, "runs": 1 },
"viaIR": true,
"outputSelection": {
"src/common/GasService.sol": {
"*": ["abi", "evm.methodIdentifiers", "metadata", "evm.bytecode"],
},
// Rest of files..
}
}
}
```
The differences in compilation times depending on whether `evm.bytecode`
is selected in every file, one file, or no files can be seen below:
| Solc Optimizer (runs=1) | ViaIR | Request `abi`,
`evm.methodIdentifiers`, `metadata` | Request `evm.bytecode` | resolc
before | resolc after | solc v0.8.33 |
|:-----------------------:|:-----:|:---------:|:---------:|:-------------:|:------------:|:----------:|
| ✅ | ✅ | All files | All files | `~14.5s` | `~14.5s` | `~13.5s` |
| ✅ | ✅ | All files | One file | `~14.5s` | `~450ms` | `~13.5s` |
| ✅ | ✅ | All files | No files | `~14.5s` | `~390ms` | `~350ms` |
**Observations:**
* `resolc before` is roughly the same no matter the request
* This is due to unconditionally generating bytecode
* When not requesting bytecode for any contracts:
* `resolc after` now compiles in ~390ms (vs ~14.5s), similar to `solc`
* Neither `solc` nor `resolc after` generates bytecode when none of the
contracts request it
* When requesting bytecode for all contracts in _only one_ file:
* `resolc after` now compiles in ~450ms (vs ~14.5s)
* `solc` still compiles in the same time as when requesting bytecode for
all contracts in all files
* This is something they have tried to improve (see
[Solidity#15373](https://github.com/argotorg/solidity/issues/15373) and
[Solidity#15615](https://github.com/argotorg/solidity/issues/15615)),
and the intended behavior seems to now be that bytecode should only be
generated when explicitly requested for each contract.
* Even though PRs have merged to try to fix it, their issue seems to
persist as of v0.8.33.
# Open Questions
* Foundry:
* [x] Pruning of the AST:
* Just saw [this past
commit](https://github.com/paritytech/revive/pull/385) to not prune the
AST for Foundry compatibility.
* Can Foundry not explicitly request `"": "ast"`?
* **Answer:**
* Pruning the AST when not requested should be fine, as long as Foundry
explicitly requests it when needed.
* Will be tested by Foundry maintainer.
# Review Notes
Changes in `docs/` (~25 files) can be skipped as they are automatically
updated after adding content to `book/` and rebuilding it.
# Resolved Issues
Closes #326
---------
Co-authored-by: xermicus <cyrill@parity.io>
This commit is contained in:
1 parent
95ae938ddf
commit
a4163512ff
52 files changed
+3827
-187
No files matched your search
@@ -35,7 +35,7 @@
|
||||
const path_to_root = "../";
|
||||
const default_light_theme = "light";
|
||||
const default_dark_theme = "navy";
|
||||
window.path_to_searchindex_js = "../searchindex-c7304031.js";
|
||||
window.path_to_searchindex_js = "../searchindex-575cfd18.js";
|
||||
</script>
|
||||
<!-- Start loading toc.js asap -->
|
||||
<script src="../toc-6f3f265e.js"></script>
|
||||
@@ -175,16 +175,16 @@
|
||||
<div id="mdbook-content" class="content">
|
||||
<main>
|
||||
<h1 id="standard-json-interface"><a class="header" href="#standard-json-interface">Standard JSON interface</a></h1>
|
||||
<p>The <code>revive</code> compiler is mostly compatible with the <code>solc</code> standard JSON interface. There are a few additional (PVM related) <strong>input</strong> configurations:</p>
|
||||
<p>The <code>revive</code> compiler is mostly compatible with the <code>solc</code> standard JSON interface. There are a few differences and additional (PVM related) <strong>input</strong> configurations:</p>
|
||||
<h2 id="the-settingspolkavm-object"><a class="header" href="#the-settingspolkavm-object">The <code>settings.polkavm</code> object</a></h2>
|
||||
<p>Used to configure PVM specific compiler settings.</p>
|
||||
<h3 id="settingspolkavmdebuginformation"><a class="header" href="#settingspolkavmdebuginformation"><code>settings.polkavm.debugInformation</code></a></h3>
|
||||
<p>A boolean value allowing to enable debug information. Corresponds to <code>resolc -g</code>.</p>
|
||||
<h3 id="the-settingspolkavmmemoryconfig-object"><a class="header" href="#the-settingspolkavmmemoryconfig-object">The <code>settings.polkavm.memoryConfig</code> object</a></h3>
|
||||
<p>Used to apply PVM specific memory configuration settings.</p>
|
||||
<h4 id="settingspolkavmmemoryconifgheapsize"><a class="header" href="#settingspolkavmmemoryconifgheapsize"><code>settings.polkavm.memoryConifg.heapSize</code></a></h4>
|
||||
<h4 id="settingspolkavmmemoryconfigheapsize"><a class="header" href="#settingspolkavmmemoryconfigheapsize"><code>settings.polkavm.memoryConfig.heapSize</code></a></h4>
|
||||
<p>A numerical value allowing to configure the contract heap size. Corresponds to <code>resolc --heap-size</code>.</p>
|
||||
<h4 id="settingspolkavmmemoryconifgstacksize"><a class="header" href="#settingspolkavmmemoryconifgstacksize"><code>settings.polkavm.memoryConifg.stackSize</code></a></h4>
|
||||
<h4 id="settingspolkavmmemoryconfigstacksize"><a class="header" href="#settingspolkavmmemoryconfigstacksize"><code>settings.polkavm.memoryConfig.stackSize</code></a></h4>
|
||||
<p>A numerical value allowing to configure the contract stack size. Corresponds to <code>resolc --stack-size</code>.</p>
|
||||
<h2 id="the-settingsoptimizer-object"><a class="header" href="#the-settingsoptimizer-object">The <code>settings.optimizer</code> object</a></h2>
|
||||
<p>The <code>settings.optimizer</code> object is augmented with support for PVM specific optimization settings.</p>
|
||||
@@ -192,6 +192,63 @@
|
||||
<p>A single char value to configure the LLVM optimizer settings. Corresponds to <code>resolc -O</code>.</p>
|
||||
<h2 id="settingsllvmarguments"><a class="header" href="#settingsllvmarguments"><code>settings.llvmArguments</code></a></h2>
|
||||
<p>Allows to specify arbitrary command line arguments to LLVM initialization. Used mainly for development and debugging purposes.</p>
|
||||
<h2 id="the-settingsoutputselection-object"><a class="header" href="#the-settingsoutputselection-object">The <code>settings.outputSelection</code> object</a></h2>
|
||||
<p>Used to select desired outputs.</p>
|
||||
<h3 id="the-all--wildcard"><a class="header" href="#the-all--wildcard">The “all” (<code>*</code>) wildcard</a></h3>
|
||||
<p>Resolc supports the “all” (<code>*</code>) wildcard for the file-level (first-level) and contract-level (second-level) keys. A file-level key can be either the wildcard or a specific file name, whereas the contract-level key can only be the wildcard for robustness reasons.</p>
|
||||
<p>Thus, output can be requested in 2 ways:</p>
|
||||
<pre><code class="language-json">// All files and all contracts:
|
||||
{
|
||||
"settings": {
|
||||
"outputSelection": {
|
||||
"*": {
|
||||
"*": [/* specific contract-level output fields */],
|
||||
"": [/* specific file-level output fields */]
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Specific files and all their contracts:
|
||||
{
|
||||
"settings": {
|
||||
"outputSelection": {
|
||||
"path/to/my/file.sol": {
|
||||
"*": [/* specific contract-level output fields */],
|
||||
"": [/* specific file-level output fields */]
|
||||
},
|
||||
// Rest of files...
|
||||
}
|
||||
}
|
||||
}
|
||||
</code></pre>
|
||||
<h3 id="the-contract-level-evm-output-selection"><a class="header" href="#the-contract-level-evm-output-selection">The contract-level <code>evm</code> output selection</a></h3>
|
||||
<blockquote class="blockquote-tag blockquote-tag-note">
|
||||
<p class="blockquote-tag-title"><svg viewbox="0 0 16 16" width="18" height="18"><path d="M0 8a8 8 0 1 1 16 0A8 8 0 0 1 0 8Zm8-6.5a6.5 6.5 0 1 0 0 13 6.5 6.5 0 0 0 0-13ZM6.5 7.75A.75.75 0 0 1 7.25 7h1a.75.75 0 0 1 .75.75v2.75h.25a.75.75 0 0 1 0 1.5h-2a.75.75 0 0 1 0-1.5h.25v-2h-.25a.75.75 0 0 1-.75-.75ZM8 6a1 1 0 1 1 0-2 1 1 0 0 1 0 2Z"></path></svg>Note</p>
|
||||
<p>Currently, resolc supports requesting either the full <code>evm</code> output, or one more level of specificity, such as <code>evm.bytecode</code>.</p>
|
||||
</blockquote>
|
||||
<p>When requesting code generation, such as <code>evm.bytecode</code> or <code>evm.assembly</code>, the resolc compilation process additionally needs <code>ast</code>, <code>metadata</code>, <code>irOptimized</code>, and <code>evm.methodIdentifiers</code> selectors. These selectors will be automatically added if code generation is needed, but will only be included in the output if explicitly requested.</p>
|
||||
<pre><code class="language-json">{
|
||||
"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).
|
||||
"": []
|
||||
},
|
||||
}
|
||||
}
|
||||
}
|
||||
</code></pre>
|
||||
|
||||
</main>
|
||||
|
||||
|
||||
Reference in new issue
Block a user