You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

468 lines
12 KiB

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