copiler: add function attributes to some runtime calls

This allows better escape analysis even without being able to see the
entire program. This makes the stack allocation test case more complete
but probably won't have much of an effect outside of that (as the
compiler is able to infer these attributes in the whole-program
functionattrs pass).
Этот коммит содержится в:
Ayke van Laethem 2021-04-22 14:24:22 +02:00 коммит произвёл Ron Evans
родитель c466465c32
коммит 80caf2dab2
3 изменённых файлов: 24 добавлений и 2 удалений

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

@ -139,6 +139,17 @@ func (c *compilerContext) getFunction(fn *ssa.Function) llvm.Value {
for _, attrName := range []string{"noalias", "nonnull"} {
llvmFn.AddAttributeAtIndex(0, c.ctx.CreateEnumAttribute(llvm.AttributeKindID(attrName), 0))
}
case "runtime.sliceAppend":
// Appending a slice will only read the to-be-appended slice, it won't
// be modified.
llvmFn.AddAttributeAtIndex(2, c.ctx.CreateEnumAttribute(llvm.AttributeKindID("nocapture"), 0))
llvmFn.AddAttributeAtIndex(2, c.ctx.CreateEnumAttribute(llvm.AttributeKindID("readonly"), 0))
case "runtime.sliceCopy":
// Copying a slice won't capture any of the parameters.
llvmFn.AddAttributeAtIndex(1, c.ctx.CreateEnumAttribute(llvm.AttributeKindID("writeonly"), 0))
llvmFn.AddAttributeAtIndex(1, c.ctx.CreateEnumAttribute(llvm.AttributeKindID("nocapture"), 0))
llvmFn.AddAttributeAtIndex(2, c.ctx.CreateEnumAttribute(llvm.AttributeKindID("readonly"), 0))
llvmFn.AddAttributeAtIndex(2, c.ctx.CreateEnumAttribute(llvm.AttributeKindID("nocapture"), 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

4
compiler/testdata/slice.ll предоставленный
Просмотреть файл

@ -60,7 +60,7 @@ entry:
ret { i32*, i32, i32 } %7
}
declare { i8*, i32, i32 } @runtime.sliceAppend(i8*, i8*, i32, i32, i32, i32, i8*, i8*)
declare { i8*, i32, i32 } @runtime.sliceAppend(i8*, i8* nocapture readonly, i32, i32, i32, i32, i8*, i8*)
define hidden { i32*, i32, i32 } @main.sliceAppendSlice(i32* %ints.data, i32 %ints.len, i32 %ints.cap, i32* %added.data, i32 %added.len, i32 %added.cap, i8* %context, i8* %parentHandle) unnamed_addr {
entry:
@ -85,4 +85,4 @@ entry:
ret i32 %copy.n
}
declare i32 @runtime.sliceCopy(i8*, i8*, i32, i32, i32, i8*, i8*)
declare i32 @runtime.sliceCopy(i8* nocapture writeonly, i8* nocapture readonly, i32, i32, i32, i8*, i8*)

11
transform/testdata/allocs2.go предоставленный
Просмотреть файл

@ -22,6 +22,13 @@ func main() {
s4 := make([]byte, 300) // OUT: object allocated on the heap: object size 300 exceeds maximum stack allocation size 256
readByteSlice(s4)
s5 := make([]int, 4) // OUT: object allocated on the heap: escapes at line 27
s5 = append(s5, 5)
s6 := make([]int, 3)
s7 := []int{1, 2, 3}
copySlice(s6, s7)
}
func derefInt(x *int) int {
@ -45,3 +52,7 @@ func returnIntSlice(s []int) []int {
}
func getUnknownNumber() int
func copySlice(out, in []int) {
copy(out, in)
}