github.com/alexanius/gollvm12@v0.0.0-20230419200121-b152358b84f3/README.md (about) 1 2 3 # Gollvm 4 5 Gollvm is an LLVM-based Go compiler. It incorporates "gofrontend" (a Go language front end written in C++ and shared with GCCGO), a bridge component (which translates from gofrontend IR to LLVM IR), and a driver that sends the resulting IR through the LLVM back end. 6 7 Gollvm is set up to be a subproject within the LLVM tools directory, similar to 8 how things work for "clang" or "compiler-rt": you check out a copy of the LLVM 9 source tree, then within the LLVM tree you check out additional git repos. 10 11 12 # Table of contents <a name="toc"></a> 13 14 * [Building gollvm](#building) 15 * [Work area setup](#workarea) 16 * [Invoking cmake and ninja](#cmakeninja) 17 * [Installing gollvm](#installing) 18 * [Using an installed copy of gollvm](#using) 19 * [Information for gollvm developers](#developers) 20 21 [FAQ](#FAQ) 22 23 * [Where should I post questions about gollvm?](#wheretopostquestions) 24 * [Where should I file gollvm bugs?](#wheretofile) 25 * [How can I go about contributing to gollvm?](#contributing) 26 * [Is gollvm a replacement for the main Go compiler (gc)?](#replacegc) 27 * [Which architectures and operating systems are supported for gollvm?](#supported) 28 * [How does the gollvm runtime differ from the main Go runtime?](#runtimediffs) 29 * [Shared linkage is the default for gollvm. How do I build non-shared?](#buildstatic) 30 * [What command line options are supported for gollvm?](#cmdlineopts) 31 * [How do I see the LLVM IR generated by gollvm?](#seetheir) 32 * [What is the relationship between gollvm and gccgo?](#gollvmandgccgo) 33 * [Can I use FDO or Thin LTO with gollvm?](#thinltofdo) 34 * [Can I use the race detector?](#racedetector) 35 * [I am seeing "undefined symbol: `__get_cpuid_count`" from my gollvm install](#getcpuidcount_undefined) 36 37 # Building gollvm <a name="building"></a> 38 39 Gollvm is currently in development -- releases are not yet available for download. Instructions for building gollvm follow. 40 41 ## Setting up a gollvm work area <a name="workarea"></a> 42 43 To set up a work area for Gollvm, check out a copy of LLVM, the overlay the gollvm repo (and other associated dependencies) within the LLVM tools subdir, as follows: 44 45 ``` 46 // Here 'workarea' will contain a copy of the LLVM source tree and one or more build areas 47 % mkdir workarea 48 % cd workarea 49 50 // Sources 51 % git clone https://github.com/llvm/llvm-project.git 52 ... 53 % cd llvm-project/llvm/tools 54 % git clone https://go.googlesource.com/gollvm 55 ... 56 % cd gollvm 57 % git clone https://go.googlesource.com/gofrontend 58 ... 59 % cd libgo 60 % git clone https://github.com/libffi/libffi.git 61 ... 62 % git clone https://github.com/ianlancetaylor/libbacktrace.git 63 ... 64 % 65 ``` 66 67 ## Building gollvm with cmake and ninja <a name="cmakeninja"></a> 68 69 You'll need to have an up-to-date copy of cmake on your system (3.6 or later vintage) to build Gollvm, as well as a C/C++ compiler (V10.0 or later for Clang, or V6.0 or later of GCC), and a working copy of 'm4'. 70 71 Create a build directory (separate from the source tree) and run 'cmake' within the build area to set up for the build. Assuming that 'workarea' is the directory created as above: 72 73 ``` 74 % cd workarea 75 % mkdir build-debug 76 % cd build-debug 77 % cmake -DCMAKE_BUILD_TYPE=Debug -DLLVM_USE_LINKER=gold -G Ninja ../llvm-project/llvm 78 ... 79 % ninja gollvm 80 ... 81 % 82 ``` 83 84 This will build the various tools and libraries needed for Gollvm. To select a specific C/C++ compiler for the build, you can use the "-DCMAKE_C_COMPILER" and "-DCMAKE_CXX_COMPILER" options to select your desired C/C++ compiler when invoking cmake (details [here](https://gitlab.kitware.com/cmake/community/wikis/FAQ#how-do-i-use-a-different-compiler)). Use the "-DLLVM_USE_LINKER=<variant>" cmake variable to control which linker is selected to link the Gollvm compiler and tools (where variant is one of "bfd", "gold", "lld", etc). 85 86 The Gollvm compiler driver defaults to using the gold linker when linking Go programs. If some other linker is desired, this can be accomplished by passing "-DGOLLVM_DEFAULT_LINKER=<variant>" when running cmake. Note that this default can still be overridden on the command line using the "-fuse-ld" option. 87 88 Gollvm's cmake rules expect a valid value for the SHELL environment variable; if not set, a default shell of /bin/bash will be used. 89 90 ## Installing gollvm <a name="installing"></a> 91 92 A gollvm installation will contain 'llvm-goc' (the compiler driver), the libgo standard Go libraries, and the standard Go tools ("go", "vet", "cgo", etc). 93 94 The installation directory for gollvm needs to be specified when invoking cmake prior to the build: 95 96 ``` 97 % mkdir build.rel 98 % cd build.rel 99 % cmake -DCMAKE_INSTALL_PREFIX=/my/install/dir -DCMAKE_BUILD_TYPE=Release -DLLVM_USE_LINKER=gold -G Ninja ../llvm-project/llvm 100 101 // Build all of gollvm 102 % ninja gollvm 103 ... 104 105 // Install gollvm to "/my/install/dir" 106 % ninja install-gollvm 107 108 ``` 109 110 ## Using an installed copy of gollvm <a name="using"></a> 111 112 Programs build with the Gollvm Go compiler default to shared linkage, meaning that they need to pick up the Go runtime library via LD_LIBRARY_PATH: 113 114 ``` 115 // Root of Gollvm install is /tmp/gollvm-install 116 % export LD_LIBRARY_PATH=/tmp/gollvm-install/lib64 117 % export PATH=/tmp/gollvm-install/bin:$PATH 118 % go run himom.go 119 hi mom! 120 % 121 ``` 122 123 # Information for gollvm developers <a name="developers"></a> 124 125 ## Source code structure 126 127 Within \<workarea\>/llvm/tools/gollvm, the following directories are of interest: 128 129 .../llvm/tools/gollvm: 130 131 * contains rules to build third party libraries needed for gollvm, 132 along with common definitions for subdirs. 133 134 .../llvm/tools/gollvm/driver, 135 .../llvm/tools/gollvm/driver-main: 136 137 * contains build rules and source code for llvm-goc 138 139 .../llvm/tools/gollvm/gofrontend: 140 141 * source code for gofrontend and libgo (note: no cmake files here) 142 143 .../llvm/tools/gollvm/bridge: 144 145 * contains build rules for the libLLVMCppGoFrontEnd.a, a library that contains both the gofrontend code and the LLVM-specific middle layer (for example, the definition of the class Llvm_backend, which inherits from Backend). 146 147 .../llvm/tools/gollvm/libgo: 148 149 * build rules and supporting infrastructure to build Gollvm's copy of the Go runtime and standard packages. 150 151 .../llvm/tools/gollvm/unittests: 152 153 * source code for the unit tests 154 155 ## The llvm-goc program 156 157 The executable llvm-goc is the main compiler driver for gollvm; it functions as a compiler (consuming source for a Go package and producing an object file), an assembler, and/or a linker. While it is possible to build and run llvm-goc directly from the command line, in practice there is little point in doing this (better to build using "go build", which will invoke llvm-goc on your behalf. 158 159 ``` 160 // From within <workarea>/build.opt: 161 162 % ninja llvm-goc 163 ... 164 % cat micro.go 165 package foo 166 func Bar() int { 167 return 1 168 } 169 % ./bin/llvm-goc -fgo-pkgpath=foo -O3 -S -o micro.s micro.go 170 % 171 ``` 172 173 174 ## Building and running the unit tests 175 176 Here are instructions on building and running the unit tests for the middle layer: 177 178 ``` 179 // From within <workarea>/build.opt: 180 181 // Build unit test 182 % ninja GoBackendCoreTests 183 184 // Run a unit test 185 % ./tools/gollvm/unittests/BackendCore/GoBackendCoreTests 186 [==========] Running 10 tests from 2 test cases. 187 [----------] Global test environment set-up. 188 [----------] 9 tests from BackendCoreTests 189 [ RUN ] BackendCoreTests.MakeBackend 190 [ OK ] BackendCoreTests.MakeBackend (1 ms) 191 [ RUN ] BackendCoreTests.ScalarTypes 192 [ OK ] BackendCoreTests.ScalarTypes (0 ms) 193 [ RUN ] BackendCoreTests.StructTypes 194 [ OK ] BackendCoreTests.StructTypes (1 ms) 195 [ RUN ] BackendCoreTests.ComplexTypes 196 [ OK ] BackendCoreTests.ComplexTypes (0 ms) 197 [ RUN ] BackendCoreTests.FunctionTypes 198 [ OK ] BackendCoreTests.FunctionTypes (0 ms) 199 [ RUN ] BackendCoreTests.PlaceholderTypes 200 [ OK ] BackendCoreTests.PlaceholderTypes (0 ms) 201 [ RUN ] BackendCoreTests.ArrayTypes 202 [ OK ] BackendCoreTests.ArrayTypes (0 ms) 203 [ RUN ] BackendCoreTests.NamedTypes 204 [ OK ] BackendCoreTests.NamedTypes (0 ms) 205 [ RUN ] BackendCoreTests.TypeUtils 206 207 ... 208 209 [ PASSED ] 10 tests. 210 ``` 211 212 The unit tests currently work by instantiating an LLVM Backend instance and making backend method calls (to mimic what the frontend would do), then inspects the results to make sure they are as expected. Here is an example: 213 214 ``` 215 TEST(BackendCoreTests, ComplexTypes) { 216 LLVMContext C; 217 218 Type *ft = Type::getFloatTy(C); 219 Type *dt = Type::getDoubleTy(C); 220 221 std::unique_ptr<Backend> be(go_get_backend(C, gollvm::driver::CallingConvId::X86_64_SysV)); 222 Btype *c32 = be->complex_type(64); 223 ASSERT_TRUE(c32 != NULL); 224 ASSERT_EQ(c32->type(), mkTwoFieldLLvmStruct(C, ft, ft)); 225 Btype *c64 = be->complex_type(128); 226 ASSERT_TRUE(c64 != NULL); 227 ASSERT_EQ(c64->type(), mkTwoFieldLLvmStruct(C, dt, dt)); 228 } 229 ``` 230 231 The test above makes sure that the LLVM type we get as a result of calling Backend::complex_type() is kosher and matches up to expectations. 232 233 ## Building libgo (Go runtime and standard libraries) 234 235 To build the Go runtime and standard libraries, use the following: 236 237 ``` 238 // From within <workarea>/build.opt: 239 240 // Build Go runtime and standard libraries 241 % ninja libgo_all 242 243 ``` 244 245 This will compile static (\*.a) and dynamic (\*.so) versions of the library. 246 247 # FAQ <a name="FAQ"></a> 248 249 ## Where should I post questions about gollvm? <a name="wheretopostquestions"></a> 250 251 Please send questions about gollvm to the [golang-nuts](https://groups.google.com/d/forum/golang-nuts) mailing list. Posting questions to the issue tracker is generally not the right way to start discussions or get information. 252 253 ## Where should I file gollvm bugs? <a name="wheretofile"></a> 254 255 Please file an issue on the golang [issue tracker](https://github.com/golang/go/issues); please be sure to use "gollvm" somewhere in the headline. 256 257 ## How can I go about contributing to gollvm? <a name="contributing"></a> 258 259 Please see the Go project guidelines at [https://golang.org/doc/contribute.html](https://golang.org/doc/contribute.html). Changes to [https://go.googlesource.com/gollvm](https://go.googlesource.com/gollvm) can be made by any Go contributor; for changes to gofrontend see [the gccgo guidelines](https://golang.org/doc/gccgo_contribute.html). 260 261 ## Is gollvm a replacement for the main Go compiler? (gc) <a name="replacegc"></a> 262 263 Gollvm is not intended as a replacement for the main Go compiler -- the 264 expectation is that the bulk of users will want to continue to use the main Go 265 compiler due to its superior compilation speed, ease of use, broader 266 functionality, and higher-performance runtime. Gollvm is intended to provide a 267 Go compiler with a more powerful back end, enabling such benefits as better 268 inlining, vectorization, register allocation, etc. 269 270 ## Which architectures and operating systems are supported for gollvm? <a name="supported"></a> 271 272 Gollvm is currently supported only for x86_64 and aarch64 Linux. 273 274 ## How does the gollvm runtime differ from the main Go runtime? <a name="runtimediffs"></a> 275 276 The main Go runtime supports generation of accurate stack maps, which allows the 277 garbage collector to do precise stack scanning; gollvm does not yet support 278 stack map generation (note that we're actively working on fixing this), hence 279 for gollvm the garbage collector has to scan stacks conservatively (which can 280 lead to longer scan times and increased memory usage). The main Go runtime 281 compiles to a different calling convention, whereas Gollvm uses the standard 282 C/C++ calling convention. There are many other smaller differences as well. 283 284 ## Shared linkage is the default for gollvm. How do I build non-shared? <a name="buildstatic"></a> 285 286 Linking with "-static-libgo" will yield a binary that incorporates a full copy of the Go runtime. Example: 287 288 ``` 289 % go build -gccgoflags -static-libgo myprogram.go 290 ``` 291 292 Note that this will increase binary size. 293 294 ## What command line options are supported for gollvm? <a name="cmdlineopts"></a> 295 296 You can run 'llvm-goc -help' to see a full set of supported options. These can be passed to the compiler via '-gccgoflags' option. Example: 297 298 ``` 299 % go build -gccgoflags -fno-inline mumble.go 300 ``` 301 302 ## How do I see the LLVM IR generated by gollvm? <a name="seetheir"></a> 303 304 The 'llvm-goc' command supports the -emit-llvm flag, however passing this option 305 to a "go build" command is not practical, since the "go build" won't be 306 expecting the compiler to emit LLVM bitcode or assembly. 307 308 A better recipe is to run "go build" with "-x -work" to capture the commands 309 being executed, then rerun the llvm-goc command shown adding "-S -emit-llvm". 310 The resulting output will be an LLVM IR dump. Example: 311 312 ``` 313 % go build -work -x mypackage.go 1> transcript.txt 2>&1 314 % egrep '(WORK=|llvm-goc -c)' transcript.txt 315 WORK=/tmp/go-build887931787 316 /t/bin/llvm-goc -c -g -m64 -fdebug-prefix-map=$WORK=/tmp/go-build \ 317 -gno-record-gcc-switches -fgo-pkgpath=command-line-arguments \ 318 -fgo-relative-import-path=/mygopath/src/tmp -o $WORK/b001/_go_.o \ 319 -I $WORK/b001/_importcfgroot_ ./mypackage.go 320 % /t/bin/llvm-goc -c -g -m64 -fdebug-prefix-map=$WORK=/tmp/go-build \ 321 -gno-record-gcc-switches -fgo-pkgpath=command-line-arguments \ 322 -fgo-relative-import-path=/mygopath/src/tmp \ 323 -I $WORK/b001/_importcfgroot_ -o mypackage.ll -S -emit-llvm \ 324 ./mypackage.go 325 % ls -l mypackage.ll 326 ... 327 % 328 ``` 329 330 331 ## What is the relationship between gollvm and gccgo? <a name="gollvmandgccgo"></a> 332 333 Gollvm and gccgo share a common front end (gofrontend) and associated runtime 334 (libgo), however each uses a separate back end. When using "go build", the Go 335 command currently treats gollvm as an instance of gccgo (hence the need to pass 336 compile flags via "-gccgoflags"). This is expected to be temporary. 337 338 ## Can I use FDO or ThinLTO with gollvm? <a name="thinltofdo"></a> 339 340 There are plans to support FDO, AutoFDO, and ThinLTO for gollvm, however these features have not yet been implemented. 341 342 ## Can I use the race detector? <a name="racedetector"></a> 343 344 Gollvm does not support the Go race detector; please use the main Go compiler for this purpose. 345 346 ## I am seeing "undefined symbol: `__get_cpuid_count`" from my gollvm install <a name="getcpuidcount_undefined"> 347 348 The Gollvm build procedure requires an up-to-date C/C++ compiler; there is code in the gollvm runtime (libgo) that refers to functions defined in `<cpuid.h>`, however some older versions of clang (prior to 5.0) don't provide definitions for all the needed functions. If you encounter this problem, rerun `cmake` to configure your build to use a more recent version of Clang (or use GCC), as described above.