<div dir="ltr"><div>Congratulations on this monumental achievement!  Bringing up a whole back-end compiler is a huge amount of work and doing it in a year with only a couple of people is pretty impressive.  It's great to see this work finally see the light of day and I look forward to seeing how it progresses going forward.</div><div><br></div><div>--Jason  <br></div></div><br><div class="gmail_quote"><div dir="ltr" class="gmail_attr">On Wed, Jul 3, 2019 at 12:23 PM Daniel Schürmann <<a href="mailto:daniel@schuermann.dev">daniel@schuermann.dev</a>> wrote:<br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">Hello everyone,<br>
as some of you already know, for a little over one year I have been <br>
working on<br>
an alternate compiler backend for the RADV driver. At the beginning, Bas <br>
Nieuwenhuizen<br>
helped out a lot, and since last December Rhys Perry has also helped <br>
tremendously<br>
working full-time on ACO.<br>
<br>
In this RFC, I'd like to share with you our motivation for this work as <br>
well as some<br>
implementation details and the current state.<br>
<br>
The current development branch of ACO with full commit history can be <br>
found at<br>
  <a href="https://github.com/daniel-schuermann/mesa/tree/backend" rel="noreferrer" target="_blank">https://github.com/daniel-schuermann/mesa/tree/backend</a><br>
while a slightly more stable branch is (until upstream) maintained at<br>
  <a href="https://github.com/daniel-schuermann/mesa/tree/master/" rel="noreferrer" target="_blank">https://github.com/daniel-schuermann/mesa/tree/master/</a><br>
<br>
For initial results, I'd like to refer to this post:<br>
  <a href="https://steamcommunity.com/games/221410/announcements/detail/1602634609636894200" rel="noreferrer" target="_blank">https://steamcommunity.com/games/221410/announcements/detail/1602634609636894200</a><br>
