
LICM currently requests optimized use MSSA form. This is wasteful, because LICM doesn't actually care about most uses, only those of invariant pointers in loops. Everything else doesn't need to be optimized. LICM already uses the clobber walker in most places. This patch adjusts one place that was using getDefiningAccess() to use it as well, so we no longer have a dependence on pre-optimized uses. This change is not NFC in that the fallback on the defining access when there are too many clobber calls may now fall back to an unoptimized use. In practice, I've not seen any problems with this though. If desired, we could also increase licm-mssa-optimization-cap to a higher value (increasing this from 100 to 200 has no impact on average compile-time -- but also doesn't appear to have any impact on LICM quality either). This makes for a 0.9% geomean compile-time improvement on CTMark. Differential Revision: https://reviews.llvm.org/D147437
97 lines
3.4 KiB
LLVM
97 lines
3.4 KiB
LLVM
; RUN: opt -passes='loop-mssa(licm),print<memoryssa>' -disable-output < %s 2>&1 | FileCheck %s
|
|
; REQUIRES: asserts
|
|
|
|
@arr = global [12 x i8] [i8 1, i8 2, i8 3, i8 4, i8 5, i8 6, i8 7, i8 8, i8 9, i8 10, i8 11, i8 12], align 1
|
|
|
|
; CHECK-LABEL: @func()
|
|
define void @func() {
|
|
entry:
|
|
%res.addr.i = alloca i8, align 1
|
|
%sum = alloca i8, align 1
|
|
%n = alloca i8, align 1
|
|
%i = alloca i8, align 1
|
|
%cleanup.dest.slot = alloca i32, align 1
|
|
call void @llvm.lifetime.start.p0(i64 1, ptr %sum) #3
|
|
store i8 0, ptr %sum, align 1
|
|
call void @llvm.lifetime.start.p0(i64 1, ptr %n) #3
|
|
%call = call i8 @idi(i8 10)
|
|
store i8 %call, ptr %n, align 1
|
|
call void @llvm.lifetime.start.p0(i64 1, ptr %i) #3
|
|
store i8 0, ptr %i, align 1
|
|
br label %for.cond
|
|
|
|
for.cond: ; preds = %for.inc, %entry
|
|
%0 = load i8, ptr %i, align 1
|
|
%1 = load i8, ptr %n, align 1
|
|
%cmp = icmp slt i8 %0, %1
|
|
br i1 %cmp, label %for.body, label %for.cond.cleanup
|
|
|
|
for.cond.cleanup: ; preds = %for.cond
|
|
store i32 2, ptr %cleanup.dest.slot, align 1
|
|
br label %final.cleanup
|
|
|
|
for.body: ; preds = %for.cond
|
|
%2 = load i8, ptr %i, align 1
|
|
%idxprom = sext i8 %2 to i32
|
|
%arrayidx = getelementptr inbounds [12 x i8], ptr @arr, i32 0, i32 %idxprom
|
|
%3 = load i8, ptr %arrayidx, align 1
|
|
%cmp1 = icmp eq i8 %3, 3
|
|
br i1 %cmp1, label %if.then, label %if.end
|
|
|
|
if.then: ; preds = %for.body
|
|
store i32 2, ptr %cleanup.dest.slot, align 1
|
|
br label %final.cleanup
|
|
|
|
if.end: ; preds = %for.body
|
|
%4 = load i8, ptr %i, align 1
|
|
%idxprom2 = sext i8 %4 to i32
|
|
%arrayidx3 = getelementptr inbounds [12 x i8], ptr @arr, i32 0, i32 %idxprom2
|
|
%5 = load i8, ptr %arrayidx3, align 1
|
|
%6 = load i8, ptr %sum, align 1
|
|
%add = add nsw i8 %6, %5
|
|
store i8 %add, ptr %sum, align 1
|
|
br label %for.inc
|
|
|
|
for.inc: ; preds = %if.end
|
|
%7 = load i8, ptr %i, align 1
|
|
%inc = add nsw i8 %7, 1
|
|
store i8 %inc, ptr %i, align 1
|
|
br label %for.cond
|
|
|
|
; CHECK: final.cleanup:
|
|
; CHECK-NEXT: ; [[NO20:.*]] = MemoryPhi({if.then,[[NO9:.*]]},{for.cond.cleanup,[[NO8:.*]]})
|
|
; CHECK-NEXT: ; [[NO12:.*]] = MemoryDef([[NO20]])
|
|
; CHECK-NEXT: call void @llvm.lifetime.end.p0(i64 1, ptr %i)
|
|
final.cleanup: ; preds = %if.then, %for.cond.cleanup
|
|
call void @llvm.lifetime.end.p0(i64 1, ptr %i) #3
|
|
br label %for.end
|
|
|
|
; CHECK: for.end:
|
|
; CHECK-NEXT: ; MemoryUse([[NO20]])
|
|
; CHECK-NEXT: %3 = load i8, ptr %sum, align 1
|
|
for.end: ; preds = %final.cleanup
|
|
%8 = load i8, ptr %sum, align 1
|
|
call void @llvm.lifetime.start.p0(i64 1, ptr %res.addr.i)
|
|
store i8 %8, ptr %res.addr.i, align 1
|
|
%9 = load i8, ptr %res.addr.i, align 1
|
|
call void @foo(i8 %9) #3
|
|
call void @llvm.lifetime.end.p0(i64 1, ptr %res.addr.i)
|
|
call void @llvm.lifetime.end.p0(i64 1, ptr %n) #3
|
|
call void @llvm.lifetime.end.p0(i64 1, ptr %sum) #3
|
|
ret void
|
|
}
|
|
|
|
; Function Attrs: argmemonly nofree nosync nounwind willreturn
|
|
declare void @llvm.lifetime.start.p0(i64 immarg, ptr nocapture) #1
|
|
|
|
declare i8 @idi(i8)
|
|
|
|
; Function Attrs: argmemonly nofree nosync nounwind willreturn
|
|
declare void @llvm.lifetime.end.p0(i64 immarg, ptr nocapture) #1
|
|
|
|
; Function Attrs: nounwind
|
|
declare void @foo(i8)
|
|
|
|
attributes #1 = { argmemonly nofree nosync nounwind willreturn }
|
|
attributes #3 = { nounwind }
|