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
|
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.
|
// Add debug info, if needed.
|
||||||
if c.Debug {
|
if c.Debug {
|
||||||
if frame.fn.Synthetic == "package initializer" {
|
if frame.fn.Synthetic == "package initializer" {
|
||||||
|
|
23
ir/ir.go
23
ir/ir.go
|
@ -38,6 +38,7 @@ type Function struct {
|
||||||
nobounds bool // go:nobounds
|
nobounds bool // go:nobounds
|
||||||
flag bool // used by dead code elimination
|
flag bool // used by dead code elimination
|
||||||
interrupt bool // go:interrupt
|
interrupt bool // go:interrupt
|
||||||
|
inline InlineType // go:inline
|
||||||
}
|
}
|
||||||
|
|
||||||
// Global variable, possibly constant.
|
// Global variable, possibly constant.
|
||||||
|
@ -69,6 +70,21 @@ type Interface struct {
|
||||||
Type *types.Interface
|
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.
|
// Create and initialize a new *Program from a *ssa.Program.
|
||||||
func NewProgram(lprogram *loader.Program, mainPath string) *Program {
|
func NewProgram(lprogram *loader.Program, mainPath string) *Program {
|
||||||
comments := map[string]*ast.CommentGroup{}
|
comments := map[string]*ast.CommentGroup{}
|
||||||
|
@ -279,6 +295,8 @@ func (f *Function) parsePragmas() {
|
||||||
}
|
}
|
||||||
f.linkName = parts[1]
|
f.linkName = parts[1]
|
||||||
f.exported = true
|
f.exported = true
|
||||||
|
case "//go:inline":
|
||||||
|
f.inline = InlineHint
|
||||||
case "//go:interrupt":
|
case "//go:interrupt":
|
||||||
if len(parts) != 2 {
|
if len(parts) != 2 {
|
||||||
continue
|
continue
|
||||||
|
@ -332,6 +350,11 @@ func (f *Function) IsInterrupt() bool {
|
||||||
return f.interrupt
|
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.
|
// Return the link name for this function.
|
||||||
func (f *Function) LinkName() string {
|
func (f *Function) LinkName() string {
|
||||||
if f.linkName != "" {
|
if f.linkName != "" {
|
||||||
|
|
Загрузка…
Создание таблицы
Сослаться в новой задаче