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

     1  // Copyright 2013 The Go Authors. All rights reserved.
     2  // Use of this source code is governed by a BSD-style
     3  // license that can be found in the LICENSE file.
     4  
     5  package ssa
     6  
     7  // Helpers for emitting SSA instructions.
     8  
     9  import (
    10  	"fmt"
    11  	"go/ast"
    12  	"go/token"
    13  
    14  	"llvm.org/llgo/third_party/gotools/go/types"
    15  )
    16  
    17  // emitNew emits to f a new (heap Alloc) instruction allocating an
    18  // object of type typ.  pos is the optional source location.
    19  //
    20  func emitNew(f *Function, typ types.Type, pos token.Pos) *Alloc {
    21  	v := &Alloc{Heap: true}
    22  	v.setType(types.NewPointer(typ))
    23  	v.setPos(pos)
    24  	f.emit(v)
    25  	return v
    26  }
    27  
    28  // emitLoad emits to f an instruction to load the address addr into a
    29  // new temporary, and returns the value so defined.
    30  //
    31  func emitLoad(f *Function, addr Value) *UnOp {
    32  	v := &UnOp{Op: token.MUL, X: addr}
    33  	v.setType(deref(addr.Type()))
    34  	f.emit(v)
    35  	return v
    36  }
    37  
    38  // emitDebugRef emits to f a DebugRef pseudo-instruction associating
    39  // expression e with value v.
    40  //
    41  func emitDebugRef(f *Function, e ast.Expr, v Value, isAddr bool) {
    42  	if !f.debugInfo() {
    43  		return // debugging not enabled
    44  	}
    45  	if v == nil || e == nil {
    46  		panic("nil")
    47  	}
    48  	var obj types.Object
    49  	e = unparen(e)
    50  	if id, ok := e.(*ast.Ident); ok {
    51  		if isBlankIdent(id) {
    52  			return
    53  		}
    54  		obj = f.Pkg.objectOf(id)
    55  		switch obj.(type) {
    56  		case *types.Nil, *types.Const, *types.Builtin:
    57  			return
    58  		}
    59  	}
    60  	f.emit(&DebugRef{
    61  		X:      v,
    62  		Expr:   e,
    63  		IsAddr: isAddr,
    64  		object: obj,
    65  	})
    66  }
    67  
    68  // emitArith emits to f code to compute the binary operation op(x, y)
    69  // where op is an eager shift, logical or arithmetic operation.
    70  // (Use emitCompare() for comparisons and Builder.logicalBinop() for
    71  // non-eager operations.)
    72  //
    73  func emitArith(f *Function, op token.Token, x, y Value, t types.Type, pos token.Pos) Value {
    74  	switch op {
    75  	case token.SHL, token.SHR:
    76  		x = emitConv(f, x, t)
    77  		// y may be signed or an 'untyped' constant.
    78  		// TODO(adonovan): whence signed values?
    79  		if b, ok := y.Type().Underlying().(*types.Basic); ok && b.Info()&types.IsUnsigned == 0 {
    80  			y = emitConv(f, y, types.Typ[types.Uint64])
    81  		}
    82  
    83  	case token.ADD, token.SUB, token.MUL, token.QUO, token.REM, token.AND, token.OR, token.XOR, token.AND_NOT:
    84  		x = emitConv(f, x, t)
    85  		y = emitConv(f, y, t)
    86  
    87  	default:
    88  		panic("illegal op in emitArith: " + op.String())
    89  
    90  	}
    91  	v := &BinOp{
    92  		Op: op,
    93  		X:  x,
    94  		Y:  y,
    95  	}
    96  	v.setPos(pos)
    97  	v.setType(t)
    98  	return f.emit(v)
    99  }
   100  
   101  // emitCompare emits to f code compute the boolean result of
   102  // comparison comparison 'x op y'.
   103  //
   104  func emitCompare(f *Function, op token.Token, x, y Value, pos token.Pos) Value {
   105  	xt := x.Type().Underlying()
   106  	yt := y.Type().Underlying()
   107  
   108  	// Special case to optimise a tagless SwitchStmt so that
   109  	// these are equivalent
   110  	//   switch { case e: ...}
   111  	//   switch true { case e: ... }
   112  	//   if e==true { ... }
   113  	// even in the case when e's type is an interface.
   114  	// TODO(adonovan): opt: generalise to x==true, false!=y, etc.
   115  	if x == vTrue && op == token.EQL {
   116  		if yt, ok := yt.(*types.Basic); ok && yt.Info()&types.IsBoolean != 0 {
   117  			return y
   118  		}
   119  	}
   120  
   121  	if types.Identical(xt, yt) {
   122  		// no conversion necessary
   123  	} else if _, ok := xt.(*types.Interface); ok {
   124  		y = emitConv(f, y, x.Type())
   125  	} else if _, ok := yt.(*types.Interface); ok {
   126  		x = emitConv(f, x, y.Type())
   127  	} else if _, ok := x.(*Const); ok {
   128  		x = emitConv(f, x, y.Type())
   129  	} else if _, ok := y.(*Const); ok {
   130  		y = emitConv(f, y, x.Type())
   131  	} else {
   132  		// other cases, e.g. channels.  No-op.
   133  	}
   134  
   135  	v := &BinOp{
   136  		Op: op,
   137  		X:  x,
   138  		Y:  y,
   139  	}
   140  	v.setPos(pos)
   141  	v.setType(tBool)
   142  	return f.emit(v)
   143  }
   144  
   145  // isValuePreserving returns true if a conversion from ut_src to
   146  // ut_dst is value-preserving, i.e. just a change of type.
   147  // Precondition: neither argument is a named type.
   148  //
   149  func isValuePreserving(ut_src, ut_dst types.Type) bool {
   150  	// Identical underlying types?
   151  	if types.Identical(ut_dst, ut_src) {
   152  		return true
   153  	}
   154  
   155  	switch ut_dst.(type) {
   156  	case *types.Chan:
   157  		// Conversion between channel types?
   158  		_, ok := ut_src.(*types.Chan)
   159  		return ok
   160  
   161  	case *types.Pointer:
   162  		// Conversion between pointers with identical base types?
   163  		_, ok := ut_src.(*types.Pointer)
   164  		return ok
   165  	}
   166  	return false
   167  }
   168  
   169  // emitConv emits to f code to convert Value val to exactly type typ,
   170  // and returns the converted value.  Implicit conversions are required
   171  // by language assignability rules in assignments, parameter passing,
   172  // etc.  Conversions cannot fail dynamically.
   173  //
   174  func emitConv(f *Function, val Value, typ types.Type) Value {
   175  	t_src := val.Type()
   176  
   177  	// Identical types?  Conversion is a no-op.
   178  	if types.Identical(t_src, typ) {
   179  		return val
   180  	}
   181  
   182  	ut_dst := typ.Underlying()
   183  	ut_src := t_src.Underlying()
   184  
   185  	// Just a change of type, but not value or representation?
   186  	if isValuePreserving(ut_src, ut_dst) {
   187  		c := &ChangeType{X: val}
   188  		c.setType(typ)
   189  		return f.emit(c)
   190  	}
   191  
   192  	// Conversion to, or construction of a value of, an interface type?
   193  	if _, ok := ut_dst.(*types.Interface); ok {
   194  		// Assignment from one interface type to another?
   195  		if _, ok := ut_src.(*types.Interface); ok {
   196  			c := &ChangeInterface{X: val}
   197  			c.setType(typ)
   198  			return f.emit(c)
   199  		}
   200  
   201  		// Untyped nil constant?  Return interface-typed nil constant.
   202  		if ut_src == tUntypedNil {
   203  			return nilConst(typ)
   204  		}
   205  
   206  		// Convert (non-nil) "untyped" literals to their default type.
   207  		if t, ok := ut_src.(*types.Basic); ok && t.Info()&types.IsUntyped != 0 {
   208  			val = emitConv(f, val, DefaultType(ut_src))
   209  		}
   210  
   211  		f.Pkg.Prog.needMethodsOf(val.Type())
   212  		mi := &MakeInterface{X: val}
   213  		mi.setType(typ)
   214  		return f.emit(mi)
   215  	}
   216  
   217  	// Conversion of a compile-time constant value?
   218  	if c, ok := val.(*Const); ok {
   219  		if _, ok := ut_dst.(*types.Basic); ok || c.IsNil() {
   220  			// Conversion of a compile-time constant to
   221  			// another constant type results in a new
   222  			// constant of the destination type and
   223  			// (initially) the same abstract value.
   224  			// We don't truncate the value yet.
   225  			return NewConst(c.Value, typ)
   226  		}
   227  
   228  		// We're converting from constant to non-constant type,
   229  		// e.g. string -> []byte/[]rune.
   230  	}
   231  
   232  	// A representation-changing conversion?
   233  	// At least one of {ut_src,ut_dst} must be *Basic.
   234  	// (The other may be []byte or []rune.)
   235  	_, ok1 := ut_src.(*types.Basic)
   236  	_, ok2 := ut_dst.(*types.Basic)
   237  	if ok1 || ok2 {
   238  		c := &Convert{X: val}
   239  		c.setType(typ)
   240  		return f.emit(c)
   241  	}
   242  
   243  	panic(fmt.Sprintf("in %s: cannot convert %s (%s) to %s", f, val, val.Type(), typ))
   244  }
   245  
   246  // emitStore emits to f an instruction to store value val at location
   247  // addr, applying implicit conversions as required by assignability rules.
   248  //
   249  func emitStore(f *Function, addr, val Value, pos token.Pos) *Store {
   250  	s := &Store{
   251  		Addr: addr,
   252  		Val:  emitConv(f, val, deref(addr.Type())),
   253  		pos:  pos,
   254  	}
   255  	f.emit(s)
   256  	return s
   257  }
   258  
   259  // emitJump emits to f a jump to target, and updates the control-flow graph.
   260  // Postcondition: f.currentBlock is nil.
   261  //
   262  func emitJump(f *Function, target *BasicBlock) {
   263  	b := f.currentBlock
   264  	b.emit(new(Jump))
   265  	addEdge(b, target)
   266  	f.currentBlock = nil
   267  }
   268  
   269  // emitIf emits to f a conditional jump to tblock or fblock based on
   270  // cond, and updates the control-flow graph.
   271  // Postcondition: f.currentBlock is nil.
   272  //
   273  func emitIf(f *Function, cond Value, tblock, fblock *BasicBlock) {
   274  	b := f.currentBlock
   275  	b.emit(&If{Cond: cond})
   276  	addEdge(b, tblock)
   277  	addEdge(b, fblock)
   278  	f.currentBlock = nil
   279  }
   280  
   281  // emitExtract emits to f an instruction to extract the index'th
   282  // component of tuple.  It returns the extracted value.
   283  //
   284  func emitExtract(f *Function, tuple Value, index int) Value {
   285  	e := &Extract{Tuple: tuple, Index: index}
   286  	e.setType(tuple.Type().(*types.Tuple).At(index).Type())
   287  	return f.emit(e)
   288  }
   289  
   290  // emitTypeAssert emits to f a type assertion value := x.(t) and
   291  // returns the value.  x.Type() must be an interface.
   292  //
   293  func emitTypeAssert(f *Function, x Value, t types.Type, pos token.Pos) Value {
   294  	a := &TypeAssert{X: x, AssertedType: t}
   295  	a.setPos(pos)
   296  	a.setType(t)
   297  	return f.emit(a)
   298  }
   299  
   300  // emitTypeTest emits to f a type test value,ok := x.(t) and returns
   301  // a (value, ok) tuple.  x.Type() must be an interface.
   302  //
   303  func emitTypeTest(f *Function, x Value, t types.Type, pos token.Pos) Value {
   304  	a := &TypeAssert{
   305  		X:            x,
   306  		AssertedType: t,
   307  		CommaOk:      true,
   308  	}
   309  	a.setPos(pos)
   310  	a.setType(types.NewTuple(
   311  		newVar("value", t),
   312  		varOk,
   313  	))
   314  	return f.emit(a)
   315  }
   316  
   317  // emitTailCall emits to f a function call in tail position.  The
   318  // caller is responsible for all fields of 'call' except its type.
   319  // Intended for wrapper methods.
   320  // Precondition: f does/will not use deferred procedure calls.
   321  // Postcondition: f.currentBlock is nil.
   322  //
   323  func emitTailCall(f *Function, call *Call) {
   324  	tresults := f.Signature.Results()
   325  	nr := tresults.Len()
   326  	if nr == 1 {
   327  		call.typ = tresults.At(0).Type()
   328  	} else {
   329  		call.typ = tresults
   330  	}
   331  	tuple := f.emit(call)
   332  	var ret Return
   333  	switch nr {
   334  	case 0:
   335  		// no-op
   336  	case 1:
   337  		ret.Results = []Value{tuple}
   338  	default:
   339  		for i := 0; i < nr; i++ {
   340  			v := emitExtract(f, tuple, i)
   341  			// TODO(adonovan): in principle, this is required:
   342  			//   v = emitConv(f, o.Type, f.Signature.Results[i].Type)
   343  			// but in practice emitTailCall is only used when
   344  			// the types exactly match.
   345  			ret.Results = append(ret.Results, v)
   346  		}
   347  	}
   348  	f.emit(&ret)
   349  	f.currentBlock = nil
   350  }
   351  
   352  // emitImplicitSelections emits to f code to apply the sequence of
   353  // implicit field selections specified by indices to base value v, and
   354  // returns the selected value.
   355  //
   356  // If v is the address of a struct, the result will be the address of
   357  // a field; if it is the value of a struct, the result will be the
   358  // value of a field.
   359  //
   360  func emitImplicitSelections(f *Function, v Value, indices []int) Value {
   361  	for _, index := range indices {
   362  		fld := deref(v.Type()).Underlying().(*types.Struct).Field(index)
   363  
   364  		if isPointer(v.Type()) {
   365  			instr := &FieldAddr{
   366  				X:     v,
   367  				Field: index,
   368  			}
   369  			instr.setType(types.NewPointer(fld.Type()))
   370  			v = f.emit(instr)
   371  			// Load the field's value iff indirectly embedded.
   372  			if isPointer(fld.Type()) {
   373  				v = emitLoad(f, v)
   374  			}
   375  		} else {
   376  			instr := &Field{
   377  				X:     v,
   378  				Field: index,
   379  			}
   380  			instr.setType(fld.Type())
   381  			v = f.emit(instr)
   382  		}
   383  	}
   384  	return v
   385  }
   386  
   387  // emitFieldSelection emits to f code to select the index'th field of v.
   388  //
   389  // If wantAddr, the input must be a pointer-to-struct and the result
   390  // will be the field's address; otherwise the result will be the
   391  // field's value.
   392  // Ident id is used for position and debug info.
   393  //
   394  func emitFieldSelection(f *Function, v Value, index int, wantAddr bool, id *ast.Ident) Value {
   395  	fld := deref(v.Type()).Underlying().(*types.Struct).Field(index)
   396  	if isPointer(v.Type()) {
   397  		instr := &FieldAddr{
   398  			X:     v,
   399  			Field: index,
   400  		}
   401  		instr.setPos(id.Pos())
   402  		instr.setType(types.NewPointer(fld.Type()))
   403  		v = f.emit(instr)
   404  		// Load the field's value iff we don't want its address.
   405  		if !wantAddr {
   406  			v = emitLoad(f, v)
   407  		}
   408  	} else {
   409  		instr := &Field{
   410  			X:     v,
   411  			Field: index,
   412  		}
   413  		instr.setPos(id.Pos())
   414  		instr.setType(fld.Type())
   415  		v = f.emit(instr)
   416  	}
   417  	emitDebugRef(f, id, v, wantAddr)
   418  	return v
   419  }
   420  
   421  // zeroValue emits to f code to produce a zero value of type t,
   422  // and returns it.
   423  //
   424  func zeroValue(f *Function, t types.Type) Value {
   425  	switch t.Underlying().(type) {
   426  	case *types.Struct, *types.Array:
   427  		return emitLoad(f, f.addLocal(t, token.NoPos))
   428  	default:
   429  		return zeroConst(t)
   430  	}
   431  }
   432  
   433  // createRecoverBlock emits to f a block of code to return after a
   434  // recovered panic, and sets f.Recover to it.
   435  //
   436  // If f's result parameters are named, the code loads and returns
   437  // their current values, otherwise it returns the zero values of their
   438  // type.
   439  //
   440  // Idempotent.
   441  //
   442  func createRecoverBlock(f *Function) {
   443  	if f.Recover != nil {
   444  		return // already created
   445  	}
   446  	saved := f.currentBlock
   447  
   448  	f.Recover = f.newBasicBlock("recover")
   449  	f.currentBlock = f.Recover
   450  
   451  	var results []Value
   452  	if f.namedResults != nil {
   453  		// Reload NRPs to form value tuple.
   454  		for _, r := range f.namedResults {
   455  			results = append(results, emitLoad(f, r))
   456  		}
   457  	} else {
   458  		R := f.Signature.Results()
   459  		for i, n := 0, R.Len(); i < n; i++ {
   460  			T := R.At(i).Type()
   461  
   462  			// Return zero value of each result type.
   463  			results = append(results, zeroValue(f, T))
   464  		}
   465  	}
   466  	f.emit(&Return{Results: results})
   467  
   468  	f.currentBlock = saved
   469  }