buildFunction builds SSA code for the body of function fn. Idempotent.
(info *Info, fn *Function)
| 2834 | |
| 2835 | // buildFunction builds SSA code for the body of function fn. Idempotent. |
| 2836 | func (prog *Program) buildFunction(info *Info, fn *Function) { |
| 2837 | if fn.Blocks != nil { |
| 2838 | return // building already started |
| 2839 | } |
| 2840 | |
| 2841 | body := fn.object.body |
| 2842 | if body == nil { |
| 2843 | // External function. |
| 2844 | if fn.Params == nil { |
| 2845 | // This condition ensures we add a non-empty |
| 2846 | // params list once only, but we may attempt |
| 2847 | // the degenerate empty case repeatedly. |
| 2848 | // TODO(adonovan): opt: don't do that. |
| 2849 | |
| 2850 | // We set Function.Params even though there is no body |
| 2851 | // code to reference them. This simplifies clients. |
| 2852 | if recv := fn.Signature.Recv(); recv != nil { |
| 2853 | fn.addParamObj(recv) |
| 2854 | } |
| 2855 | params := fn.Signature.Params() |
| 2856 | for i, n := 0, params.Len(); i < n; i++ { |
| 2857 | fn.addParamObj(params.At(i)) |
| 2858 | } |
| 2859 | } |
| 2860 | return |
| 2861 | } |
| 2862 | |
| 2863 | if prog.mode&LogSource != 0 { |
| 2864 | defer logStack("build function %s @ %s", fn, fn.Pos())() |
| 2865 | } |
| 2866 | |
| 2867 | prog.build(fn, info, func(b *builder) { |
| 2868 | b.createSyntacticParams() |
| 2869 | b.stmt(body) |
| 2870 | if cb := b.currentBlock; cb != nil && (cb == fn.Blocks[0] || cb == fn.Recover || cb.Preds != nil) { |
| 2871 | // Control fell off the end of the function's body block. |
| 2872 | // |
| 2873 | // Block optimizations eliminate the current block, if |
| 2874 | // unreachable. It is a builder invariant that |
| 2875 | // if this no-arg return is ill-typed for |
| 2876 | // b.Fn.Signature.Results, this block must be |
| 2877 | // unreachable. The sanity checker checks this. |
| 2878 | b.emit(new(RunDefers)) |
| 2879 | b.emit(new(Return)) |
| 2880 | } |
| 2881 | }) |
| 2882 | } |
| 2883 | |
| 2884 | // Build calls Package.Build for each package in prog. |
| 2885 | // Building occurs in parallel unless the BuildSerially mode flag was set. |