github.com/llvm-mirror/llgo@v0.0.0-20190322182713-bf6f0a60fce1/irgen/ssa.go (about)

     1  //===- ssa.go - IR generation from go/ssa ---------------------------------===//
     2  //
     3  // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
     4  // See https://llvm.org/LICENSE.txt for license information.
     5  // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
     6  //
     7  //===----------------------------------------------------------------------===//
     8  //
     9  // This file implements the top-level LLVM IR generation from go/ssa form.
    10  //
    11  //===----------------------------------------------------------------------===//
    12  
    13  package irgen
    14  
    15  import (
    16  	"fmt"
    17  	"go/ast"
    18  	"go/token"
    19  	"os"
    20  	"sort"
    21  
    22  	"llvm.org/llgo/ssaopt"
    23  	"llvm.org/llgo/third_party/gotools/go/ssa"
    24  	"llvm.org/llgo/third_party/gotools/go/ssa/ssautil"
    25  	"llvm.org/llgo/third_party/gotools/go/types"
    26  	"llvm.org/llvm/bindings/go/llvm"
    27  )
    28  
    29  // A globalInit is used to temporarily store a global's initializer until
    30  // we are ready to build it.
    31  type globalInit struct {
    32  	val   llvm.Value
    33  	elems []globalInit
    34  }
    35  
    36  func (gi *globalInit) update(typ llvm.Type, indices []uint32, val llvm.Value) {
    37  	if len(indices) == 0 {
    38  		gi.val = val
    39  		return
    40  	}
    41  
    42  	if gi.val.C != nil {
    43  		gi.val = llvm.ConstInsertValue(gi.val, val, indices)
    44  	}
    45  
    46  	tk := typ.TypeKind()
    47  
    48  	if len(gi.elems) == 0 {
    49  		switch tk {
    50  		case llvm.StructTypeKind:
    51  			gi.elems = make([]globalInit, typ.StructElementTypesCount())
    52  		case llvm.ArrayTypeKind:
    53  			gi.elems = make([]globalInit, typ.ArrayLength())
    54  		default:
    55  			panic("unexpected type")
    56  		}
    57  	}
    58  
    59  	var eltyp llvm.Type
    60  	switch tk {
    61  	case llvm.StructTypeKind:
    62  		eltyp = typ.StructElementTypes()[indices[0]]
    63  	case llvm.ArrayTypeKind:
    64  		eltyp = typ.ElementType()
    65  	default:
    66  		panic("unexpected type")
    67  	}
    68  
    69  	gi.elems[indices[0]].update(eltyp, indices[1:], val)
    70  }
    71  
    72  func (gi *globalInit) build(typ llvm.Type) llvm.Value {
    73  	if gi.val.C != nil {
    74  		return gi.val
    75  	}
    76  	if len(gi.elems) == 0 {
    77  		return llvm.ConstNull(typ)
    78  	}
    79  
    80  	switch typ.TypeKind() {
    81  	case llvm.StructTypeKind:
    82  		eltypes := typ.StructElementTypes()
    83  		elems := make([]llvm.Value, len(eltypes))
    84  		for i, eltyp := range eltypes {
    85  			elems[i] = gi.elems[i].build(eltyp)
    86  		}
    87  		return llvm.ConstStruct(elems, false)
    88  	case llvm.ArrayTypeKind:
    89  		eltyp := typ.ElementType()
    90  		elems := make([]llvm.Value, len(gi.elems))
    91  		for i := range gi.elems {
    92  			elems[i] = gi.elems[i].build(eltyp)
    93  		}
    94  		return llvm.ConstArray(eltyp, elems)
    95  	default:
    96  		panic("unexpected type")
    97  	}
    98  }
    99  
   100  type unit struct {
   101  	*compiler
   102  	pkg         *ssa.Package
   103  	globals     map[ssa.Value]llvm.Value
   104  	globalInits map[llvm.Value]*globalInit
   105  
   106  	// funcDescriptors maps *ssa.Functions to function descriptors,
   107  	// the first-class representation of functions.
   108  	funcDescriptors map[*ssa.Function]llvm.Value
   109  
   110  	// undefinedFuncs contains functions that have been resolved
   111  	// (declared) but not defined.
   112  	undefinedFuncs map[*ssa.Function]bool
   113  
   114  	gcRoots []llvm.Value
   115  }
   116  
   117  func newUnit(c *compiler, pkg *ssa.Package) *unit {
   118  	u := &unit{
   119  		compiler:        c,
   120  		pkg:             pkg,
   121  		globals:         make(map[ssa.Value]llvm.Value),
   122  		globalInits:     make(map[llvm.Value]*globalInit),
   123  		funcDescriptors: make(map[*ssa.Function]llvm.Value),
   124  		undefinedFuncs:  make(map[*ssa.Function]bool),
   125  	}
   126  	return u
   127  }
   128  
   129  type byMemberName []ssa.Member
   130  
   131  func (ms byMemberName) Len() int { return len(ms) }
   132  func (ms byMemberName) Swap(i, j int) {
   133  	ms[i], ms[j] = ms[j], ms[i]
   134  }
   135  func (ms byMemberName) Less(i, j int) bool {
   136  	return ms[i].Name() < ms[j].Name()
   137  }
   138  
   139  type byFunctionString []*ssa.Function
   140  
   141  func (fns byFunctionString) Len() int { return len(fns) }
   142  func (fns byFunctionString) Swap(i, j int) {
   143  	fns[i], fns[j] = fns[j], fns[i]
   144  }
   145  func (fns byFunctionString) Less(i, j int) bool {
   146  	return fns[i].String() < fns[j].String()
   147  }
   148  
   149  // Emit functions in order of their fully qualified names. This is so that a
   150  // bootstrap build can be verified by comparing the stage2 and stage3 binaries.
   151  func (u *unit) defineFunctionsInOrder(functions map[*ssa.Function]bool) {
   152  	fns := []*ssa.Function{}
   153  	for f, _ := range functions {
   154  		fns = append(fns, f)
   155  	}
   156  	sort.Sort(byFunctionString(fns))
   157  	for _, f := range fns {
   158  		u.defineFunction(f)
   159  	}
   160  }
   161  
   162  // translatePackage translates an *ssa.Package into an LLVM module, and returns
   163  // the translation unit information.
   164  func (u *unit) translatePackage(pkg *ssa.Package) {
   165  	ms := make([]ssa.Member, len(pkg.Members))
   166  	i := 0
   167  	for _, m := range pkg.Members {
   168  		ms[i] = m
   169  		i++
   170  	}
   171  
   172  	sort.Sort(byMemberName(ms))
   173  
   174  	// Initialize global storage and type descriptors for this package.
   175  	// We must create globals regardless of whether they're referenced,
   176  	// hence the duplication in frame.value.
   177  	for _, m := range ms {
   178  		switch v := m.(type) {
   179  		case *ssa.Global:
   180  			elemtyp := deref(v.Type())
   181  			llelemtyp := u.llvmtypes.ToLLVM(elemtyp)
   182  			vname := u.types.mc.mangleGlobalName(v)
   183  			global := llvm.AddGlobal(u.module.Module, llelemtyp, vname)
   184  			if !v.Object().Exported() {
   185  				global.SetLinkage(llvm.InternalLinkage)
   186  			}
   187  			u.addGlobal(global, elemtyp)
   188  			global = llvm.ConstBitCast(global, u.llvmtypes.ToLLVM(v.Type()))
   189  			u.globals[v] = global
   190  		case *ssa.Type:
   191  			u.types.getTypeDescriptorPointer(v.Type())
   192  		}
   193  	}
   194  
   195  	// Define functions.
   196  	u.defineFunctionsInOrder(ssautil.AllFunctions(pkg.Prog))
   197  
   198  	// Emit initializers for type descriptors, which may trigger
   199  	// the resolution of additional functions.
   200  	u.types.emitTypeDescInitializers()
   201  
   202  	// Define remaining functions that were resolved during
   203  	// runtime type mapping, but not defined.
   204  	u.defineFunctionsInOrder(u.undefinedFuncs)
   205  
   206  	// Set initializers for globals.
   207  	for global, init := range u.globalInits {
   208  		initval := init.build(global.Type().ElementType())
   209  		global.SetInitializer(initval)
   210  	}
   211  }
   212  
   213  func (u *unit) addGlobal(global llvm.Value, ty types.Type) {
   214  	u.globalInits[global] = new(globalInit)
   215  
   216  	if hasPointers(ty) {
   217  		global = llvm.ConstBitCast(global, llvm.PointerType(llvm.Int8Type(), 0))
   218  		size := llvm.ConstInt(u.types.inttype, uint64(u.types.Sizeof(ty)), false)
   219  		root := llvm.ConstStruct([]llvm.Value{global, size}, false)
   220  		u.gcRoots = append(u.gcRoots, root)
   221  	}
   222  }
   223  
   224  // ResolveMethod implements MethodResolver.ResolveMethod.
   225  func (u *unit) ResolveMethod(s *types.Selection) *govalue {
   226  	m := u.pkg.Prog.Method(s)
   227  	llfn := u.resolveFunctionGlobal(m)
   228  	llfn = llvm.ConstBitCast(llfn, llvm.PointerType(llvm.Int8Type(), 0))
   229  	return newValue(llfn, m.Signature)
   230  }
   231  
   232  // resolveFunctionDescriptorGlobal returns a reference to the LLVM global
   233  // storing the function's descriptor.
   234  func (u *unit) resolveFunctionDescriptorGlobal(f *ssa.Function) llvm.Value {
   235  	llfd, ok := u.funcDescriptors[f]
   236  	if !ok {
   237  		name := u.types.mc.mangleFunctionName(f) + "$descriptor"
   238  		llfd = llvm.AddGlobal(u.module.Module, llvm.PointerType(llvm.Int8Type(), 0), name)
   239  		llfd.SetGlobalConstant(true)
   240  		u.funcDescriptors[f] = llfd
   241  	}
   242  	return llfd
   243  }
   244  
   245  // resolveFunctionDescriptor returns a function's
   246  // first-class value representation.
   247  func (u *unit) resolveFunctionDescriptor(f *ssa.Function) *govalue {
   248  	llfd := u.resolveFunctionDescriptorGlobal(f)
   249  	llfd = llvm.ConstBitCast(llfd, llvm.PointerType(llvm.Int8Type(), 0))
   250  	return newValue(llfd, f.Signature)
   251  }
   252  
   253  // resolveFunctionGlobal returns an llvm.Value for a function global.
   254  func (u *unit) resolveFunctionGlobal(f *ssa.Function) llvm.Value {
   255  	if v, ok := u.globals[f]; ok {
   256  		return v
   257  	}
   258  	name := u.types.mc.mangleFunctionName(f)
   259  	// It's possible that the function already exists in the module;
   260  	// for example, if it's a runtime intrinsic that the compiler
   261  	// has already referenced.
   262  	llvmFunction := u.module.Module.NamedFunction(name)
   263  	if llvmFunction.IsNil() {
   264  		fti := u.llvmtypes.getSignatureInfo(f.Signature)
   265  		llvmFunction = fti.declare(u.module.Module, name)
   266  		u.undefinedFuncs[f] = true
   267  	}
   268  	u.globals[f] = llvmFunction
   269  	return llvmFunction
   270  }
   271  
   272  func (u *unit) getFunctionLinkage(f *ssa.Function) llvm.Linkage {
   273  	switch {
   274  	case f.Pkg == nil:
   275  		// Synthetic functions outside packages may appear in multiple packages.
   276  		return llvm.LinkOnceODRLinkage
   277  
   278  	case f.Parent() != nil:
   279  		// Anonymous.
   280  		return llvm.InternalLinkage
   281  
   282  	case f.Signature.Recv() == nil && !ast.IsExported(f.Name()) &&
   283  		!(f.Name() == "main" && f.Pkg.Object.Path() == "main") &&
   284  		f.Name() != "init":
   285  		// Unexported methods may be referenced as part of an interface method
   286  		// table in another package. TODO(pcc): detect when this cannot happen.
   287  		return llvm.InternalLinkage
   288  
   289  	default:
   290  		return llvm.ExternalLinkage
   291  	}
   292  }
   293  
   294  func (u *unit) defineFunction(f *ssa.Function) {
   295  	// Only define functions from this package, or synthetic
   296  	// wrappers (which do not have a package).
   297  	if f.Pkg != nil && f.Pkg != u.pkg {
   298  		return
   299  	}
   300  
   301  	llfn := u.resolveFunctionGlobal(f)
   302  	linkage := u.getFunctionLinkage(f)
   303  
   304  	isMethod := f.Signature.Recv() != nil
   305  
   306  	// Methods cannot be referred to via a descriptor.
   307  	if !isMethod {
   308  		llfd := u.resolveFunctionDescriptorGlobal(f)
   309  		llfd.SetInitializer(llvm.ConstBitCast(llfn, llvm.PointerType(llvm.Int8Type(), 0)))
   310  		llfd.SetLinkage(linkage)
   311  	}
   312  
   313  	// We only need to emit a descriptor for functions without bodies.
   314  	if len(f.Blocks) == 0 {
   315  		return
   316  	}
   317  
   318  	ssaopt.LowerAllocsToStack(f)
   319  
   320  	if u.DumpSSA {
   321  		f.WriteTo(os.Stderr)
   322  	}
   323  
   324  	fr := newFrame(u, llfn)
   325  	defer fr.dispose()
   326  	fr.addCommonFunctionAttrs(fr.function)
   327  	fr.function.SetLinkage(linkage)
   328  
   329  	fr.logf("Define function: %s @ %s", f.String(), fr.pkg.Prog.Fset.Position(f.Pos()))
   330  	fti := u.llvmtypes.getSignatureInfo(f.Signature)
   331  	delete(u.undefinedFuncs, f)
   332  	fr.retInf = fti.retInf
   333  
   334  	// Push the compile unit and function onto the debug context.
   335  	if u.GenerateDebug {
   336  		u.debug.PushFunction(fr.function, f.Signature, f.Pos())
   337  		defer u.debug.PopFunction()
   338  		u.debug.SetLocation(fr.builder, f.Pos())
   339  	}
   340  
   341  	// If a function calls recover, we create a separate function to
   342  	// hold the real function, and this function calls __go_can_recover
   343  	// and bridges to it.
   344  	if callsRecover(f) {
   345  		fr = fr.bridgeRecoverFunc(fr.function, fti)
   346  	}
   347  
   348  	fr.blocks = make([]llvm.BasicBlock, len(f.Blocks))
   349  	fr.lastBlocks = make([]llvm.BasicBlock, len(f.Blocks))
   350  	for i, block := range f.Blocks {
   351  		fr.blocks[i] = llvm.AddBasicBlock(fr.function, fmt.Sprintf(".%d.%s", i, block.Comment))
   352  	}
   353  	fr.builder.SetInsertPointAtEnd(fr.blocks[0])
   354  	fr.transformSwitches(f)
   355  
   356  	prologueBlock := llvm.InsertBasicBlock(fr.blocks[0], "prologue")
   357  	fr.builder.SetInsertPointAtEnd(prologueBlock)
   358  
   359  	for i, param := range f.Params {
   360  		llparam := fti.argInfos[i].decode(llvm.GlobalContext(), fr.builder, fr.builder)
   361  		if isMethod && i == 0 {
   362  			if _, ok := param.Type().Underlying().(*types.Pointer); !ok {
   363  				llparam = fr.builder.CreateBitCast(llparam, llvm.PointerType(fr.types.ToLLVM(param.Type()), 0), "")
   364  				llparam = fr.builder.CreateLoad(llparam, "")
   365  			}
   366  		}
   367  		fr.env[param] = newValue(llparam, param.Type())
   368  	}
   369  
   370  	// Load closure, extract free vars.
   371  	if len(f.FreeVars) > 0 {
   372  		for _, fv := range f.FreeVars {
   373  			fr.env[fv] = newValue(llvm.ConstNull(u.llvmtypes.ToLLVM(fv.Type())), fv.Type())
   374  		}
   375  		elemTypes := make([]llvm.Type, len(f.FreeVars)+1)
   376  		elemTypes[0] = llvm.PointerType(llvm.Int8Type(), 0) // function pointer
   377  		for i, fv := range f.FreeVars {
   378  			elemTypes[i+1] = u.llvmtypes.ToLLVM(fv.Type())
   379  		}
   380  		structType := llvm.StructType(elemTypes, false)
   381  		closure := fr.function.Param(fti.chainIndex)
   382  		closure = fr.builder.CreateBitCast(closure, llvm.PointerType(structType, 0), "")
   383  		for i, fv := range f.FreeVars {
   384  			ptr := fr.builder.CreateStructGEP(closure, i+1, "")
   385  			ptr = fr.builder.CreateLoad(ptr, "")
   386  			fr.env[fv] = newValue(ptr, fv.Type())
   387  		}
   388  	}
   389  
   390  	// Allocate stack space for locals in the prologue block.
   391  	for _, local := range f.Locals {
   392  		typ := fr.llvmtypes.ToLLVM(deref(local.Type()))
   393  		alloca := fr.builder.CreateAlloca(typ, local.Comment)
   394  		fr.memsetZero(alloca, llvm.SizeOf(typ))
   395  		bcalloca := fr.builder.CreateBitCast(alloca, llvm.PointerType(llvm.Int8Type(), 0), "")
   396  		value := newValue(bcalloca, local.Type())
   397  		fr.env[local] = value
   398  	}
   399  
   400  	// If the function contains any defers, we must first create
   401  	// an unwind block. We can short-circuit the check for defers with
   402  	// f.Recover != nil.
   403  	if f.Recover != nil || hasDefer(f) {
   404  		fr.unwindBlock = llvm.AddBasicBlock(fr.function, "unwind")
   405  		fr.frameptr = fr.builder.CreateAlloca(llvm.Int8Type(), "")
   406  	}
   407  
   408  	// Keep track of the block into which we need to insert the call
   409  	// to __go_register_gc_roots. This needs to be inserted after the
   410  	// init guard check under the llgo ABI.
   411  	var registerGcBlock llvm.BasicBlock
   412  
   413  	// If this is the "init" function, emit the init guard check and
   414  	// enable init-specific optimizations.
   415  	if !isMethod && f.Name() == "init" {
   416  		registerGcBlock = fr.emitInitPrologue()
   417  		fr.isInit = true
   418  	}
   419  
   420  	fr.builder.CreateBr(fr.blocks[0])
   421  	fr.allocaBuilder.SetInsertPointBefore(prologueBlock.FirstInstruction())
   422  
   423  	for _, block := range f.DomPreorder() {
   424  		llblock := fr.blocks[block.Index]
   425  		if llblock.IsNil() {
   426  			continue
   427  		}
   428  		fr.translateBlock(block, llblock)
   429  	}
   430  
   431  	fr.fixupPhis()
   432  
   433  	if !fr.unwindBlock.IsNil() {
   434  		fr.setupUnwindBlock(f.Recover)
   435  	}
   436  
   437  	// The init function needs to register the GC roots first. We do this
   438  	// after generating code for it because allocations may have caused
   439  	// additional GC roots to be created.
   440  	if fr.isInit {
   441  		fr.builder.SetInsertPointBefore(registerGcBlock.FirstInstruction())
   442  		fr.registerGcRoots()
   443  	}
   444  }
   445  
   446  type pendingPhi struct {
   447  	ssa  *ssa.Phi
   448  	llvm llvm.Value
   449  }
   450  
   451  type frame struct {
   452  	*unit
   453  	function               llvm.Value
   454  	builder, allocaBuilder llvm.Builder
   455  	retInf                 retInfo
   456  	blocks                 []llvm.BasicBlock
   457  	lastBlocks             []llvm.BasicBlock
   458  	runtimeErrorBlocks     [gccgoRuntimeErrorCount]llvm.BasicBlock
   459  	unwindBlock            llvm.BasicBlock
   460  	frameptr               llvm.Value
   461  	env                    map[ssa.Value]*govalue
   462  	ptr                    map[ssa.Value]llvm.Value
   463  	tuples                 map[ssa.Value][]*govalue
   464  	phis                   []pendingPhi
   465  	canRecover             llvm.Value
   466  	isInit                 bool
   467  }
   468  
   469  func newFrame(u *unit, fn llvm.Value) *frame {
   470  	return &frame{
   471  		unit:          u,
   472  		function:      fn,
   473  		builder:       llvm.GlobalContext().NewBuilder(),
   474  		allocaBuilder: llvm.GlobalContext().NewBuilder(),
   475  		env:           make(map[ssa.Value]*govalue),
   476  		ptr:           make(map[ssa.Value]llvm.Value),
   477  		tuples:        make(map[ssa.Value][]*govalue),
   478  	}
   479  }
   480  
   481  func (fr *frame) dispose() {
   482  	fr.builder.Dispose()
   483  	fr.allocaBuilder.Dispose()
   484  }
   485  
   486  // emitInitPrologue emits the init-specific function prologue (guard check and
   487  // initialization of dependent packages under the llgo native ABI), and returns
   488  // the basic block into which the GC registration call should be emitted.
   489  func (fr *frame) emitInitPrologue() llvm.BasicBlock {
   490  	if fr.GccgoABI {
   491  		return fr.builder.GetInsertBlock()
   492  	}
   493  
   494  	initGuard := llvm.AddGlobal(fr.module.Module, llvm.Int1Type(), "init$guard")
   495  	initGuard.SetLinkage(llvm.InternalLinkage)
   496  	initGuard.SetInitializer(llvm.ConstNull(llvm.Int1Type()))
   497  
   498  	returnBlock := llvm.AddBasicBlock(fr.function, "")
   499  	initBlock := llvm.AddBasicBlock(fr.function, "")
   500  
   501  	initGuardVal := fr.builder.CreateLoad(initGuard, "")
   502  	fr.builder.CreateCondBr(initGuardVal, returnBlock, initBlock)
   503  
   504  	fr.builder.SetInsertPointAtEnd(returnBlock)
   505  	fr.builder.CreateRetVoid()
   506  
   507  	fr.builder.SetInsertPointAtEnd(initBlock)
   508  	fr.builder.CreateStore(llvm.ConstInt(llvm.Int1Type(), 1, false), initGuard)
   509  	int8ptr := llvm.PointerType(fr.types.ctx.Int8Type(), 0)
   510  	ftyp := llvm.FunctionType(llvm.VoidType(), []llvm.Type{int8ptr}, false)
   511  	for _, pkg := range fr.pkg.Object.Imports() {
   512  		initname := ManglePackagePath(pkg.Path()) + "..import"
   513  		initfn := fr.module.Module.NamedFunction(initname)
   514  		if initfn.IsNil() {
   515  			initfn = llvm.AddFunction(fr.module.Module, initname, ftyp)
   516  		}
   517  		args := []llvm.Value{llvm.Undef(int8ptr)}
   518  		fr.builder.CreateCall(initfn, args, "")
   519  	}
   520  
   521  	return initBlock
   522  }
   523  
   524  // bridgeRecoverFunc creates a function that may call recover(), and creates
   525  // a call to it from the current frame. The created function will be called
   526  // with a boolean parameter that indicates whether it may call recover().
   527  //
   528  // The created function will have the same name as the current frame's function
   529  // with "$recover" appended, having the same return types and parameters with
   530  // an additional boolean parameter appended.
   531  //
   532  // A new frame will be returned for the newly created function.
   533  func (fr *frame) bridgeRecoverFunc(llfn llvm.Value, fti functionTypeInfo) *frame {
   534  	// The bridging function must not be inlined, or the return address
   535  	// may not correspond to the source function.
   536  	attrKind := llvm.AttributeKindID("noinline")
   537  	noInlineAttr := fr.module.Context().CreateEnumAttribute(attrKind, 0)
   538  	llfn.AddFunctionAttr(noInlineAttr)
   539  
   540  	// Call __go_can_recover, passing in the function's return address.
   541  	entry := llvm.AddBasicBlock(llfn, "entry")
   542  	fr.builder.SetInsertPointAtEnd(entry)
   543  	canRecover := fr.runtime.canRecover.call(fr, fr.returnAddress(0))[0]
   544  	returnType := fti.functionType.ReturnType()
   545  	argTypes := fti.functionType.ParamTypes()
   546  	argTypes = append(argTypes, canRecover.Type())
   547  
   548  	// Create and call the $recover function.
   549  	ftiRecover := fti
   550  	ftiRecover.functionType = llvm.FunctionType(returnType, argTypes, false)
   551  	llfnRecover := ftiRecover.declare(fr.module.Module, llfn.Name()+"$recover")
   552  	fr.addCommonFunctionAttrs(llfnRecover)
   553  	llfnRecover.SetLinkage(llvm.InternalLinkage)
   554  	args := make([]llvm.Value, len(argTypes)-1, len(argTypes))
   555  	for i := range args {
   556  		args[i] = llfn.Param(i)
   557  	}
   558  	args = append(args, canRecover)
   559  	result := fr.builder.CreateCall(llfnRecover, args, "")
   560  	if returnType.TypeKind() == llvm.VoidTypeKind {
   561  		fr.builder.CreateRetVoid()
   562  	} else {
   563  		fr.builder.CreateRet(result)
   564  	}
   565  
   566  	// The $recover function must condition calls to __go_recover on
   567  	// the result of __go_can_recover passed in as an argument.
   568  	fr = newFrame(fr.unit, llfnRecover)
   569  	fr.retInf = ftiRecover.retInf
   570  	fr.canRecover = fr.function.Param(len(argTypes) - 1)
   571  	return fr
   572  }
   573  
   574  func (fr *frame) registerGcRoots() {
   575  	if len(fr.gcRoots) != 0 {
   576  		rootty := fr.gcRoots[0].Type()
   577  		roots := append(fr.gcRoots, llvm.ConstNull(rootty))
   578  		rootsarr := llvm.ConstArray(rootty, roots)
   579  		rootsstruct := llvm.ConstStruct([]llvm.Value{llvm.ConstNull(llvm.PointerType(llvm.Int8Type(), 0)), rootsarr}, false)
   580  
   581  		rootsglobal := llvm.AddGlobal(fr.module.Module, rootsstruct.Type(), "")
   582  		rootsglobal.SetInitializer(rootsstruct)
   583  		rootsglobal.SetLinkage(llvm.InternalLinkage)
   584  		fr.runtime.registerGcRoots.callOnly(fr, llvm.ConstBitCast(rootsglobal, llvm.PointerType(llvm.Int8Type(), 0)))
   585  	}
   586  }
   587  
   588  func (fr *frame) fixupPhis() {
   589  	for _, phi := range fr.phis {
   590  		values := make([]llvm.Value, len(phi.ssa.Edges))
   591  		blocks := make([]llvm.BasicBlock, len(phi.ssa.Edges))
   592  		block := phi.ssa.Block()
   593  		for i, edge := range phi.ssa.Edges {
   594  			values[i] = fr.llvmvalue(edge)
   595  			blocks[i] = fr.lastBlock(block.Preds[i])
   596  		}
   597  		phi.llvm.AddIncoming(values, blocks)
   598  	}
   599  }
   600  
   601  func (fr *frame) createLandingPad(cleanup bool) llvm.Value {
   602  	fr.function.SetPersonality(fr.runtime.gccgoPersonality)
   603  	lp := fr.builder.CreateLandingPad(fr.runtime.gccgoExceptionType, 0, "")
   604  	if cleanup {
   605  		lp.SetCleanup(true)
   606  	} else {
   607  		lp.AddClause(llvm.ConstNull(llvm.PointerType(llvm.Int8Type(), 0)))
   608  	}
   609  	return lp
   610  }
   611  
   612  // Runs defers. If a defer panics, check for recovers in later defers.
   613  func (fr *frame) runDefers() {
   614  	loopbb := llvm.AddBasicBlock(fr.function, "")
   615  	fr.builder.CreateBr(loopbb)
   616  
   617  	retrylpad := llvm.AddBasicBlock(fr.function, "")
   618  	fr.builder.SetInsertPointAtEnd(retrylpad)
   619  	fr.createLandingPad(false)
   620  	fr.runtime.checkDefer.callOnly(fr, fr.frameptr)
   621  	fr.builder.CreateBr(loopbb)
   622  
   623  	fr.builder.SetInsertPointAtEnd(loopbb)
   624  	fr.runtime.undefer.invoke(fr, retrylpad, fr.frameptr)
   625  }
   626  
   627  func (fr *frame) setupUnwindBlock(rec *ssa.BasicBlock) {
   628  	var recoverbb llvm.BasicBlock
   629  	if rec != nil {
   630  		recoverbb = fr.blocks[rec.Index]
   631  	} else {
   632  		recoverbb = llvm.AddBasicBlock(fr.function, "recover")
   633  		fr.builder.SetInsertPointAtEnd(recoverbb)
   634  		fr.builder.CreateUnreachable()
   635  	}
   636  
   637  	checkunwindbb := llvm.AddBasicBlock(fr.function, "")
   638  	fr.builder.SetInsertPointAtEnd(checkunwindbb)
   639  	exc := fr.createLandingPad(true)
   640  	fr.runDefers()
   641  
   642  	frame := fr.builder.CreateLoad(fr.frameptr, "")
   643  	shouldresume := fr.builder.CreateIsNull(frame, "")
   644  
   645  	resumebb := llvm.AddBasicBlock(fr.function, "")
   646  	fr.builder.CreateCondBr(shouldresume, resumebb, recoverbb)
   647  
   648  	fr.builder.SetInsertPointAtEnd(resumebb)
   649  	fr.builder.CreateResume(exc)
   650  
   651  	fr.builder.SetInsertPointAtEnd(fr.unwindBlock)
   652  	fr.createLandingPad(false)
   653  	fr.runtime.checkDefer.invoke(fr, checkunwindbb, fr.frameptr)
   654  	fr.runDefers()
   655  	fr.builder.CreateBr(recoverbb)
   656  }
   657  
   658  func (fr *frame) translateBlock(b *ssa.BasicBlock, llb llvm.BasicBlock) {
   659  	fr.builder.SetInsertPointAtEnd(llb)
   660  	for _, instr := range b.Instrs {
   661  		fr.instruction(instr)
   662  	}
   663  	fr.lastBlocks[b.Index] = fr.builder.GetInsertBlock()
   664  }
   665  
   666  func (fr *frame) block(b *ssa.BasicBlock) llvm.BasicBlock {
   667  	return fr.blocks[b.Index]
   668  }
   669  
   670  func (fr *frame) lastBlock(b *ssa.BasicBlock) llvm.BasicBlock {
   671  	return fr.lastBlocks[b.Index]
   672  }
   673  
   674  func (fr *frame) value(v ssa.Value) (result *govalue) {
   675  	switch v := v.(type) {
   676  	case nil:
   677  		return nil
   678  	case *ssa.Function:
   679  		return fr.resolveFunctionDescriptor(v)
   680  	case *ssa.Const:
   681  		return fr.newValueFromConst(v.Value, v.Type())
   682  	case *ssa.Global:
   683  		if g, ok := fr.globals[v]; ok {
   684  			return newValue(g, v.Type())
   685  		}
   686  		// Create an external global. Globals for this package are defined
   687  		// on entry to translatePackage, and have initialisers.
   688  		llelemtyp := fr.llvmtypes.ToLLVM(deref(v.Type()))
   689  		vname := fr.types.mc.mangleGlobalName(v)
   690  		llglobal := llvm.AddGlobal(fr.module.Module, llelemtyp, vname)
   691  		llglobal = llvm.ConstBitCast(llglobal, fr.llvmtypes.ToLLVM(v.Type()))
   692  		fr.globals[v] = llglobal
   693  		return newValue(llglobal, v.Type())
   694  	}
   695  	if value, ok := fr.env[v]; ok {
   696  		return value
   697  	}
   698  
   699  	panic(fmt.Errorf("Instruction %q not visited yet", v.Name()))
   700  }
   701  
   702  func (fr *frame) llvmvalue(v ssa.Value) llvm.Value {
   703  	if gv := fr.value(v); gv != nil {
   704  		return gv.value
   705  	} else {
   706  		return llvm.Value{nil}
   707  	}
   708  }
   709  
   710  func (fr *frame) isNonNull(v ssa.Value) bool {
   711  	switch v.(type) {
   712  	case
   713  		// Globals have a fixed (non-nil) address.
   714  		*ssa.Global,
   715  		// The language does not specify what happens if an allocation fails.
   716  		*ssa.Alloc,
   717  		// These have already been nil checked.
   718  		*ssa.FieldAddr, *ssa.IndexAddr:
   719  		return true
   720  	default:
   721  		return false
   722  	}
   723  }
   724  
   725  func (fr *frame) nilCheck(v ssa.Value, llptr llvm.Value) {
   726  	if !fr.isNonNull(v) {
   727  		ptrnull := fr.builder.CreateIsNull(llptr, "")
   728  		fr.condBrRuntimeError(ptrnull, gccgoRuntimeErrorNIL_DEREFERENCE)
   729  	}
   730  }
   731  
   732  func (fr *frame) canAvoidElementLoad(ptr ssa.Value) bool {
   733  	for _, ref := range *ptr.Referrers() {
   734  		switch ref := ref.(type) {
   735  		case *ssa.Field:
   736  		case *ssa.Index:
   737  			if ref.X != ptr {
   738  				return false
   739  			}
   740  			// ok
   741  		default:
   742  			return false
   743  		}
   744  	}
   745  
   746  	return true
   747  }
   748  
   749  // If this value is sufficiently large, look through referrers to see if we can
   750  // avoid a load.
   751  func (fr *frame) canAvoidLoad(instr *ssa.UnOp, op llvm.Value) bool {
   752  	if fr.types.Sizeof(instr.Type()) < 2*fr.types.Sizeof(types.Typ[types.Int]) {
   753  		// Don't bother with small values.
   754  		return false
   755  	}
   756  
   757  	// Keep track of whether our pointer may escape. We conservatively assume
   758  	// that MakeInterfaces will escape.
   759  	esc := false
   760  
   761  	// We only know how to avoid loads if they are used to create an interface
   762  	// or read an element of the structure. If we see any other referrer, abort.
   763  	for _, ref := range *instr.Referrers() {
   764  		switch ref := ref.(type) {
   765  		case *ssa.MakeInterface:
   766  			esc = true
   767  		case *ssa.Field:
   768  		case *ssa.Index:
   769  			if ref.X != instr {
   770  				// This should never happen, as indices are always of type int
   771  				// and we don't bother with values smaller than 2*sizeof(int).
   772  				panic("impossible")
   773  			}
   774  			// ok
   775  		default:
   776  			return false
   777  		}
   778  	}
   779  
   780  	var opcopy llvm.Value
   781  	if esc {
   782  		opcopy = fr.createTypeMalloc(instr.Type())
   783  	} else {
   784  		opcopy = fr.allocaBuilder.CreateAlloca(fr.types.ToLLVM(instr.Type()), "")
   785  	}
   786  	fr.memcpy(opcopy, op, llvm.ConstInt(fr.types.inttype, uint64(fr.types.Sizeof(instr.Type())), false))
   787  
   788  	fr.ptr[instr] = opcopy
   789  	return true
   790  }
   791  
   792  // Return true iff we think it might be beneficial to turn this alloc instruction
   793  // into a statically allocated global.
   794  // Precondition: we are compiling the init function.
   795  func (fr *frame) shouldStaticallyAllocate(alloc *ssa.Alloc) bool {
   796  	// First, see if the allocated type is an array or struct, and if so determine
   797  	// the number of elements in the type. If the type is anything else, we
   798  	// statically allocate unconditionally.
   799  	var numElems int64
   800  	switch ty := deref(alloc.Type()).Underlying().(type) {
   801  	case *types.Array:
   802  		numElems = ty.Len()
   803  	case *types.Struct:
   804  		numElems = int64(ty.NumFields())
   805  	default:
   806  		return true
   807  	}
   808  
   809  	// We treat the number of referrers to the alloc instruction as a rough
   810  	// proxy for the number of elements initialized. If the data structure
   811  	// is densely initialized (> 1/4 elements initialized), enable the
   812  	// optimization.
   813  	return int64(len(*alloc.Referrers()))*4 > numElems
   814  }
   815  
   816  // If val is a constant and addr refers to a global variable which is defined in
   817  // this module or an element thereof, simulate the effect of storing val at addr
   818  // in the global variable's initializer and return true, otherwise return false.
   819  // Precondition: we are compiling the init function.
   820  func (fr *frame) maybeStoreInInitializer(val, addr llvm.Value) bool {
   821  	if val.IsAConstant().IsNil() {
   822  		return false
   823  	}
   824  
   825  	if !addr.IsAConstantExpr().IsNil() && addr.OperandsCount() >= 2 &&
   826  		// TODO(pcc): Explicitly check that this is a constant GEP.
   827  		// I don't think there are any other kinds of constantexpr which
   828  		// satisfy the conditions we test for here, so this is probably safe.
   829  		!addr.Operand(0).IsAGlobalVariable().IsNil() &&
   830  		addr.Operand(1).IsNull() {
   831  		gv := addr.Operand(0)
   832  		globalInit, ok := fr.globalInits[gv]
   833  		if !ok {
   834  			return false
   835  		}
   836  		indices := make([]uint32, addr.OperandsCount()-2)
   837  		for i := range indices {
   838  			op := addr.Operand(i + 2)
   839  			if op.IsAConstantInt().IsNil() {
   840  				return false
   841  			}
   842  			indices[i] = uint32(op.ZExtValue())
   843  		}
   844  		globalInit.update(gv.Type().ElementType(), indices, val)
   845  		return true
   846  	} else if !addr.IsAGlobalVariable().IsNil() {
   847  		if globalInit, ok := fr.globalInits[addr]; ok {
   848  			globalInit.update(addr.Type().ElementType(), nil, val)
   849  			return true
   850  		}
   851  		return false
   852  	} else {
   853  		return false
   854  	}
   855  }
   856  
   857  func (fr *frame) instruction(instr ssa.Instruction) {
   858  	fr.logf("[%T] %v @ %s\n", instr, instr, fr.pkg.Prog.Fset.Position(instr.Pos()))
   859  	if fr.GenerateDebug {
   860  		fr.debug.SetLocation(fr.builder, instr.Pos())
   861  	}
   862  
   863  	switch instr := instr.(type) {
   864  	case *ssa.Alloc:
   865  		typ := deref(instr.Type())
   866  		llvmtyp := fr.llvmtypes.ToLLVM(typ)
   867  		var value llvm.Value
   868  		if !instr.Heap {
   869  			value = fr.env[instr].value
   870  			fr.memsetZero(value, llvm.SizeOf(llvmtyp))
   871  		} else if fr.isInit && fr.shouldStaticallyAllocate(instr) {
   872  			// If this is the init function and we think it may be beneficial,
   873  			// allocate memory statically in the object file rather than on the
   874  			// heap. This allows us to optimize constant stores into such
   875  			// variables as static initializations.
   876  			global := llvm.AddGlobal(fr.module.Module, llvmtyp, "")
   877  			global.SetLinkage(llvm.InternalLinkage)
   878  			fr.addGlobal(global, typ)
   879  			ptr := llvm.ConstBitCast(global, llvm.PointerType(llvm.Int8Type(), 0))
   880  			fr.env[instr] = newValue(ptr, instr.Type())
   881  		} else {
   882  			value = fr.createTypeMalloc(typ)
   883  			value.SetName(instr.Comment)
   884  			value = fr.builder.CreateBitCast(value, llvm.PointerType(llvm.Int8Type(), 0), "")
   885  			fr.env[instr] = newValue(value, instr.Type())
   886  		}
   887  
   888  	case *ssa.BinOp:
   889  		lhs, rhs := fr.value(instr.X), fr.value(instr.Y)
   890  		fr.env[instr] = fr.binaryOp(lhs, instr.Op, rhs)
   891  
   892  	case *ssa.Call:
   893  		tuple := fr.callInstruction(instr)
   894  		if len(tuple) == 1 {
   895  			fr.env[instr] = tuple[0]
   896  		} else {
   897  			fr.tuples[instr] = tuple
   898  		}
   899  
   900  	case *ssa.ChangeInterface:
   901  		x := fr.value(instr.X)
   902  		// The source type must be a non-empty interface,
   903  		// as ChangeInterface cannot fail (E2I may fail).
   904  		if instr.Type().Underlying().(*types.Interface).NumMethods() > 0 {
   905  			x = fr.changeInterface(x, instr.Type(), false)
   906  		} else {
   907  			x = fr.convertI2E(x)
   908  		}
   909  		fr.env[instr] = x
   910  
   911  	case *ssa.ChangeType:
   912  		value := fr.llvmvalue(instr.X)
   913  		if _, ok := instr.Type().Underlying().(*types.Pointer); ok {
   914  			value = fr.builder.CreateBitCast(value, fr.llvmtypes.ToLLVM(instr.Type()), "")
   915  		}
   916  		fr.env[instr] = newValue(value, instr.Type())
   917  
   918  	case *ssa.Convert:
   919  		v := fr.value(instr.X)
   920  		fr.env[instr] = fr.convert(v, instr.Type())
   921  
   922  	case *ssa.Defer:
   923  		fn, arg := fr.createThunk(instr)
   924  		fr.runtime.Defer.call(fr, fr.frameptr, fn, arg)
   925  
   926  	case *ssa.Extract:
   927  		var elem llvm.Value
   928  		if t, ok := fr.tuples[instr.Tuple]; ok {
   929  			elem = t[instr.Index].value
   930  		} else {
   931  			tuple := fr.llvmvalue(instr.Tuple)
   932  			elem = fr.builder.CreateExtractValue(tuple, instr.Index, instr.Name())
   933  		}
   934  		elemtyp := instr.Type()
   935  		fr.env[instr] = newValue(elem, elemtyp)
   936  
   937  	case *ssa.Field:
   938  		fieldtyp := instr.Type()
   939  		if p, ok := fr.ptr[instr.X]; ok {
   940  			field := fr.builder.CreateStructGEP(p, instr.Field, instr.Name())
   941  			if fr.canAvoidElementLoad(instr) {
   942  				fr.ptr[instr] = field
   943  			} else {
   944  				fr.env[instr] = newValue(fr.builder.CreateLoad(field, ""), fieldtyp)
   945  			}
   946  		} else {
   947  			value := fr.llvmvalue(instr.X)
   948  			field := fr.builder.CreateExtractValue(value, instr.Field, instr.Name())
   949  			fr.env[instr] = newValue(field, fieldtyp)
   950  		}
   951  
   952  	case *ssa.FieldAddr:
   953  		ptr := fr.llvmvalue(instr.X)
   954  		fr.nilCheck(instr.X, ptr)
   955  		xtyp := instr.X.Type().Underlying().(*types.Pointer).Elem()
   956  		ptrtyp := llvm.PointerType(fr.llvmtypes.ToLLVM(xtyp), 0)
   957  		ptr = fr.builder.CreateBitCast(ptr, ptrtyp, "")
   958  		fieldptr := fr.builder.CreateStructGEP(ptr, instr.Field, instr.Name())
   959  		fieldptr = fr.builder.CreateBitCast(fieldptr, llvm.PointerType(llvm.Int8Type(), 0), "")
   960  		fieldptrtyp := instr.Type()
   961  		fr.env[instr] = newValue(fieldptr, fieldptrtyp)
   962  
   963  	case *ssa.Go:
   964  		fn, arg := fr.createThunk(instr)
   965  		fr.runtime.Go.call(fr, fn, arg)
   966  
   967  	case *ssa.If:
   968  		cond := fr.llvmvalue(instr.Cond)
   969  		block := instr.Block()
   970  		trueBlock := fr.block(block.Succs[0])
   971  		falseBlock := fr.block(block.Succs[1])
   972  		cond = fr.builder.CreateTrunc(cond, llvm.Int1Type(), "")
   973  		fr.builder.CreateCondBr(cond, trueBlock, falseBlock)
   974  
   975  	case *ssa.Index:
   976  		var arrayptr llvm.Value
   977  
   978  		if ptr, ok := fr.ptr[instr.X]; ok {
   979  			arrayptr = ptr
   980  		} else {
   981  			array := fr.llvmvalue(instr.X)
   982  			arrayptr = fr.allocaBuilder.CreateAlloca(array.Type(), "")
   983  
   984  			fr.builder.CreateStore(array, arrayptr)
   985  		}
   986  		index := fr.llvmvalue(instr.Index)
   987  
   988  		arraytyp := instr.X.Type().Underlying().(*types.Array)
   989  		arraylen := llvm.ConstInt(fr.llvmtypes.inttype, uint64(arraytyp.Len()), false)
   990  
   991  		// The index may not have been promoted to int (for example, if it
   992  		// came from a composite literal).
   993  		index = fr.createZExtOrTrunc(index, fr.types.inttype, "")
   994  
   995  		// Bounds checking: 0 <= index < len
   996  		zero := llvm.ConstNull(fr.types.inttype)
   997  		i0 := fr.builder.CreateICmp(llvm.IntSLT, index, zero, "")
   998  		li := fr.builder.CreateICmp(llvm.IntSLE, arraylen, index, "")
   999  
  1000  		cond := fr.builder.CreateOr(i0, li, "")
  1001  
  1002  		fr.condBrRuntimeError(cond, gccgoRuntimeErrorARRAY_INDEX_OUT_OF_BOUNDS)
  1003  
  1004  		addr := fr.builder.CreateGEP(arrayptr, []llvm.Value{zero, index}, "")
  1005  		if fr.canAvoidElementLoad(instr) {
  1006  			fr.ptr[instr] = addr
  1007  		} else {
  1008  			fr.env[instr] = newValue(fr.builder.CreateLoad(addr, ""), instr.Type())
  1009  		}
  1010  
  1011  	case *ssa.IndexAddr:
  1012  		x := fr.llvmvalue(instr.X)
  1013  		index := fr.llvmvalue(instr.Index)
  1014  		var arrayptr, arraylen llvm.Value
  1015  		var elemtyp types.Type
  1016  		var errcode uint64
  1017  		switch typ := instr.X.Type().Underlying().(type) {
  1018  		case *types.Slice:
  1019  			elemtyp = typ.Elem()
  1020  			arrayptr = fr.builder.CreateExtractValue(x, 0, "")
  1021  			arraylen = fr.builder.CreateExtractValue(x, 1, "")
  1022  			errcode = gccgoRuntimeErrorSLICE_INDEX_OUT_OF_BOUNDS
  1023  		case *types.Pointer: // *array
  1024  			arraytyp := typ.Elem().Underlying().(*types.Array)
  1025  			elemtyp = arraytyp.Elem()
  1026  			fr.nilCheck(instr.X, x)
  1027  			arrayptr = x
  1028  			arraylen = llvm.ConstInt(fr.llvmtypes.inttype, uint64(arraytyp.Len()), false)
  1029  			errcode = gccgoRuntimeErrorARRAY_INDEX_OUT_OF_BOUNDS
  1030  		}
  1031  
  1032  		// The index may not have been promoted to int (for example, if it
  1033  		// came from a composite literal).
  1034  		index = fr.createZExtOrTrunc(index, fr.types.inttype, "")
  1035  
  1036  		// Bounds checking: 0 <= index < len
  1037  		zero := llvm.ConstNull(fr.types.inttype)
  1038  		i0 := fr.builder.CreateICmp(llvm.IntSLT, index, zero, "")
  1039  		li := fr.builder.CreateICmp(llvm.IntSLE, arraylen, index, "")
  1040  
  1041  		cond := fr.builder.CreateOr(i0, li, "")
  1042  
  1043  		fr.condBrRuntimeError(cond, errcode)
  1044  
  1045  		ptrtyp := llvm.PointerType(fr.llvmtypes.ToLLVM(elemtyp), 0)
  1046  		arrayptr = fr.builder.CreateBitCast(arrayptr, ptrtyp, "")
  1047  		addr := fr.builder.CreateGEP(arrayptr, []llvm.Value{index}, "")
  1048  		addr = fr.builder.CreateBitCast(addr, llvm.PointerType(llvm.Int8Type(), 0), "")
  1049  		fr.env[instr] = newValue(addr, types.NewPointer(elemtyp))
  1050  
  1051  	case *ssa.Jump:
  1052  		succ := instr.Block().Succs[0]
  1053  		fr.builder.CreateBr(fr.block(succ))
  1054  
  1055  	case *ssa.Lookup:
  1056  		x := fr.value(instr.X)
  1057  		index := fr.value(instr.Index)
  1058  		if isString(x.Type().Underlying()) {
  1059  			fr.env[instr] = fr.stringIndex(x, index)
  1060  		} else {
  1061  			v, ok := fr.mapLookup(x, index)
  1062  			if instr.CommaOk {
  1063  				fr.tuples[instr] = []*govalue{v, ok}
  1064  			} else {
  1065  				fr.env[instr] = v
  1066  			}
  1067  		}
  1068  
  1069  	case *ssa.MakeChan:
  1070  		fr.env[instr] = fr.makeChan(instr.Type(), fr.value(instr.Size))
  1071  
  1072  	case *ssa.MakeClosure:
  1073  		llfn := fr.resolveFunctionGlobal(instr.Fn.(*ssa.Function))
  1074  		llfn = llvm.ConstBitCast(llfn, llvm.PointerType(llvm.Int8Type(), 0))
  1075  		fn := newValue(llfn, instr.Fn.(*ssa.Function).Signature)
  1076  		bindings := make([]*govalue, len(instr.Bindings))
  1077  		for i, binding := range instr.Bindings {
  1078  			bindings[i] = fr.value(binding)
  1079  		}
  1080  		fr.env[instr] = fr.makeClosure(fn, bindings)
  1081  
  1082  	case *ssa.MakeInterface:
  1083  		// fr.ptr[instr.X] will be set if a pointer load was elided by canAvoidLoad
  1084  		if ptr, ok := fr.ptr[instr.X]; ok {
  1085  			fr.env[instr] = fr.makeInterfaceFromPointer(ptr, instr.X.Type(), instr.Type())
  1086  		} else {
  1087  			receiver := fr.llvmvalue(instr.X)
  1088  			fr.env[instr] = fr.makeInterface(receiver, instr.X.Type(), instr.Type())
  1089  		}
  1090  
  1091  	case *ssa.MakeMap:
  1092  		fr.env[instr] = fr.makeMap(instr.Type(), fr.value(instr.Reserve))
  1093  
  1094  	case *ssa.MakeSlice:
  1095  		length := fr.value(instr.Len)
  1096  		capacity := fr.value(instr.Cap)
  1097  		fr.env[instr] = fr.makeSlice(instr.Type(), length, capacity)
  1098  
  1099  	case *ssa.MapUpdate:
  1100  		m := fr.value(instr.Map)
  1101  		k := fr.value(instr.Key)
  1102  		v := fr.value(instr.Value)
  1103  		fr.mapUpdate(m, k, v)
  1104  
  1105  	case *ssa.Next:
  1106  		iter := fr.tuples[instr.Iter]
  1107  		if instr.IsString {
  1108  			fr.tuples[instr] = fr.stringIterNext(iter)
  1109  		} else {
  1110  			fr.tuples[instr] = fr.mapIterNext(iter)
  1111  		}
  1112  
  1113  	case *ssa.Panic:
  1114  		arg := fr.value(instr.X)
  1115  		fr.callPanic(arg, true)
  1116  
  1117  	case *ssa.Phi:
  1118  		typ := instr.Type()
  1119  		phi := fr.builder.CreatePHI(fr.llvmtypes.ToLLVM(typ), instr.Comment)
  1120  		fr.env[instr] = newValue(phi, typ)
  1121  		fr.phis = append(fr.phis, pendingPhi{instr, phi})
  1122  
  1123  	case *ssa.Range:
  1124  		x := fr.value(instr.X)
  1125  		switch x.Type().Underlying().(type) {
  1126  		case *types.Map:
  1127  			fr.tuples[instr] = fr.mapIterInit(x)
  1128  		case *types.Basic: // string
  1129  			fr.tuples[instr] = fr.stringIterInit(x)
  1130  		default:
  1131  			panic(fmt.Sprintf("unhandled range for type %T", x.Type()))
  1132  		}
  1133  
  1134  	case *ssa.Return:
  1135  		vals := make([]llvm.Value, len(instr.Results))
  1136  		for i, res := range instr.Results {
  1137  			vals[i] = fr.llvmvalue(res)
  1138  		}
  1139  		fr.retInf.encode(llvm.GlobalContext(), fr.allocaBuilder, fr.builder, vals)
  1140  
  1141  	case *ssa.RunDefers:
  1142  		fr.runDefers()
  1143  
  1144  	case *ssa.Select:
  1145  		index, recvOk, recvElems := fr.chanSelect(instr)
  1146  		tuple := append([]*govalue{index, recvOk}, recvElems...)
  1147  		fr.tuples[instr] = tuple
  1148  
  1149  	case *ssa.Send:
  1150  		fr.chanSend(fr.value(instr.Chan), fr.value(instr.X))
  1151  
  1152  	case *ssa.Slice:
  1153  		x := fr.llvmvalue(instr.X)
  1154  		low := fr.llvmvalue(instr.Low)
  1155  		high := fr.llvmvalue(instr.High)
  1156  		max := fr.llvmvalue(instr.Max)
  1157  		slice := fr.slice(x, instr.X.Type(), low, high, max)
  1158  		fr.env[instr] = newValue(slice, instr.Type())
  1159  
  1160  	case *ssa.Store:
  1161  		addr := fr.llvmvalue(instr.Addr)
  1162  		value := fr.llvmvalue(instr.Val)
  1163  		addr = fr.builder.CreateBitCast(addr, llvm.PointerType(value.Type(), 0), "")
  1164  		// If this is the init function, see if we can simulate the effect
  1165  		// of the store in a global's initializer, in which case we can avoid
  1166  		// generating code for it.
  1167  		if !fr.isInit || !fr.maybeStoreInInitializer(value, addr) {
  1168  			fr.nilCheck(instr.Addr, addr)
  1169  			fr.builder.CreateStore(value, addr)
  1170  		}
  1171  
  1172  	case *switchInstr:
  1173  		fr.emitSwitch(instr)
  1174  
  1175  	case *ssa.TypeAssert:
  1176  		x := fr.value(instr.X)
  1177  		if instr.CommaOk {
  1178  			v, ok := fr.interfaceTypeCheck(x, instr.AssertedType)
  1179  			fr.tuples[instr] = []*govalue{v, ok}
  1180  		} else {
  1181  			fr.env[instr] = fr.interfaceTypeAssert(x, instr.AssertedType)
  1182  		}
  1183  
  1184  	case *ssa.UnOp:
  1185  		operand := fr.value(instr.X)
  1186  		switch instr.Op {
  1187  		case token.ARROW:
  1188  			x, ok := fr.chanRecv(operand, instr.CommaOk)
  1189  			if instr.CommaOk {
  1190  				fr.tuples[instr] = []*govalue{x, ok}
  1191  			} else {
  1192  				fr.env[instr] = x
  1193  			}
  1194  		case token.MUL:
  1195  			fr.nilCheck(instr.X, operand.value)
  1196  			if !fr.canAvoidLoad(instr, operand.value) {
  1197  				// The bitcast is necessary to handle recursive pointer loads.
  1198  				llptr := fr.builder.CreateBitCast(operand.value, llvm.PointerType(fr.llvmtypes.ToLLVM(instr.Type()), 0), "")
  1199  				fr.env[instr] = newValue(fr.builder.CreateLoad(llptr, ""), instr.Type())
  1200  			}
  1201  		default:
  1202  			fr.env[instr] = fr.unaryOp(operand, instr.Op)
  1203  		}
  1204  
  1205  	default:
  1206  		panic(fmt.Sprintf("unhandled: %v", instr))
  1207  	}
  1208  }
  1209  
  1210  func (fr *frame) callBuiltin(typ types.Type, builtin *ssa.Builtin, args []ssa.Value) []*govalue {
  1211  	switch builtin.Name() {
  1212  	case "print", "println":
  1213  		llargs := make([]*govalue, len(args))
  1214  		for i, arg := range args {
  1215  			llargs[i] = fr.value(arg)
  1216  		}
  1217  		fr.printValues(builtin.Name() == "println", llargs...)
  1218  		return nil
  1219  
  1220  	case "panic":
  1221  		fr.callPanic(fr.value(args[0]), false)
  1222  		return nil
  1223  
  1224  	case "recover":
  1225  		return []*govalue{fr.callRecover(false)}
  1226  
  1227  	case "append":
  1228  		return []*govalue{fr.callAppend(fr.value(args[0]), fr.value(args[1]))}
  1229  
  1230  	case "close":
  1231  		fr.chanClose(fr.value(args[0]))
  1232  		return nil
  1233  
  1234  	case "cap":
  1235  		return []*govalue{fr.callCap(fr.value(args[0]))}
  1236  
  1237  	case "len":
  1238  		return []*govalue{fr.callLen(fr.value(args[0]))}
  1239  
  1240  	case "copy":
  1241  		return []*govalue{fr.callCopy(fr.value(args[0]), fr.value(args[1]))}
  1242  
  1243  	case "delete":
  1244  		fr.mapDelete(fr.value(args[0]), fr.value(args[1]))
  1245  		return nil
  1246  
  1247  	case "real":
  1248  		return []*govalue{fr.extractRealValue(fr.value(args[0]))}
  1249  
  1250  	case "imag":
  1251  		return []*govalue{fr.extractImagValue(fr.value(args[0]))}
  1252  
  1253  	case "complex":
  1254  		r := fr.llvmvalue(args[0])
  1255  		i := fr.llvmvalue(args[1])
  1256  		cmplx := llvm.Undef(fr.llvmtypes.ToLLVM(typ))
  1257  		cmplx = fr.builder.CreateInsertValue(cmplx, r, 0, "")
  1258  		cmplx = fr.builder.CreateInsertValue(cmplx, i, 1, "")
  1259  		return []*govalue{newValue(cmplx, typ)}
  1260  
  1261  	case "ssa:wrapnilchk":
  1262  		ptr := fr.value(args[0])
  1263  		fr.nilCheck(args[0], ptr.value)
  1264  		return []*govalue{ptr}
  1265  
  1266  	default:
  1267  		panic("unimplemented: " + builtin.Name())
  1268  	}
  1269  }
  1270  
  1271  // callInstruction translates function call instructions.
  1272  func (fr *frame) callInstruction(instr ssa.CallInstruction) []*govalue {
  1273  	call := instr.Common()
  1274  	if builtin, ok := call.Value.(*ssa.Builtin); ok {
  1275  		var typ types.Type
  1276  		if v := instr.Value(); v != nil {
  1277  			typ = v.Type()
  1278  		}
  1279  		return fr.callBuiltin(typ, builtin, call.Args)
  1280  	}
  1281  
  1282  	args := make([]*govalue, len(call.Args))
  1283  	for i, arg := range call.Args {
  1284  		args[i] = fr.value(arg)
  1285  	}
  1286  
  1287  	var fn *govalue
  1288  	var chain llvm.Value
  1289  	if call.IsInvoke() {
  1290  		var recv *govalue
  1291  		fn, recv = fr.interfaceMethod(fr.llvmvalue(call.Value), call.Value.Type(), call.Method)
  1292  		args = append([]*govalue{recv}, args...)
  1293  	} else {
  1294  		if ssafn, ok := call.Value.(*ssa.Function); ok {
  1295  			llfn := fr.resolveFunctionGlobal(ssafn)
  1296  			llfn = llvm.ConstBitCast(llfn, llvm.PointerType(llvm.Int8Type(), 0))
  1297  			fn = newValue(llfn, ssafn.Type())
  1298  		} else {
  1299  			// First-class function values are stored as *{*fnptr}, so
  1300  			// we must extract the function pointer. We must also
  1301  			// set the chain, in case the function is a closure.
  1302  			fn = fr.value(call.Value)
  1303  			chain = fn.value
  1304  			fnptr := fr.builder.CreateBitCast(fn.value, llvm.PointerType(fn.value.Type(), 0), "")
  1305  			fnptr = fr.builder.CreateLoad(fnptr, "")
  1306  			fn = newValue(fnptr, fn.Type())
  1307  		}
  1308  		if recv := call.Signature().Recv(); recv != nil {
  1309  			if _, ok := recv.Type().Underlying().(*types.Pointer); !ok {
  1310  				recvalloca := fr.allocaBuilder.CreateAlloca(args[0].value.Type(), "")
  1311  				fr.builder.CreateStore(args[0].value, recvalloca)
  1312  				args[0] = newValue(recvalloca, types.NewPointer(args[0].Type()))
  1313  			}
  1314  		}
  1315  	}
  1316  	return fr.createCall(fn, chain, args)
  1317  }
  1318  
  1319  func hasDefer(f *ssa.Function) bool {
  1320  	for _, b := range f.Blocks {
  1321  		for _, instr := range b.Instrs {
  1322  			if _, ok := instr.(*ssa.Defer); ok {
  1323  				return true
  1324  			}
  1325  		}
  1326  	}
  1327  	return false
  1328  }
  1329  
  1330  func callsRecover(f *ssa.Function) bool {
  1331  	for _, b := range f.Blocks {
  1332  		for _, instr := range b.Instrs {
  1333  			if instr, ok := instr.(ssa.CallInstruction); ok {
  1334  				b, ok := instr.Common().Value.(*ssa.Builtin)
  1335  				if ok && b.Name() == "recover" {
  1336  					return true
  1337  				}
  1338  			}
  1339  		}
  1340  	}
  1341  	return false
  1342  }