Rietveld Code Review Tool
Help | Bug tracker | Discussion group | Source code | Sign in
(874)

Delta Between Two Patch Sets: src/pkg/exp/ssa/builder.go

Issue 7229074: code review 7229074: exp/ssa: build fully pruned SSA form. (Closed)
Left Patch Set: Created 11 years, 1 month ago
Right Patch Set: diff -r 734059df2768 https://code.google.com/p/go/ Created 11 years, 1 month ago
Left:
Right:
Use n/p to move between diff chunks; N/P to move between comments. Please Sign in to add in-line comments.
Jump to:
Right: Side by side diff | Download
« no previous file with change/comment | « src/pkg/exp/ssa/blockopt.go ('k') | src/pkg/exp/ssa/doc.go » ('j') | no next file with change/comment »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
LEFTRIGHT
(no file at all)
1 package ssa 1 package ssa
2 2
3 // This file defines the SSA builder. 3 // This file defines the SSA builder.
4 // 4 //
5 // The builder has two phases, CREATE and BUILD. In the CREATE 5 // The builder has two phases, CREATE and BUILD. In the CREATE
6 // phase, all packages are constructed and type-checked and 6 // phase, all packages are constructed and type-checked and
7 // definitions of all package members are created, method-sets are 7 // definitions of all package members are created, method-sets are
8 // computed, and bridge methods are synthesized. The create phase 8 // computed, and bridge methods are synthesized. The create phase
9 // proceeds in topological order over the import dependency graph, 9 // proceeds in topological order over the import dependency graph,
10 // initiated by client calls to CreatePackage. 10 // initiated by client calls to CreatePackage.
(...skipping 104 matching lines...) Expand 10 before | Expand all | Expand 10 after
115 115
116 // BuilderMode is a bitmask of options for diagnostics and checking. 116 // BuilderMode is a bitmask of options for diagnostics and checking.
117 type BuilderMode uint 117 type BuilderMode uint
118 118
119 const ( 119 const (
120 LogPackages BuilderMode = 1 << iota // Dump package inventory t o stderr 120 LogPackages BuilderMode = 1 << iota // Dump package inventory t o stderr
121 LogFunctions // Dump function SSA code t o stderr 121 LogFunctions // Dump function SSA code t o stderr
122 LogSource // Show source locations as SSA builder progresses 122 LogSource // Show source locations as SSA builder progresses
123 SanityCheckFunctions // Perform sanity checking of function bodies 123 SanityCheckFunctions // Perform sanity checking of function bodies
124 UseGCImporter // Ignore SourceLoader; use gc-compiled object code for all imports 124 UseGCImporter // Ignore SourceLoader; use gc-compiled object code for all imports
125 NaiveForm // Build naïve SSA form: do n't replace local loads/stores with registers
125 ) 126 )
126 127
127 // NewBuilder creates and returns a new SSA builder. 128 // NewBuilder creates and returns a new SSA builder.
128 // 129 //
129 // mode is a bitfield of options controlling verbosity, logging and 130 // mode is a bitfield of options controlling verbosity, logging and
130 // additional sanity checks. 131 // additional sanity checks.
131 // 132 //
132 // loader is a SourceLoader function that finds, loads and parses Go 133 // loader is a SourceLoader function that finds, loads and parses Go
133 // source files for a given import path. (It is ignored if the mode 134 // source files for a given import path. (It is ignored if the mode
134 // bits include UseGCImporter.) 135 // bits include UseGCImporter.)
(...skipping 238 matching lines...) Expand 10 before | Expand all | Expand 10 after
373 } 374 }
374 375
375 // The edge from e.Y to done carries the value of e.Y. 376 // The edge from e.Y to done carries the value of e.Y.
376 fn.currentBlock = rhs 377 fn.currentBlock = rhs
377 edges = append(edges, b.expr(fn, e.Y)) 378 edges = append(edges, b.expr(fn, e.Y))
378 emitJump(fn, done) 379 emitJump(fn, done)
379 fn.currentBlock = done 380 fn.currentBlock = done
380 381
381 // TODO(adonovan): do we need emitConv on each edge? 382 // TODO(adonovan): do we need emitConv on each edge?
382 // Test with named boolean types. 383 // Test with named boolean types.
383 » phi := &Phi{Edges: edges} 384 » phi := &Phi{Edges: edges, Comment: e.Op.String()}
384 phi.Type_ = phi.Edges[0].Type() 385 phi.Type_ = phi.Edges[0].Type()
385 return done.emit(phi) 386 return done.emit(phi)
386 } 387 }
387 388
388 // exprN lowers a multi-result expression e to SSA form, emitting code 389 // exprN lowers a multi-result expression e to SSA form, emitting code
389 // to fn and returning a single Value whose type is a *types.Results 390 // to fn and returning a single Value whose type is a *types.Results
390 // (tuple). The caller must access the components via Extract. 391 // (tuple). The caller must access the components via Extract.
391 // 392 //
392 // Multi-result expressions include CallExprs in a multi-value 393 // Multi-result expressions include CallExprs in a multi-value
393 // assignment or return statement, and "value,ok" uses of 394 // assignment or return statement, and "value,ok" uses of
(...skipping 939 matching lines...) Expand 10 before | Expand all | Expand 10 after
1333 if !b.nTo1Vars[spec] { 1334 if !b.nTo1Vars[spec] {
1334 b.nTo1Vars[spec] = true 1335 b.nTo1Vars[spec] = true
1335 if b.mode&LogSource != 0 { 1336 if b.mode&LogSource != 0 {
1336 fmt.Fprintln(os.Stderr, "build globals", spec.Na mes) // ugly... 1337 fmt.Fprintln(os.Stderr, "build globals", spec.Na mes) // ugly...
1337 } 1338 }
1338 tuple := b.exprN(init, spec.Values[0]) 1339 tuple := b.exprN(init, spec.Values[0])
1339 rtypes := tuple.Type().(*types.Result).Values 1340 rtypes := tuple.Type().(*types.Result).Values
1340 for i, id := range spec.Names { 1341 for i, id := range spec.Names {
1341 if !isBlankIdent(id) { 1342 if !isBlankIdent(id) {
1342 g := b.globals[b.obj(id)].(*Global) 1343 g := b.globals[b.obj(id)].(*Global)
1343 » » » » » g.spec = nil // just an optimisation 1344 » » » » » g.spec = nil // just an optimization
1344 emitStore(init, g, 1345 emitStore(init, g,
1345 emitExtract(init, tuple, i, rtyp es[i].Type)) 1346 emitExtract(init, tuple, i, rtyp es[i].Type))
1346 } 1347 }
1347 } 1348 }
1348 } 1349 }
1349 } 1350 }
1350 } 1351 }
1351 1352
1352 // localValueSpec emits to fn code to define all of the vars in the 1353 // localValueSpec emits to fn code to define all of the vars in the
1353 // function-local ValueSpec, spec. 1354 // function-local ValueSpec, spec.
(...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after
1412 } 1413 }
1413 } 1414 }
1414 lval = b.addr(fn, lhs, false) // non-escaping 1415 lval = b.addr(fn, lhs, false) // non-escaping
1415 } 1416 }
1416 lvals = append(lvals, lval) 1417 lvals = append(lvals, lval)
1417 } 1418 }
1418 if len(lhss) == len(rhss) { 1419 if len(lhss) == len(rhss) {
1419 // e.g. x, y = f(), g() 1420 // e.g. x, y = f(), g()
1420 if len(lhss) == 1 { 1421 if len(lhss) == 1 {
1421 // x = type{...} 1422 // x = type{...}
1422 » » » // Optimisation: in-place construction 1423 » » » // Optimization: in-place construction
1423 // of composite literals. 1424 // of composite literals.
1424 b.exprInPlace(fn, lvals[0], rhss[0]) 1425 b.exprInPlace(fn, lvals[0], rhss[0])
1425 } else { 1426 } else {
1426 // Parallel assignment. All reads must occur 1427 // Parallel assignment. All reads must occur
1427 // before all updates, precluding exprInPlace. 1428 // before all updates, precluding exprInPlace.
1428 // TODO(adonovan): opt: is it sound to 1429 // TODO(adonovan): opt: is it sound to
1429 // perform exprInPlace if !isDef? 1430 // perform exprInPlace if !isDef?
1430 var rvals []Value 1431 var rvals []Value
1431 for _, rval := range rhss { 1432 for _, rval := range rhss {
1432 rvals = append(rvals, b.expr(fn, rval)) 1433 rvals = append(rvals, b.expr(fn, rval))
(...skipping 324 matching lines...) Expand 10 before | Expand all | Expand 10 after
1757 emitJump(fn, done) 1758 emitJump(fn, done)
1758 fn.currentBlock = done 1759 fn.currentBlock = done
1759 } 1760 }
1760 1761
1761 // selectStmt emits to fn code for the select statement s, optionally 1762 // selectStmt emits to fn code for the select statement s, optionally
1762 // labelled by label. 1763 // labelled by label.
1763 // 1764 //
1764 func (b *Builder) selectStmt(fn *Function, s *ast.SelectStmt, label *lblock) { 1765 func (b *Builder) selectStmt(fn *Function, s *ast.SelectStmt, label *lblock) {
1765 // A blocking select of a single case degenerates to a 1766 // A blocking select of a single case degenerates to a
1766 // simple send or receive. 1767 // simple send or receive.
1767 » // TODO(adonovan): is this optimisation worth its weight? 1768 » // TODO(adonovan): is this optimization worth its weight?
1768 if len(s.Body.List) == 1 { 1769 if len(s.Body.List) == 1 {
1769 clause := s.Body.List[0].(*ast.CommClause) 1770 clause := s.Body.List[0].(*ast.CommClause)
1770 if clause.Comm != nil { 1771 if clause.Comm != nil {
1771 b.stmt(fn, clause.Comm) 1772 b.stmt(fn, clause.Comm)
1772 done := fn.newBasicBlock("select.done") 1773 done := fn.newBasicBlock("select.done")
1773 if label != nil { 1774 if label != nil {
1774 label._break = done 1775 label._break = done
1775 } 1776 }
1776 fn.targets = &targets{ 1777 fn.targets = &targets{
1777 tail: fn.targets, 1778 tail: fn.targets,
(...skipping 999 matching lines...) Expand 10 before | Expand all | Expand 10 after
2777 } 2778 }
2778 } 2779 }
2779 p.files = nil 2780 p.files = nil
2780 2781
2781 // Finish up. 2782 // Finish up.
2782 emitJump(init, done) 2783 emitJump(init, done)
2783 init.currentBlock = done 2784 init.currentBlock = done
2784 init.emit(new(Ret)) 2785 init.emit(new(Ret))
2785 init.finish() 2786 init.finish()
2786 } 2787 }
LEFTRIGHT

Powered by Google App Engine
RSS Feeds Recent Issues | This issue
This is Rietveld f62528b