compiler: add param attrs to memmove and memcpy

Add nocapture, readonly, and writeonly to runtime.memmove and
runtime.memcpy where appropriate. This teaches LLVM some more
optimizations it may perform, leading to reduced .text size in some
cases.
Этот коммит содержится в:
Ayke van Laethem 2019-04-07 16:36:14 +02:00 коммит произвёл Ron Evans
родитель 6a2a587dff
коммит dcffbc49c4

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

@ -371,18 +371,33 @@ func (c *Compiler) Compile(mainPath string) error {
c.mod.NamedFunction("runtime.activateTask").SetLinkage(llvm.ExternalLinkage) c.mod.NamedFunction("runtime.activateTask").SetLinkage(llvm.ExternalLinkage)
c.mod.NamedFunction("runtime.scheduler").SetLinkage(llvm.ExternalLinkage) c.mod.NamedFunction("runtime.scheduler").SetLinkage(llvm.ExternalLinkage)
// Load some attributes
getAttr := func(attrName string) llvm.Attribute {
attrKind := llvm.AttributeKindID(attrName)
return c.ctx.CreateEnumAttribute(attrKind, 0)
}
nocapture := getAttr("nocapture")
writeonly := getAttr("writeonly")
readonly := getAttr("readonly")
// Tell the optimizer that runtime.alloc is an allocator, meaning that it // 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. // returns values that are never null and never alias to an existing value.
for _, name := range []string{"noalias", "nonnull"} { for _, attrName := range []string{"noalias", "nonnull"} {
attrKind := llvm.AttributeKindID(name) c.mod.NamedFunction("runtime.alloc").AddAttributeAtIndex(0, getAttr(attrName))
attr := c.ctx.CreateEnumAttribute(attrKind, 0)
c.mod.NamedFunction("runtime.alloc").AddAttributeAtIndex(0, attr)
} }
// See emitNilCheck in asserts.go. // See emitNilCheck in asserts.go.
attrKind := llvm.AttributeKindID("nocapture") c.mod.NamedFunction("runtime.isnil").AddAttributeAtIndex(1, nocapture)
attr := c.ctx.CreateEnumAttribute(attrKind, 0)
c.mod.NamedFunction("runtime.isnil").AddAttributeAtIndex(1, attr) // Memory copy operations do not capture pointers, even though some weird
// pointer arithmetic is happening in the Go implementation.
for _, fnName := range []string{"runtime.memcpy", "runtime.memmove"} {
fn := c.mod.NamedFunction(fnName)
fn.AddAttributeAtIndex(1, nocapture)
fn.AddAttributeAtIndex(1, writeonly)
fn.AddAttributeAtIndex(2, nocapture)
fn.AddAttributeAtIndex(2, readonly)
}
// see: https://reviews.llvm.org/D18355 // see: https://reviews.llvm.org/D18355
if c.Debug { if c.Debug {