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
13package irgen
14
15import (
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.
31type globalInit struct {
32	val   llvm.Value
33	elems []globalInit
34}
35
36func (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
72func (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
100type 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
117func 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
129type byMemberName []ssa.Member
130
131func (ms byMemberName) Len() int { return len(ms) }
132func (ms byMemberName) Swap(i, j int) {
133	ms[i], ms[j] = ms[j], ms[i]
134}
135func (ms byMemberName) Less(i, j int) bool {
136	return ms[i].Name() < ms[j].Name()
137}
138
139type byFunctionString []*ssa.Function
140
141func (fns byFunctionString) Len() int { return len(fns) }
142func (fns byFunctionString) Swap(i, j int) {
143	fns[i], fns[j] = fns[j], fns[i]
144}
145func (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.
151func (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.
164func (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
213func (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.
225func (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.
234func (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.
247func (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.
254func (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
272func (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
294func (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
446type pendingPhi struct {
447	ssa  *ssa.Phi
448	llvm llvm.Value
449}
450
451type 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
469func 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
481func (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.
489func (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.
533func (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
574func (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
588func (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
601func (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.
613func (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
627func (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
658func (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
666func (fr *frame) block(b *ssa.BasicBlock) llvm.BasicBlock {
667	return fr.blocks[b.Index]
668}
669
670func (fr *frame) lastBlock(b *ssa.BasicBlock) llvm.BasicBlock {
671	return fr.lastBlocks[b.Index]
672}
673
674func (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
702func (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
710func (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
725func (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
732func (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.
751func (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.
795func (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.
820func (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
857func (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
1210func (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.
1272func (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
1319func 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
1330func 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}
1343