Open akiramenai opened 3 weeks ago
Rematerialization of CALLDATALOAD
and ADD
is not trivial, since we need to rematerialize 2 instructions where second instruction is a constant. In some cases, it is more profitable to reuse results of CALLDATALOAD
and ADD
from the stack, instead of doing rematerialization.
One of the tests where this is the case is tests/solidity/simple/yul_instructions/keccak256.sol
:
Loop with rematerialization:
.BB0_8: ; %for_body
; =>This Inner Loop Header: Depth=1
JUMPDEST
PUSH1 68
CALLDATALOAD
PUSH1 4
CALLDATALOAD
DUP3
ADD
MSTORE8
ADD
PUSH1 36
CALLDATALOAD
DUP2
LT
PUSH4 @.BB0_17
JUMPI
Loop without rematerialization:
.BB0_8: ; %for_body
; =>This Inner Loop Header: Depth=1
JUMPDEST
DUP3 <- No remat
DUP6 <- No remat
DUP3
ADD
MSTORE8
ADD
DUP3 <- No remat
DUP2
LT
PUSH4 @.BB0_17
JUMPI
There are two places where we rematerialize stack slots:
EVMSingleUseExpression
pass handles rematerialization for constants (plus ad-hoc solutions forCALLDATALOAD
,ADD
).StackLayoutGenerator::compressStack
also does it for constants, function call labels, symbols, and junk slots.The suggestion is to handle constants exclusively in the
EVMSingleUseExpression
pass and remove their handling from other areas. Rematerialization of the remaining rematerializable items (e.g., function call labels, symbols, junk slots) should become the default behavior, rather than relying on thecompressStack
logic.