Live data from Hacker News

CS 6120: Advanced Compilers: The Self-Guided Online Course (2020)

cs.cornell.edu

51–60 of 63 posts

Re: CS 6120: Advanced Compilers: The Self-Guided Online Course (2020)

#51
post #30
post #7

Earlier quoted context omitted.

Well, course numbers are regular enough that you can look up what the "intro compilers" course is: https://www.cs.cornell.edu/courses/cs4120/2026sp/?schedule The short answer is that compilers is basically broken up into two courses, with the first course largely being the minimum necessary to build a compiler (lexing, parsing, codegen, register allocation), and the second course being how to build an optimizing comp…

I am actively opposed to this design for a first compiler. There is no need for a lexer with a recursive descent parser. Register allocation is also an unnecessary distraction. It is better for a first compiler to compile to a higher level language in which neither register assignment nor memory management are necessary. Optimizing compilers are suboptimal in that they waste enormous amount of time optimizing code th…

I disagree with several parts here. But hopefully, this leads to a fun discussion!

> no need for a lexer with a recursive descent parser

I'd argue that teaching how to write a lexer + recursive descent parser is more relevant in the context of production compilers: many major production compilers out there use hand-written recursive descent parsers (cpp, javac, rust, go,javascript...). Recursive descent parsers are also really nice for emitting error messages.

> It is better for a first compiler to compile to a higher level language in which neither register assignment nor memory management are necessary.

