ethereum / solidity

Solidity, the Smart Contract Programming Language
https://soliditylang.org
GNU General Public License v3.0
22.67k stars 5.62k forks source link

[ethdebug] Transport debug data through common subexpression eliminator. #15088

Open aarlt opened 1 month ago

aarlt commented 1 month ago

Depends on #14969 and #15009.

(#15009 is just cherry-picked here and should be removed once merged)

See https://notes.ethereum.org/lznAP49lRj6zrLJdLpkqwg.

CommonSubExpressionEliminator

Effect

{
    let x := 42
    let y := add(sload(42), calldataload(0))
    ....
    let z := 42
    ....

    f(42, add(sload(42), calldataload(0)))
}

---->

{
    let x := 42
    let y := add(sload(42), calldataload(0))
    ....
    let z := x
    ...    
    f(x, y)
}

Arbitrarily complex expressions that we know to evaluate to a value currently in a yul variable can be replaced by a yul variable. This can happen through complex control flow (into branches, across loops, etc.) and across arbitrary distances.

Relevance

Very High. This is one of the main aspects of moving things around together with Rematerializing (see below). Especially when done in sequence, we loose a strict division between variable and value. For the optimizer the concepts fuse. TODO: need to elaborate in more complex examples. There may appear to be simple solutions like only preserving the debugging info of the replaced expression, but in more complex examples it should become apparent that the distinction cannot be reasonably kept up across multiple optimizations.

Implementation

TBD.