llgo/ssa: pkg.NewFunc bugfix
This commit is contained in:
@@ -13,7 +13,7 @@ type Foo struct {
|
||||
|
||||
var format = [...]int8{'H', 'e', 'l', 'l', 'o', ' ', '%', 'd', '\n', 0}
|
||||
|
||||
func (p *Foo) Print() {
|
||||
func (p Foo) Print() {
|
||||
if p.ok {
|
||||
printf(&format[0], p.A)
|
||||
}
|
||||
|
||||
@@ -6,22 +6,32 @@ source_filename = "main"
|
||||
@main.format = global ptr null
|
||||
@"main.init$guard" = global ptr null
|
||||
|
||||
define void @"(*main.Foo).Print"(ptr %0) {
|
||||
define void @"(main.Foo).Print"(%main.Foo %0) {
|
||||
_llgo_0:
|
||||
%1 = getelementptr inbounds %main.Foo, ptr %0, i32 0, i32 1
|
||||
%2 = load i1, ptr %1, align 1
|
||||
br i1 %2, label %_llgo_1, label %_llgo_2
|
||||
%1 = alloca %main.Foo, align 8
|
||||
store %main.Foo %0, ptr %1, align 4
|
||||
%2 = getelementptr inbounds %main.Foo, ptr %1, i32 0, i32 1
|
||||
%3 = load i1, ptr %2, align 1
|
||||
br i1 %3, label %_llgo_1, label %_llgo_2
|
||||
|
||||
_llgo_1: ; preds = %_llgo_0
|
||||
%3 = getelementptr inbounds %main.Foo, ptr %0, i32 0, i32 0
|
||||
%4 = load i32, ptr %3, align 4
|
||||
call void (ptr, ...) @printf(ptr @main.format, i32 %4)
|
||||
%4 = alloca %main.Foo, align 8
|
||||
%5 = getelementptr inbounds %main.Foo, ptr %4, i32 0, i32 0
|
||||
%6 = load i32, ptr %5, align 4
|
||||
call void (ptr, ...) @printf(ptr @main.format, i32 %6)
|
||||
br label %_llgo_2
|
||||
|
||||
_llgo_2: ; preds = %_llgo_1, %_llgo_0
|
||||
ret void
|
||||
}
|
||||
|
||||
define void @"(*main.Foo).Print"(ptr %0) {
|
||||
_llgo_0:
|
||||
%1 = load %main.Foo, ptr %0, align 4
|
||||
call void @"(main.Foo).Print"(%main.Foo %1)
|
||||
ret void
|
||||
}
|
||||
|
||||
define void @main.init() {
|
||||
_llgo_0:
|
||||
%0 = load i1, ptr @"main.init$guard", align 1
|
||||
@@ -53,7 +63,8 @@ _llgo_0:
|
||||
%2 = getelementptr inbounds %main.Foo, ptr %0, i32 0, i32 1
|
||||
store i32 100, ptr %1, align 4
|
||||
store i1 true, ptr %2, align 1
|
||||
call void @"(*main.Foo).Print"(ptr %0)
|
||||
%3 = load %main.Foo, ptr %0, align 4
|
||||
call void @"(main.Foo).Print"(%main.Foo %3)
|
||||
ret void
|
||||
}
|
||||
|
||||
|
||||
@@ -46,7 +46,7 @@ _llgo_2: ; preds = %_llgo_1, %_llgo_0
|
||||
define void @main() {
|
||||
_llgo_0:
|
||||
call void @main.init()
|
||||
%0 = alloca { i32, i1 }, align 8
|
||||
%0 = call ptr @"github.com/goplus/llgo/internal/runtime.Alloc"(i64 16)
|
||||
%1 = getelementptr inbounds { i32, i1 }, ptr %0, i32 0, i32 0
|
||||
%2 = getelementptr inbounds { i32, i1 }, ptr %0, i32 0, i32 1
|
||||
store i32 100, ptr %1, align 4
|
||||
@@ -56,3 +56,5 @@ _llgo_0:
|
||||
}
|
||||
|
||||
declare void @printf(ptr, ...)
|
||||
|
||||
declare ptr @"github.com/goplus/llgo/internal/runtime.Alloc"(i64)
|
||||
|
||||
@@ -63,6 +63,17 @@ func FromDir(t *testing.T, sel, relDir string, byLLGen bool) {
|
||||
}
|
||||
}
|
||||
|
||||
func Pkg(t *testing.T, pkgPath, outFile string) {
|
||||
b, err := os.ReadFile(outFile)
|
||||
if err != nil {
|
||||
t.Fatal("ReadFile failed:", err)
|
||||
}
|
||||
expected := string(b)
|
||||
if v := llgen.GenFrom(pkgPath); v != expected {
|
||||
t.Fatalf("\n==> got:\n%s\n==> expected:\n%s\n", v, expected)
|
||||
}
|
||||
}
|
||||
|
||||
func testFrom(t *testing.T, pkgDir, sel string, byLLGen bool) {
|
||||
if sel != "" && !strings.Contains(pkgDir, sel) {
|
||||
return
|
||||
@@ -76,7 +87,7 @@ func testFrom(t *testing.T, pkgDir, sel string, byLLGen bool) {
|
||||
}
|
||||
expected := string(b)
|
||||
if byLLGen {
|
||||
if v := llgen.GenFromFile(in); v != expected {
|
||||
if v := llgen.GenFrom(in); v != expected {
|
||||
t.Fatalf("\n==> got:\n%s\n==> expected:\n%s\n", v, expected)
|
||||
}
|
||||
} else {
|
||||
|
||||
@@ -35,6 +35,12 @@ func TestFromTestdata(t *testing.T) {
|
||||
cltest.FromDir(t, "", "./_testdata", false)
|
||||
}
|
||||
|
||||
/*
|
||||
func TestRuntime(t *testing.T) {
|
||||
cltest.Pkg(t, "github.com/goplus/llgo/internal/runtime", "../internal/runtime/llgo_autogen.ll")
|
||||
}
|
||||
*/
|
||||
|
||||
func TestVar(t *testing.T) {
|
||||
testCompile(t, `package foo
|
||||
|
||||
|
||||
@@ -35,11 +35,11 @@ const (
|
||||
loadSyntax = loadTypes | packages.NeedSyntax | packages.NeedTypesInfo
|
||||
)
|
||||
|
||||
func GenFromFile(inFile string) string {
|
||||
func GenFrom(fileOrPkg string) string {
|
||||
cfg := &packages.Config{
|
||||
Mode: loadSyntax,
|
||||
}
|
||||
initial, err := packages.Load(cfg, inFile)
|
||||
initial, err := packages.Load(cfg, fileOrPkg)
|
||||
check(err)
|
||||
|
||||
_, pkgs := ssautil.AllPackages(initial, ssa.SanityCheckFunctions)
|
||||
@@ -61,8 +61,8 @@ func GenFromFile(inFile string) string {
|
||||
return ret.String()
|
||||
}
|
||||
|
||||
func DoFile(inFile, outFile string) {
|
||||
ret := GenFromFile(inFile)
|
||||
func DoFile(fileOrPkg, outFile string) {
|
||||
ret := GenFrom(fileOrPkg)
|
||||
err := os.WriteFile(outFile, []byte(ret), 0644)
|
||||
check(err)
|
||||
}
|
||||
|
||||
@@ -1,5 +0,0 @@
|
||||
// Copyright 2014 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
package runtime
|
||||
@@ -1,15 +0,0 @@
|
||||
// Copyright 2009 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
package runtime
|
||||
|
||||
import (
|
||||
"unsafe"
|
||||
)
|
||||
|
||||
type slice struct {
|
||||
array unsafe.Pointer
|
||||
len int
|
||||
cap int
|
||||
}
|
||||
@@ -16,8 +16,16 @@
|
||||
|
||||
package runtime
|
||||
|
||||
import (
|
||||
"unsafe"
|
||||
)
|
||||
|
||||
// Slice is the runtime representation of a slice.
|
||||
type Slice = slice
|
||||
type Slice struct {
|
||||
array unsafe.Pointer
|
||||
len int
|
||||
cap int
|
||||
}
|
||||
|
||||
// NilSlice returns a nil slice.
|
||||
func NilSlice() Slice {
|
||||
|
||||
@@ -187,7 +187,7 @@ func (p Program) NewPackage(name, pkgPath string) Package {
|
||||
// mod.Finalize()
|
||||
fns := make(map[string]Function)
|
||||
gbls := make(map[string]Global)
|
||||
return &aPackage{mod, fns, gbls, p, nil}
|
||||
return &aPackage{mod, fns, gbls, p}
|
||||
}
|
||||
|
||||
// Void returns void type.
|
||||
@@ -267,8 +267,6 @@ type aPackage struct {
|
||||
fns map[string]Function
|
||||
vars map[string]Global
|
||||
prog Program
|
||||
|
||||
abort Function
|
||||
}
|
||||
|
||||
type Package = *aPackage
|
||||
@@ -294,6 +292,9 @@ func (p Package) VarOf(name string) Global {
|
||||
|
||||
// NewFunc creates a new function.
|
||||
func (p Package) NewFunc(name string, sig *types.Signature) Function {
|
||||
if v, ok := p.fns[name]; ok {
|
||||
return v
|
||||
}
|
||||
t := p.prog.llvmSignature(sig)
|
||||
fn := llvm.AddFunction(p.mod, name, t.ll)
|
||||
ret := newFunction(fn, t, p, p.prog)
|
||||
@@ -306,21 +307,14 @@ func (p Package) FuncOf(name string) Function {
|
||||
return p.fns[name]
|
||||
}
|
||||
|
||||
func (p Package) rtAbort() Function {
|
||||
if p.abort == nil {
|
||||
p.abort = p.NewFunc("abort", types.NewSignatureType(nil, nil, nil, nil, nil, false))
|
||||
}
|
||||
return p.abort
|
||||
func (p Package) rtAbort() Expr {
|
||||
return p.NewFunc("abort", types.NewSignatureType(nil, nil, nil, nil, nil, false)).Expr
|
||||
}
|
||||
|
||||
func (p Package) rtFunc(fnName string) Expr {
|
||||
fn := p.prog.runtime().Lookup(fnName).(*types.Func)
|
||||
name := FullName(fn.Pkg(), fnName)
|
||||
v, ok := p.fns[name]
|
||||
if !ok {
|
||||
v = p.NewFunc(name, fn.Type().(*types.Signature))
|
||||
}
|
||||
return v.Expr
|
||||
return p.NewFunc(name, fn.Type().(*types.Signature)).Expr
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
@@ -74,7 +74,7 @@ func (b Builder) Panic(v Expr) {
|
||||
log.Printf("Panic %v\n", v.impl)
|
||||
}
|
||||
pkg := b.fn.pkg
|
||||
b.Call(pkg.rtAbort().Expr)
|
||||
b.Call(pkg.rtAbort()) // TODO(xsw): pass v
|
||||
}
|
||||
|
||||
// Return emits a return instruction.
|
||||
|
||||
@@ -123,6 +123,9 @@ func (p Program) Field(typ Type, i int) Type {
|
||||
}
|
||||
|
||||
func (p Program) Type(typ types.Type) Type {
|
||||
if sig, ok := typ.(*types.Signature); ok { // should methodToFunc
|
||||
return p.llvmSignature(sig)
|
||||
}
|
||||
if v := p.typs.At(typ); v != nil {
|
||||
return v.(Type)
|
||||
}
|
||||
@@ -253,8 +256,6 @@ func (p Program) toLLVMType(typ types.Type) Type {
|
||||
return p.toLLVMStruct(t)
|
||||
case *types.Named:
|
||||
return p.toLLVMNamed(t)
|
||||
case *types.Signature:
|
||||
return p.toLLVMFunc(t)
|
||||
case *types.Array:
|
||||
elem := p.Type(t.Elem())
|
||||
return &aType{llvm.ArrayType(elem.ll, int(t.Len())), typ, vkInvalid}
|
||||
|
||||
Reference in New Issue
Block a user