From f63c389f1aa9583fd425e9e781a0cf65c8afaa22 Mon Sep 17 00:00:00 2001 From: Ayke van Laethem Date: Fri, 29 Oct 2021 04:09:38 +0200 Subject: [PATCH] compiler: change symbol name for string and packed data constants This new symbol name format (package name + "$string" or "$pack" suffix) is easier to parse for analysis. --- compiler/compiler.go | 16 +++++++++------- compiler/llvm.go | 2 +- compiler/llvmutil/wordpack.go | 7 +++---- compiler/testdata/goroutine-cortex-m-qemu.ll | 4 ++-- compiler/testdata/goroutine-wasm.ll | 12 ++++++------ compiler/testdata/string.ll | 4 ++-- 6 files changed, 23 insertions(+), 22 deletions(-) diff --git a/compiler/compiler.go b/compiler/compiler.go index e908549d..5caf932d 100644 --- a/compiler/compiler.go +++ b/compiler/compiler.go @@ -83,6 +83,7 @@ type compilerContext struct { program *ssa.Program diagnostics []error astComments map[string]*ast.CommentGroup + pkg *types.Package runtimePkg *types.Package } @@ -253,6 +254,7 @@ func Sizes(machine llvm.TargetMachine) types.Sizes { // CompilePackage compiles a single package to a LLVM module. func CompilePackage(moduleName string, pkg *loader.Package, ssaPkg *ssa.Package, machine llvm.TargetMachine, config *Config, dumpSSA bool) (llvm.Module, []error) { c := newCompilerContext(moduleName, machine, config, dumpSSA) + c.pkg = pkg.Pkg c.runtimePkg = ssaPkg.Prog.ImportedPackage("runtime").Pkg c.program = ssaPkg.Prog @@ -1458,7 +1460,7 @@ func (b *builder) createFunctionCall(instr *ssa.CallCommon) (llvm.Value, error) func (b *builder) getValue(expr ssa.Value) llvm.Value { switch expr := expr.(type) { case *ssa.Const: - return b.createConst(b.info.linkName, expr) + return b.createConst(expr) case *ssa.Function: if b.getFunctionInfo(expr).exported { b.addError(expr.Pos(), "cannot use an exported function as value: "+expr.String()) @@ -2411,7 +2413,7 @@ func (b *builder) createBinOp(op token.Token, typ, ytyp types.Type, x, y llvm.Va } // createConst creates a LLVM constant value from a Go constant. -func (b *builder) createConst(prefix string, expr *ssa.Const) llvm.Value { +func (b *builder) createConst(expr *ssa.Const) llvm.Value { switch typ := expr.Type().Underlying().(type) { case *types.Basic: llvmType := b.getLLVMType(typ) @@ -2427,7 +2429,7 @@ func (b *builder) createConst(prefix string, expr *ssa.Const) llvm.Value { strLen := llvm.ConstInt(b.uintptrType, uint64(len(str)), false) var strPtr llvm.Value if str != "" { - objname := prefix + "$string" + objname := b.pkg.Path() + "$string" global := llvm.AddGlobal(b.mod, llvm.ArrayType(b.ctx.Int8Type(), len(str)), objname) global.SetInitializer(b.ctx.ConstString(str, false)) global.SetLinkage(llvm.InternalLinkage) @@ -2457,15 +2459,15 @@ func (b *builder) createConst(prefix string, expr *ssa.Const) llvm.Value { n, _ := constant.Float64Val(expr.Value) return llvm.ConstFloat(llvmType, n) } else if typ.Kind() == types.Complex64 { - r := b.createConst(prefix, ssa.NewConst(constant.Real(expr.Value), types.Typ[types.Float32])) - i := b.createConst(prefix, ssa.NewConst(constant.Imag(expr.Value), types.Typ[types.Float32])) + r := b.createConst(ssa.NewConst(constant.Real(expr.Value), types.Typ[types.Float32])) + i := b.createConst(ssa.NewConst(constant.Imag(expr.Value), types.Typ[types.Float32])) cplx := llvm.Undef(b.ctx.StructType([]llvm.Type{b.ctx.FloatType(), b.ctx.FloatType()}, false)) cplx = b.CreateInsertValue(cplx, r, 0, "") cplx = b.CreateInsertValue(cplx, i, 1, "") return cplx } else if typ.Kind() == types.Complex128 { - r := b.createConst(prefix, ssa.NewConst(constant.Real(expr.Value), types.Typ[types.Float64])) - i := b.createConst(prefix, ssa.NewConst(constant.Imag(expr.Value), types.Typ[types.Float64])) + r := b.createConst(ssa.NewConst(constant.Real(expr.Value), types.Typ[types.Float64])) + i := b.createConst(ssa.NewConst(constant.Imag(expr.Value), types.Typ[types.Float64])) cplx := llvm.Undef(b.ctx.StructType([]llvm.Type{b.ctx.DoubleType(), b.ctx.DoubleType()}, false)) cplx = b.CreateInsertValue(cplx, r, 0, "") cplx = b.CreateInsertValue(cplx, i, 1, "") diff --git a/compiler/llvm.go b/compiler/llvm.go index 17f642d7..9b5d40fc 100644 --- a/compiler/llvm.go +++ b/compiler/llvm.go @@ -34,7 +34,7 @@ func (b *builder) emitLifetimeEnd(ptr, size llvm.Value) { // bitcasts, or else allocates a value on the heap if it cannot be packed in the // pointer value directly. It returns the pointer with the packed data. func (b *builder) emitPointerPack(values []llvm.Value) llvm.Value { - return llvmutil.EmitPointerPack(b.Builder, b.mod, b.NeedsStackObjects, values) + return llvmutil.EmitPointerPack(b.Builder, b.mod, b.pkg.Path(), b.NeedsStackObjects, values) } // emitPointerUnpack extracts a list of values packed using emitPointerPack. diff --git a/compiler/llvmutil/wordpack.go b/compiler/llvmutil/wordpack.go index e2b6c7d9..3783fb9b 100644 --- a/compiler/llvmutil/wordpack.go +++ b/compiler/llvmutil/wordpack.go @@ -12,7 +12,7 @@ import ( // bitcasts, or else allocates a value on the heap if it cannot be packed in the // pointer value directly. It returns the pointer with the packed data. // If the values are all constants, they are be stored in a constant global and deduplicated. -func EmitPointerPack(builder llvm.Builder, mod llvm.Module, needsStackObjects bool, values []llvm.Value) llvm.Value { +func EmitPointerPack(builder llvm.Builder, mod llvm.Module, prefix string, needsStackObjects bool, values []llvm.Value) llvm.Value { ctx := mod.Context() targetData := llvm.NewTargetData(mod.DataLayout()) i8ptrType := llvm.PointerType(mod.Context().Int8Type(), 0) @@ -83,12 +83,11 @@ func EmitPointerPack(builder llvm.Builder, mod llvm.Module, needsStackObjects bo if constant { // The data is known at compile time, so store it in a constant global. // The global address is marked as unnamed, which allows LLVM to merge duplicates. - funcName := builder.GetInsertBlock().Parent().Name() - global := llvm.AddGlobal(mod, packedType, funcName+"$pack") + global := llvm.AddGlobal(mod, packedType, prefix+"$pack") global.SetInitializer(ctx.ConstStruct(values, false)) global.SetGlobalConstant(true) global.SetUnnamedAddr(true) - global.SetLinkage(llvm.PrivateLinkage) + global.SetLinkage(llvm.InternalLinkage) return llvm.ConstBitCast(global, i8ptrType) } diff --git a/compiler/testdata/goroutine-cortex-m-qemu.ll b/compiler/testdata/goroutine-cortex-m-qemu.ll index 079d47f6..279ecc5a 100644 --- a/compiler/testdata/goroutine-cortex-m-qemu.ll +++ b/compiler/testdata/goroutine-cortex-m-qemu.ll @@ -9,7 +9,7 @@ target triple = "armv7m-unknown-unknown-eabi" %"internal/task.state" = type { i32, i32* } %runtime.chanSelectState = type { %runtime.channel*, i8* } -@"main.startInterfaceMethod$string" = internal unnamed_addr constant [4 x i8] c"test", align 1 +@"main$string" = internal unnamed_addr constant [4 x i8] c"test", align 1 declare noalias nonnull i8* @runtime.alloc(i32, i8*, i8*, i8*) @@ -168,7 +168,7 @@ entry: store i8* %itf.value, i8** %1, align 4 %2 = getelementptr inbounds i8, i8* %0, i32 4 %.repack = bitcast i8* %2 to i8** - store i8* getelementptr inbounds ([4 x i8], [4 x i8]* @"main.startInterfaceMethod$string", i32 0, i32 0), i8** %.repack, align 4 + store i8* getelementptr inbounds ([4 x i8], [4 x i8]* @"main$string", i32 0, i32 0), i8** %.repack, align 4 %.repack1 = getelementptr inbounds i8, i8* %0, i32 8 %3 = bitcast i8* %.repack1 to i32* store i32 4, i32* %3, align 4 diff --git a/compiler/testdata/goroutine-wasm.ll b/compiler/testdata/goroutine-wasm.ll index 553eb1cc..6f308247 100644 --- a/compiler/testdata/goroutine-wasm.ll +++ b/compiler/testdata/goroutine-wasm.ll @@ -10,11 +10,11 @@ target triple = "wasm32-unknown-wasi" %"internal/task.state" = type { i8* } %runtime.chanSelectState = type { %runtime.channel*, i8* } -@"main.regularFunctionGoroutine$pack" = private unnamed_addr constant { i32, i8* } { i32 5, i8* undef } -@"main.inlineFunctionGoroutine$pack" = private unnamed_addr constant { i32, i8* } { i32 5, i8* undef } +@"main$pack" = internal unnamed_addr constant { i32, i8* } { i32 5, i8* undef } +@"main$pack.1" = internal unnamed_addr constant { i32, i8* } { i32 5, i8* undef } @"reflect/types.funcid:func:{basic:int}{}" = external constant i8 @"main.closureFunctionGoroutine$1$withSignature" = linkonce_odr constant %runtime.funcValueWithSignature { i32 ptrtoint (void (i32, i8*, i8*)* @"main.closureFunctionGoroutine$1" to i32), i8* @"reflect/types.funcid:func:{basic:int}{}" } -@"main.startInterfaceMethod$string" = internal unnamed_addr constant [4 x i8] c"test", align 1 +@"main$string" = internal unnamed_addr constant [4 x i8] c"test", align 1 declare noalias nonnull i8* @runtime.alloc(i32, i8*, i8*, i8*) @@ -27,7 +27,7 @@ entry: ; Function Attrs: nounwind define hidden void @main.regularFunctionGoroutine(i8* %context, i8* %parentHandle) unnamed_addr #0 { entry: - call void @"internal/task.start"(i32 ptrtoint (void (i32, i8*, i8*)* @main.regularFunction to i32), i8* bitcast ({ i32, i8* }* @"main.regularFunctionGoroutine$pack" to i8*), i32 undef, i8* undef, i8* null) #0 + call void @"internal/task.start"(i32 ptrtoint (void (i32, i8*, i8*)* @main.regularFunction to i32), i8* bitcast ({ i32, i8* }* @"main$pack" to i8*), i32 undef, i8* undef, i8* null) #0 ret void } @@ -38,7 +38,7 @@ declare void @"internal/task.start"(i32, i8*, i32, i8*, i8*) ; Function Attrs: nounwind define hidden void @main.inlineFunctionGoroutine(i8* %context, i8* %parentHandle) unnamed_addr #0 { entry: - call void @"internal/task.start"(i32 ptrtoint (void (i32, i8*, i8*)* @"main.inlineFunctionGoroutine$1" to i32), i8* bitcast ({ i32, i8* }* @"main.inlineFunctionGoroutine$pack" to i8*), i32 undef, i8* undef, i8* null) #0 + call void @"internal/task.start"(i32 ptrtoint (void (i32, i8*, i8*)* @"main.inlineFunctionGoroutine$1" to i32), i8* bitcast ({ i32, i8* }* @"main$pack.1" to i8*), i32 undef, i8* undef, i8* null) #0 ret void } @@ -124,7 +124,7 @@ entry: store i8* %itf.value, i8** %1, align 4 %2 = getelementptr inbounds i8, i8* %0, i32 4 %.repack = bitcast i8* %2 to i8** - store i8* getelementptr inbounds ([4 x i8], [4 x i8]* @"main.startInterfaceMethod$string", i32 0, i32 0), i8** %.repack, align 4 + store i8* getelementptr inbounds ([4 x i8], [4 x i8]* @"main$string", i32 0, i32 0), i8** %.repack, align 4 %.repack1 = getelementptr inbounds i8, i8* %0, i32 8 %3 = bitcast i8* %.repack1 to i32* store i32 4, i32* %3, align 4 diff --git a/compiler/testdata/string.ll b/compiler/testdata/string.ll index cdc8619a..75812865 100644 --- a/compiler/testdata/string.ll +++ b/compiler/testdata/string.ll @@ -5,7 +5,7 @@ target triple = "wasm32-unknown-wasi" %runtime._string = type { i8*, i32 } -@"main.someString$string" = internal unnamed_addr constant [3 x i8] c"foo", align 1 +@"main$string" = internal unnamed_addr constant [3 x i8] c"foo", align 1 declare noalias nonnull i8* @runtime.alloc(i32, i8*, i8*, i8*) @@ -18,7 +18,7 @@ entry: ; Function Attrs: nounwind define hidden %runtime._string @main.someString(i8* %context, i8* %parentHandle) unnamed_addr #0 { entry: - ret %runtime._string { i8* getelementptr inbounds ([3 x i8], [3 x i8]* @"main.someString$string", i32 0, i32 0), i32 3 } + ret %runtime._string { i8* getelementptr inbounds ([3 x i8], [3 x i8]* @"main$string", i32 0, i32 0), i32 3 } } ; Function Attrs: nounwind