diff options
author | Ayke van Laethem <[email protected]> | 2023-03-06 17:28:41 +0100 |
---|---|---|
committer | Ron Evans <[email protected]> | 2023-03-08 07:09:46 +0100 |
commit | 71be24e4f9a47ef8e12078632f52e5e2605c7872 (patch) | |
tree | 8bf6c77005711ab90772bf85c8b9470a59f04be5 /transform | |
parent | 3701e6eac1774c96ef221de4644abbb4d1fa1f61 (diff) | |
download | tinygo-71be24e4f9a47ef8e12078632f52e5e2605c7872.tar.gz tinygo-71be24e4f9a47ef8e12078632f52e5e2605c7872.zip |
transform: add debug information to internal/task.stackSize
This has two benefits:
1. It attributes these bytes to the internal/task package (in
-size=full), instead of (unknown).
2. It makes it possible to print the stack sizes variable in GDB.
This is what it might look like in GDB:
(gdb) p 'internal/task.stackSizes'
$13 = {344, 120, 80, 2048, 360, 112, 80, 120, 2048, 2048}
Diffstat (limited to 'transform')
-rw-r--r-- | transform/stacksize.go | 42 | ||||
-rw-r--r-- | transform/testdata/stacksize.out.ll | 2 |
2 files changed, 43 insertions, 1 deletions
diff --git a/transform/stacksize.go b/transform/stacksize.go index 3e46a5794..2f7a6c1d6 100644 --- a/transform/stacksize.go +++ b/transform/stacksize.go @@ -1,8 +1,11 @@ package transform import ( + "path/filepath" + "github.com/tinygo-org/tinygo/compileopts" "github.com/tinygo-org/tinygo/compiler/llvmutil" + "github.com/tinygo-org/tinygo/goenv" "tinygo.org/x/go-llvm" ) @@ -47,10 +50,49 @@ func CreateStackSizeLoads(mod llvm.Module, config *compileopts.Config) []string stackSizesGlobal.SetSection(".tinygo_stacksizes") defaultStackSizes := make([]llvm.Value, len(functions)) defaultStackSize := llvm.ConstInt(functions[0].Type(), config.StackSize(), false) + alignment := targetData.ABITypeAlignment(functions[0].Type()) for i := range defaultStackSizes { defaultStackSizes[i] = defaultStackSize } stackSizesGlobal.SetInitializer(llvm.ConstArray(functions[0].Type(), defaultStackSizes)) + stackSizesGlobal.SetAlignment(alignment) + // TODO: make this a constant. For some reason, that incrases code size though. + if config.Debug() { + dibuilder := llvm.NewDIBuilder(mod) + dibuilder.CreateCompileUnit(llvm.DICompileUnit{ + Language: 0xb, // DW_LANG_C99 (0xc, off-by-one?) + File: "<unknown>", + Dir: "", + Producer: "TinyGo", + Optimized: true, + }) + ditype := dibuilder.CreateArrayType(llvm.DIArrayType{ + SizeInBits: targetData.TypeAllocSize(stackSizesGlobalType) * 8, + AlignInBits: uint32(alignment * 8), + ElementType: dibuilder.CreateBasicType(llvm.DIBasicType{ + Name: "uintptr", + SizeInBits: targetData.TypeAllocSize(functions[0].Type()) * 8, + Encoding: llvm.DW_ATE_unsigned, + }), + Subscripts: []llvm.DISubrange{ + { + Lo: 0, + Count: int64(len(functions)), + }, + }, + }) + diglobal := dibuilder.CreateGlobalVariableExpression(llvm.Metadata{}, llvm.DIGlobalVariableExpression{ + Name: "internal/task.stackSizes", + File: dibuilder.CreateFile("internal/task/task_stack.go", filepath.Join(goenv.Get("TINYGOROOT"), "src")), + Line: 1, + Type: ditype, + Expr: dibuilder.CreateExpression(nil), + }) + stackSizesGlobal.AddMetadata(0, diglobal) + + dibuilder.Finalize() + dibuilder.Destroy() + } // Add all relevant values to llvm.used (for LTO). llvmutil.AppendToGlobal(mod, "llvm.used", append([]llvm.Value{stackSizesGlobal}, functionValues...)...) diff --git a/transform/testdata/stacksize.out.ll b/transform/testdata/stacksize.out.ll index cea820ec1..574758154 100644 --- a/transform/testdata/stacksize.out.ll +++ b/transform/testdata/stacksize.out.ll @@ -1,7 +1,7 @@ target datalayout = "e-m:e-p:32:32-i64:64-v128:64:128-a:0:32-n32-S64" target triple = "armv7m-none-eabi" -@"internal/task.stackSizes" = global [1 x i32] [i32 1024], section ".tinygo_stacksizes" +@"internal/task.stackSizes" = global [1 x i32] [i32 1024], section ".tinygo_stacksizes", align 4 @llvm.used = appending global [2 x i8*] [i8* bitcast ([1 x i32]* @"internal/task.stackSizes" to i8*), i8* bitcast (void (i8*)* @"runtime.run$1$gowrapper" to i8*)] declare i32 @"internal/task.getGoroutineStackSize"(i32, i8*, i8*) |