Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: Blackbox code from compiler #12951

Closed
brockelmore opened this issue Apr 21, 2022 · 4 comments
Closed

feat: Blackbox code from compiler #12951

brockelmore opened this issue Apr 21, 2022 · 4 comments
Labels
closed due inactivity The issue/PR was automatically closed due to inactivity. language design :rage4: Any changes to the language, e.g. new features medium effort Default level of effort medium impact Default level of impact stale The issue/PR was marked as stale because it has been open for too long.

Comments

@brockelmore
Copy link

brockelmore commented Apr 21, 2022

Abstract

As the compiler gets smarter at inlining, const evaling, and keeping variables around (with stack-to-deep avoidance and the like), there is a growing need to hide/blackbox chunks of code from the compiler for testing and profiling reasons.

Motivation

I am extremely encouraged that I need to make this request. Effectively, the optimizer (especially with viaIR) is getting so smart there is a growing need to be able to tell the compiler "dont touch this". For example: foundry-rs/foundry#1373

Foundry allows users to change global variables like block parameters in a test. The issue is the optimizer now is smart enough that later usage of block.timestamp is compiled away after the first usage and duped, because in normal circumstances, this is constant throughout a transaction. There have also been times when trying to gas profile a library that under viaIR, it gets const evaled (in these tests for example: https://github.com/recmo/experiment-solexp/blob/main/src/test/FixedPointMathLib.t.sol).

Specification

Blackboxing would take an expression/code block and not perform any constant evaluation on it or perform optimizations on its output.

One option is to add a blackbox code block similar to unchecked or assembly blocks:

function t() public returns (uint256 a) {
    blackbox { a = 5 + 5; }
}

The above would never evaluate the function at compile time and would always effectively generate:

PUSH1(0x05)
PUSH1(0x05)
ADD
PUSH1(0x00)
MSTORE
PUSH1(0x00)
PUSH1(0x20)
RETURN

Or whatever. I am not entirely sure of optimizations that occur on raw bytecode, but if peephole optimizations may still take place on it, one way you might avoid that is basically just trick the peephole optimizer into thinking its a sort of link reference (i.e. _$blackboxRef1$_)? Then as the last step, fill in any references with the associated blackbox opcodes.

Backwards Compatibility

Would add a new keyword blackbox

@cameel
Copy link
Member

cameel commented Apr 26, 2022

This seems related to this earlier issue from @cgewecke and @Ferparishuertas: #10354. That issue is about something else (getting "stack too deep" with optimizer disabled) but the underlying use case is very similar - needing to insert some "instrumentation" code that should go through the optimizer unmodified - for the purpose of tracking coverage in that specific case.

@brockelmore Do you need to be able to do this at Solidity level or would compiling first to Yul, then inserting your snippet and finally assembling to bytecode be enough? If it's the latter then I guess verbatim could be used as a workaround since the compiler won't optimize verbatim blocks.

I am not entirely sure of optimizations that occur on raw bytecode, but if peephole optimizations may still take place on it,

Yeah, there's another optimization pass on EVM assembly after Yul optimizer finishes. It's basically the same optimizer that's used in the legacy non-Yul pipeline. We have fine-grained settings for selecting optimizations done at this stage. You can disable the peephole optimizer by setting settings.optimizer.details.peephole to false in Standard JSON. Also note that you have to explicitly disable it - it still runs if you just set settings.optimizer.enabled to false (at least on 0.8.6+, there was a bug related to that earlier, see Input description for details).

@cameel cameel added feature language design :rage4: Any changes to the language, e.g. new features labels Apr 26, 2022
@axic
Copy link
Member

axic commented Jun 26, 2022

I think this function is really about verbatim, given the goal of blackbox would be the code remains untouched. One just needs to finish #12067.

@brockelmore can this be closed or do you think blackbox would be useful beyond small snippets accomplishable via verbatim?

@cameel cameel added medium effort Default level of effort medium impact Default level of impact labels Oct 6, 2022
@github-actions
Copy link

This issue has been marked as stale due to inactivity for the last 90 days.
It will be automatically closed in 7 days.

@github-actions github-actions bot added the stale The issue/PR was marked as stale because it has been open for too long. label Mar 27, 2023
@github-actions
Copy link

github-actions bot commented Apr 4, 2023

Hi everyone! This issue has been automatically closed due to inactivity.
If you think this issue is still relevant in the latest Solidity version and you have something to contribute, feel free to reopen.
However, unless the issue is a concrete proposal that can be implemented, we recommend starting a language discussion on the forum instead.

@github-actions github-actions bot added the closed due inactivity The issue/PR was automatically closed due to inactivity. label Apr 4, 2023
@github-actions github-actions bot closed this as not planned Won't fix, can't repro, duplicate, stale Apr 4, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
closed due inactivity The issue/PR was automatically closed due to inactivity. language design :rage4: Any changes to the language, e.g. new features medium effort Default level of effort medium impact Default level of impact stale The issue/PR was marked as stale because it has been open for too long.
Projects
None yet
Development

No branches or pull requests

4 participants