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.

689 lines
18 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. // This file implements the Function and BasicBlock types.
  6. import (
  7. "bytes"
  8. "fmt"
  9. "go/ast"
  10. "go/token"
  11. "go/types"
  12. "io"
  13. "os"
  14. "strings"
  15. )
  16. // addEdge adds a control-flow graph edge from from to to.
  17. func addEdge(from, to *BasicBlock) {
  18. from.Succs = append(from.Succs, to)
  19. to.Preds = append(to.Preds, from)
  20. }
  21. // Parent returns the function that contains block b.
  22. func (b *BasicBlock) Parent() *Function { return b.parent }
  23. // String returns a human-readable label of this block.
  24. // It is not guaranteed unique within the function.
  25. //
  26. func (b *BasicBlock) String() string {
  27. return fmt.Sprintf("%d", b.Index)
  28. }
  29. // emit appends an instruction to the current basic block.
  30. // If the instruction defines a Value, it is returned.
  31. //
  32. func (b *BasicBlock) emit(i Instruction) Value {
  33. i.setBlock(b)
  34. b.Instrs = append(b.Instrs, i)
  35. v, _ := i.(Value)
  36. return v
  37. }
  38. // predIndex returns the i such that b.Preds[i] == c or panics if
  39. // there is none.
  40. func (b *BasicBlock) predIndex(c *BasicBlock) int {
  41. for i, pred := range b.Preds {
  42. if pred == c {
  43. return i
  44. }
  45. }
  46. panic(fmt.Sprintf("no edge %s -> %s", c, b))
  47. }
  48. // hasPhi returns true if b.Instrs contains φ-nodes.
  49. func (b *BasicBlock) hasPhi() bool {
  50. _, ok := b.Instrs[0].(*Phi)
  51. return ok
  52. }
  53. // phis returns the prefix of b.Instrs containing all the block's φ-nodes.
  54. func (b *BasicBlock) phis() []Instruction {
  55. for i, instr := range b.Instrs {
  56. if _, ok := instr.(*Phi); !ok {
  57. return b.Instrs[:i]
  58. }
  59. }
  60. return nil // unreachable in well-formed blocks
  61. }
  62. // replacePred replaces all occurrences of p in b's predecessor list with q.
  63. // Ordinarily there should be at most one.
  64. //
  65. func (b *BasicBlock) replacePred(p, q *BasicBlock) {
  66. for i, pred := range b.Preds {
  67. if pred == p {
  68. b.Preds[i] = q
  69. }
  70. }
  71. }
  72. // replaceSucc replaces all occurrences of p in b's successor list with q.
  73. // Ordinarily there should be at most one.
  74. //
  75. func (b *BasicBlock) replaceSucc(p, q *BasicBlock) {
  76. for i, succ := range b.Succs {
  77. if succ == p {
  78. b.Succs[i] = q
  79. }
  80. }
  81. }
  82. // removePred removes all occurrences of p in b's
  83. // predecessor list and φ-nodes.
  84. // Ordinarily there should be at most one.
  85. //
  86. func (b *BasicBlock) removePred(p *BasicBlock) {
  87. phis := b.phis()
  88. // We must preserve edge order for φ-nodes.
  89. j := 0
  90. for i, pred := range b.Preds {
  91. if pred != p {
  92. b.Preds[j] = b.Preds[i]
  93. // Strike out φ-edge too.
  94. for _, instr := range phis {
  95. phi := instr.(*Phi)
  96. phi.Edges[j] = phi.Edges[i]
  97. }
  98. j++
  99. }
  100. }
  101. // Nil out b.Preds[j:] and φ-edges[j:] to aid GC.
  102. for i := j; i < len(b.Preds); i++ {
  103. b.Preds[i] = nil
  104. for _, instr := range phis {
  105. instr.(*Phi).Edges[i] = nil
  106. }
  107. }
  108. b.Preds = b.Preds[:j]
  109. for _, instr := range phis {
  110. phi := instr.(*Phi)
  111. phi.Edges = phi.Edges[:j]
  112. }
  113. }
  114. // Destinations associated with unlabelled for/switch/select stmts.
  115. // We push/pop one of these as we enter/leave each construct and for
  116. // each BranchStmt we scan for the innermost target of the right type.
  117. //
  118. type targets struct {
  119. tail *targets // rest of stack
  120. _break *BasicBlock
  121. _continue *BasicBlock
  122. _fallthrough *BasicBlock
  123. }
  124. // Destinations associated with a labelled block.
  125. // We populate these as labels are encountered in forward gotos or
  126. // labelled statements.
  127. //
  128. type lblock struct {
  129. _goto *BasicBlock
  130. _break *BasicBlock
  131. _continue *BasicBlock
  132. }
  133. // labelledBlock returns the branch target associated with the
  134. // specified label, creating it if needed.
  135. //
  136. func (f *Function) labelledBlock(label *ast.Ident) *lblock {
  137. lb := f.lblocks[label.Obj]
  138. if lb == nil {
  139. lb = &lblock{_goto: f.newBasicBlock(label.Name)}
  140. if f.lblocks == nil {
  141. f.lblocks = make(map[*ast.Object]*lblock)
  142. }
  143. f.lblocks[label.Obj] = lb
  144. }
  145. return lb
  146. }
  147. // addParam adds a (non-escaping) parameter to f.Params of the
  148. // specified name, type and source position.
  149. //
  150. func (f *Function) addParam(name string, typ types.Type, pos token.Pos) *Parameter {
  151. v := &Parameter{
  152. name: name,
  153. typ: typ,
  154. pos: pos,
  155. parent: f,
  156. }
  157. f.Params = append(f.Params, v)
  158. return v
  159. }
  160. func (f *Function) addParamObj(obj types.Object) *Parameter {
  161. name := obj.Name()
  162. if name == "" {
  163. name = fmt.Sprintf("arg%d", len(f.Params))
  164. }
  165. param := f.addParam(name, obj.Type(), obj.Pos())
  166. param.object = obj
  167. return param
  168. }
  169. // addSpilledParam declares a parameter that is pre-spilled to the
  170. // stack; the function body will load/store the spilled location.
  171. // Subsequent lifting will eliminate spills where possible.
  172. //
  173. func (f *Function) addSpilledParam(obj types.Object) {
  174. param := f.addParamObj(obj)
  175. spill := &Alloc{Comment: obj.Name()}
  176. spill.setType(types.NewPointer(obj.Type()))
  177. spill.setPos(obj.Pos())
  178. f.objects[obj] = spill
  179. f.Locals = append(f.Locals, spill)
  180. f.emit(spill)
  181. f.emit(&Store{Addr: spill, Val: param})
  182. }
  183. // startBody initializes the function prior to generating SSA code for its body.
  184. // Precondition: f.Type() already set.
  185. //
  186. func (f *Function) startBody() {
  187. f.currentBlock = f.newBasicBlock("entry")
  188. f.objects = make(map[types.Object]Value) // needed for some synthetics, e.g. init
  189. }
  190. // createSyntacticParams populates f.Params and generates code (spills
  191. // and named result locals) for all the parameters declared in the
  192. // syntax. In addition it populates the f.objects mapping.
  193. //
  194. // Preconditions:
  195. // f.startBody() was called.
  196. // Postcondition:
  197. // len(f.Params) == len(f.Signature.Params) + (f.Signature.Recv() ? 1 : 0)
  198. //
  199. func (f *Function) createSyntacticParams(recv *ast.FieldList, functype *ast.FuncType) {
  200. // Receiver (at most one inner iteration).
  201. if recv != nil {
  202. for _, field := range recv.List {
  203. for _, n := range field.Names {
  204. f.addSpilledParam(f.Pkg.info.Defs[n])
  205. }
  206. // Anonymous receiver? No need to spill.
  207. if field.Names == nil {
  208. f.addParamObj(f.Signature.Recv())
  209. }
  210. }
  211. }
  212. // Parameters.
  213. if functype.Params != nil {
  214. n := len(f.Params) // 1 if has recv, 0 otherwise
  215. for _, field := range functype.Params.List {
  216. for _, n := range field.Names {
  217. f.addSpilledParam(f.Pkg.info.Defs[n])
  218. }
  219. // Anonymous parameter? No need to spill.
  220. if field.Names == nil {
  221. f.addParamObj(f.Signature.Params().At(len(f.Params) - n))
  222. }
  223. }
  224. }
  225. // Named results.
  226. if functype.Results != nil {
  227. for _, field := range functype.Results.List {
  228. // Implicit "var" decl of locals for named results.
  229. for _, n := range field.Names {
  230. f.namedResults = append(f.namedResults, f.addLocalForIdent(n))
  231. }
  232. }
  233. }
  234. }
  235. // numberRegisters assigns numbers to all SSA registers
  236. // (value-defining Instructions) in f, to aid debugging.
  237. // (Non-Instruction Values are named at construction.)
  238. //
  239. func numberRegisters(f *Function) {
  240. v := 0
  241. for _, b := range f.Blocks {
  242. for _, instr := range b.Instrs {
  243. switch instr.(type) {
  244. case Value:
  245. instr.(interface {
  246. setNum(int)
  247. }).setNum(v)
  248. v++
  249. }
  250. }
  251. }
  252. }
  253. // buildReferrers populates the def/use information in all non-nil
  254. // Value.Referrers slice.
  255. // Precondition: all such slices are initially empty.
  256. func buildReferrers(f *Function) {
  257. var rands []*Value
  258. for _, b := range f.Blocks {
  259. for _, instr := range b.Instrs {
  260. rands = instr.Operands(rands[:0]) // recycle storage
  261. for _, rand := range rands {
  262. if r := *rand; r != nil {
  263. if ref := r.Referrers(); ref != nil {
  264. *ref = append(*ref, instr)
  265. }
  266. }
  267. }
  268. }
  269. }
  270. }
  271. // finishBody() finalizes the function after SSA code generation of its body.
  272. func (f *Function) finishBody() {
  273. f.objects = nil
  274. f.currentBlock = nil
  275. f.lblocks = nil
  276. // Don't pin the AST in memory (except in debug mode).
  277. if n := f.syntax; n != nil && !f.debugInfo() {
  278. f.syntax = extentNode{n.Pos(), n.End()}
  279. }
  280. // Remove from f.Locals any Allocs that escape to the heap.
  281. j := 0
  282. for _, l := range f.Locals {
  283. if !l.Heap {
  284. f.Locals[j] = l
  285. j++
  286. }
  287. }
  288. // Nil out f.Locals[j:] to aid GC.
  289. for i := j; i < len(f.Locals); i++ {
  290. f.Locals[i] = nil
  291. }
  292. f.Locals = f.Locals[:j]
  293. optimizeBlocks(f)
  294. buildReferrers(f)
  295. buildDomTree(f)
  296. if f.Prog.mode&NaiveForm == 0 {
  297. // For debugging pre-state of lifting pass:
  298. // numberRegisters(f)
  299. // f.WriteTo(os.Stderr)
  300. lift(f)
  301. }
  302. f.namedResults = nil // (used by lifting)
  303. numberRegisters(f)
  304. if f.Prog.mode&PrintFunctions != 0 {
  305. printMu.Lock()
  306. f.WriteTo(os.Stdout)
  307. printMu.Unlock()
  308. }
  309. if f.Prog.mode&SanityCheckFunctions != 0 {
  310. mustSanityCheck(f, nil)
  311. }
  312. }
  313. // removeNilBlocks eliminates nils from f.Blocks and updates each
  314. // BasicBlock.Index. Use this after any pass that may delete blocks.
  315. //
  316. func (f *Function) removeNilBlocks() {
  317. j := 0
  318. for _, b := range f.Blocks {
  319. if b != nil {
  320. b.Index = j
  321. f.Blocks[j] = b
  322. j++
  323. }
  324. }
  325. // Nil out f.Blocks[j:] to aid GC.
  326. for i := j; i < len(f.Blocks); i++ {
  327. f.Blocks[i] = nil
  328. }
  329. f.Blocks = f.Blocks[:j]
  330. }
  331. // SetDebugMode sets the debug mode for package pkg. If true, all its
  332. // functions will include full debug info. This greatly increases the
  333. // size of the instruction stream, and causes Functions to depend upon
  334. // the ASTs, potentially keeping them live in memory for longer.
  335. //
  336. func (pkg *Package) SetDebugMode(debug bool) {
  337. // TODO(adonovan): do we want ast.File granularity?
  338. pkg.debug = debug
  339. }
  340. // debugInfo reports whether debug info is wanted for this function.
  341. func (f *Function) debugInfo() bool {
  342. return f.Pkg != nil && f.Pkg.debug
  343. }
  344. // addNamedLocal creates a local variable, adds it to function f and
  345. // returns it. Its name and type are taken from obj. Subsequent
  346. // calls to f.lookup(obj) will return the same local.
  347. //
  348. func (f *Function) addNamedLocal(obj types.Object) *Alloc {
  349. l := f.addLocal(obj.Type(), obj.Pos())
  350. l.Comment = obj.Name()
  351. f.objects[obj] = l
  352. return l
  353. }
  354. func (f *Function) addLocalForIdent(id *ast.Ident) *Alloc {
  355. return f.addNamedLocal(f.Pkg.info.Defs[id])
  356. }
  357. // addLocal creates an anonymous local variable of type typ, adds it
  358. // to function f and returns it. pos is the optional source location.
  359. //
  360. func (f *Function) addLocal(typ types.Type, pos token.Pos) *Alloc {
  361. v := &Alloc{}
  362. v.setType(types.NewPointer(typ))
  363. v.setPos(pos)
  364. f.Locals = append(f.Locals, v)
  365. f.emit(v)
  366. return v
  367. }
  368. // lookup returns the address of the named variable identified by obj
  369. // that is local to function f or one of its enclosing functions.
  370. // If escaping, the reference comes from a potentially escaping pointer
  371. // expression and the referent must be heap-allocated.
  372. //
  373. func (f *Function) lookup(obj types.Object, escaping bool) Value {
  374. if v, ok := f.objects[obj]; ok {
  375. if alloc, ok := v.(*Alloc); ok && escaping {
  376. alloc.Heap = true
  377. }
  378. return v // function-local var (address)
  379. }
  380. // Definition must be in an enclosing function;
  381. // plumb it through intervening closures.
  382. if f.parent == nil {
  383. panic("no ssa.Value for " + obj.String())
  384. }
  385. outer := f.parent.lookup(obj, true) // escaping
  386. v := &FreeVar{
  387. name: obj.Name(),
  388. typ: outer.Type(),
  389. pos: outer.Pos(),
  390. outer: outer,
  391. parent: f,
  392. }
  393. f.objects[obj] = v
  394. f.FreeVars = append(f.FreeVars, v)
  395. return v
  396. }
  397. // emit emits the specified instruction to function f.
  398. func (f *Function) emit(instr Instruction) Value {
  399. return f.currentBlock.emit(instr)
  400. }
  401. // RelString returns the full name of this function, qualified by
  402. // package name, receiver type, etc.
  403. //
  404. // The specific formatting rules are not guaranteed and may change.
  405. //
  406. // Examples:
  407. // "math.IsNaN" // a package-level function
  408. // "(*bytes.Buffer).Bytes" // a declared method or a wrapper
  409. // "(*bytes.Buffer).Bytes$thunk" // thunk (func wrapping method; receiver is param 0)
  410. // "(*bytes.Buffer).Bytes$bound" // bound (func wrapping method; receiver supplied by closure)
  411. // "main.main$1" // an anonymous function in main
  412. // "main.init#1" // a declared init function
  413. // "main.init" // the synthesized package initializer
  414. //
  415. // When these functions are referred to from within the same package
  416. // (i.e. from == f.Pkg.Object), they are rendered without the package path.
  417. // For example: "IsNaN", "(*Buffer).Bytes", etc.
  418. //
  419. // All non-synthetic functions have distinct package-qualified names.
  420. // (But two methods may have the same name "(T).f" if one is a synthetic
  421. // wrapper promoting a non-exported method "f" from another package; in
  422. // that case, the strings are equal but the identifiers "f" are distinct.)
  423. //
  424. func (f *Function) RelString(from *types.Package) string {
  425. // Anonymous?
  426. if f.parent != nil {
  427. // An anonymous function's Name() looks like "parentName$1",
  428. // but its String() should include the type/package/etc.
  429. parent := f.parent.RelString(from)
  430. for i, anon := range f.parent.AnonFuncs {
  431. if anon == f {
  432. return fmt.Sprintf("%s$%d", parent, 1+i)
  433. }
  434. }
  435. return f.name // should never happen
  436. }
  437. // Method (declared or wrapper)?
  438. if recv := f.Signature.Recv(); recv != nil {
  439. return f.relMethod(from, recv.Type())
  440. }
  441. // Thunk?
  442. if f.method != nil {
  443. return f.relMethod(from, f.method.Recv())
  444. }
  445. // Bound?
  446. if len(f.FreeVars) == 1 && strings.HasSuffix(f.name, "$bound") {
  447. return f.relMethod(from, f.FreeVars[0].Type())
  448. }
  449. // Package-level function?
  450. // Prefix with package name for cross-package references only.
  451. if p := f.pkg(); p != nil && p != from {
  452. return fmt.Sprintf("%s.%s", p.Path(), f.name)
  453. }
  454. // Unknown.
  455. return f.name
  456. }
  457. func (f *Function) relMethod(from *types.Package, recv types.Type) string {
  458. return fmt.Sprintf("(%s).%s", relType(recv, from), f.name)
  459. }
  460. // writeSignature writes to buf the signature sig in declaration syntax.
  461. func writeSignature(buf *bytes.Buffer, from *types.Package, name string, sig *types.Signature, params []*Parameter) {
  462. buf.WriteString("func ")
  463. if recv := sig.Recv(); recv != nil {
  464. buf.WriteString("(")
  465. if n := params[0].Name(); n != "" {
  466. buf.WriteString(n)
  467. buf.WriteString(" ")
  468. }
  469. types.WriteType(buf, params[0].Type(), types.RelativeTo(from))
  470. buf.WriteString(") ")
  471. }
  472. buf.WriteString(name)
  473. types.WriteSignature(buf, sig, types.RelativeTo(from))
  474. }
  475. func (f *Function) pkg() *types.Package {
  476. if f.Pkg != nil {
  477. return f.Pkg.Pkg
  478. }
  479. return nil
  480. }
  481. var _ io.WriterTo = (*Function)(nil) // *Function implements io.Writer
  482. func (f *Function) WriteTo(w io.Writer) (int64, error) {
  483. var buf bytes.Buffer
  484. WriteFunction(&buf, f)
  485. n, err := w.Write(buf.Bytes())
  486. return int64(n), err
  487. }
  488. // WriteFunction writes to buf a human-readable "disassembly" of f.
  489. func WriteFunction(buf *bytes.Buffer, f *Function) {
  490. fmt.Fprintf(buf, "# Name: %s\n", f.String())
  491. if f.Pkg != nil {
  492. fmt.Fprintf(buf, "# Package: %s\n", f.Pkg.Pkg.Path())
  493. }
  494. if syn := f.Synthetic; syn != "" {
  495. fmt.Fprintln(buf, "# Synthetic:", syn)
  496. }
  497. if pos := f.Pos(); pos.IsValid() {
  498. fmt.Fprintf(buf, "# Location: %s\n", f.Prog.Fset.Position(pos))
  499. }
  500. if f.parent != nil {
  501. fmt.Fprintf(buf, "# Parent: %s\n", f.parent.Name())
  502. }
  503. if f.Recover != nil {
  504. fmt.Fprintf(buf, "# Recover: %s\n", f.Recover)
  505. }
  506. from := f.pkg()
  507. if f.FreeVars != nil {
  508. buf.WriteString("# Free variables:\n")
  509. for i, fv := range f.FreeVars {
  510. fmt.Fprintf(buf, "# % 3d:\t%s %s\n", i, fv.Name(), relType(fv.Type(), from))
  511. }
  512. }
  513. if len(f.Locals) > 0 {
  514. buf.WriteString("# Locals:\n")
  515. for i, l := range f.Locals {
  516. fmt.Fprintf(buf, "# % 3d:\t%s %s\n", i, l.Name(), relType(deref(l.Type()), from))
  517. }
  518. }
  519. writeSignature(buf, from, f.Name(), f.Signature, f.Params)
  520. buf.WriteString(":\n")
  521. if f.Blocks == nil {
  522. buf.WriteString("\t(external)\n")
  523. }
  524. // NB. column calculations are confused by non-ASCII
  525. // characters and assume 8-space tabs.
  526. const punchcard = 80 // for old time's sake.
  527. const tabwidth = 8
  528. for _, b := range f.Blocks {
  529. if b == nil {
  530. // Corrupt CFG.
  531. fmt.Fprintf(buf, ".nil:\n")
  532. continue
  533. }
  534. n, _ := fmt.Fprintf(buf, "%d:", b.Index)
  535. bmsg := fmt.Sprintf("%s P:%d S:%d", b.Comment, len(b.Preds), len(b.Succs))
  536. fmt.Fprintf(buf, "%*s%s\n", punchcard-1-n-len(bmsg), "", bmsg)
  537. if false { // CFG debugging
  538. fmt.Fprintf(buf, "\t# CFG: %s --> %s --> %s\n", b.Preds, b, b.Succs)
  539. }
  540. for _, instr := range b.Instrs {
  541. buf.WriteString("\t")
  542. switch v := instr.(type) {
  543. case Value:
  544. l := punchcard - tabwidth
  545. // Left-align the instruction.
  546. if name := v.Name(); name != "" {
  547. n, _ := fmt.Fprintf(buf, "%s = ", name)
  548. l -= n
  549. }
  550. n, _ := buf.WriteString(instr.String())
  551. l -= n
  552. // Right-align the type if there's space.
  553. if t := v.Type(); t != nil {
  554. buf.WriteByte(' ')
  555. ts := relType(t, from)
  556. l -= len(ts) + len(" ") // (spaces before and after type)
  557. if l > 0 {
  558. fmt.Fprintf(buf, "%*s", l, "")
  559. }
  560. buf.WriteString(ts)
  561. }
  562. case nil:
  563. // Be robust against bad transforms.
  564. buf.WriteString("<deleted>")
  565. default:
  566. buf.WriteString(instr.String())
  567. }
  568. buf.WriteString("\n")
  569. }
  570. }
  571. fmt.Fprintf(buf, "\n")
  572. }
  573. // newBasicBlock adds to f a new basic block and returns it. It does
  574. // not automatically become the current block for subsequent calls to emit.
  575. // comment is an optional string for more readable debugging output.
  576. //
  577. func (f *Function) newBasicBlock(comment string) *BasicBlock {
  578. b := &BasicBlock{
  579. Index: len(f.Blocks),
  580. Comment: comment,
  581. parent: f,
  582. }
  583. b.Succs = b.succs2[:0]
  584. f.Blocks = append(f.Blocks, b)
  585. return b
  586. }
  587. // NewFunction returns a new synthetic Function instance belonging to
  588. // prog, with its name and signature fields set as specified.
  589. //
  590. // The caller is responsible for initializing the remaining fields of
  591. // the function object, e.g. Pkg, Params, Blocks.
  592. //
  593. // It is practically impossible for clients to construct well-formed
  594. // SSA functions/packages/programs directly, so we assume this is the
  595. // job of the Builder alone. NewFunction exists to provide clients a
  596. // little flexibility. For example, analysis tools may wish to
  597. // construct fake Functions for the root of the callgraph, a fake
  598. // "reflect" package, etc.
  599. //
  600. // TODO(adonovan): think harder about the API here.
  601. //
  602. func (prog *Program) NewFunction(name string, sig *types.Signature, provenance string) *Function {
  603. return &Function{Prog: prog, name: name, Signature: sig, Synthetic: provenance}
  604. }
  605. type extentNode [2]token.Pos
  606. func (n extentNode) Pos() token.Pos { return n[0] }
  607. func (n extentNode) End() token.Pos { return n[1] }
  608. // Syntax returns an ast.Node whose Pos/End methods provide the
  609. // lexical extent of the function if it was defined by Go source code
  610. // (f.Synthetic==""), or nil otherwise.
  611. //
  612. // If f was built with debug information (see Package.SetDebugRef),
  613. // the result is the *ast.FuncDecl or *ast.FuncLit that declared the
  614. // function. Otherwise, it is an opaque Node providing only position
  615. // information; this avoids pinning the AST in memory.
  616. //
  617. func (f *Function) Syntax() ast.Node { return f.syntax }