solidity icon indicating copy to clipboard operation
solidity copied to clipboard

Allow for unchecked function pointer jumps

Open brockelmore opened this issue 2 years ago • 3 comments

Abstract

With viaIR & 0.8.13, there is an internal function dispatcher. This is quite the hefty gas overhead without anyway to breakout of it to do unchecked internal function calls.

Motivation

It would be nice to be able to use the old version of direct jumps via unchecked or something in yul, even with viaIR enabled.

Specification

One solution may be something like the following:

contract T {

    function intoPtr(function(uint256 a) internal view returns (uint256 b) op) internal pure returns (uint256 ptr) {
        assembly ("memory-safe") {
            ptr := op
        }
    }

    function intoOp(uint256 ptr) internal pure returns (function(uint256 a) internal view returns (uint256 b) op) {
        assembly ("memory-safe") {
            op := ptr
        }
    }

    function addOne(uint256 a) internal pure returns(uint256 b) {
        b = a + 1;
    }
    function exec(uint256 c) public returns (uint256 d) {
        uint256 ptr = intoPtr(addOne);
 
        // would not do the internal function dispatch checking.
        unchecked { d = intoOp(ptr)(c); }
    }
}

Alternatively, could do something like:

contract T {
    /// snip ....
    function exec(uint256 c) public returns (uint256 d) {
        uint256 ptr = intoPtr(addOne);
 
        // would not do the internal function dispatch checking.
        assembly ("memory-safe") {
            /// by specifying 1 output, the compiler implies that its a 1-in-1-out stack affecting function
            d := goto(ptr)
        }
    }
}

Note: The change made to restrict function pointers to a known set makes sense, but there is no escape hatch for more optimized usage. The yul approach I think actually makes more sense long term as the optimizer could likely eventually recognize it doesn't need to do the internal function dispatching and can directly jump in certain cases.

Further alternative: finally allow verbatim in solidity contracts

Backwards Compatibility

Fully compatible to my knowledge

brockelmore avatar Apr 18 '22 19:04 brockelmore

The main reason for having a dispatch function in Yul (rather than direct jumps like in the legacy codegen) is the expectation that the support for dynamic jumps in the EVM will eventually be removed. There's ongoing work on this and at some point we're likely to get some alternative mechanism, e.g. some opcodes for managing jump tables with a set of predefined destinations. Or a new variant of the jump opcode.

This is actually a deeper discussion and @chfast, @axic, @ekpyron and @chriseth would probably like to chime in on this. I think that adding the old mechanism back through unchecked is unlikely.

Also #12650 is a bit related to this.

cameel avatar Apr 26 '22 18:04 cameel

The reason we do not allow "goto" is more that we would otherwise have to remove some optimizations we are currently able to do.

chriseth avatar Apr 28 '22 11:04 chriseth

i guess i'm running into this

i'm not sure how to check whether i am or not, but my gas costs go up noticeably when i enable viaIR and i make heavy use of calling functions by their pointer, so i assume this is at least contributing

for me at least it seems these additional optimizations that @chriseth is pointing to (no pun intended) are less impactful overall than the cost of the slower dispatch

also i'd be willing to measure whether this is indeed the gas problem i'm facing with viaIR if i could get some pointers (no pun intended) on how to do that

thedavidmeister avatar Jul 28 '22 08:07 thedavidmeister

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[bot] avatar Mar 27 '23 12:03 github-actions[bot]

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[bot] avatar Apr 04 '23 12:04 github-actions[bot]