aboutsummaryrefslogtreecommitdiff
path: root/src/cmd/internal/obj/x86/a.out.go
diff options
context:
space:
mode:
authorHeschi Kreinick <heschi@google.com>2017-07-21 18:30:19 -0400
committerHeschi Kreinick <heschi@google.com>2017-07-27 20:19:44 +0000
commit4c54a047c6ea88dd77416a3b878f6935165f6129 (patch)
tree8b680905cd4b42a16861b80b5f9f32c203315d51 /src/cmd/internal/obj/x86/a.out.go
parentcd702b171c90be4b410d19bd93d5ea2899eaa809 (diff)
downloadgo-4c54a047c6ea88dd77416a3b878f6935165f6129.tar.gz
go-4c54a047c6ea88dd77416a3b878f6935165f6129.zip
[dev.debug] cmd/compile: better DWARF with optimizations ondev.debug
Debuggers use DWARF information to find local variables on the stack and in registers. Prior to this CL, the DWARF information for functions claimed that all variables were on the stack at all times. That's incorrect when optimizations are enabled, and results in debuggers showing data that is out of date or complete gibberish. After this CL, the compiler is capable of representing variable locations more accurately, and attempts to do so. Due to limitations of the SSA backend, it's not possible to be completely correct. There are a number of problems in the current design. One of the easier to understand is that variable names currently must be attached to an SSA value, but not all assignments in the source code actually result in machine code. For example: type myint int var a int b := myint(int) and b := (*uint64)(unsafe.Pointer(a)) don't generate machine code because the underlying representation is the same, so the correct value of b will not be set when the user would expect. Generating the more precise debug information is behind a flag, dwarflocationlists. Because of the issues described above, setting the flag may not make the debugging experience much better, and may actually make it worse in cases where the variable actually is on the stack and the more complicated analysis doesn't realize it. A number of changes are included: - Add a new pseudo-instruction, RegKill, which indicates that the value in the register has been clobbered. - Adjust regalloc to emit RegKills in the right places. Significantly, this means that phis are mixed with StoreReg and RegKills after regalloc. - Track variable decomposition in ssa.LocalSlots. - After the SSA backend is done, analyze the result and build location lists for each LocalSlot. - After assembly is done, update the location lists with the assembled PC offsets, recompose variables, and build DWARF location lists. Emit the list as a new linker symbol, one per function. - In the linker, aggregate the location lists into a .debug_loc section. TODO: - currently disabled for non-X86/AMD64 because there are no data tables. go build -toolexec 'toolstash -cmp' -a std succeeds. With -dwarflocationlists false: before: f02812195637909ff675782c0b46836a8ff01976 after: 06f61e8112a42ac34fb80e0c818b3cdb84a5e7ec benchstat -geomean /tmp/220352263 /tmp/621364410 completed 15 of 15, estimated time remaining 0s (eta 3:52PM) name old time/op new time/op delta Template 199ms ± 3% 198ms ± 2% ~ (p=0.400 n=15+14) Unicode 96.6ms ± 5% 96.4ms ± 5% ~ (p=0.838 n=15+15) GoTypes 653ms ± 2% 647ms ± 2% ~ (p=0.102 n=15+14) Flate 133ms ± 6% 129ms ± 3% -2.62% (p=0.041 n=15+15) GoParser 164ms ± 5% 159ms ± 3% -3.05% (p=0.000 n=15+15) Reflect 428ms ± 4% 422ms ± 3% ~ (p=0.156 n=15+13) Tar 123ms ±10% 124ms ± 8% ~ (p=0.461 n=15+15) XML 228ms ± 3% 224ms ± 3% -1.57% (p=0.045 n=15+15) [Geo mean] 206ms 377ms +82.86% name old user-time/op new user-time/op delta Template 292ms ±10% 301ms ±12% ~ (p=0.189 n=15+15) Unicode 166ms ±37% 158ms ±14% ~ (p=0.418 n=15+14) GoTypes 962ms ± 6% 963ms ± 7% ~ (p=0.976 n=15+15) Flate 207ms ±19% 200ms ±14% ~ (p=0.345 n=14+15) GoParser 246ms ±22% 240ms ±15% ~ (p=0.587 n=15+15) Reflect 611ms ±13% 587ms ±14% ~ (p=0.085 n=15+13) Tar 211ms ±12% 217ms ±14% ~ (p=0.355 n=14+15) XML 335ms ±15% 320ms ±18% ~ (p=0.169 n=15+15) [Geo mean] 317ms 583ms +83.72% name old alloc/op new alloc/op delta Template 40.2MB ± 0% 40.2MB ± 0% -0.15% (p=0.000 n=14+15) Unicode 29.2MB ± 0% 29.3MB ± 0% ~ (p=0.624 n=15+15) GoTypes 114MB ± 0% 114MB ± 0% -0.15% (p=0.000 n=15+14) Flate 25.7MB ± 0% 25.6MB ± 0% -0.18% (p=0.000 n=13+15) GoParser 32.2MB ± 0% 32.2MB ± 0% -0.14% (p=0.003 n=15+15) Reflect 77.8MB ± 0% 77.9MB ± 0% ~ (p=0.061 n=15+15) Tar 27.1MB ± 0% 27.0MB ± 0% -0.11% (p=0.029 n=15+15) XML 42.7MB ± 0% 42.5MB ± 0% -0.29% (p=0.000 n=15+15) [Geo mean] 42.1MB 75.0MB +78.05% name old allocs/op new allocs/op delta Template 402k ± 1% 398k ± 0% -0.91% (p=0.000 n=15+15) Unicode 344k ± 1% 344k ± 0% ~ (p=0.715 n=15+14) GoTypes 1.18M ± 0% 1.17M ± 0% -0.91% (p=0.000 n=15+14) Flate 243k ± 0% 240k ± 1% -1.05% (p=0.000 n=13+15) GoParser 327k ± 1% 324k ± 1% -0.96% (p=0.000 n=15+15) Reflect 984k ± 1% 982k ± 0% ~ (p=0.050 n=15+15) Tar 261k ± 1% 259k ± 1% -0.77% (p=0.000 n=15+15) XML 411k ± 0% 404k ± 1% -1.55% (p=0.000 n=15+15) [Geo mean] 439k 755k +72.01% name old text-bytes new text-bytes delta HelloSize 694kB ± 0% 694kB ± 0% -0.00% (p=0.000 n=15+15) name old data-bytes new data-bytes delta HelloSize 5.55kB ± 0% 5.55kB ± 0% ~ (all equal) name old bss-bytes new bss-bytes delta HelloSize 133kB ± 0% 133kB ± 0% ~ (all equal) name old exe-bytes new exe-bytes delta HelloSize 1.04MB ± 0% 1.04MB ± 0% ~ (all equal) Change-Id: I991fc553ef175db46bb23b2128317bbd48de70d8 Reviewed-on: https://go-review.googlesource.com/41770 Reviewed-by: Josh Bleecher Snyder <josharian@gmail.com>
Diffstat (limited to 'src/cmd/internal/obj/x86/a.out.go')
-rw-r--r--src/cmd/internal/obj/x86/a.out.go117
1 files changed, 117 insertions, 0 deletions
diff --git a/src/cmd/internal/obj/x86/a.out.go b/src/cmd/internal/obj/x86/a.out.go
index 04f9ef68a4..92d358ba4e 100644
--- a/src/cmd/internal/obj/x86/a.out.go
+++ b/src/cmd/internal/obj/x86/a.out.go
@@ -1006,3 +1006,120 @@ const (
T_64 = 1 << 6
T_GOTYPE = 1 << 7
)
+
+// https://www.uclibc.org/docs/psABI-x86_64.pdf, figure 3.36
+var AMD64DWARFRegisters = map[int16]int16{
+ REG_AX: 0,
+ REG_DX: 1,
+ REG_CX: 2,
+ REG_BX: 3,
+ REG_SI: 4,
+ REG_DI: 5,
+ REG_BP: 6,
+ REG_SP: 7,
+ REG_R8: 8,
+ REG_R9: 9,
+ REG_R10: 10,
+ REG_R11: 11,
+ REG_R12: 12,
+ REG_R13: 13,
+ REG_R14: 14,
+ REG_R15: 15,
+ // 16 is "Return Address RA", whatever that is.
+ // XMM registers. %xmmN => XN.
+ REG_X0: 17,
+ REG_X1: 18,
+ REG_X2: 19,
+ REG_X3: 20,
+ REG_X4: 21,
+ REG_X5: 22,
+ REG_X6: 23,
+ REG_X7: 24,
+ REG_X8: 25,
+ REG_X9: 26,
+ REG_X10: 27,
+ REG_X11: 28,
+ REG_X12: 29,
+ REG_X13: 30,
+ REG_X14: 31,
+ REG_X15: 32,
+ // ST registers. %stN => FN.
+ REG_F0: 33,
+ REG_F1: 34,
+ REG_F2: 35,
+ REG_F3: 36,
+ REG_F4: 37,
+ REG_F5: 38,
+ REG_F6: 39,
+ REG_F7: 40,
+ // MMX registers. %mmN => MN.
+ REG_M0: 41,
+ REG_M1: 42,
+ REG_M2: 43,
+ REG_M3: 44,
+ REG_M4: 45,
+ REG_M5: 46,
+ REG_M6: 47,
+ REG_M7: 48,
+ // 48 is flags, which doesn't have a name.
+ REG_ES: 50,
+ REG_CS: 51,
+ REG_SS: 52,
+ REG_DS: 53,
+ REG_FS: 54,
+ REG_GS: 55,
+ // 58 and 59 are {fs,gs}base, which don't have names.
+ REG_TR: 62,
+ REG_LDTR: 63,
+ // 64-66 are mxcsr, fcw, fsw, which don't have names.
+}
+
+// https://www.uclibc.org/docs/psABI-i386.pdf, table 2.14
+var X86DWARFRegisters = map[int16]int16{
+ REG_AX: 0,
+ REG_CX: 1,
+ REG_DX: 2,
+ REG_BX: 3,
+ REG_SP: 4,
+ REG_BP: 5,
+ REG_SI: 6,
+ REG_DI: 7,
+ // 8 is "Return Address RA", whatever that is.
+ // 9 is flags, which doesn't have a name.
+ // ST registers. %stN => FN.
+ REG_F0: 11,
+ REG_F1: 12,
+ REG_F2: 13,
+ REG_F3: 14,
+ REG_F4: 15,
+ REG_F5: 16,
+ REG_F6: 17,
+ REG_F7: 18,
+ // XMM registers. %xmmN => XN.
+ REG_X0: 21,
+ REG_X1: 22,
+ REG_X2: 23,
+ REG_X3: 24,
+ REG_X4: 25,
+ REG_X5: 26,
+ REG_X6: 27,
+ REG_X7: 28,
+ // MMX registers. %mmN => MN.
+ REG_M0: 29,
+ REG_M1: 30,
+ REG_M2: 31,
+ REG_M3: 32,
+ REG_M4: 33,
+ REG_M5: 34,
+ REG_M6: 35,
+ REG_M7: 36,
+ // 39 is mxcsr, which doesn't have a name.
+ REG_ES: 40,
+ REG_CS: 41,
+ REG_SS: 42,
+ REG_DS: 43,
+ REG_FS: 44,
+ REG_GS: 45,
+ REG_TR: 48,
+ REG_LDTR: 49,
+}