<br>
Feel free to ask questions or just add your thoughts.<br>
<br>
Motivation:<br>
The RADV driver currently uses LLVM as backend for shader compilation. <br>
There are some<br>
shortcomings regarding LLVM's compilation of graphic shaders which need <br>
to be addressed.<br>
The idea and motivation of ACO is the expectation that it would be less <br>
work long-term to<br>
re-write the backend than to fix LLVM.<br>
Without going to much into detail here, the main shortcomings of LLVM <br>
are compile times and<br>
the handling of control flow, which has lead to some serious bugs in the <br>
past.<br>
Additionally, we were able to implement a more aggressive divergence <br>
analysis and having more<br>
precise control over register pressure which can ultimately lead to more <br>
efficient binaries.<br>
A welcome side-effect is an integrated development process without <br>
having to deal with LLVM's<br>
release cycles.<br>
<br>
Implementation:<br>
What started as a proof-of-concept and interesting experimental platform <br>
advanced quickly to<br>
a full-featured backend capable of replacing LLVM in the RADV driver in <br>
the near future.<br>
ACO is based on principles from recent compiler research results and <br>
tries to avoid the issues<br>
we are experiencing with LLVM. The IR is fully SSA-based and also does <br>
register allocation on<br>
SSA which allows to precisely pre-calculate the register demand of a shader.<br>
We implemented the notion of a logical and linear (or physical) control <br>
flow graph which let us<br>
quickly and easily add horizontal reductions (thx Connor Abbott) - a <br>
problem which took almost<br>
two years and various attempts to solve in LLVM, still being far slower <br>
than our solution.<br>
ACO is written with just-in-time compilation in mind and uses data <br>
structures which are quick to<br>
iterate. Avoiding pointer-based data structures like linked lists and <br>
the common def-use chains<br>
leads to much faster compile times. ACO is fully written in C++.<br>
<br>
Current State:<br>
Currently, ACO only supports FS and CS, only on VI+ and only on 32bit <br>
and some 64bit operations.<br>
It misses VGPR spilling (we didn't need it on any tested game so far) <br>
and has a theoretical<br>
issue (in case a divergent/uniform memory write is followed by a memory <br>
read of the other kind)<br>
which needs a proper alias analysis to resolve.<br>
Nevertheless, ACO is able to correctly compile the shaders of (almost?) <br>
all games including<br>
complex ones like Shadow of the Tomb Raider and Wolfenstein II.<br>
We'd like to upstream ACO as experimental driver option to ease <br>
development synchronization,<br>
get more feedback, but ultimately also to give access to the performance <br>
enhancements we achieved.<br>
<br>
<br>
To ease the upstreaming efforts, we created MRs for all changes to the <br>
NIR infrastructure.<br>
After these MRs have went through the reviewing process and landed, we <br>
are going to create a<br>
single MR for ACO. Meanwhile, we will refactor the coding style and <br>
squash the commits.<br>
Please review!<br>
<br>
nir: lowering shared memory derefs with nir_lower_io_explicit():<br>
  <a href="https://gitlab.freedesktop.org/mesa/mesa/merge_requests/622" rel="noreferrer" target="_blank">https://gitlab.freedesktop.org/mesa/mesa/merge_requests/622</a><br>
<br>
radv/radeonsi: Use NIR barycentric interpolation intrinsics:<br>
  <a href="https://gitlab.freedesktop.org/mesa/mesa/merge_requests/906" rel="noreferrer" target="_blank">https://gitlab.freedesktop.org/mesa/mesa/merge_requests/906</a><br>
<br>
WIP: nir: add divergence analysis pass:<br>
  <a href="https://gitlab.freedesktop.org/mesa/mesa/merge_requests/918" rel="noreferrer" target="_blank">https://gitlab.freedesktop.org/mesa/mesa/merge_requests/918</a><br>
<br>
WIP: nir: lower int64 in a single pass:<br>
  <a href="https://gitlab.freedesktop.org/mesa/mesa/merge_requests/1224" rel="noreferrer" target="_blank">https://gitlab.freedesktop.org/mesa/mesa/merge_requests/1224</a><br>
<br>
nir: A Couple of Comparison Optimizations:<br>
  <a href="https://gitlab.freedesktop.org/mesa/mesa/merge_requests/1228" rel="noreferrer" target="_blank">https://gitlab.freedesktop.org/mesa/mesa/merge_requests/1228</a><br>
<br>
radv: disable lower_sub:<br>
  <a href="https://gitlab.freedesktop.org/mesa/mesa/merge_requests/1236" rel="noreferrer" target="_blank">https://gitlab.freedesktop.org/mesa/mesa/merge_requests/1236</a><br>
<br>
nir: change nir_lower_io_to_vector() so that it can always vectorize FS <br>
outputs:<br>
  <a href="https://gitlab.freedesktop.org/mesa/mesa/merge_requests/1238" rel="noreferrer" target="_blank">https://gitlab.freedesktop.org/mesa/mesa/merge_requests/1238</a><br>
<br>
nir/lower_idiv: add new urcp path:<br>
  <a href="https://gitlab.freedesktop.org/mesa/mesa/merge_requests/1239" rel="noreferrer" target="_blank">https://gitlab.freedesktop.org/mesa/mesa/merge_requests/1239</a><br>
<br>
nir: add a memory load/store vectorization and combining pass:<br>
<a href="https://gitlab.freedesktop.org/mesa/mesa/merge_requests/1240" rel="noreferrer" target="_blank">https://gitlab.freedesktop.org/mesa/mesa/merge_requests/1240</a><br>
<br>
nir: replace nir_move_load_const() with nir_opt_sink():<br>
  <a href="https://gitlab.freedesktop.org/mesa/mesa/merge_requests/1241" rel="noreferrer" target="_blank">https://gitlab.freedesktop.org/mesa/mesa/merge_requests/1241</a><br>
<br>
<br>
We welcome any testing feedback and bug reports at<br>
  <a href="https://github.com/daniel-schuermann/mesa/issues" rel="noreferrer" target="_blank">https://github.com/daniel-schuermann/mesa/issues</a><br>
<br>
Thanks,<br>
Daniel Schürmann<br>
Rhys Perry<br>
Bas Nieuwenhuizen<br>
_______________________________________________<br>
mesa-dev mailing list<br>
<a href="mailto:mesa-dev@lists.freedesktop.org" target="_blank">mesa-dev@lists.freedesktop.org</a><br>
<a href="https://lists.freedesktop.org/mailman/listinfo/mesa-dev" rel="noreferrer" target="_blank">https://lists.freedesktop.org/mailman/listinfo/mesa-dev</a></blockquote></div>