//===- compiler.go - IR generator entry point -----------------------------===//
//
//                     The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// This file implements the main IR generator entry point, (*Compiler).Compile.
//
//===----------------------------------------------------------------------===//

package irgen

import (
	"bytes"
	"go/ast"
	"go/token"
	"log"
	"sort"
	"strconv"

	llgobuild "llvm.org/llgo/build"
	"llvm.org/llgo/debug"
	"llvm.org/llvm/bindings/go/llvm"

	"llvm.org/llgo/third_party/gotools/go/gccgoimporter"
	"llvm.org/llgo/third_party/gotools/go/importer"
	"llvm.org/llgo/third_party/gotools/go/loader"
	"llvm.org/llgo/third_party/gotools/go/ssa"
	"llvm.org/llgo/third_party/gotools/go/types"
)

type Module struct {
	llvm.Module
	Path       string
	ExportData []byte
	Package    *types.Package
	disposed   bool
}

func (m *Module) Dispose() {
	if m.disposed {
		return
	}
	m.Module.Dispose()
	m.disposed = true
}

///////////////////////////////////////////////////////////////////////////////

type CompilerOptions struct {
	// TargetTriple is the LLVM triple for the target.
	TargetTriple string

	// GenerateDebug decides whether debug data is
	// generated in the output module.
	GenerateDebug bool

	// DebugPrefixMaps is a list of mappings from source prefixes to
	// replacement prefixes, to be applied in debug info.
	DebugPrefixMaps []debug.PrefixMap

	// Logger is a logger used for tracing compilation.
	Logger *log.Logger

	// DumpSSA is a debugging option that dumps each SSA function
	// to stderr before generating code for it.
	DumpSSA bool

	// GccgoPath is the path to the gccgo binary whose libgo we read import
	// data from. If blank, the caller is expected to supply an import
	// path in ImportPaths.
	GccgoPath string

	// Whether to use the gccgo ABI.
	GccgoABI bool

	// ImportPaths is the list of additional import paths
	ImportPaths []string

	// SanitizerAttribute is an attribute to apply to functions to enable
	// dynamic instrumentation using a sanitizer.
	SanitizerAttribute llvm.Attribute

	// Importer is the importer. If nil, the compiler will set this field
	// automatically using MakeImporter().
	Importer types.Importer

	// InitMap is the init map used by Importer. If Importer is nil, the
	// compiler will set this field automatically using MakeImporter().
	// If Importer is non-nil, InitMap must be non-nil also.
	InitMap map[*types.Package]gccgoimporter.InitData

	// PackageCreated is a hook passed to the go/loader package via
	// loader.Config, see the documentation for that package for more
	// information.
	PackageCreated func(*types.Package)

	// DisableUnusedImportCheck disables the unused import check performed
	// by go/types if set to true.
	DisableUnusedImportCheck bool

	// Packages is used by go/types as the imported package map if non-nil.
	Packages map[string]*types.Package
}

type Compiler struct {
	opts       CompilerOptions
	dataLayout string
}

func NewCompiler(opts CompilerOptions) (*Compiler, error) {
	compiler := &Compiler{opts: opts}
	dataLayout, err := llvmDataLayout(compiler.opts.TargetTriple)
	if err != nil {
		return nil, err
	}
	compiler.dataLayout = dataLayout
	return compiler, nil
}

func (c *Compiler) Compile(fset *token.FileSet, astFiles []*ast.File, importpath string) (m *Module, err error) {
	target := llvm.NewTargetData(c.dataLayout)
	compiler := &compiler{
		CompilerOptions: c.opts,
		dataLayout:      c.dataLayout,
		target:          target,
		llvmtypes:       NewLLVMTypeMap(llvm.GlobalContext(), target),
	}
	return compiler.compile(fset, astFiles, importpath)
}

type compiler struct {
	CompilerOptions

	module     *Module
	dataLayout string
	target     llvm.TargetData
	fileset    *token.FileSet

	runtime   *runtimeInterface
	llvmtypes *llvmTypeMap
	types     *TypeMap

	debug *debug.DIBuilder
}

func (c *compiler) logf(format string, v ...interface{}) {
	if c.Logger != nil {
		c.Logger.Printf(format, v...)
	}
}

