mirror of
https://github.com/tinygo-org/tinygo.git
synced 2026-08-16 02:33:28 +00:00
compiler: add //go:inline pragma
This commit is contained in:
committed by
Ron Evans
parent
397b90753c
commit
6f6afb0515
@@ -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" {
|
||||||
|
|||||||
@@ -33,11 +33,12 @@ type Program struct {
|
|||||||
type Function struct {
|
type Function struct {
|
||||||
*ssa.Function
|
*ssa.Function
|
||||||
LLVMFn llvm.Value
|
LLVMFn llvm.Value
|
||||||
linkName string // go:linkname, go:export, go:interrupt
|
linkName string // go:linkname, go:export, go:interrupt
|
||||||
exported bool // go:export
|
exported bool // go:export
|
||||||
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 != "" {
|
||||||
|
|||||||
Reference in New Issue
Block a user