B05, sixty lines of C++ and you are inside the compiler - #74
Merged
Merged
Conversation
The last lesson of M2, and the one that turns a reader from somebody who watches GCC into somebody who runs code inside it. A plugin cannot be built in a notebook. It is C++ compiled against GCC's private headers by the compiler that will load it, and Colab has neither. So the lesson is in three layers. The five example plugins live in the repository, where a --depth 1 clone still gets them and every line can be read. Eleven real compilations by a real GCC 16.2.0 are recorded in corpora/plug/b05.json, with argv, return code, both streams and the assembly of every run that produced any. Ten spans of GCC's own plugin machinery are cut into corpora/source/b05.json. The five examples, all under gxplug/examples/: hello the contract, in the smallest form that still works countpass a GIMPLE pass of your own, inserted after ssa gate switching one of GCC's own passes off from outside nolicence hello without the GPL symbol, refused at load time wrongver a staged version mismatch, refused by its own check make examples-check builds all five, loads each, and asserts that hello and countpass leave the assembly byte identical, that gate does not, and that the two broken ones fail the compilation rather than being skipped. The plugin workflow now runs it on Debian, Fedora, Homebrew and the GCC this project builds itself, so the lesson cannot describe plugins that only work where they were written. Its program is an array traversal rather than the accumulator `make check` uses, because the pass being switched off is ivopts and a loop with no memory reference gives ivopts nothing to rewrite, and the two halves of the result are checked apart: how many times the pass was refused, which catches a name that matched nothing, and whether the assembly moved, which catches a pass whose absence makes no difference. Two things the lesson goes out of its way to say, because both cost an afternoon and neither is written down anywhere obvious. Three of the twenty six names in plugin.def are pseudo-events, handled inside register_callback and never fired, so registering a pass looks exactly like registering a callback and is a function call. And the digit in -fdump-tree-cddce1 is an instance number and not part of the pass name, so gating "cddce1" matches nothing, reports nothing, and looks like a successful experiment. The more useful of the two gate results is the one that changes nothing: einline is refused twice and the assembly is byte for byte what it was, because the IPA inliner later on does the work. A pass switched off with no visible effect is the normal case. Also here: six glossary terms under a new "Extending the compiler" group, a tier 0 offline experiment, a corpus-b05 recipe, gxray.plug's recorded half, and eleven tests including one that runs examples-check.
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.
The last lesson of M2. Closes the M2 lesson list; the milestone's second gate (issue #21) is the four green
bootruns, which is separate.What is here
A plugin cannot be built in a notebook: it is C++ compiled against GCC's private headers by the compiler that will load it, and Colab has neither. So B05 is three layers.
gxplug/examples/, in the repository, so a--depth 1clone has them and every line can be read.corpora/plug/b05.json: argv, return code, both streams, and the assembly of every run that produced any.corpora/source/b05.json, fromplugin.cc,plugin.def,tree-pass.handpasses.cc.hello.cccountpass.ccssa, with its own dump filegate.ccnolicence.cchello.ccwithout the GPL symbol, refused at load timewrongver.ccThe check
make -C gxplug examples-checkbuilds all five, loads each, and asserts thathelloandcountpassleave the assembly byte identical, thatgatedoes not, and that the two broken ones fail the compilation rather than being skipped. Thepluginworkflow now runs it on all four channels, so the lesson cannot describe plugins that only work on the machine they were written on.Its program is an array traversal rather than the accumulator
make checkuses, because the pass being switched off isivoptsand a loop with no memory reference givesivoptsnothing to rewrite. The two halves of the gate result are checked apart: how many times the pass was refused, which catches a pass name that matched nothing, and whether the assembly moved, which catches a pass whose absence makes no difference. They fail for different reasons and the messages say which.Two traps the lesson is built around
Three of the twenty six names in
plugin.defare pseudo-events, handled insideregister_callbackand never fired. So registering a pass is spelled exactly like registering a callback and is a function call, and passing a callback alongside the pass info trips agcc_assertrather than producing a diagnostic.The digit in
-fdump-tree-cddce1is an instance number and not part of the pass name. Gatingcddce1matches nothing, reports nothing, and looks like a successful experiment. There is a recorded run of exactly that in the corpus.The more useful of the two gate results is the one that changes nothing:
einlineis refused twice and the assembly is byte for byte what it was, because the IPA inliner later on does the work.Also
b05-plugin, 30 registeredjust corpus-b05, with--checkre-asserting every fact without compilinggxray.plug's recorded half:example,body,Invocation,Session,load_sessionexamples-checkbehind@needs_plugin_gcc, and three over the grader's computed answersGates
pytest -q1450 passed.ruff check,ruff format --check,prosecheck,bpc check,bpc pages --check,refcheck check(492 citations),dumpparse check,matrix table --check,tier0 check(30 passed),nbbuild check,nbbuild verify,python -m gxray.glossaryall clean.matrix digests --checkstill reports the two known-missingbootimages.The notebook was executed in a real kernel and every cell read; the grader scores 8 of 8 on the answers the notebook leads you to.