func (c *compiler) addCommonFunctionAttrs(fn llvm.Value) {
	fn.AddTargetDependentFunctionAttr("disable-tail-calls", "true")
	fn.AddTargetDependentFunctionAttr("split-stack", "")
	if attr := c.SanitizerAttribute; attr != 0 {
		fn.AddFunctionAttr(attr)
	}
}

// MakeImporter sets CompilerOptions.Importer to an appropriate importer
// for the search paths given in CompilerOptions.ImportPaths, and sets
// CompilerOptions.InitMap to an init map belonging to that importer.
// If CompilerOptions.GccgoPath is non-empty, the importer will also use
// the search paths for that gccgo installation.
func (opts *CompilerOptions) MakeImporter() error {
	opts.InitMap = make(map[*types.Package]gccgoimporter.InitData)
	if opts.GccgoPath == "" {
		paths := append(append([]string{}, opts.ImportPaths...), ".")
		opts.Importer = gccgoimporter.GetImporter(paths, opts.InitMap)
	} else {
		var inst gccgoimporter.GccgoInstallation
		err := inst.InitFromDriver(opts.GccgoPath)
		if err != nil {
			return err
		}
		opts.Importer = inst.GetImporter(opts.ImportPaths, opts.InitMap)
	}
	return nil
}

func (compiler *compiler) compile(fset *token.FileSet, astFiles []*ast.File, importpath string) (m *Module, err error) {
	buildctx, err := llgobuild.ContextFromTriple(compiler.TargetTriple)
	if err != nil {
		return nil, err
	}

	if compiler.Importer == nil {
		err = compiler.MakeImporter()
		if err != nil {
			return nil, err
		}
	}

	impcfg := &loader.Config{
		Fset: fset,
		TypeChecker: types.Config{
			Packages: compiler.Packages,
			Import:   compiler.Importer,
			Sizes:    compiler.llvmtypes,
			DisableUnusedImportCheck: compiler.DisableUnusedImportCheck,
		},
		ImportFromBinary: true,
		Build:            &buildctx.Context,
		PackageCreated:   compiler.PackageCreated,
	}
	// If no import path is specified, then set the import
	// path to be the same as the package's name.
	if importpath == "" {
		importpath = astFiles[0].Name.String()
	}
	impcfg.CreateFromFiles(importpath, astFiles...)
	iprog, err := impcfg.Load()
	if err != nil {
		return nil, err
	}
	program := ssa.Create(iprog, ssa.BareInits)
	mainPkginfo := iprog.InitialPackages()[0]
	mainPkg := program.CreatePackage(mainPkginfo)

	// Create a Module, which contains the LLVM module.
	modulename := importpath
	compiler.module = &Module{Module: llvm.NewModule(modulename), Path: modulename, Package: mainPkg.Object}
	compiler.module.SetTarget(compiler.TargetTriple)
	compiler.module.SetDataLayout(compiler.dataLayout)

	// Create a new translation unit.
	unit := newUnit(compiler, mainPkg)

	// Create the runtime interface.
	compiler.runtime, err = newRuntimeInterface(compiler.module.Module, compiler.llvmtypes)
	if err != nil {
		return nil, err
	}

	mainPkg.Build()

	// Create a struct responsible for mapping static types to LLVM types,
	// and to runtime/dynamic type values.
	compiler.types = NewTypeMap(
		mainPkg,
		compiler.llvmtypes,
		compiler.module.Module,
		compiler.runtime,
		MethodResolver(unit),
	)

	if compiler.GenerateDebug {
		compiler.debug = debug.NewDIBuilder(
			types.Sizes(compiler.llvmtypes),
			compiler.module.Module,
			impcfg.Fset,
			compiler.DebugPrefixMaps,
		)
		defer compiler.debug.Destroy()
		defer compiler.debug.Finalize()
	}

	unit.translatePackage(mainPkg)
	compiler.processAnnotations(unit, mainPkginfo)

	if importpath == "main" {
		compiler.createInitMainFunction(mainPkg)
	} else {
		compiler.module.ExportData = compiler.buildExportData(mainPkg)
	}

	return compiler.module, nil
}

type byPriorityThenFunc []gccgoimporter.PackageInit

