diff --git a/cl/_testpy/callpy/out.ll b/cl/_testpy/callpy/out.ll index d3892453..437dd6f7 100644 --- a/cl/_testpy/callpy/out.ll +++ b/cl/_testpy/callpy/out.ll @@ -8,6 +8,10 @@ source_filename = "main" @__llgo_py.os.getcwd = linkonce global ptr null @0 = private unnamed_addr constant [14 x i8] c"sqrt(2) = %f\0A\00", align 1 @1 = private unnamed_addr constant [10 x i8] c"cwd = %s\0A\00", align 1 +@__llgo_py.math = external global ptr +@2 = private unnamed_addr constant [5 x i8] c"sqrt\00", align 1 +@__llgo_py.os = external global ptr +@3 = private unnamed_addr constant [7 x i8] c"getcwd\00", align 1 define void @main.init() { _llgo_0: @@ -18,6 +22,10 @@ _llgo_1: ; preds = %_llgo_0 store i1 true, ptr @"main.init$guard", align 1 call void @"github.com/goplus/llgo/py/math.init"() call void @"github.com/goplus/llgo/py/os.init"() + %1 = load ptr, ptr @__llgo_py.math, align 8 + call void (ptr, ...) @llgoLoadPyModSyms(ptr %1, ptr @2, ptr @__llgo_py.math.sqrt, ptr null) + %2 = load ptr, ptr @__llgo_py.os, align 8 + call void (ptr, ...) @llgoLoadPyModSyms(ptr %2, ptr @3, ptr @__llgo_py.os.getcwd, ptr null) br label %_llgo_2 _llgo_2: ; preds = %_llgo_1, %_llgo_0 @@ -59,4 +67,6 @@ declare i32 @printf(ptr, ...) declare ptr @PyBytes_AsString() +declare void @llgoLoadPyModSyms(ptr, ...) + declare void @Py_Initialize() diff --git a/cl/compile.go b/cl/compile.go index 4d3c95d5..18142e64 100644 --- a/cl/compile.go +++ b/cl/compile.go @@ -355,7 +355,7 @@ func (p *context) compileBlock(b llssa.Builder, block *ssa.BasicBlock, n int, do modName := modOf(name) mods[modName] = append(mods[modName], obj) } - b.SetBlockEx(ret, llssa.AtStart) + b.SetBlockEx(ret, llssa.AfterInit) for modName, objs := range mods { b.LoadPyModSyms(modName, objs...) } diff --git a/ssa/stmt_builder.go b/ssa/stmt_builder.go index 817d6524..579e744b 100644 --- a/ssa/stmt_builder.go +++ b/ssa/stmt_builder.go @@ -21,6 +21,7 @@ import ( "fmt" "go/types" "log" + "strings" "github.com/goplus/llvm" ) @@ -76,6 +77,7 @@ type InsertPoint int const ( AtEnd InsertPoint = iota AtStart + AfterInit ) // SetBlockEx sets blk as current basic block and pos as its insert point. @@ -88,12 +90,35 @@ func (b Builder) SetBlockEx(blk BasicBlock, pos InsertPoint) Builder { b.impl.SetInsertPointAtEnd(blk.impl) case AtStart: b.impl.SetInsertPointBefore(blk.impl.FirstInstruction()) + case AfterInit: + b.impl.SetInsertPointBefore(instrAfterInit(blk.impl)) default: panic("SetBlockEx: invalid pos") } return b } +func instrAfterInit(blk llvm.BasicBlock) llvm.Value { + instr := blk.FirstInstruction() + for { + instr = llvm.NextInstruction(instr) + if notInit(instr) { + return instr + } + } +} + +func notInit(instr llvm.Value) bool { + switch op := instr.InstructionOpcode(); op { + case llvm.Call: + if n := instr.OperandsCount(); n == 1 { + fn := instr.Operand(0) + return !strings.HasSuffix(fn.Name(), ".init") + } + } + return true +} + // Panic emits a panic instruction. func (b Builder) Panic(v Expr) { if debugInstr {