1
2
3
4
5 package gc
6
7 import (
8 "bufio"
9 "bytes"
10 "cmd/compile/internal/base"
11 "cmd/compile/internal/deadcode"
12 "cmd/compile/internal/devirtualize"
13 "cmd/compile/internal/dwarfgen"
14 "cmd/compile/internal/escape"
15 "cmd/compile/internal/inline"
16 "cmd/compile/internal/ir"
17 "cmd/compile/internal/logopt"
18 "cmd/compile/internal/noder"
19 "cmd/compile/internal/pkginit"
20 "cmd/compile/internal/reflectdata"
21 "cmd/compile/internal/ssa"
22 "cmd/compile/internal/ssagen"
23 "cmd/compile/internal/typecheck"
24 "cmd/compile/internal/types"
25 "cmd/internal/dwarf"
26 "cmd/internal/obj"
27 "cmd/internal/objabi"
28 "cmd/internal/src"
29 "flag"
30 "fmt"
31 "internal/buildcfg"
32 "log"
33 "os"
34 "runtime"
35 "sort"
36 )
37
38
39
40
41
42 func handlePanic() {
43 if err := recover(); err != nil {
44 if err == "-h" {
45
46
47 panic(err)
48 }
49 base.Fatalf("panic: %v", err)
50 }
51 }
52
53
54
55
56 func Main(archInit func(*ssagen.ArchInfo)) {
57 base.Timer.Start("fe", "init")
58
59 defer handlePanic()
60
61 archInit(&ssagen.Arch)
62
63 base.Ctxt = obj.Linknew(ssagen.Arch.LinkArch)
64 base.Ctxt.DiagFunc = base.Errorf
65 base.Ctxt.DiagFlush = base.FlushErrors
66 base.Ctxt.Bso = bufio.NewWriter(os.Stdout)
67
68
69
70
71
72 base.Ctxt.UseBASEntries = base.Ctxt.Headtype != objabi.Hdarwin
73
74 types.LocalPkg = types.NewPkg("", "")
75 types.LocalPkg.Prefix = "\"\""
76
77
78
79
80 types.LocalPkg.Height = types.MaxPkgHeight
81
82
83 types.BuiltinPkg = types.NewPkg("go.builtin", "")
84 types.BuiltinPkg.Prefix = "go.builtin"
85
86
87 types.UnsafePkg = types.NewPkg("unsafe", "unsafe")
88
89
90
91
92
93
94 ir.Pkgs.Runtime = types.NewPkg("go.runtime", "runtime")
95 ir.Pkgs.Runtime.Prefix = "runtime"
96
97
98 ir.Pkgs.Itab = types.NewPkg("go.itab", "go.itab")
99 ir.Pkgs.Itab.Prefix = "go.itab"
100
101
102 ir.Pkgs.Go = types.NewPkg("go", "")
103
104 base.DebugSSA = ssa.PhaseOption
105 base.ParseFlags()
106
107
108
109
110 dwarfgen.RecordFlags("B", "N", "l", "msan", "race", "asan", "shared", "dynlink", "dwarf", "dwarflocationlists", "dwarfbasentries", "smallframes", "spectre")
111
112 if !base.EnableTrace && base.Flag.LowerT {
113 log.Fatalf("compiler not built with support for -t")
114 }
115
116
117
118
119
120 if base.Flag.LowerL <= 1 {
121 base.Flag.LowerL = 1 - base.Flag.LowerL
122 }
123
124 if base.Flag.SmallFrames {
125 ir.MaxStackVarSize = 128 * 1024
126 ir.MaxImplicitStackVarSize = 16 * 1024
127 }
128
129 if base.Flag.Dwarf {
130 base.Ctxt.DebugInfo = dwarfgen.Info
131 base.Ctxt.GenAbstractFunc = dwarfgen.AbstractFunc
132 base.Ctxt.DwFixups = obj.NewDwarfFixupTable(base.Ctxt)
133 } else {
134
135 base.Flag.GenDwarfInl = 0
136 base.Ctxt.Flag_locationlists = false
137 }
138 if base.Ctxt.Flag_locationlists && len(base.Ctxt.Arch.DWARFRegisters) == 0 {
139 log.Fatalf("location lists requested but register mapping not available on %v", base.Ctxt.Arch.Name)
140 }
141
142 types.ParseLangFlag()
143
144 symABIs := ssagen.NewSymABIs(base.Ctxt.Pkgpath)
145 if base.Flag.SymABIs != "" {
146 symABIs.ReadSymABIs(base.Flag.SymABIs)
147 }
148
149 if base.Compiling(base.NoInstrumentPkgs) {
150 base.Flag.Race = false
151 base.Flag.MSan = false
152 base.Flag.ASan = false
153 }
154
155 ssagen.Arch.LinkArch.Init(base.Ctxt)
156 startProfile()
157 if base.Flag.Race || base.Flag.MSan || base.Flag.ASan {
158 base.Flag.Cfg.Instrumenting = true
159 }
160 if base.Flag.Dwarf {
161 dwarf.EnableLogging(base.Debug.DwarfInl != 0)
162 }
163 if base.Debug.SoftFloat != 0 {
164 ssagen.Arch.SoftFloat = true
165 }
166
167 if base.Flag.JSON != "" {
168 logopt.LogJsonOption(base.Flag.JSON)
169 }
170
171 ir.EscFmt = escape.Fmt
172 ir.IsIntrinsicCall = ssagen.IsIntrinsicCall
173 inline.SSADumpInline = ssagen.DumpInline
174 ssagen.InitEnv()
175 ssagen.InitTables()
176
177 types.PtrSize = ssagen.Arch.LinkArch.PtrSize
178 types.RegSize = ssagen.Arch.LinkArch.RegSize
179 types.MaxWidth = ssagen.Arch.MAXWIDTH
180
181 typecheck.Target = new(ir.Package)
182
183 typecheck.NeedRuntimeType = reflectdata.NeedRuntimeType
184
185 base.AutogeneratedPos = makePos(src.NewFileBase("<autogenerated>", "<autogenerated>"), 1, 0)
186
187 typecheck.InitUniverse()
188 typecheck.InitRuntime()
189
190
191 noder.LoadPackage(flag.Args())
192
193 dwarfgen.RecordPackageName()
194
195
196
197 ssagen.InitConfig()
198
199
200
201
202
203
204
205
206 pkginit.MakeInit()
207
208
209
210
211
212 if base.Debug.UnifiedQuirks != 0 {
213 s := typecheck.Target.Decls
214 sort.SliceStable(s, func(i, j int) bool {
215 return s[i].Pos().Before(s[j].Pos())
216 })
217 }
218
219
220
221 for _, n := range typecheck.Target.Decls {
222 if n.Op() == ir.ODCLFUNC {
223 deadcode.Func(n.(*ir.Func))
224 }
225 }
226
227
228
229
230
231
232 if typecheck.DirtyAddrtaken {
233 typecheck.ComputeAddrtaken(typecheck.Target.Decls)
234 typecheck.DirtyAddrtaken = false
235 }
236 typecheck.IncrementalAddrtaken = true
237
238 if base.Debug.TypecheckInl != 0 {
239
240
241 typecheck.AllImportedBodies()
242 }
243
244
245 base.Timer.Start("fe", "inlining")
246 if base.Flag.LowerL != 0 {
247 inline.InlinePackage()
248 }
249 noder.MakeWrappers(typecheck.Target)
250
251
252 for _, n := range typecheck.Target.Decls {
253 if n.Op() == ir.ODCLFUNC {
254 devirtualize.Func(n.(*ir.Func))
255 }
256 }
257 ir.CurFunc = nil
258
259
260 if initTask := pkginit.Task(); initTask != nil {
261 typecheck.Export(initTask)
262 }
263
264
265
266 symABIs.GenABIWrappers()
267
268
269
270
271
272
273
274
275
276 base.Timer.Start("fe", "escapes")
277 escape.Funcs(typecheck.Target.Decls)
278
279
280
281
282 reflectdata.AfterGlobalEscapeAnalysis = true
283
284
285
286
287
288 if base.Flag.CompilingRuntime {
289 ssagen.EnableNoWriteBarrierRecCheck()
290 }
291
292 ir.CurFunc = nil
293
294
295
296 base.Timer.Start("be", "compilefuncs")
297 fcount := int64(0)
298 for i := 0; i < len(typecheck.Target.Decls); i++ {
299 if fn, ok := typecheck.Target.Decls[i].(*ir.Func); ok {
300
301 if fn.IsDeadcodeClosure() {
302 continue
303 }
304 enqueueFunc(fn)
305 fcount++
306 }
307 }
308 base.Timer.AddEvent(fcount, "funcs")
309
310 compileFunctions()
311
312 if base.Flag.CompilingRuntime {
313
314 ssagen.NoWriteBarrierRecCheck()
315 }
316
317
318
319
320 if base.Ctxt.DwFixups != nil {
321 base.Ctxt.DwFixups.Finalize(base.Ctxt.Pkgpath, base.Debug.DwarfInl != 0)
322 base.Ctxt.DwFixups = nil
323 base.Flag.GenDwarfInl = 0
324 }
325
326
327 base.Timer.Start("be", "dumpobj")
328 dumpdata()
329 base.Ctxt.NumberSyms()
330 dumpobj()
331 if base.Flag.AsmHdr != "" {
332 dumpasmhdr()
333 }
334
335 ssagen.CheckLargeStacks()
336 typecheck.CheckFuncStack()
337
338 if len(compilequeue) != 0 {
339 base.Fatalf("%d uncompiled functions", len(compilequeue))
340 }
341
342 logopt.FlushLoggedOpts(base.Ctxt, base.Ctxt.Pkgpath)
343 base.ExitIfErrors()
344
345 base.FlushErrors()
346 base.Timer.Stop()
347
348 if base.Flag.Bench != "" {
349 if err := writebench(base.Flag.Bench); err != nil {
350 log.Fatalf("cannot write benchmark data: %v", err)
351 }
352 }
353 }
354
355 func writebench(filename string) error {
356 f, err := os.OpenFile(filename, os.O_WRONLY|os.O_CREATE|os.O_APPEND, 0666)
357 if err != nil {
358 return err
359 }
360
361 var buf bytes.Buffer
362 fmt.Fprintln(&buf, "commit:", buildcfg.Version)
363 fmt.Fprintln(&buf, "goos:", runtime.GOOS)
364 fmt.Fprintln(&buf, "goarch:", runtime.GOARCH)
365 base.Timer.Write(&buf, "BenchmarkCompile:"+base.Ctxt.Pkgpath+":")
366
367 n, err := f.Write(buf.Bytes())
368 if err != nil {
369 return err
370 }
371 if n != buf.Len() {
372 panic("bad writer")
373 }
374
375 return f.Close()
376 }
377
378 func makePos(b *src.PosBase, line, col uint) src.XPos {
379 return base.Ctxt.PosTable.XPos(src.MakePos(b, line, col))
380 }
381
View as plain text