func (a byPriorityThenFunc) Len() int      { return len(a) }
func (a byPriorityThenFunc) Swap(i, j int) { a[i], a[j] = a[j], a[i] }
func (a byPriorityThenFunc) Less(i, j int) bool {
	switch {
	case a[i].Priority < a[j].Priority:
		return true
	case a[i].Priority > a[j].Priority:
		return false
	case a[i].InitFunc < a[j].InitFunc:
		return true
	default:
		return false
	}
}

func (c *compiler) buildPackageInitData(mainPkg *ssa.Package) gccgoimporter.InitData {
	var inits []gccgoimporter.PackageInit
	for _, imp := range mainPkg.Object.Imports() {
		inits = append(inits, c.InitMap[imp].Inits...)
	}
	sort.Sort(byPriorityThenFunc(inits))

	// Deduplicate init entries. We want to preserve the entry with the highest priority.
	// Normally a package's priorities will be consistent among its dependencies, but it is
	// possible for them to be different. For example, if a standard library test augments a
	// package which is a dependency of 'regexp' (which is imported by every test main package)
	// with additional dependencies, those dependencies may cause the package under test to
	// receive a higher priority than indicated by its init clause in 'regexp'.
	uniqinits := make([]gccgoimporter.PackageInit, len(inits))
	uniqinitpos := len(inits)
	uniqinitnames := make(map[string]struct{})
	for i, _ := range inits {
		init := inits[len(inits)-1-i]
		if _, ok := uniqinitnames[init.InitFunc]; !ok {
			uniqinitnames[init.InitFunc] = struct{}{}
			uniqinitpos--
			uniqinits[uniqinitpos] = init
		}
	}
	uniqinits = uniqinits[uniqinitpos:]

	ourprio := 1
	if len(uniqinits) != 0 {
		ourprio = uniqinits[len(uniqinits)-1].Priority + 1
	}

	if imp := mainPkg.Func("init"); imp != nil {
		impname := c.types.mc.mangleFunctionName(imp)
		uniqinits = append(uniqinits, gccgoimporter.PackageInit{mainPkg.Object.Name(), impname, ourprio})
	}

	return gccgoimporter.InitData{ourprio, uniqinits}
}

func (c *compiler) createInitMainFunction(mainPkg *ssa.Package) {
	int8ptr := llvm.PointerType(c.types.ctx.Int8Type(), 0)
	ftyp := llvm.FunctionType(llvm.VoidType(), []llvm.Type{int8ptr}, false)
	initMain := llvm.AddFunction(c.module.Module, "__go_init_main", ftyp)
	c.addCommonFunctionAttrs(initMain)
	entry := llvm.AddBasicBlock(initMain, "entry")

	builder := llvm.GlobalContext().NewBuilder()
	defer builder.Dispose()
	builder.SetInsertPointAtEnd(entry)

	args := []llvm.Value{llvm.Undef(int8ptr)}

	if !c.GccgoABI {
		initfn := c.module.Module.NamedFunction("main..import")
		if !initfn.IsNil() {
			builder.CreateCall(initfn, args, "")
		}
		builder.CreateRetVoid()
		return
	}

	initdata := c.buildPackageInitData(mainPkg)

	for _, init := range initdata.Inits {
		initfn := c.module.Module.NamedFunction(init.InitFunc)
		if initfn.IsNil() {
			initfn = llvm.AddFunction(c.module.Module, init.InitFunc, ftyp)
		}
		builder.CreateCall(initfn, args, "")
	}

	builder.CreateRetVoid()
}

func (c *compiler) buildExportData(mainPkg *ssa.Package) []byte {
	exportData := importer.ExportData(mainPkg.Object)
	b := bytes.NewBuffer(exportData)

	b.WriteString("v1;\n")
	if !c.GccgoABI {
		return b.Bytes()
	}

	initdata := c.buildPackageInitData(mainPkg)
	b.WriteString("priority ")
	b.WriteString(strconv.Itoa(initdata.Priority))
	b.WriteString(";\n")

	if len(initdata.Inits) != 0 {
		b.WriteString("init")
		for _, init := range initdata.Inits {
			b.WriteRune(' ')
			b.WriteString(init.Name)
			b.WriteRune(' ')
			b.WriteString(init.InitFunc)
			b.WriteRune(' ')
			b.WriteString(strconv.Itoa(init.Priority))
		}
		b.WriteString(";\n")
	}

	return b.Bytes()
}

// vim: set ft=go :
