Repository navigation
Conversation
The text dumps say what the IR looked like at a few chosen points. They do not say which passes ran, in what order, on which function, how long each took, or what the compiler believed about the IR at the time. gxplug emits that as newline delimited JSON. On l1.c at -O2: 247 passes run and 44 leave a mark you can see from outside. -fdump-passes lists 395. The gap between those three numbers is what T04 is about, and until now there was no way to measure the middle one. The one rule is that the plugin never changes what GCC compiles, and a rule in a design document is not a guarantee. `make check` compiles the same program twice, with and without, and compares the assembly byte for byte. The new plugin workflow runs that against four channels on both architectures: Debian sid, Fedora rawhide, Homebrew, and the rel image this project builds itself. They disagree about where the headers live, what the compiler is called, and how a shared object resolves its undefined symbols, and every one of those differences is probed for rather than assumed. Two things cost real time and are written down so they cost nobody else any. A basic block holds GIMPLE or RTL in a union, so counting statements after expand does not fail a check, it reads whichever pointer is there and segfaults in *rest_of_compilation. And emit-rtl.h uses enum memmodel without including the header that defines it, which never shows up in tree because GCC's own sources include memmodel.h first. gxray.plug reads the stream. Its property table restates bit values from gcc/tree-pass.h, which is exactly the kind of copy that rots, so a test reads that header out of the pinned tree and fails if the two disagree in either direction.
Four channels built the plugin and four passed the byte comparison. All three failures were in the scaffolding around it. A dataclass looks its own class up in sys.modules while the module body is still running, so loading gxray.plug by path without registering it first fails on Python 3.14 with an AttributeError about NoneType. Fedora rawhide passed only because its python3 is older. A plugin is C++. The gcc driver knows what to do with a .cc file and goes all the way to exec'ing a cc1plus that only the g++ package ships, so a machine with gcc-16 and no g++-16 gets No such file or directory. Both the Makefile and the test gate now ask the compiler whether it can compile C++ before believing it can build a plugin. And the build fixture passed check=True with capture_output=True, which reports an exit status and throws away the compiler error explaining it. That cost a round trip through CI to learn something make had already said. Also: test_the_lockfile_is_read_even_when_it_is_empty asserted the committed lockfile was empty, which stopped being true the moment the matrix first published. It now writes an empty file in a tmp dir, which is the thing it was trying to test, and a second test checks that whatever is in the real lockfile is a digest.
Owner
Author
|
All seven plugin jobs pass. Something worth writing down came out of them.
Three independently packaged GCC 16.2.0 builds, configured by three different sets of people, produce an identical pass trace on the same input. The architecture is what moves the number, not the packaging. That is a better fact than anything I would have guessed, and T04 gets to use it. |
3 tasks
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
gxplugv0.1, the last piece of the M0 toolchain, plus the reader for what it emits.What it does
The text dumps say what the IR looked like at a few chosen points. They do not say which passes ran, in what order, on which function, how long each took, or what the compiler believed about the IR at that moment. This plugin emits that as one JSON object per line.
Measured on
corpora/programs/l1.cat-O2:-fdump-passeslists 395 passes. 247 of them actually run. 44 change something visible from outside. The gap between those three numbers is what T04 is about, and until now there was no way to measure the middle one.The guarantee
gxplugnever changes what GCC compiles. That is a rule a design document cannot enforce, so it is checked:make checkcompiles the same program twice, with and without the plugin, and compares the assembly byte for byte.pluginworkflow runs that against four channels on both architectures: Debian sid, Fedora rawhide, Homebrew, and therelimage this project builds itself. They disagree about where the plugin headers live, what the compiler is called, and how a shared object resolves its undefined symbols. Every one of those differences is probed for ingxplug/Makefilerather than assumed, and this is what proves the probes work.Dockerfile.plugnow runsmake && make checkrather thanmake, so the image a reader pulls ships a plugin that has been shown not to change the code, not one that merely compiled.That closes the M0 exit item about two distribution channels with four, and the three unchecked boxes on #4.
Two things that cost real time
Written down in the source so they cost nobody else any:
basic_blockholds a GIMPLE sequence or an RTL insn chain, in a union. Counting statements afterexpanddoes not fail a check. It reads whichever pointer happens to be there and segfaults in*rest_of_compilation.emit-rtl.hdeclares a function taking anenum memmodeland does not include the header that defines it. This never shows up in tree, because GCC's own sources includememmodel.hfirst. Out of tree you get an error about an enum without a previous declaration, pointing at a line that has nothing to do with you.The reader
gxray.plugturns a stream intoEvent,RunandStream. ItsPROPERTIEStable restates bit values fromgcc/tree-pass.h, which is exactly the kind of copy that goes stale, sotest_plug.pyreads that header out of the pinned tree and fails if the two disagree in either direction.changedis deliberately narrow: statement count, insn count, block count, or property bits moved. A pass that rewrote an expression without moving any of those reportsFalse, and the prose has to say so rather than let a reader conclude that most passes do nothing.Also here
gxplug/README.md, the record format field by field, and the install table for all four channels.just plugin,just plugin-probe,just plugin-check,just plugin-run FILE.needs_gcc_pluginmarker, because a GCC 16 without its plugin development package is the ordinary case and should skip rather than fail.