aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorAyke van Laethem <[email protected]>2019-04-07 16:36:14 +0200
committerRon Evans <[email protected]>2019-04-11 09:16:10 +0200
commitdcffbc49c4ed919f3d41556e9d56d3f50784f069 (patch)
tree981728945dd7304d9b132db20a274b8e6f820622
parent6a2a587dffff29089aea2eba197ae61086acbc4f (diff)
downloadtinygo-dcffbc49c4ed919f3d41556e9d56d3f50784f069.tar.gz
tinygo-dcffbc49c4ed919f3d41556e9d56d3f50784f069.zip
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.
-rw-r--r--compiler/compiler.go29
1 files changed, 22 insertions, 7 deletions
diff --git a/compiler/compiler.go b/compiler/compiler.go
index 3ed910c58..b19765de0 100644
--- a/compiler/compiler.go
+++ b/compiler/compiler.go
@@ -371,18 +371,33 @@ func (c *Compiler) Compile(mainPath string) error {
c.mod.NamedFunction("runtime.activateTask").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
// returns values that are never null and never alias to an existing value.
- for _, name := range []string{"noalias", "nonnull"} {
- attrKind := llvm.AttributeKindID(name)
- attr := c.ctx.CreateEnumAttribute(attrKind, 0)
- c.mod.NamedFunction("runtime.alloc").AddAttributeAtIndex(0, attr)
+ for _, attrName := range []string{"noalias", "nonnull"} {
+ c.mod.NamedFunction("runtime.alloc").AddAttributeAtIndex(0, getAttr(attrName))
}
// See emitNilCheck in asserts.go.
- attrKind := llvm.AttributeKindID("nocapture")
- attr := c.ctx.CreateEnumAttribute(attrKind, 0)
- c.mod.NamedFunction("runtime.isnil").AddAttributeAtIndex(1, attr)
+ c.mod.NamedFunction("runtime.isnil").AddAttributeAtIndex(1, nocapture)
+
+ // 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
if c.Debug {