fix incorrect starting value for optimized allocations in a loop
Этот коммит содержится в:
родитель
acdaaa17d8
коммит
93961f9d41
4 изменённых файлов: 36 добавлений и 2 удалений
|
@ -69,8 +69,13 @@ func OptimizeAllocs(mod llvm.Module) {
|
||||||
sizeInWords := (size + uint64(alignment) - 1) / uint64(alignment)
|
sizeInWords := (size + uint64(alignment) - 1) / uint64(alignment)
|
||||||
allocaType := llvm.ArrayType(mod.Context().IntType(alignment*8), int(sizeInWords))
|
allocaType := llvm.ArrayType(mod.Context().IntType(alignment*8), int(sizeInWords))
|
||||||
alloca := builder.CreateAlloca(allocaType, "stackalloc.alloca")
|
alloca := builder.CreateAlloca(allocaType, "stackalloc.alloca")
|
||||||
|
|
||||||
|
// Zero the allocation inside the block where the value was originally allocated.
|
||||||
zero := llvm.ConstNull(alloca.Type().ElementType())
|
zero := llvm.ConstNull(alloca.Type().ElementType())
|
||||||
|
builder.SetInsertPointBefore(bitcast)
|
||||||
builder.CreateStore(zero, alloca)
|
builder.CreateStore(zero, alloca)
|
||||||
|
|
||||||
|
// Replace heap alloc bitcast with stack alloc bitcast.
|
||||||
stackalloc := builder.CreateBitCast(alloca, bitcast.Type(), "stackalloc")
|
stackalloc := builder.CreateBitCast(alloca, bitcast.Type(), "stackalloc")
|
||||||
bitcast.ReplaceAllUsesWith(stackalloc)
|
bitcast.ReplaceAllUsesWith(stackalloc)
|
||||||
if heapalloc != bitcast {
|
if heapalloc != bitcast {
|
||||||
|
|
14
transform/testdata/allocs.ll
предоставленный
14
transform/testdata/allocs.ll
предоставленный
|
@ -54,6 +54,20 @@ define i32* @testEscapingReturn() {
|
||||||
ret i32* %2
|
ret i32* %2
|
||||||
}
|
}
|
||||||
|
|
||||||
|
; Do a non-escaping allocation in a loop.
|
||||||
|
define void @testNonEscapingLoop() {
|
||||||
|
entry:
|
||||||
|
br label %loop
|
||||||
|
loop:
|
||||||
|
%0 = call i8* @runtime.alloc(i32 4)
|
||||||
|
%1 = bitcast i8* %0 to i32*
|
||||||
|
%2 = call i32* @noescapeIntPtr(i32* %1)
|
||||||
|
%3 = icmp eq i32* null, %2
|
||||||
|
br i1 %3, label %loop, label %end
|
||||||
|
end:
|
||||||
|
ret void
|
||||||
|
}
|
||||||
|
|
||||||
declare i32* @escapeIntPtr(i32*)
|
declare i32* @escapeIntPtr(i32*)
|
||||||
|
|
||||||
declare i32* @noescapeIntPtr(i32* nocapture)
|
declare i32* @noescapeIntPtr(i32* nocapture)
|
||||||
|
|
14
transform/testdata/allocs.out.ll
предоставленный
14
transform/testdata/allocs.out.ll
предоставленный
|
@ -50,6 +50,20 @@ define i32* @testEscapingReturn() {
|
||||||
ret i32* %2
|
ret i32* %2
|
||||||
}
|
}
|
||||||
|
|
||||||
|
define void @testNonEscapingLoop() {
|
||||||
|
entry:
|
||||||
|
%stackalloc.alloca = alloca [1 x i32]
|
||||||
|
br label %loop
|
||||||
|
loop:
|
||||||
|
store [1 x i32] zeroinitializer, [1 x i32]* %stackalloc.alloca
|
||||||
|
%stackalloc = bitcast [1 x i32]* %stackalloc.alloca to i32*
|
||||||
|
%0 = call i32* @noescapeIntPtr(i32* %stackalloc)
|
||||||
|
%1 = icmp eq i32* null, %0
|
||||||
|
br i1 %1, label %loop, label %end
|
||||||
|
end:
|
||||||
|
ret void
|
||||||
|
}
|
||||||
|
|
||||||
declare i32* @escapeIntPtr(i32*)
|
declare i32* @escapeIntPtr(i32*)
|
||||||
|
|
||||||
declare i32* @noescapeIntPtr(i32* nocapture)
|
declare i32* @noescapeIntPtr(i32* nocapture)
|
||||||
|
|
|
@ -70,8 +70,9 @@ func fuzzyEqualIR(s1, s2 string) bool {
|
||||||
func filterIrrelevantIRLines(lines []string) []string {
|
func filterIrrelevantIRLines(lines []string) []string {
|
||||||
var out []string
|
var out []string
|
||||||
for _, line := range lines {
|
for _, line := range lines {
|
||||||
line = strings.TrimSpace(line) // drop '\r' on Windows
|
line = strings.Split(line, ";")[0] // strip out comments/info
|
||||||
if line == "" || line[0] == ';' {
|
line = strings.TrimRight(line, "\r ") // drop '\r' on Windows and remove trailing spaces from comments
|
||||||
|
if line == "" {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
if strings.HasPrefix(line, "source_filename = ") {
|
if strings.HasPrefix(line, "source_filename = ") {
|
||||||
|
|
Загрузка…
Создание таблицы
Сослаться в новой задаче