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.
Этот коммит содержится в:
родитель
7c24925aa7
коммит
f63c389f1a
6 изменённых файлов: 23 добавлений и 22 удалений
|
@ -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, "")
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -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)
|
||||
}
|
||||
|
||||
|
|
4
compiler/testdata/goroutine-cortex-m-qemu.ll
предоставленный
4
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
|
||||
|
|
12
compiler/testdata/goroutine-wasm.ll
предоставленный
12
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
|
||||
|
|
4
compiler/testdata/string.ll
предоставленный
4
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
|
||||
|
|
Загрузка…
Создание таблицы
Сослаться в новой задаче