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 }