Merge pull request #210 from xushiwei/q
README: matplotlib; llgo/ssa: pkg.PyLoadModSyms (source code stablility)
This commit is contained in:
@@ -58,6 +58,7 @@ And you can import any Python library into `llgo` through a program called `llpy
|
|||||||
* [numpy](https://pkg.go.dev/github.com/goplus/llgo/py/numpy)
|
* [numpy](https://pkg.go.dev/github.com/goplus/llgo/py/numpy)
|
||||||
* [pandas](https://pkg.go.dev/github.com/goplus/llgo/py/pandas)
|
* [pandas](https://pkg.go.dev/github.com/goplus/llgo/py/pandas)
|
||||||
* [pytorch](https://pkg.go.dev/github.com/goplus/llgo/py/torch)
|
* [pytorch](https://pkg.go.dev/github.com/goplus/llgo/py/torch)
|
||||||
|
* [matplotlib](https://pkg.go.dev/github.com/goplus/llgo/py/matplotlib)
|
||||||
|
|
||||||
Here is an example using the Python `math` library:
|
Here is an example using the Python `math` library:
|
||||||
|
|
||||||
|
|||||||
@@ -8,9 +8,9 @@ source_filename = "main"
|
|||||||
@__llgo_py.builtins.print = linkonce global ptr null
|
@__llgo_py.builtins.print = linkonce global ptr null
|
||||||
@__llgo_py.builtins.iter = linkonce global ptr null
|
@__llgo_py.builtins.iter = linkonce global ptr null
|
||||||
@__llgo_py.builtins = external global ptr
|
@__llgo_py.builtins = external global ptr
|
||||||
@0 = private unnamed_addr constant [4 x i8] c"max\00", align 1
|
@0 = private unnamed_addr constant [5 x i8] c"iter\00", align 1
|
||||||
@1 = private unnamed_addr constant [6 x i8] c"print\00", align 1
|
@1 = private unnamed_addr constant [4 x i8] c"max\00", align 1
|
||||||
@2 = private unnamed_addr constant [5 x i8] c"iter\00", align 1
|
@2 = private unnamed_addr constant [6 x i8] c"print\00", align 1
|
||||||
|
|
||||||
define void @main.init() {
|
define void @main.init() {
|
||||||
_llgo_0:
|
_llgo_0:
|
||||||
@@ -21,7 +21,7 @@ _llgo_1: ; preds = %_llgo_0
|
|||||||
store i1 true, ptr @"main.init$guard", align 1
|
store i1 true, ptr @"main.init$guard", align 1
|
||||||
call void @"github.com/goplus/llgo/py/std.init"()
|
call void @"github.com/goplus/llgo/py/std.init"()
|
||||||
%1 = load ptr, ptr @__llgo_py.builtins, align 8
|
%1 = load ptr, ptr @__llgo_py.builtins, align 8
|
||||||
call void (ptr, ...) @llgoLoadPyModSyms(ptr %1, ptr @0, ptr @__llgo_py.builtins.max, ptr @1, ptr @__llgo_py.builtins.print, ptr @2, ptr @__llgo_py.builtins.iter, ptr null)
|
call void (ptr, ...) @llgoLoadPyModSyms(ptr %1, ptr @0, ptr @__llgo_py.builtins.iter, ptr @1, ptr @__llgo_py.builtins.max, ptr @2, ptr @__llgo_py.builtins.print, ptr null)
|
||||||
br label %_llgo_2
|
br label %_llgo_2
|
||||||
|
|
||||||
_llgo_2: ; preds = %_llgo_1, %_llgo_0
|
_llgo_2: ; preds = %_llgo_1, %_llgo_0
|
||||||
|
|||||||
@@ -339,13 +339,6 @@ func (p *context) funcOf(fn *ssa.Function) (aFn llssa.Function, pyFn llssa.PyObj
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
func modOf(name string) string {
|
|
||||||
if pos := strings.LastIndexByte(name, '.'); pos > 0 {
|
|
||||||
return name[:pos]
|
|
||||||
}
|
|
||||||
return ""
|
|
||||||
}
|
|
||||||
|
|
||||||
func (p *context) compileBlock(b llssa.Builder, block *ssa.BasicBlock, n int, doMainInit, doModInit bool) llssa.BasicBlock {
|
func (p *context) compileBlock(b llssa.Builder, block *ssa.BasicBlock, n int, doMainInit, doModInit bool) llssa.BasicBlock {
|
||||||
var last int
|
var last int
|
||||||
var pyModInit bool
|
var pyModInit bool
|
||||||
@@ -361,26 +354,7 @@ func (p *context) compileBlock(b llssa.Builder, block *ssa.BasicBlock, n int, do
|
|||||||
} else {
|
} else {
|
||||||
// TODO(xsw): confirm pyMod don't need to call LoadPyModSyms
|
// TODO(xsw): confirm pyMod don't need to call LoadPyModSyms
|
||||||
p.inits = append(p.inits, func() {
|
p.inits = append(p.inits, func() {
|
||||||
if objs := pkg.PyObjs(); len(objs) > 0 {
|
pkg.PyLoadModSyms(b, ret)
|
||||||
mods := make(map[string][]llssa.PyObjRef)
|
|
||||||
for name, obj := range objs {
|
|
||||||
modName := modOf(name)
|
|
||||||
mods[modName] = append(mods[modName], obj)
|
|
||||||
}
|
|
||||||
|
|
||||||
// sort by module name
|
|
||||||
modNames := make([]string, 0, len(mods))
|
|
||||||
for modName := range mods {
|
|
||||||
modNames = append(modNames, modName)
|
|
||||||
}
|
|
||||||
sort.Strings(modNames)
|
|
||||||
|
|
||||||
b.SetBlockEx(ret, llssa.AfterInit)
|
|
||||||
for _, modName := range modNames {
|
|
||||||
objs := mods[modName]
|
|
||||||
b.PyLoadModSyms(modName, objs...)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
} else if doMainInit {
|
} else if doMainInit {
|
||||||
|
|||||||
BIN
py/matplotlib/pyplot/llgo_autogen.lla
Normal file
BIN
py/matplotlib/pyplot/llgo_autogen.lla
Normal file
Binary file not shown.
22
py/matplotlib/pyplot/pyplot.go
Normal file
22
py/matplotlib/pyplot/pyplot.go
Normal file
@@ -0,0 +1,22 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2024 The GoPlus Authors (goplus.org). All rights reserved.
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package pyplot
|
||||||
|
|
||||||
|
import "github.com/goplus/llgo/py"
|
||||||
|
|
||||||
|
//llgo:linkname Style py.style
|
||||||
|
var Style *py.Object
|
||||||
43
ssa/decl.go
43
ssa/decl.go
@@ -19,7 +19,9 @@ package ssa
|
|||||||
import (
|
import (
|
||||||
"go/types"
|
"go/types"
|
||||||
"log"
|
"log"
|
||||||
|
"sort"
|
||||||
"strconv"
|
"strconv"
|
||||||
|
"strings"
|
||||||
|
|
||||||
"github.com/goplus/llvm"
|
"github.com/goplus/llvm"
|
||||||
)
|
)
|
||||||
@@ -350,9 +352,44 @@ func (p Package) PyObjOf(name string) PyObjRef {
|
|||||||
return p.pyobjs[name]
|
return p.pyobjs[name]
|
||||||
}
|
}
|
||||||
|
|
||||||
// PyObjs returns all used python objects in this project.
|
// PyLoadModSyms loads module symbols used in this package.
|
||||||
func (p Package) PyObjs() map[string]PyObjRef {
|
func (p Package) PyLoadModSyms(b Builder, ret BasicBlock) {
|
||||||
return p.pyobjs
|
objs := p.pyobjs
|
||||||
|
n := len(objs)
|
||||||
|
if n == 0 {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
names := make([]string, 0, n)
|
||||||
|
for name := range objs {
|
||||||
|
names = append(names, name)
|
||||||
|
}
|
||||||
|
sort.Strings(names)
|
||||||
|
|
||||||
|
mods := make(map[string][]PyObjRef)
|
||||||
|
modNames := make([]string, 0, 8)
|
||||||
|
lastMod := ""
|
||||||
|
for _, name := range names {
|
||||||
|
modName := modOf(name)
|
||||||
|
mods[modName] = append(mods[modName], objs[name])
|
||||||
|
if modName != lastMod {
|
||||||
|
modNames = append(modNames, modName)
|
||||||
|
lastMod = modName
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
b.SetBlockEx(ret, afterInit)
|
||||||
|
for _, modName := range modNames {
|
||||||
|
objs := mods[modName]
|
||||||
|
b.PyLoadModSyms(modName, objs...)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func modOf(name string) string {
|
||||||
|
if pos := strings.LastIndexByte(name, '.'); pos > 0 {
|
||||||
|
return name[:pos]
|
||||||
|
}
|
||||||
|
panic("unreachable")
|
||||||
}
|
}
|
||||||
|
|
||||||
// -----------------------------------------------------------------------------
|
// -----------------------------------------------------------------------------
|
||||||
|
|||||||
@@ -77,7 +77,7 @@ type InsertPoint int
|
|||||||
const (
|
const (
|
||||||
AtEnd InsertPoint = iota
|
AtEnd InsertPoint = iota
|
||||||
AtStart
|
AtStart
|
||||||
AfterInit
|
afterInit
|
||||||
)
|
)
|
||||||
|
|
||||||
// SetBlockEx sets blk as current basic block and pos as its insert point.
|
// SetBlockEx sets blk as current basic block and pos as its insert point.
|
||||||
@@ -90,7 +90,7 @@ func (b Builder) SetBlockEx(blk BasicBlock, pos InsertPoint) Builder {
|
|||||||
b.impl.SetInsertPointAtEnd(blk.impl)
|
b.impl.SetInsertPointAtEnd(blk.impl)
|
||||||
case AtStart:
|
case AtStart:
|
||||||
b.impl.SetInsertPointBefore(blk.impl.FirstInstruction())
|
b.impl.SetInsertPointBefore(blk.impl.FirstInstruction())
|
||||||
case AfterInit:
|
case afterInit:
|
||||||
b.impl.SetInsertPointBefore(instrAfterInit(blk.impl))
|
b.impl.SetInsertPointBefore(instrAfterInit(blk.impl))
|
||||||
default:
|
default:
|
||||||
panic("SetBlockEx: invalid pos")
|
panic("SetBlockEx: invalid pos")
|
||||||
|
|||||||
Reference in New Issue
Block a user