compiler: add //go:inline pragma
Этот коммит содержится в:
родитель
397b90753c
коммит
6f6afb0515
2 изменённых файлов: 36 добавлений и 5 удалений
|
@ -828,6 +828,14 @@ func (c *Compiler) parseFunc(frame *Frame) {
|
|||
frame.fn.LLVMFn.SetFunctionCallConv(85) // CallingConv::AVR_SIGNAL
|
||||
}
|
||||
|
||||
// Some functions have a pragma controlling the inlining level.
|
||||
switch frame.fn.Inline() {
|
||||
case ir.InlineHint:
|
||||
// Add LLVM inline hint to functions with //go:inline pragma.
|
||||
inline := c.ctx.CreateEnumAttribute(llvm.AttributeKindID("inlinehint"), 0)
|
||||
frame.fn.LLVMFn.AddFunctionAttr(inline)
|
||||
}
|
||||
|
||||
// Add debug info, if needed.
|
||||
if c.Debug {
|
||||
if frame.fn.Synthetic == "package initializer" {
|
||||
|
|
33
ir/ir.go
33
ir/ir.go
|
@ -33,11 +33,12 @@ type Program struct {
|
|||
type Function struct {
|
||||
*ssa.Function
|
||||
LLVMFn llvm.Value
|
||||
linkName string // go:linkname, go:export, go:interrupt
|
||||
exported bool // go:export
|
||||
nobounds bool // go:nobounds
|
||||
flag bool // used by dead code elimination
|
||||
interrupt bool // go:interrupt
|
||||
linkName string // go:linkname, go:export, go:interrupt
|
||||
exported bool // go:export
|
||||
nobounds bool // go:nobounds
|
||||
flag bool // used by dead code elimination
|
||||
interrupt bool // go:interrupt
|
||||
inline InlineType // go:inline
|
||||
}
|
||||
|
||||
// Global variable, possibly constant.
|
||||
|
@ -69,6 +70,21 @@ type Interface struct {
|
|||
Type *types.Interface
|
||||
}
|
||||
|
||||
type InlineType int
|
||||
|
||||
// How much to inline.
|
||||
const (
|
||||
// Default behavior. The compiler decides for itself whether any given
|
||||
// function will be inlined. Whether any function is inlined depends on the
|
||||
// optimization level.
|
||||
InlineDefault InlineType = iota
|
||||
|
||||
// Inline hint, just like the C inline keyword (signalled using
|
||||
// //go:inline). The compiler will be more likely to inline this function,
|
||||
// but it is not a guarantee.
|
||||
InlineHint
|
||||
)
|
||||
|
||||
// Create and initialize a new *Program from a *ssa.Program.
|
||||
func NewProgram(lprogram *loader.Program, mainPath string) *Program {
|
||||
comments := map[string]*ast.CommentGroup{}
|
||||
|
@ -279,6 +295,8 @@ func (f *Function) parsePragmas() {
|
|||
}
|
||||
f.linkName = parts[1]
|
||||
f.exported = true
|
||||
case "//go:inline":
|
||||
f.inline = InlineHint
|
||||
case "//go:interrupt":
|
||||
if len(parts) != 2 {
|
||||
continue
|
||||
|
@ -332,6 +350,11 @@ func (f *Function) IsInterrupt() bool {
|
|||
return f.interrupt
|
||||
}
|
||||
|
||||
// Return the inline directive of this function.
|
||||
func (f *Function) Inline() InlineType {
|
||||
return f.inline
|
||||
}
|
||||
|
||||
// Return the link name for this function.
|
||||
func (f *Function) LinkName() string {
|
||||
if f.linkName != "" {
|
||||
|
|
Загрузка…
Создание таблицы
Сослаться в новой задаче