From 17433e5f2c91475e3fb87cb819cdd8d62ddbf7c8 Mon Sep 17 00:00:00 2001 From: "Arch D. Robison" Date: Tue, 16 Dec 2014 16:00:08 -0600 Subject: [PATCH] Add tips on working with LLVM. --- doc/devdocs/julia.rst | 1 + doc/devdocs/llvm.rst | 103 ++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 104 insertions(+) create mode 100644 doc/devdocs/llvm.rst diff --git a/doc/devdocs/julia.rst b/doc/devdocs/julia.rst index e7b7f13fe6b5b..ee9ed0b868783 100644 --- a/doc/devdocs/julia.rst +++ b/doc/devdocs/julia.rst @@ -13,3 +13,4 @@ meta subarrays sysimg + llvm diff --git a/doc/devdocs/llvm.rst b/doc/devdocs/llvm.rst new file mode 100644 index 0000000000000..c56e58b7a9692 --- /dev/null +++ b/doc/devdocs/llvm.rst @@ -0,0 +1,103 @@ +.. _devdocs-llvm: + +Working with LLVM +================= + +This is not a replacement for the LLVM documentation, but a collection +of tips for working on LLVM for Julia. + +Overview of Julia to LLVM Interface +----------------------------------- + +Julia statically links in LLVM by default. +Build with ``USE_LLVM_SHLIB=1`` to link dynamically. + +The code for lowering Julia AST to LLVM IR or interpreting it directly is in +directory ``src/``. + ++---------------------+-------------------------------------------------------------+ +|``builtins.c`` | Builtin functions | ++---------------------+-------------------------------------------------------------+ +|``ccall.cpp`` | Lowering ``ccall`` | ++---------------------+-------------------------------------------------------------+ +|``cgutils.cpp`` | Lowering utilities, notably for array and tuple accesses | ++---------------------+-------------------------------------------------------------+ +|``codegen.cpp`` | Top-level of code generation, pass list, lowering builtins | ++---------------------+-------------------------------------------------------------+ +|``debuginfo.cpp`` | Tracks debug information for JIT code | ++---------------------+-------------------------------------------------------------+ +|``disasm.cpp`` | Handles native object file and JIT code diassembly | ++---------------------+-------------------------------------------------------------+ +|``gf.c`` | Generic functions | ++---------------------+-------------------------------------------------------------+ +|``intrinsics.cpp`` | Lowering intrinsics | ++---------------------+-------------------------------------------------------------+ +|``llvm-simdloop.cpp``| Custom LLVM pass for ``@simd`` | ++---------------------+-------------------------------------------------------------+ +|``sys.c`` | I/O and operating system utility functions | ++---------------------+-------------------------------------------------------------+ + +Some of the `.cpp` files form a group that compile to a single object. + +The difference between an intrinsic and a builtin is that a builtin is a first class +function that can be used like any other Julia function. An intrinsic can operate +only on unboxed data, and therefore its arguments must be statically typed. + +Alias Analysis +^^^^^^^^^^^^^^ + +Julia currently uses LLVM's `Type Based Alias Analysis `_. +To find the comments that document the inclusion relationships, look for ``static MDNode*`` +in ``src/codegen.cpp``. + +The `-O` option enables LLVM's `Basic Alias Analysis `_. + +Building Julia with a different version of LLVM +----------------------------------------------- + +The default version of LLVM is specified in ``deps/Versions.make``. +You can override it in your ``Make.user`` by adding a line such as: + + ``LLVM_VER = 3.5.0`` + +Besides the LLVM release numerals, you can +also use ``LLVM_VER = svn`` to bulid against the latest development version +of LLVM. + +Passing options to LLVM +----------------------- + +You can pass options to LLVM using *debug* builds of Julia. To create a debug +build, run ``make debug``. The resulting executable is ``usr/bin/julia-debug``. +You can pass LLVM options to this executable via the environment variable ``JULIA_LLVM_ARGS``. +Here are example settings using ``bash`` syntax: + +* ``export JULIA_LLVM_ARGS = -print-after-all`` dumps IR after each pass. + +* ``export JULIA_LLVM_ARGS = -debug-only=loop-vectorize`` dumps LLVM `DEBUG(`...`)` + diagnostics for loop vectorizer *if* you built Julia with ``LLVM_ASSERTIONS=1``. + Otherwise you will get warnings about "Unknown command line argument". + Counter-intuitively, building Julia with ``LLVM_DEBUG=1`` is *not* enough to + dump ``DEBUG`` diagnostics from a pass. + +Improving LLVM optimizations for Julia +-------------------------------------- + +Improving LLVM code generation usually involves either changing Julia lowering +to be more friendly to LLVM's passes, or improving a pass. + +If you are planning to improve a pass, be sure to read the +`LLVM developer policy `_. +The best strategy is to create a code example in a form where you can use LLVM's +``opt`` tool to study it and the pass of interest in isolation. + +1. Create an example Julia code of interest. + +2. Use ``JULIA_LLVM_ARGS = -print-after-all`` to dump the IR. + +3. Pick out the IR at the point just before the pass of interest runs. + +4. Strip the debug metadata and fix up the TBAA metadata by hand. + +The last step is labor intensive. Suggestions on a better way would be appreciated. +