Description
Abstract
In Solidity, we can delegatecall public functions of a library to execute external library code, a pattern originally introduced to help contracts stay below the byte-size limit at deployment time. Unfortunately, the current compiler implementation defeats this purpose: on every delegatecall the generated bytecode embeds a redundant PUSH20 <LibraryAddress>
instruction—often longer than the library code itself. As a result, in many scenarios the delegatecall pattern simultaneously increases gas consumption and bytecode size. This is a problem that the compiler could solve through optimization.
Motivation
Consider the following example:
pragma solidity >=0.7.0 <0.9.0;
library Ballot {
function B() public { }
function C() public { }
}
contract A {
function C() public {
Ballot.B();
}
function D() public {
Ballot.C();
}
}
The bytecode of contract A
is roughly when Optimization is set.
60806040..73__$17280f6b09cfc0597fda7b4937e1c059ab$__63c89e43..
73__$17280f6b09cfc0597fda7b4937e1c059ab$__63fe073d1160..
Because A.C()
and A.D()
each make a library call, we see two separate PUSH20 <LibraryAddress>
sequences in the bytecode. A feature meant to compress code actually injects sizeable, duplicate address literals every time the library is invoked. Hoisting this address into a shared basic block would eliminate the redundancy.
Most libraries function are far smaller than 20 bytes, yet each external call still emits a full PUSH20
.
Proposal
For the library delegatecall scenario, users care primarily about shrinking deployment bytecode, not marginal gas savings. We therefore propose that the compiler, by default, consolidate all identical PUSH20 <address>
instructions for a given library into a single basic block and reuse it across every call site. This would remove redundant code fragments and restore the original byte-size advantage of the library mechanism.
PUSH20 Address
...
PUSH20 Address
TO
JUMPDEST
PUSH20 Address
JUMP
...
PUSH <ORIGINPC>
PUSH <PUSHADDREPC>
JUMP
...
PUSH <ORIGINPC>
PUSH <PUSHADDRE>
JUMP