Compiling to a high-level target can be a reasonable first project(e.g., you can emit LLVM), but imo its a different objective from learning the full stack. Emitting actual ISA instructions(even sub-optimally, after all it's a university course) forces you to learn calling conventions, isel, register pressure, stack layouts etc. Building a compiler,at least for me, is probably one of the easiest ways to understand how all of it works together.

> optimize a specific function by source level rewrite

I don't think replacing optimizations with a per-function source-level rewrite works as a general model. Many optimizations are not local to a single function (for example, inlining function calls can lead to new constant-propagation opportunities). If your argument rests on the fact that not all functions are hot, a lot of general-purpose JIT compilers out there already use runtime info to decide when to optimize hot functions, so part of what you're proposing already exists.

> implementation is human readable and not buried in a binary

Is this really a requirement for your program? In most cases, I think the optimization story is more like: "code you want to write" != "code you want to run"

> Moreover, and perhaps even more importantly, by not doing optimizations in the compiler, compilation times can be much faster, easily 100-1000x than state of the art optimizing compiler, while generating equivalent or even better runtime performance

I think the actual answer here is "it depends". For long-running programs, one tradeoff is build time vs future execution time. Also many optimizations cannot be expressed in source code itself. For example, in C++, you can do stuff like whole program de-virtualization only at link time, which is why LTO exists.

Aside: I personally work on source-to-source automatic differentiation inside compilers, and I can give examples for missed optimizations in generated derivative code if you don't run existing optimization passes like LICM/CSE before differentiating a function.

Re: CS 6120: Advanced Compilers: The Self-Guided Online Course (2020)

#52

Is there also a self guided course for "basic compilers", before stepping into an advanced level?

I suggest starting with the old but classic Compiler Construction for Digital Computers by David Gries. Pair it with some modern books recommended here and you should be good.

David Gries - https://www.cs.cornell.edu/gries/ and https://en.wikipedia.org/wiki/David_Gries

Dutch computer scientist Dick Grune has written of Compiler Construction for Digital Computers that "entire generations of compiler constructors have grown up with it and they have not regretted it."

Note that Dick Grune himself is famous for his books on compilers/programming languages - https://dickgrune.com/index.html and https://en.wikipedia.org/wiki/Dick_Grune

Re: CS 6120: Advanced Compilers: The Self-Guided Online Course (2020)

#53
post #32

Earlier quoted context omitted.

I'd say check out Crafting Interpreters [1]. It has 2 parts, the first in Java for doing a treewalk Interpreter in Java before going farther with a version written in C. 1. https://craftinginterpreters.com/

Not GP, but after doing Crafting Interpreters I was kinda left with a gap in my knowledge regarding the conversion of an AST into native code. Also kinda missing was optimization passes over an AST. I somewhat understand the idea, but it would definitely be nice to have a more guided book/article for this. Crafting Interpreters is definitely a recommended read, but it stops at Interpreters (fair enough, the book is t…

Most of the work involved in emitting code deals with somewhat arbitrary hardware details. Pretty much the only way is to get familiar with your target hardware features, instructions, and platform ABIs. ISA manuals all have sections describing these, they're pretty much always very dry and "linguistically rigorous" so it's not easy to read but everything you need is there. Actually emitting instructions is pretty boring and mechanical outside of some considerations and subtleties with hardware-specific optimization, OS calling conventions, register selection, etc.

Re: CS 6120: Advanced Compilers: The Self-Guided Online Course (2020)

#55

Are there any other self-guided online university level CS courses like this?

There are dozens. Search "mooc". Also some professors will release their lectures and homework outside of a "mooc" framework. I've even had professors respond to questions in the comments. The Internet can still be pretty cool.

Re: CS 6120: Advanced Compilers: The Self-Guided Online Course (2020)

#56
post #38

Earlier quoted context omitted.

I didn't believe the optimal algorithm is linear time, so I checked the source: a simple register allocation algorithm can achieve most ot the performance of the more complex algorithms: linear-scan register allocation, developed by Poletto and Sarkar "Most of the performance" is not optimal. Were you referring to a different source?

The big caveat in what I was saying is that it is only the pure graph coloring portion that has an optimal linear time algorithm. Take code in static single assignment form, or another form where it is values that are tracked with live ranges. For a single basic block the interference graph of the live ranges is an interval graph. As the live ranges are just intervals from the instruction that produces the value to t…

There is a wonderful paper "Register Allocation: What Does the NP-Completeness Proof of Chaitin et al. Really Prove?" (2006) by Bouchez, Darte, and Rastello [0]. I'll just quote the abstract in full because there is really nothing much I could add to it:

    Register allocation is one of the most studied problem in compilation. It is
    considered as an NP-complete problem since Chaitin, in 1981, showed that
    assigning temporary variables to k machine registers amounts to color, with
    k colors, the interference graph associated to variables and that this graph
    can be arbitrary, thereby proving the NP-completeness of the problem. However,
    this original proof does not really show where the complexity comes from.
    Recently, the re-discovery that interference graphs of SSA programs can be
    colored in polynomial time raised the question: Can we exploit SSA to perform
    register allocation in polynomial time, without contradicting Chaitin's NP-
    completeness result? To address such a question, we revisit Chaitin's proof
    to better identity the interactions between spilling (load/store insertion),
    coalescing/splitting (moves between registers), critical edges (a property of
    the control-flow graph), and coloring (assignment to registers). In particular,
    we show when it is easy to decide if temporary variables can be assigned to
    k registers or if some spilling is necessary. The real complexity comes from
    critical edges, spilling, and coalescing, which are addressed in our other
    reports.
[0] https://hal-lara.archives-ouvertes.fr/hal-02102286v1/documen...

Re: CS 6120: Advanced Compilers: The Self-Guided Online Course (2020)

#57
post #30

Earlier quoted context omitted.

I am actively opposed to this design for a first compiler. There is no need for a lexer with a recursive descent parser. Register allocation is also an unnecessary distraction. It is better for a first compiler to compile to a higher level language in which neither register assignment nor memory management are necessary. Optimizing compilers are suboptimal in that they waste enormous amount of time optimizing code th…

I disagree with several parts here. But hopefully, this leads to a fun discussion! > no need for a lexer with a recursive descent parser I'd argue that teaching how to write a lexer + recursive descent parser is more relevant in the context of production compilers: many major production compilers out there use hand-written recursive descent parsers (cpp, javac, rust, go,javascript...). Recursive descent parsers are a…

> even more importantly, by not doing optimizations in the compiler, compilation times can be much faster, easily 100-1000x than state of the art optimizing compiler, while generating equivalent or even better runtime performance

As Kent Dybvig (of Chez Scheme fame) said, "As I tell my compiler students now, there is a fine line between "optimization" and "not being stupid". There is a lot of small, simple tweaks that don't take all that much time during the compilation yet drastically improve the produced code.

Re: CS 6120: Advanced Compilers: The Self-Guided Online Course (2020)

#59
post #35

How does this compare to Nora Sandler's "Writing a C compiler" in terms of the potential gains for the reader?

I found that book to be basically useless as a passive reader.

She basically writes "do this" and you are supposed to do it.

This course is much more valuable because it actually gives a lot of information.

It really feels like most text books on compilers have massive "black hole" sections that pull you in on the technicals that you are not even supposed to use in the end.

I found that his course and the LLVM book by Quentin Colombet really useful because they both give easy to understand information that seems to be actually used in real large systems like LLVM/gcc etc.

There are also book like SSA-based compiler design that seem to be great but I am not able to read because of lacking prior knowledge.

Also thank you to Adrian if he is reading this, he is an amazing teacher and releasing this content is much appreciated

Re: CS 6120: Advanced Compilers: The Self-Guided Online Course (2020)

#60

Earlier quoted context omitted.

The big caveat in what I was saying is that it is only the pure graph coloring portion that has an optimal linear time algorithm. Take code in static single assignment form, or another form where it is values that are tracked with live ranges. For a single basic block the interference graph of the live ranges is an interval graph. As the live ranges are just intervals from the instruction that produces the value to t…

There is a wonderful paper "Register Allocation: What Does the NP-Completeness Proof of Chaitin et al. Really Prove?" (2006) by Bouchez, Darte, and Rastello [0]. I'll just quote the abstract in full because there is really nothing much I could add to it: Register allocation is one of the most studied problem in compilation. It is considered as an NP-complete problem since Chaitin, in 1981, showed that assigning tempo…

It is worth noting that register coalescing gets a lot of attention in interference graph coloring allocators because they typically have a pre-pass that inserts copies everywhere (because adding copies or spills later is so hard). So instead of worrying about where to insert copies and spills, those allocators worry about what to coalesce instead.

In my own compiler (where I don't add copies in a prepass) I have not yet found a case where any coalescing would be beneficial.

Post reply on HN