compiler: move the setting of attributes to getFunction

This is a small refactor to move code away from compiler.CompilePackage,
with the goal that compiler.CompilePackage will eventually be removed
entirely in favor of compiler.CompilePackage.
Этот коммит содержится в:
Ayke van Laethem 2021-01-24 17:43:21 +01:00 коммит произвёл Ron Evans
родитель 5642d72fbe
коммит 0bad2c9ff2
2 изменённых файлов: 22 добавлений и 29 удалений

Просмотреть файл

@ -297,35 +297,6 @@ func CompileProgram(pkgName string, lprogram *loader.Program, machine llvm.Targe
}
irbuilder.CreateRetVoid()
// Load some attributes
getAttr := func(attrName string) llvm.Attribute {
attrKind := llvm.AttributeKindID(attrName)
return c.ctx.CreateEnumAttribute(attrKind, 0)
}
nocapture := getAttr("nocapture")
readonly := getAttr("readonly")
// Tell the optimizer that runtime.alloc is an allocator, meaning that it
// returns values that are never null and never alias to an existing value.
for _, attrName := range []string{"noalias", "nonnull"} {
c.mod.NamedFunction("runtime.alloc").AddAttributeAtIndex(0, getAttr(attrName))
}
// On *nix systems, the "abort" functuion in libc is used to handle fatal panics.
// Mark it as noreturn so LLVM can optimize away code.
if abort := c.mod.NamedFunction("abort"); !abort.IsNil() && abort.IsDeclaration() {
abort.AddFunctionAttr(getAttr("noreturn"))
}
// This function is necessary for tracking pointers on the stack in a
// portable way (see gc.go). Indicate to the optimizer that the only thing
// we'll do is read the pointer.
trackPointer := c.mod.NamedFunction("runtime.trackPointer")
if !trackPointer.IsNil() {
trackPointer.AddAttributeAtIndex(1, nocapture)
trackPointer.AddAttributeAtIndex(1, readonly)
}
// see: https://reviews.llvm.org/D18355
if c.Debug() {
c.mod.AddNamedMetadataOperand("llvm.module.flags",

Просмотреть файл

@ -108,6 +108,28 @@ func (c *compilerContext) getFunction(fn *ssa.Function) llvm.Value {
}
}
// Set a number of function or parameter attributes, depending on the
// function. These functions are runtime functions that are known to have
// certain attributes that might not be inferred by the compiler.
switch info.linkName {
case "abort":
// On *nix systems, the "abort" functuion in libc is used to handle fatal panics.
// Mark it as noreturn so LLVM can optimize away code.
llvmFn.AddFunctionAttr(c.ctx.CreateEnumAttribute(llvm.AttributeKindID("noreturn"), 0))
case "runtime.alloc":
// Tell the optimizer that runtime.alloc is an allocator, meaning that it
// returns values that are never null and never alias to an existing value.
for _, attrName := range []string{"noalias", "nonnull"} {
llvmFn.AddAttributeAtIndex(0, c.ctx.CreateEnumAttribute(llvm.AttributeKindID(attrName), 0))
}
case "runtime.trackPointer":
// This function is necessary for tracking pointers on the stack in a
// portable way (see gc_stack_portable.go). Indicate to the optimizer
// that the only thing we'll do is read the pointer.
llvmFn.AddAttributeAtIndex(1, c.ctx.CreateEnumAttribute(llvm.AttributeKindID("nocapture"), 0))
llvmFn.AddAttributeAtIndex(1, c.ctx.CreateEnumAttribute(llvm.AttributeKindID("readonly"), 0))
}
// External/exported functions may not retain pointer values.
// https://golang.org/cmd/cgo/#hdr-Passing_pointers
if info.exported {