| Sean Silva | d7fb396 | 2012-12-05 00:26:32 +0000 | [diff] [blame] | 1 | ====================================================== | 
|  | 2 | Kaleidoscope: Conclusion and other useful LLVM tidbits | 
|  | 3 | ====================================================== | 
|  | 4 |  | 
|  | 5 | .. contents:: | 
|  | 6 | :local: | 
|  | 7 |  | 
| Sean Silva | d7fb396 | 2012-12-05 00:26:32 +0000 | [diff] [blame] | 8 | Tutorial Conclusion | 
|  | 9 | =================== | 
|  | 10 |  | 
|  | 11 | Welcome to the final chapter of the "`Implementing a language with | 
|  | 12 | LLVM <index.html>`_" tutorial. In the course of this tutorial, we have | 
|  | 13 | grown our little Kaleidoscope language from being a useless toy, to | 
|  | 14 | being a semi-interesting (but probably still useless) toy. :) | 
|  | 15 |  | 
|  | 16 | It is interesting to see how far we've come, and how little code it has | 
|  | 17 | taken. We built the entire lexer, parser, AST, code generator, and an | 
|  | 18 | interactive run-loop (with a JIT!) by-hand in under 700 lines of | 
|  | 19 | (non-comment/non-blank) code. | 
|  | 20 |  | 
|  | 21 | Our little language supports a couple of interesting features: it | 
|  | 22 | supports user defined binary and unary operators, it uses JIT | 
|  | 23 | compilation for immediate evaluation, and it supports a few control flow | 
|  | 24 | constructs with SSA construction. | 
|  | 25 |  | 
|  | 26 | Part of the idea of this tutorial was to show you how easy and fun it | 
|  | 27 | can be to define, build, and play with languages. Building a compiler | 
|  | 28 | need not be a scary or mystical process! Now that you've seen some of | 
|  | 29 | the basics, I strongly encourage you to take the code and hack on it. | 
|  | 30 | For example, try adding: | 
|  | 31 |  | 
|  | 32 | -  **global variables** - While global variables have questional value | 
|  | 33 | in modern software engineering, they are often useful when putting | 
|  | 34 | together quick little hacks like the Kaleidoscope compiler itself. | 
|  | 35 | Fortunately, our current setup makes it very easy to add global | 
|  | 36 | variables: just have value lookup check to see if an unresolved | 
|  | 37 | variable is in the global variable symbol table before rejecting it. | 
|  | 38 | To create a new global variable, make an instance of the LLVM | 
|  | 39 | ``GlobalVariable`` class. | 
|  | 40 | -  **typed variables** - Kaleidoscope currently only supports variables | 
|  | 41 | of type double. This gives the language a very nice elegance, because | 
|  | 42 | only supporting one type means that you never have to specify types. | 
|  | 43 | Different languages have different ways of handling this. The easiest | 
|  | 44 | way is to require the user to specify types for every variable | 
|  | 45 | definition, and record the type of the variable in the symbol table | 
|  | 46 | along with its Value\*. | 
|  | 47 | -  **arrays, structs, vectors, etc** - Once you add types, you can start | 
|  | 48 | extending the type system in all sorts of interesting ways. Simple | 
|  | 49 | arrays are very easy and are quite useful for many different | 
|  | 50 | applications. Adding them is mostly an exercise in learning how the | 
| Alex Denisov | 596e979 | 2015-12-15 20:50:29 +0000 | [diff] [blame] | 51 | LLVM `getelementptr <../LangRef.html#getelementptr-instruction>`_ instruction | 
| Sean Silva | d7fb396 | 2012-12-05 00:26:32 +0000 | [diff] [blame] | 52 | works: it is so nifty/unconventional, it `has its own | 
|  | 53 | FAQ <../GetElementPtr.html>`_! If you add support for recursive types | 
|  | 54 | (e.g. linked lists), make sure to read the `section in the LLVM | 
|  | 55 | Programmer's Manual <../ProgrammersManual.html#TypeResolve>`_ that | 
|  | 56 | describes how to construct them. | 
|  | 57 | -  **standard runtime** - Our current language allows the user to access | 
|  | 58 | arbitrary external functions, and we use it for things like "printd" | 
|  | 59 | and "putchard". As you extend the language to add higher-level | 
|  | 60 | constructs, often these constructs make the most sense if they are | 
|  | 61 | lowered to calls into a language-supplied runtime. For example, if | 
|  | 62 | you add hash tables to the language, it would probably make sense to | 
|  | 63 | add the routines to a runtime, instead of inlining them all the way. | 
|  | 64 | -  **memory management** - Currently we can only access the stack in | 
|  | 65 | Kaleidoscope. It would also be useful to be able to allocate heap | 
|  | 66 | memory, either with calls to the standard libc malloc/free interface | 
|  | 67 | or with a garbage collector. If you would like to use garbage | 
|  | 68 | collection, note that LLVM fully supports `Accurate Garbage | 
|  | 69 | Collection <../GarbageCollection.html>`_ including algorithms that | 
|  | 70 | move objects and need to scan/update the stack. | 
|  | 71 | -  **debugger support** - LLVM supports generation of `DWARF Debug | 
|  | 72 | info <../SourceLevelDebugging.html>`_ which is understood by common | 
|  | 73 | debuggers like GDB. Adding support for debug info is fairly | 
|  | 74 | straightforward. The best way to understand it is to compile some | 
| Sean Silva | e0ddc73 | 2014-02-19 00:12:34 +0000 | [diff] [blame] | 75 | C/C++ code with "``clang -g -O0``" and taking a look at what it | 
| Sean Silva | d7fb396 | 2012-12-05 00:26:32 +0000 | [diff] [blame] | 76 | produces. | 
|  | 77 | -  **exception handling support** - LLVM supports generation of `zero | 
|  | 78 | cost exceptions <../ExceptionHandling.html>`_ which interoperate with | 
|  | 79 | code compiled in other languages. You could also generate code by | 
|  | 80 | implicitly making every function return an error value and checking | 
|  | 81 | it. You could also make explicit use of setjmp/longjmp. There are | 
|  | 82 | many different ways to go here. | 
|  | 83 | -  **object orientation, generics, database access, complex numbers, | 
|  | 84 | geometric programming, ...** - Really, there is no end of crazy | 
|  | 85 | features that you can add to the language. | 
|  | 86 | -  **unusual domains** - We've been talking about applying LLVM to a | 
|  | 87 | domain that many people are interested in: building a compiler for a | 
|  | 88 | specific language. However, there are many other domains that can use | 
|  | 89 | compiler technology that are not typically considered. For example, | 
|  | 90 | LLVM has been used to implement OpenGL graphics acceleration, | 
|  | 91 | translate C++ code to ActionScript, and many other cute and clever | 
|  | 92 | things. Maybe you will be the first to JIT compile a regular | 
|  | 93 | expression interpreter into native code with LLVM? | 
|  | 94 |  | 
|  | 95 | Have fun - try doing something crazy and unusual. Building a language | 
|  | 96 | like everyone else always has, is much less fun than trying something a | 
|  | 97 | little crazy or off the wall and seeing how it turns out. If you get | 
| Tanya Lattner | 0d28f80 | 2015-08-05 03:51:17 +0000 | [diff] [blame] | 98 | stuck or want to talk about it, feel free to email the `llvm-dev mailing | 
|  | 99 | list <http://lists.llvm.org/mailman/listinfo/llvm-dev>`_: it has lots | 
| Sean Silva | d7fb396 | 2012-12-05 00:26:32 +0000 | [diff] [blame] | 100 | of people who are interested in languages and are often willing to help | 
|  | 101 | out. | 
|  | 102 |  | 
|  | 103 | Before we end this tutorial, I want to talk about some "tips and tricks" | 
|  | 104 | for generating LLVM IR. These are some of the more subtle things that | 
|  | 105 | may not be obvious, but are very useful if you want to take advantage of | 
|  | 106 | LLVM's capabilities. | 
|  | 107 |  | 
|  | 108 | Properties of the LLVM IR | 
|  | 109 | ========================= | 
|  | 110 |  | 
|  | 111 | We have a couple common questions about code in the LLVM IR form - lets | 
|  | 112 | just get these out of the way right now, shall we? | 
|  | 113 |  | 
|  | 114 | Target Independence | 
|  | 115 | ------------------- | 
|  | 116 |  | 
|  | 117 | Kaleidoscope is an example of a "portable language": any program written | 
|  | 118 | in Kaleidoscope will work the same way on any target that it runs on. | 
|  | 119 | Many other languages have this property, e.g. lisp, java, haskell, | 
|  | 120 | javascript, python, etc (note that while these languages are portable, | 
|  | 121 | not all their libraries are). | 
|  | 122 |  | 
|  | 123 | One nice aspect of LLVM is that it is often capable of preserving target | 
|  | 124 | independence in the IR: you can take the LLVM IR for a | 
|  | 125 | Kaleidoscope-compiled program and run it on any target that LLVM | 
|  | 126 | supports, even emitting C code and compiling that on targets that LLVM | 
|  | 127 | doesn't support natively. You can trivially tell that the Kaleidoscope | 
|  | 128 | compiler generates target-independent code because it never queries for | 
|  | 129 | any target-specific information when generating code. | 
|  | 130 |  | 
|  | 131 | The fact that LLVM provides a compact, target-independent, | 
|  | 132 | representation for code gets a lot of people excited. Unfortunately, | 
|  | 133 | these people are usually thinking about C or a language from the C | 
|  | 134 | family when they are asking questions about language portability. I say | 
|  | 135 | "unfortunately", because there is really no way to make (fully general) | 
|  | 136 | C code portable, other than shipping the source code around (and of | 
|  | 137 | course, C source code is not actually portable in general either - ever | 
|  | 138 | port a really old application from 32- to 64-bits?). | 
|  | 139 |  | 
|  | 140 | The problem with C (again, in its full generality) is that it is heavily | 
|  | 141 | laden with target specific assumptions. As one simple example, the | 
|  | 142 | preprocessor often destructively removes target-independence from the | 
|  | 143 | code when it processes the input text: | 
|  | 144 |  | 
|  | 145 | .. code-block:: c | 
|  | 146 |  | 
|  | 147 | #ifdef __i386__ | 
|  | 148 | int X = 1; | 
|  | 149 | #else | 
|  | 150 | int X = 42; | 
|  | 151 | #endif | 
|  | 152 |  | 
|  | 153 | While it is possible to engineer more and more complex solutions to | 
|  | 154 | problems like this, it cannot be solved in full generality in a way that | 
|  | 155 | is better than shipping the actual source code. | 
|  | 156 |  | 
|  | 157 | That said, there are interesting subsets of C that can be made portable. | 
|  | 158 | If you are willing to fix primitive types to a fixed size (say int = | 
|  | 159 | 32-bits, and long = 64-bits), don't care about ABI compatibility with | 
|  | 160 | existing binaries, and are willing to give up some other minor features, | 
|  | 161 | you can have portable code. This can make sense for specialized domains | 
|  | 162 | such as an in-kernel language. | 
|  | 163 |  | 
|  | 164 | Safety Guarantees | 
|  | 165 | ----------------- | 
|  | 166 |  | 
|  | 167 | Many of the languages above are also "safe" languages: it is impossible | 
|  | 168 | for a program written in Java to corrupt its address space and crash the | 
|  | 169 | process (assuming the JVM has no bugs). Safety is an interesting | 
|  | 170 | property that requires a combination of language design, runtime | 
|  | 171 | support, and often operating system support. | 
|  | 172 |  | 
|  | 173 | It is certainly possible to implement a safe language in LLVM, but LLVM | 
|  | 174 | IR does not itself guarantee safety. The LLVM IR allows unsafe pointer | 
|  | 175 | casts, use after free bugs, buffer over-runs, and a variety of other | 
|  | 176 | problems. Safety needs to be implemented as a layer on top of LLVM and, | 
| Tanya Lattner | 0d28f80 | 2015-08-05 03:51:17 +0000 | [diff] [blame] | 177 | conveniently, several groups have investigated this. Ask on the `llvm-dev | 
|  | 178 | mailing list <http://lists.llvm.org/mailman/listinfo/llvm-dev>`_ if | 
| Sean Silva | d7fb396 | 2012-12-05 00:26:32 +0000 | [diff] [blame] | 179 | you are interested in more details. | 
|  | 180 |  | 
|  | 181 | Language-Specific Optimizations | 
|  | 182 | ------------------------------- | 
|  | 183 |  | 
|  | 184 | One thing about LLVM that turns off many people is that it does not | 
|  | 185 | solve all the world's problems in one system (sorry 'world hunger', | 
|  | 186 | someone else will have to solve you some other day). One specific | 
|  | 187 | complaint is that people perceive LLVM as being incapable of performing | 
|  | 188 | high-level language-specific optimization: LLVM "loses too much | 
|  | 189 | information". | 
|  | 190 |  | 
|  | 191 | Unfortunately, this is really not the place to give you a full and | 
|  | 192 | unified version of "Chris Lattner's theory of compiler design". Instead, | 
|  | 193 | I'll make a few observations: | 
|  | 194 |  | 
|  | 195 | First, you're right that LLVM does lose information. For example, as of | 
|  | 196 | this writing, there is no way to distinguish in the LLVM IR whether an | 
|  | 197 | SSA-value came from a C "int" or a C "long" on an ILP32 machine (other | 
|  | 198 | than debug info). Both get compiled down to an 'i32' value and the | 
|  | 199 | information about what it came from is lost. The more general issue | 
|  | 200 | here, is that the LLVM type system uses "structural equivalence" instead | 
|  | 201 | of "name equivalence". Another place this surprises people is if you | 
|  | 202 | have two types in a high-level language that have the same structure | 
|  | 203 | (e.g. two different structs that have a single int field): these types | 
|  | 204 | will compile down into a single LLVM type and it will be impossible to | 
|  | 205 | tell what it came from. | 
|  | 206 |  | 
|  | 207 | Second, while LLVM does lose information, LLVM is not a fixed target: we | 
|  | 208 | continue to enhance and improve it in many different ways. In addition | 
|  | 209 | to adding new features (LLVM did not always support exceptions or debug | 
|  | 210 | info), we also extend the IR to capture important information for | 
|  | 211 | optimization (e.g. whether an argument is sign or zero extended, | 
|  | 212 | information about pointers aliasing, etc). Many of the enhancements are | 
|  | 213 | user-driven: people want LLVM to include some specific feature, so they | 
|  | 214 | go ahead and extend it. | 
|  | 215 |  | 
|  | 216 | Third, it is *possible and easy* to add language-specific optimizations, | 
|  | 217 | and you have a number of choices in how to do it. As one trivial | 
|  | 218 | example, it is easy to add language-specific optimization passes that | 
|  | 219 | "know" things about code compiled for a language. In the case of the C | 
|  | 220 | family, there is an optimization pass that "knows" about the standard C | 
|  | 221 | library functions. If you call "exit(0)" in main(), it knows that it is | 
|  | 222 | safe to optimize that into "return 0;" because C specifies what the | 
|  | 223 | 'exit' function does. | 
|  | 224 |  | 
|  | 225 | In addition to simple library knowledge, it is possible to embed a | 
|  | 226 | variety of other language-specific information into the LLVM IR. If you | 
|  | 227 | have a specific need and run into a wall, please bring the topic up on | 
| Tanya Lattner | 0d28f80 | 2015-08-05 03:51:17 +0000 | [diff] [blame] | 228 | the llvm-dev list. At the very worst, you can always treat LLVM as if it | 
| Sean Silva | d7fb396 | 2012-12-05 00:26:32 +0000 | [diff] [blame] | 229 | were a "dumb code generator" and implement the high-level optimizations | 
|  | 230 | you desire in your front-end, on the language-specific AST. | 
|  | 231 |  | 
|  | 232 | Tips and Tricks | 
|  | 233 | =============== | 
|  | 234 |  | 
|  | 235 | There is a variety of useful tips and tricks that you come to know after | 
|  | 236 | working on/with LLVM that aren't obvious at first glance. Instead of | 
|  | 237 | letting everyone rediscover them, this section talks about some of these | 
|  | 238 | issues. | 
|  | 239 |  | 
|  | 240 | Implementing portable offsetof/sizeof | 
|  | 241 | ------------------------------------- | 
|  | 242 |  | 
|  | 243 | One interesting thing that comes up, if you are trying to keep the code | 
|  | 244 | generated by your compiler "target independent", is that you often need | 
|  | 245 | to know the size of some LLVM type or the offset of some field in an | 
|  | 246 | llvm structure. For example, you might need to pass the size of a type | 
|  | 247 | into a function that allocates memory. | 
|  | 248 |  | 
|  | 249 | Unfortunately, this can vary widely across targets: for example the | 
|  | 250 | width of a pointer is trivially target-specific. However, there is a | 
|  | 251 | `clever way to use the getelementptr | 
|  | 252 | instruction <http://nondot.org/sabre/LLVMNotes/SizeOf-OffsetOf-VariableSizedStructs.txt>`_ | 
|  | 253 | that allows you to compute this in a portable way. | 
|  | 254 |  | 
|  | 255 | Garbage Collected Stack Frames | 
|  | 256 | ------------------------------ | 
|  | 257 |  | 
|  | 258 | Some languages want to explicitly manage their stack frames, often so | 
|  | 259 | that they are garbage collected or to allow easy implementation of | 
|  | 260 | closures. There are often better ways to implement these features than | 
|  | 261 | explicit stack frames, but `LLVM does support | 
|  | 262 | them, <http://nondot.org/sabre/LLVMNotes/ExplicitlyManagedStackFrames.txt>`_ | 
|  | 263 | if you want. It requires your front-end to convert the code into | 
|  | 264 | `Continuation Passing | 
|  | 265 | Style <http://en.wikipedia.org/wiki/Continuation-passing_style>`_ and | 
|  | 266 | the use of tail calls (which LLVM also supports). | 
|  | 267 |  |