compilequeue []*ir.Func // functions waiting to be compiled
)
-func funccompile(fn *ir.Func) {
+func enqueueFunc(fn *ir.Func) {
if ir.CurFunc != nil {
- base.Fatalf("funccompile %v inside %v", fn.Sym(), ir.CurFunc.Sym())
+ base.FatalfAt(fn.Pos(), "enqueueFunc %v inside %v", fn, ir.CurFunc)
}
- if fn.Type() == nil {
- if base.Errors() == 0 {
- base.Fatalf("funccompile missing type")
- }
+ if ir.FuncName(fn) == "_" {
+ // Skip compiling blank functions.
+ // Frontend already reported any spec-mandated errors (#29870).
return
}
- // assign parameter offsets
- types.CalcSize(fn.Type())
-
if len(fn.Body) == 0 {
// Initialize ABI wrappers if necessary.
ssagen.InitLSym(fn, false)
return
}
- typecheck.DeclContext = ir.PAUTO
- ir.CurFunc = fn
- compile(fn)
- ir.CurFunc = nil
- typecheck.DeclContext = ir.PEXTERN
+ errorsBefore := base.Errors()
+ prepareFunc(fn)
+ if base.Errors() > errorsBefore {
+ return
+ }
+
+ compilequeue = append(compilequeue, fn)
}
-func compile(fn *ir.Func) {
+// prepareFunc handles any remaining frontend compilation tasks that
+// aren't yet safe to perform concurrently.
+func prepareFunc(fn *ir.Func) {
// Set up the function's LSym early to avoid data races with the assemblers.
// Do this before walk, as walk needs the LSym to set attributes/relocations
// (e.g. in markTypeUsedInInterface).
ssagen.InitLSym(fn, true)
- errorsBefore := base.Errors()
- walk.Walk(fn)
- if base.Errors() > errorsBefore {
- return
- }
-
- // From this point, there should be no uses of Curfn. Enforce that.
- ir.CurFunc = nil
+ // Calculate parameter offsets.
+ types.CalcSize(fn.Type())
- if ir.FuncName(fn) == "_" {
- // We don't need to generate code for this function, just report errors in its body.
- // At this point we've generated any errors needed.
- // (Beyond here we generate only non-spec errors, like "stack frame too large".)
- // See issue 29870.
- return
- }
+ typecheck.DeclContext = ir.PAUTO
+ ir.CurFunc = fn
+ walk.Walk(fn)
+ ir.CurFunc = nil // enforce no further uses of CurFunc
+ typecheck.DeclContext = ir.PEXTERN
// Make sure type syms are declared for all types that might
// be types of stack objects. We need to do this here
}
}
}
-
- if compilenow(fn) {
- ssagen.Compile(fn, 0)
- } else {
- compilequeue = append(compilequeue, fn)
- }
-}
-
-// compilenow reports whether to compile immediately.
-// If functions are not compiled immediately,
-// they are enqueued in compilequeue,
-// which is drained by compileFunctions.
-func compilenow(fn *ir.Func) bool {
- // Issue 38068: if this function is a method AND an inline
- // candidate AND was not inlined (yet), put it onto the compile
- // queue instead of compiling it immediately. This is in case we
- // wind up inlining it into a method wrapper that is generated by
- // compiling a function later on in the Target.Decls list.
- if ir.IsMethod(fn) && isInlinableButNotInlined(fn) {
- return false
- }
- return base.Flag.LowerC == 1 && base.Debug.CompileLater == 0
}
// compileFunctions compiles all functions in compilequeue.
types.CalcSizeDisabled = false
}
}
-
-// isInlinableButNotInlined returns true if 'fn' was marked as an
-// inline candidate but then never inlined (presumably because we
-// found no call sites).
-func isInlinableButNotInlined(fn *ir.Func) bool {
- if fn.Inl == nil {
- return false
- }
- if fn.Sym() == nil {
- return true
- }
- return !fn.Linksym().WasInlined()
-}