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.
Этот коммит содержится в:
родитель
5642d72fbe
коммит
0bad2c9ff2
2 изменённых файлов: 22 добавлений и 29 удалений
|
@ -297,35 +297,6 @@ func CompileProgram(pkgName string, lprogram *loader.Program, machine llvm.Targe
|
||||||
}
|
}
|
||||||
irbuilder.CreateRetVoid()
|
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
|
// see: https://reviews.llvm.org/D18355
|
||||||
if c.Debug() {
|
if c.Debug() {
|
||||||
c.mod.AddNamedMetadataOperand("llvm.module.flags",
|
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.
|
// External/exported functions may not retain pointer values.
|
||||||
// https://golang.org/cmd/cgo/#hdr-Passing_pointers
|
// https://golang.org/cmd/cgo/#hdr-Passing_pointers
|
||||||
if info.exported {
|
if info.exported {
|
||||||
|
|
Загрузка…
Создание таблицы
Сослаться в новой задаче