Go toolchain internals and implementation based on arm64

A toolchain is a package composed of the compiler and ancillary tools, libraries and runtime for a language which together allow you to build and run code written in that language. • gc: evolved from the Plan 9 toolchain and includes its own compiler, assembler, linker and tools, as well as the Go runtime and standard library. • gccgo: extends the gcc project to support Go. • llgo: built on top of the LLVM compiler infrastructure.
展开查看详情

1.

2.Go toolchain overview A toolchain is a package composed of the compiler and ancillary tools, libraries and runtime for a language which together allow you to build and run code written in that language. • gc: evolved from the Plan 9 toolchain and includes its own compiler, assembler, linker and tools, as well as the Go runtime and standard library. • gccgo: extends the gcc project to support Go. • llgo: built on top of the LLVM compiler infrastructure. 2 © 2018 Arm Limited

3.Go toolchain example $go build -x helloworld.go …… /golang/pkg/tool/linux_arm64/compile -o $WORK/b001/_pkg_.a -trimpath $WORK/b001 -p main -complete -buildid Lz0Z4IaaV-BMteKblcuy/Lz0Z4IaaV-BMteKblcuy -D _/golang/test -importcfg $WORK/b001/importcfg -pack -c=4 ./helloworld.go /golang/pkg/tool/linux_arm64/buildid -w $WORK/b001/_pkg_.a # internal …… /golang/pkg/tool/linux_arm64/link -o $WORK/b001/exe/a.out -importcfg $WORK/b001/importcfg.link - buildmode=exe -buildid=C4PaIvbSKZNsCh5tSi2r/Lz0Z4IaaV-BMteKblcuy/fOp- Rk_DpGJ5cJq23wER/C4PaIvbSKZNsCh5tSi2r -extld=gcc $WORK/b001/_pkg_.a /golang/pkg/tool/linux_arm64/buildid -w $WORK/b001/exe/a.out # internal mv $WORK/b001/exe/a.out helloworld 3 © 2018 Arm Limited

4.Go toolchain workflow $ go tool *.go compile $WORK/b001/_pkg_.a addr2line api asm buildid cgo compile *.s asm *.o pack runtime=$WORK/b002/_pkg_.a cover dist link helloworld doc fix link internal/bytealg=$WORK/b003/_pkg_.a nm objdump pack pprof …… test2json trace vet 4 © 2018 Arm Limited

5.Compile © 2018 Arm Limited

6.Go compiler overview GCC LLVM 6 © 2018 Arm Limited

7.Front end • Syntax check • Type check • Dead code elimination • Inline • Escape analysis • Declared and not used check • Rewrite • Instrument 7 © 2018 Arm Limited

8.Middle end Machine-independent Passes Options providing insight into compiler decisions: • -d=ssa/<phase>/stats • -m 8 © 2018 Arm Limited

9.Machine-independent optimization example Div64 Sub64 Rsh64x64 Rsh64x64 Arg {a} Const64 [7] Hmul64 Const64 [1] Const64 Arg {a} Const64 [63] [5270498306774157605] a/7 (((a* 5270498306774157605)>>64)>>1)-(a>>63) 9 © 2018 Arm Limited

10.Back end Machine-dependent Passes 10 © 2018 Arm Limited

