Skip to content

Commit df85d26

Browse files
committed
Update ir-breaking-changes and make it visible.
1 parent fe6e58b commit df85d26

File tree

3 files changed

+46
-11
lines changed

3 files changed

+46
-11
lines changed

docs/conf.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -91,7 +91,7 @@ def setup(sphinx):
9191

9292
# List of patterns, relative to source directory, that match files and
9393
# directories to ignore when looking for source files.
94-
exclude_patterns = ['_build', 'contracts', 'types', 'examples', 'grammar', 'ir']
94+
exclude_patterns = ['_build', 'contracts', 'types', 'examples', 'grammar']
9595

9696
# The reST default role (used for this markup: `text`) to use for all
9797
# documents.

docs/index.rst

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -136,6 +136,7 @@ Contents
136136

137137
using-the-compiler.rst
138138
analysing-compilation-output.rst
139+
ir-breaking-changes.rst
139140

140141
.. toctree::
141142
:maxdepth: 2

docs/ir/ir-breaking-changes.rst renamed to docs/ir-breaking-changes.rst

Lines changed: 44 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -5,17 +5,40 @@
55
Solidity IR-based Codegen Changes
66
*********************************
77

8-
This section highlights the main differences between the old and the IR-based codegen,
9-
along with the reasoning behind the changes and how to update affected code.
8+
Solidity can generate EVM bytecode in two different ways:
9+
Either directly from Solidity to EVM opcodes ("old codegen") or through
10+
an intermediate representation ("IR") in Yul ("new codegen" or "IR-based codegen").
11+
12+
The IR-based code generator was introduced with an aim to not only allow
13+
code generation to be more transparent and auditable but also
14+
to enable more powerful optimization passes that span across functions.
15+
16+
Currently, the IR-based code generator is still marked experimental,
17+
but it supports all language features and has received a lot of testing,
18+
so we consider it almost ready for production use.
19+
20+
You can enable it on the command line using ``--experimental-via-ir``
21+
or with the option ``{"viaIR": true}`` in standard-json and we
22+
encourage everyone to try it out!
23+
24+
For several reasons, there are tiny semantic differences between the old
25+
and the IR-based code generator, mostly in areas where we would not
26+
expect people to rely on this behaviour anyway.
27+
This section highlights the main differences between the old and the IR-based codegen.
1028

1129
Semantic Only Changes
1230
=====================
1331

1432
This section lists the changes that are semantic-only, thus potentially
1533
hiding new and different behavior in existing code.
1634

17-
- When storage structs are deleted, every storage slot that contains a member of the struct is set to zero entirely. Formally, padding space was left untouched.
18-
Consequently, if the padding space within a struct is used to store data (e.g. in the context of a contract upgrade), you have to be aware that ``delete`` will now also clear the added member (while it wouldn't have been cleared in the past).
35+
- When storage structs are deleted, every storage slot that contains
36+
a member of the struct is set to zero entirely. Formerly, padding space
37+
was left untouched.
38+
Consequently, if the padding space within a struct is used to store data
39+
(e.g. in the context of a contract upgrade), you have to be aware that
40+
``delete`` will now also clear the added member (while it wouldn't
41+
have been cleared in the past).
1942

2043
.. code-block:: solidity
2144
@@ -132,7 +155,10 @@ This causes differences in some contracts, for example:
132155
Previously, ``y`` would be set to 0. This is due to the fact that we would first initialize state variables: First, ``x`` is set to 0, and when initializing ``y``, ``f()`` would return 0 causing ``y`` to be 0 as well.
133156
With the new rules, ``y`` will be set to 42. We first initialize ``x`` to 0, then call A's constructor which sets ``x`` to 42. Finally, when initializing ``y``, ``f()`` returns 42 causing ``y`` to be 42.
134157

135-
- Copying ``bytes`` arrays from memory to storage is implemented in a different way. The old code generator always copies full words, while the new one cuts the byte array after its end. The old behaviour can lead to dirty data being copied after the end of the array (but still in the same storage slot).
158+
- Copying ``bytes`` arrays from memory to storage is implemented in a different way.
159+
The old code generator always copies full words, while the new one cuts the byte
160+
array after its end. The old behaviour can lead to dirty data being copied after
161+
the end of the array (but still in the same storage slot).
136162
This causes differences in some contracts, for example:
137163

138164
.. code-block:: solidity
@@ -155,8 +181,10 @@ This causes differences in some contracts, for example:
155181
}
156182
}
157183
158-
Previously ``f()`` would return ``0x6465616462656566313564656164000000000000000000000000000000000010`` (it has correct length, and correct first 8 elements, but then it contains dirty data which was set via assembly).
159-
Now it is returning ``0x6465616462656566000000000000000000000000000000000000000000000010`` (it has correct length, and correct elements, but does not contain superfluous data).
184+
Previously ``f()`` would return ``0x6465616462656566313564656164000000000000000000000000000000000010``
185+
(it has correct length, and correct first 8 elements, but then it contains dirty data which was set via assembly).
186+
Now it is returning ``0x6465616462656566000000000000000000000000000000000000000000000010`` (it has
187+
correct length, and correct elements, but does not contain superfluous data).
160188

161189
.. index:: ! evaluation order; expression
162190

@@ -183,7 +211,8 @@ This causes differences in some contracts, for example:
183211

184212
.. index:: ! evaluation order; function arguments
185213

186-
On the other hand, function argument expressions are evaluated in the same order by both code generators with the exception of the global functions ``addmod`` and ``mulmod``.
214+
On the other hand, function argument expressions are evaluated in the same order
215+
by both code generators with the exception of the global functions ``addmod`` and ``mulmod``.
187216
For example:
188217

189218
.. code-block:: solidity
@@ -227,11 +256,15 @@ This causes differences in some contracts, for example:
227256
- Old code generator: ``aMod = 0`` and ``mMod = 2``
228257
- New code generator: ``aMod = 4`` and ``mMod = 0``
229258

230-
- The new code generator imposes a hard limit of ``type(uint64).max`` (``0xffffffffffffffff``) for the free memory pointer. Allocations that would increase its value beyond this limit revert. The old code generator does not have this limit.
259+
- The new code generator imposes a hard limit of ``type(uint64).max``
260+
(``0xffffffffffffffff``) for the free memory pointer. Allocations that would
261+
increase its value beyond this limit revert. The old code generator does not
262+
have this limit.
231263

232264
For example:
233265

234266
.. code-block:: solidity
267+
:force:
235268
236269
// SPDX-License-Identifier: GPL-3.0
237270
pragma solidity >0.8.0;
@@ -264,7 +297,7 @@ The old code generator uses code offsets or tags for values of internal function
264297
these offsets are different at construction time and after deployment and the values can cross this border via storage.
265298
Because of that, both offsets are encoded at construction time into the same value (into different bytes).
266299

267-
In the new code generator, function pointers use the AST IDs of the functions as values. Since calls via jumps are not possible,
300+
In the new code generator, function pointers use internal IDs that are allocated in sequence. Since calls via jumps are not possible,
268301
calls through function pointers always have to use an internal dispatch function that uses the ``switch`` statement to select
269302
the right function.
270303

@@ -280,6 +313,7 @@ Cleanup
280313

281314
The old code generator only performs cleanup before an operation whose result could be affected by the values of the dirty bits.
282315
The new code generator performs cleanup after any operation that can result in dirty bits.
316+
The hope is that the optimizer will be powerful enough to eliminate redundant cleanup operations.
283317

284318
For example:
285319

0 commit comments

Comments
 (0)