diff --git a/compiler/cl/cltest/cltest.go b/compiler/cl/cltest/cltest.go index 0e0cd0ec..96010fc8 100644 --- a/compiler/cl/cltest/cltest.go +++ b/compiler/cl/cltest/cltest.go @@ -152,10 +152,6 @@ func TestCompileEx(t *testing.T, src any, fname, expected string, dbg bool) { t.Fatal("cl.NewPackage failed:", err) } - if prog.NeedPyInit { // call PyInit if needed - ret.PyInit() - } - if v := ret.String(); v != expected && expected != ";" { // expected == ";" means skipping out.ll t.Fatalf("\n==> got:\n%s\n==> expected:\n%s\n", v, expected) } diff --git a/compiler/cl/compile.go b/compiler/cl/compile.go index 3db7bb53..78804ce7 100644 --- a/compiler/cl/compile.go +++ b/compiler/cl/compile.go @@ -127,10 +127,6 @@ const ( pkgFNoOldInit = 0x80 // flag if no initFnNameOld ) -func (p *context) inMain(instr ssa.Instruction) bool { - return p.fn.Name() == "main" -} - func (p *context) compileType(pkg llssa.Package, t *ssa.Type) { tn := t.Object().(*types.TypeName) if tn.IsAlias() { // don't need to compile alias type @@ -186,10 +182,6 @@ func makeClosureCtx(pkg *types.Package, vars []*ssa.FreeVar) *types.Var { return types.NewParam(token.NoPos, pkg, "__llgo_ctx", t) } -var ( - argvTy = types.NewPointer(types.NewPointer(types.Typ[types.Int8])) -) - func isCgoExternSymbol(f *ssa.Function) bool { name := f.Name() return isCgoCfunc(name) || isCgoCmacro(name) @@ -247,14 +239,6 @@ func (p *context) compileFuncDecl(pkg llssa.Package, f *ssa.Function) (llssa.Fun } } if fn == nil { - if name == "main" { - argc := types.NewParam(token.NoPos, pkgTypes, "", types.Typ[types.Int32]) - argv := types.NewParam(token.NoPos, pkgTypes, "", argvTy) - params := types.NewTuple(argc, argv) - ret := types.NewParam(token.NoPos, pkgTypes, "", p.prog.CInt().RawType()) - results := types.NewTuple(ret) - sig = types.NewSignatureType(nil, nil, nil, params, results, false) - } fn = pkg.NewFuncEx(name, sig, llssa.Background(ftype), hasCtx, f.Origin() != nil) if debugSymbols { fn.Inline(llssa.NoInline) @@ -309,9 +293,8 @@ func (p *context) compileFuncDecl(pkg llssa.Package, f *ssa.Function) (llssa.Fun i := 0 for { block := f.Blocks[i] - doMainInit := (i == 0 && name == "main") doModInit := (i == 1 && isInit) - p.compileBlock(b, block, off[i], doMainInit, doModInit) + p.compileBlock(b, block, off[i], doModInit) if isCgo { // just process first block for performance break @@ -385,7 +368,7 @@ func (p *context) debugParams(b llssa.Builder, f *ssa.Function) { } } -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, doModInit bool) llssa.BasicBlock { var last int var pyModInit bool var prog = p.prog @@ -408,15 +391,6 @@ func (p *context) compileBlock(b llssa.Builder, block *ssa.BasicBlock, n int, do pkg.AfterInit(b, ret) } } - } else if doMainInit { - argc := pkg.NewVar("__llgo_argc", types.NewPointer(types.Typ[types.Int32]), llssa.InC) - argv := pkg.NewVar("__llgo_argv", types.NewPointer(argvTy), llssa.InC) - argc.InitNil() - argv.InitNil() - b.Store(argc.Expr, fn.Param(0)) - b.Store(argv.Expr, fn.Param(1)) - callRuntimeInit(b, pkg) - b.Call(pkg.FuncOf("main.init").Expr) } fnName := block.Parent().Name() cgoReturned := false @@ -499,11 +473,6 @@ const ( RuntimeInit = llssa.PkgRuntime + ".init" ) -func callRuntimeInit(b llssa.Builder, pkg llssa.Package) { - fn := pkg.NewFunc(RuntimeInit, llssa.NoArgsNoRet, llssa.InC) // don't need to convert runtime.init - b.Call(fn.Expr) -} - func isAny(t types.Type) bool { if t, ok := t.Underlying().(*types.Interface); ok { return t.Empty() @@ -834,10 +803,6 @@ func (p *context) compileInstr(b llssa.Builder, instr ssa.Instruction) { results[i] = p.compileValue(b, r) } } - if p.inMain(instr) { - results = make([]llssa.Expr, 1) - results[0] = p.prog.IntVal(0, p.prog.CInt()) - } b.Return(results...) case *ssa.If: fn := p.fn diff --git a/compiler/internal/build/build.go b/compiler/internal/build/build.go index f37455a8..2b85d7c7 100644 --- a/compiler/internal/build/build.go +++ b/compiler/internal/build/build.go @@ -426,6 +426,11 @@ func linkMainPkg(ctx *context, pkg *packages.Package, pkgs []*aPackage, linkArgs } } }) + main, err := genMainModuleFile(llssa.PkgRuntime, pkg.PkgPath, needRuntime, needPyInit) + if err != nil { + panic(err) + } + args = append(args, main) var aPkg *aPackage for _, v := range pkgs { @@ -435,19 +440,9 @@ func linkMainPkg(ctx *context, pkg *packages.Package, pkgs []*aPackage, linkArgs } } - dirty := false - if needRuntime { - args = append(args, linkArgs...) - } else { - dirty = true - fn := aPkg.LPkg.FuncOf(cl.RuntimeInit) - fn.MakeBody(1).Return() - } - if needPyInit { - dirty = aPkg.LPkg.PyInit() - } + args = append(args, linkArgs...) - if dirty && needLLFile(mode) { + if needLLFile(mode) { lpkg := aPkg.LPkg os.WriteFile(pkg.ExportFile, []byte(lpkg.String()), 0644) } @@ -475,7 +470,7 @@ func linkMainPkg(ctx *context, pkg *packages.Package, pkgs []*aPackage, linkArgs if verbose { fmt.Fprintln(os.Stderr, "clang", args) } - err := ctx.env.Clang().Exec(args...) + err = ctx.env.Clang().Exec(args...) check(err) if runtime.GOOS == "darwin" { @@ -505,6 +500,60 @@ func linkMainPkg(ctx *context, pkg *packages.Package, pkgs []*aPackage, linkArgs } } +func genMainModuleFile(rtPkgPath, mainPkgPath string, needRuntime, needPyInit bool) (path string, err error) { + var ( + pyInitDecl string + pyInit string + rtInitDecl string + rtInit string + ) + if needRuntime { + rtInit = "call void @\"" + rtPkgPath + ".init\"()" + rtInitDecl = "declare void @\"" + rtPkgPath + ".init\"()" + } + if needPyInit { + pyInit = "call void @Py_Initialize()" + pyInitDecl = "declare void @Py_Initialize()" + } + mainCode := fmt.Sprintf(`; ModuleID = 'main' +source_filename = "main" + +@__llgo_argc = global i32 0, align 4 +@__llgo_argv = global ptr null, align 8 + +%s +%s +declare void @"%s.init"() +declare void @"%s.main"() + +define i32 @main(i32 %%0, ptr %%1) { +_llgo_0: + %s + store i32 %%0, ptr @__llgo_argc, align 4 + store ptr %%1, ptr @__llgo_argv, align 8 + %s + call void @"%s.init"() + call void @"%s.main"() + ret i32 0 +} +`, pyInitDecl, rtInitDecl, mainPkgPath, mainPkgPath, + pyInit, rtInit, mainPkgPath, mainPkgPath) + + f, err := os.CreateTemp("", "main*.ll") + if err != nil { + return "", err + } + _, err = f.Write([]byte(mainCode)) + if err != nil { + return "", err + } + err = f.Close() + if err != nil { + return "", err + } + return f.Name(), nil +} + func buildPkg(ctx *context, aPkg *aPackage, verbose bool) (cgoLdflags []string, err error) { pkg := aPkg.Package pkgPath := pkg.PkgPath diff --git a/compiler/ssa/abi/abi.go b/compiler/ssa/abi/abi.go index 45fb177a..5f3f8062 100644 --- a/compiler/ssa/abi/abi.go +++ b/compiler/ssa/abi/abi.go @@ -226,9 +226,6 @@ func PathOf(pkg *types.Package) string { if pkg == nil { return "" } - if pkg.Name() == "main" { - return "main" - } return strings.TrimPrefix(pkg.Path(), PatchPathPrefix) } diff --git a/compiler/ssa/python.go b/compiler/ssa/python.go index d5e49e47..01d4390b 100644 --- a/compiler/ssa/python.go +++ b/compiler/ssa/python.go @@ -231,18 +231,6 @@ func (p Program) tyGetAttrString() *types.Signature { return p.getAttrStr } -// PyInit initializes Python for a main package. -func (p Package) PyInit() bool { - if fn := p.FuncOf("main"); fn != nil { - b := fn.NewBuilder() - b.SetBlockEx(fn.Block(0), AtStart, false) - b.callPyInit() - b.Dispose() - return true - } - return false -} - // PyNewModVar creates a new global variable for a Python module. func (p Package) PyNewModVar(name string, doInit bool) Global { if v, ok := p.pymods[name]; ok { diff --git a/compiler/ssa/type.go b/compiler/ssa/type.go index 1aad5ecd..a6db12f9 100644 --- a/compiler/ssa/type.go +++ b/compiler/ssa/type.go @@ -554,9 +554,6 @@ func FuncName(pkg *types.Package, name string, recv *types.Var, org bool) string return PathOf(pkg) + "." + tName + "." + name } ret := FullName(pkg, name) - if ret == "main.main" { - ret = "main" - } return ret }