11.Convert to machine-dependent ops Example for arm64 Before After 410 Div <T> 428 Div <T> 411 b1: 429 b1: 412 v1 = InitMem <mem> 430 v1 = InitMem <mem> 413 v2 = SP <uintptr> 431 v2 = SP <uintptr> 414 v5 = Addr <*int64> {~r1} v2 433 v6 = Arg <int64> {a} 415 v6 = Arg <int64> {a} 434 v10 = VarDef <mem> {~r1} v1 416 v10 = VarDef <mem> {~r1} v1 435 v3 = MOVDconst <uint64> [5270498306774157605] 417 v3 = Const64 <uint64> [5270498306774157605] 443 v4 = MULH <int64> v3 v6 418 v12 = Const64 <uint64> [1] 444 v7 = SRAconst <int64> [1] v4 419 v14 = Const64 <uint64> [63] 445 v9 = SUBshiftRA <int64> [63] v7 v6 420 v4 = Hmul64 <int64> v3 v6 446 v11 = MOVDstore <mem> {~r1} v2 v9 v10 421 v13 = Rsh64x64 <int64> v6 v14 447 Ret v11 422 v7 = Rsh64x64 <int64> v4 v12 423 v9 = Sub64 <int64> v7 v13 424 v11 = Store <mem> {int64} v5 v9 v10 425 Ret v11 11 © 2018 Arm Limited

12.Generate Prog Prog describes a single “machine” instruction 722 00000 (3) TEXT "".Div(SB) …… 725 v19 00003 (4) MOVD $5270498306774157605, R0 726 v18 00004 (4) MOVD "".a(RSP), R1 727 v4 00005 (4) SMULH R1, R0, R0 728 v7 00006 (4) ASR $1, R0, R0 729 v9 00007 (4) SUB R1->63, R0, R0 730 v11 00008 (4) MOVD R0, "".~r1+8(RSP) 731 b1 00009 (4) RET 732 00010 (?) END 12 © 2018 Arm Limited

13.Asm © 2018 Arm Limited

14.Go assembler overview compile Flushplist WriteObjFile goobj Magic header asm Parse linkpatch Version Arch.Progedit Autolib lex Arch.Preprocess Symbol references operand Arch.Assemble Lengths linkpcln Data block pseudo populateDWARF Symbols instruction Magic footer 14 © 2018 Arm Limited

15.Go arm64 assembly example 1 // func Add(a, b int) int 2 TEXT ·Add(SB),$0-24 Semi-abstract instruction set 3 MOVD arg1+0(FP), R0 4 MOVD arg2+8(FP), R1 5 ADD R1, R0, R0 6 MOVD R0, ret+16(FP) 7 RET 15 © 2018 Arm Limited

16.Goobj ELF 16 © 2018 Arm Limited

17.Link © 2018 Arm Limited

18.Go link overview _/golang/test (testmain)=$WORK/b001/_pkg_.a runtime=$WORK/b002/_pkg_.a runtime/cgo=$WORK/b008/_pkg_.a compile internal internal/bytealg=$WORK/b003/_pkg_.a Go link a.out runtime/internal/atomic=$WORK/b006/_pkg_.a external runtime/internal/sys=$WORK/b007/_pkg_.a cgo $CC a.out internal/cpu=$WORK/b004/_pkg_.a …… C _x001.o $CC _x002.o _/golang/test =$WORK/b048/_pkg_.a _x003.o 18 © 2018 Arm Limited

19.Go link workflow 1. Load package libraries and objects (including host objects) 2. Determine link mode 3. Mark all reachable symbols 4. Prepare ELF symbols (e.g set up PLT) 5. Assign addresses to text 6. Reorganize Go meta data (pcln, functab, type and …) 7. Handle relocations of host objects (if internal link) 8. Assign addresses to data 9. Generate DWARF (set up the per-compilation unit part of the DIE tree) 10. Resolve relocations (target dependent) 11. Write out ELF (code, data, table, header and …) 12. Emit relocations for host link (if external link) 13. Check undefined symbols 14. Invoke host link to generate output (if external link) 15. Invoke host ar to generate output (if C Archive) 19 © 2018 Arm Limited

20.Others © 2018 Arm Limited

21.Some interesting topics • VGo: Go += Package Versioning • WebAssembly architecture • Safe-points everywhere • Register-based calling convention • Mid-stack inlining • …… 21 © 2018 Arm Limited

22. Thank You! Danke! Merci! ! ! Gracias! Kiitos! 감사합니다 ध"यवाद 22 © 2018 Arm Limited