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).
Этот коммит содержится в:
родитель
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
предоставленный
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
предоставленный
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)
|
||||
}
|
||||
|
|
Загрузка…
Создание таблицы
Сослаться в новой задаче