Compiler Engineering in Practice
Posted by dhruv3006 1 day ago
Comments
Comment by WalterBright 17 hours ago
I was really, really angry that the review had not attempted to contact me about this.
But the other compiler venders knew what I'd done, and the competition implemented DFA as well by the next year, and the benchmarks were updated.
The benchmarks were things like:
void foo() { int i,x = 1; for (i = 0; i < 1000; ++i) x += 1; }Comment by userbinator 10 hours ago
Comment by norir 14 hours ago
Comment by WalterBright 11 hours ago
Comment by MatejKafka 10 hours ago
Comment by munificent 11 hours ago
It's pretty common to have code that only exists in one configuration but not others. In those, you end up with some obviously pointless code that the compiler should silently discard. It would be no fun if you couldn't compile your release build because the compiler yelled at you that the removed `assert()`s turned some of the surrounding code into dead code.
Comment by netbioserror 12 hours ago
I can understand if we'd want to emit perfectly matching control flow logic with certain debug flags to verify correctness in specific scenarios. But I'd want it to be opt-in.
Comment by mrkeen 21 hours ago
Why compilers are hard – the IR data structure
If you claim an IR makes things harder, just skip it. Compilers do have an essential complexity that makes them "hard" [...waffle waffle waffle...]
The primary data [...waffle...] represents the computation that the compiler needs to preserve all the way to the output program. This data structure is usually called an IR (intermediate representation). The primary way that compilers work is by taking an IR that represents the input program, and applying a series of small transformations all of which have been individually verified to not change the meaning of the program (i.e. not miscompile). In doing so, we decompose one large translation problem into many smaller ones, making it manageable.
There we go. The section header should be updated to: Why compilers are manageable – the IR data structureComment by WalterBright 17 hours ago
An early function inliner I implemented by inlining the IR. When I wrote the D front end, I attempted to do this in the front end. This turned out to be a significantly more complicated problem, and in the end not worth it.
The difficulty with the IR versions is, for error messages, it is impractical to try and issue error messages in the context of the original parse trees. I.e. it's the ancient "turn the hamburger into a cow" problem.
Comment by UncleEntity 12 hours ago
Yeah, I've been working on an APL interpreter, just for the hell of it as it's a very interesting problem, and without the IR (or continuation graph in this case) I can't even imagine how much harder it would be as you can't really tell what most things are until you evaluate the things around it at runtime -- is it a monadic or dyadic function/operator application, variable lookup, function as an argument, whatever?
The compiler (parser, really) builds this intricate graph which curries computations, dispatches functions and, eventually, evaluates expressions to get to the result. Aside from defined operators, which get looked up in the environment at parse time, the parser just knows that it has the name of something with no real clue what it represents as that changes based on the context.
After the continuation graph is built then it's just graph transformations all the way down, at least in theory, which is what I think TFA was trying to get at because this is where the dragons be. Allegedly, haven't gotten to the optimizer yet but I have some ideas so, we'll see...
For some strange reason I have this fascination with CEK machines so that's what I built and reading the article I was thinking how much easier all this would be (for the robots) if we were dealing with a regular old IR (or a more sane language).
Comment by runtimepanic 21 hours ago
Comment by cmovq 14 hours ago
I think the AI program is plenty capable of causing bad medical advice on its own without being miscompiled.
Comment by ekipan 14 hours ago
> A compiler is a translator that translates between two different languages.
I lament the word "compile" subsuming "translate" for most of tech. Computers interpret instructions and do them now, and translate instructions from one code to another that is later interpreted or translated again.
The English word "compile" means "bring together" and compiler systems usually have lots of interpreting and translating and linking to make some kind of artifact file, to wit:
> taking a step back, a compiler is simply a program that reads a file and writes a file
But not necessarily! You don't even need that much! Just source and target codes.
Forth systems (which I enjoy) for example have a single global STATE variable to switch between _execute this word now_ and _compile a call to this word for later_ directly into memory (plus metadata on words that allow them to execute anyway, extending the compiler, but I digress). You could snapshot the memory of the Forth process with its built target program and reload that way, but the usual Forth way is to just store the source and recompile to memory when needed.
Traditional threaded Forths compile calls to a list of routine addresses for a virtual machine interpreter routine (load address then jump to code, not much more work than the processor already does). I prefer subroutine threading, though, where calls are bone fide CALL instructions and the inner interpreter is the processor itself, because it's easier to understand.
Nowadays even the processor translates the instructions you give it to its own microcode for interpreting. It's code all the way down.
(I'm still reading the article.)
Comment by lqstuart 23 hours ago
Might be worth skipping to the interesting parts that aren’t in textbooks
Comment by nn3 17 hours ago
Comment by not-so-darkstar 15 hours ago
Comment by pfdietz 22 hours ago
Comment by serge1978 1 day ago
Comment by userbinator 10 hours ago
Comment by gervwyk 17 hours ago
Comment by amelius 21 hours ago
Comment by ori_b 18 hours ago
https://github.com/inferno-os/inferno-os/blob/master/libinte...
There's lots of room to improve it, but it worked well enough to run on telephony equipment in prod.
Comment by almostgotcaught 16 hours ago
Comment by amelius 15 hours ago
Comment by cyberax 8 hours ago
Comment by almostgotcaught 7 hours ago
Comment by cyberax 6 hours ago
Comment by almostgotcaught 5 hours ago
Comment by dhruv3006 1 day ago