Skip to content

Commit 1f36ed6

Browse files
committed
[mlir][doc] Add the getting-started doc
1 parent 8970676 commit 1f36ed6

File tree

1 file changed

+172
-0
lines changed

1 file changed

+172
-0
lines changed
Lines changed: 172 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,172 @@
1+
.. _mlir-getting-started
2+
3+
===============
4+
Getting started
5+
===============
6+
7+
Build
8+
-----
9+
Build `era-compiler-llvm <https://github.com/matter-labs/era-compiler-llvm>`_
10+
checked out at branch ``app-mlir`` with mlir and lld projects enabled. Make sure
11+
rtti is on:
12+
13+
.. code-block:: bash
14+
15+
cmake <llvm> \
16+
...
17+
'-DLLVM_ENABLE_PROJECTS=mlir;lld' \
18+
'-DLLVM_ENABLE_RTTI=ON' \
19+
20+
ninja or make or ...
21+
22+
23+
Then build this project using:
24+
25+
26+
.. code-block:: bash
27+
28+
cmake <solidity> \
29+
...
30+
'-DMLIR_DIR=<llvm-build>/lib/cmake/mlir' \
31+
'-DLLD_DIR=<llvm-build>/lib/cmake/lld'
32+
# Where <llvm-build> is the *absolute* path to the llvm build.
33+
34+
ninja or make or ...
35+
36+
Style
37+
-----
38+
- More or less `mlir style guide
39+
<https://mlir.llvm.org/getting_started/DeveloperGuide/#style-guide>`_, which
40+
is the llvm style with some modification like using camelBack, no const
41+
correctness (`see <https://mlir.llvm.org/docs/Rationale/UsageOfConst>`_) etc.
42+
43+
- Some quirks I personally found helpful: Builder instances are named ``b`` and
44+
Rewriter instances are named ``r``. This makes the ir building/rewriting code
45+
look a little more concise and cleaner where the intent like "create an op",
46+
"replace an op" is more clearer. This is a little like llvm's ``IRBuilder``
47+
instances named as "irb".
48+
49+
- Tests are written to be as minimal as possible. No licenses, unnecessary
50+
specifiers (like pure) that doesn't affect the lowering etc., and the code
51+
might not make sense. The focus is purely on the behaviour of the codegen,
52+
with maximum coverage. A bit of a duh, but when you fix a bug, always add a
53+
minimal reproducer test!
54+
55+
- Location tracking is (``--mmlir --mlir-print-debuginfo``) mandatory in every
56+
source (non-mlir) FileCheck tests.
57+
58+
- Like in llvm, assert liberally. Unimplemented sections should assert-fail with
59+
an "NYI" ("Not yet implemented") message.
60+
61+
Before committing
62+
-----------------
63+
Once a patch is ready, you should do the following:
64+
65+
1. Testing
66+
~~~~~~~~~~
67+
- Run ``test/updFileCheckTest.py`` on each FileCheck test files under
68+
``test/lit/mlirCodegen`` and check if the updates are correct. I do something
69+
like this to update all tests in parallel:
70+
71+
.. code-block:: bash
72+
73+
find test/lit/mlirCodegen -type f \( -name '*.sol' -o -name '*.yul' \) \
74+
| xargs -n1 -P$(nproc) \
75+
test/updFileCheckTest.py --path "<solc-build>/solc"
76+
77+
find test/lit/mlirCodegen -type f -name '*.mlir' \
78+
| xargs -n1 -P$(nproc) \
79+
test/updFileCheckTest.py --path "<solc-build>/tools/solOpt"
80+
81+
- Run the build rule ``check-solidity-mlir`` to run the lit test suite (and make
82+
sure it passes, duh).
83+
84+
- Run semantic tests using soltest. For this you need to build `evmone
85+
<https://github.com/ethereum/evmone>`_ using simple cmake, nothing fancy,
86+
which will build the ``libevmone.so`` used for the semantic testing. Then run:
87+
88+
.. code-block:: bash
89+
90+
soltest -t semanticTests/mlir -- --testpath <test-path> --vm <libevmone.so-path>.
91+
92+
Where ``<test-path>`` is ``<solc-root>/test``. Note that "semanticTests/mlir"
93+
is a filter. You can restrict to, say, one test with ``-t
94+
semanticTests/mlir/<file>``
95+
96+
2. Add tests
97+
~~~~~~~~~~~~
98+
- Add a new test under ``test/lit/mlirCodegen`` that tests your change. Follow
99+
the existing formats of adding both a high level dialect test and standard
100+
dialect test. It's better to generate the check-lines using
101+
``updFileCheckTest.py`` as our mlir dialect representations are not fully
102+
stable yet.
103+
104+
(We don’t test dialects/ir/asm below the standard dialects - the lowering
105+
chain beneath them is already covered by llvm and mlir test suites. But we do
106+
keep one or two full-lowering smoke tests around for good measure.)
107+
108+
- If possible, add a semantic test under ``test/libsolidity/semanticTests/mlir``
109+
following the format of other tests there.
110+
111+
3. Linting
112+
~~~~~~~~~~
113+
- Once all the tests pass, if possible, fix all compiler warnings.
114+
115+
- clang-format your changes using something like:
116+
117+
.. code-block:: bash
118+
119+
git clang-format
120+
121+
Don’t run clang-format on upstream solc files! Follow the surrounding style
122+
instead - afaik, upstream solc doesn't use auto-formatters.
123+
124+
- Then, optionally, run clang-tidy on your changes. I just run this:
125+
126+
.. code-block:: bash
127+
128+
find libsolidity/codegen/mlir -name '*.cpp' \
129+
| xargs -n1 -P"$(nproc)" clang-tidy -p <build-path>
130+
131+
Intro to the codegen
132+
--------------------
133+
``libsolidity/codegen/mlir`` has all the mlir lowering code, dialect
134+
definitions, transformations etc. The code in there is built into the
135+
``libsolidity`` library by ``libsolidity/CMakeLists.txt``. From now on, all file
136+
paths are relative to ``libsolidity/codegen/mlir`` (unless stated otherwise).
137+
138+
Dialects
139+
~~~~~~~~
140+
``Sol/`` directory defines the sol dialect, which is a high level dialect to
141+
represent solidity. Its type-system is defined in ``Sol/SolBase.td`` and its
142+
operations in ``Sol/SolOps.td``. Similarly ``Yul/`` for the yul dialect, which
143+
is more or less the yul ir from solc. Both dialects are under the ``mlir``
144+
namespaces (``mlir::sol`` and ``mlir::yul``)
145+
146+
``mlir-tblgen`` generates the C++ into the build directory's
147+
``libsolidity/codegen/mlir/<dialect>/*.inc`` which can be consulted when the
148+
build errors are harder to follow.
149+
150+
The lowering of high level dialect for evm is under ``Target/EVM``. evm specific
151+
code and utilities are under the ``evm`` namespace.
152+
153+
Pipeline
154+
~~~~~~~~
155+
``SolidityToMLIR.cpp`` lowers the solidity ast to the sol dialect and
156+
``YulToMLIR.cpp`` lowers the yul ast to the yul dialect. ``Passes.cpp`` track
157+
the pass-manager that further lowers the high level dialects. The functions
158+
under the ``CompilerStack`` are integrated with solc's core pipeline. We try to
159+
minimize adding functions in ``CompilerStack``, and instead use the
160+
``solidity::mlirgen`` namespace for things like parsing mlir options, pass
161+
management etc. This namespace is almost like a dumping ground for everything in
162+
the mlir codegen that's not in an mlir dialect and neither in the ``evm``
163+
namespace.
164+
165+
Builder extensions
166+
~~~~~~~~~~~~~~~~~~
167+
There are generic and target specific utilities. The generic builder extension
168+
in the ``solidity::mlirgen`` namespace (called ``BuilderExt``) a builder that
169+
generates frequently used snippets that are not evm specific. While the ``evm``
170+
namespace has its own builder for building frequently generated snippets that
171+
are evm specific. Frequently occurring ir generations should ideally go in one
172+
of these builder extensions.

0 commit comments

Comments
 (0)