forked from OSchip/llvm-project
[LICM] Allow freeze to hoist/sink out of a loop
Summary: This patch allows LICM to hoist/sink freeze instructions out of a loop. Reviewers: reames, fhahn, efriedma Reviewed By: reames Subscribers: jfb, lebedev.ri, hiraditya, asbirlea, llvm-commits Tags: #llvm Differential Revision: https://reviews.llvm.org/D75400
This commit is contained in:
parent
af57b139a0
commit
9f1f244d3c
|
@ -988,12 +988,12 @@ namespace {
|
||||||
bool isHoistableAndSinkableInst(Instruction &I) {
|
bool isHoistableAndSinkableInst(Instruction &I) {
|
||||||
// Only these instructions are hoistable/sinkable.
|
// Only these instructions are hoistable/sinkable.
|
||||||
return (isa<LoadInst>(I) || isa<StoreInst>(I) || isa<CallInst>(I) ||
|
return (isa<LoadInst>(I) || isa<StoreInst>(I) || isa<CallInst>(I) ||
|
||||||
isa<FenceInst>(I) || isa<CastInst>(I) ||
|
isa<FenceInst>(I) || isa<CastInst>(I) || isa<UnaryOperator>(I) ||
|
||||||
isa<UnaryOperator>(I) || isa<BinaryOperator>(I) ||
|
isa<BinaryOperator>(I) || isa<SelectInst>(I) ||
|
||||||
isa<SelectInst>(I) || isa<GetElementPtrInst>(I) || isa<CmpInst>(I) ||
|
isa<GetElementPtrInst>(I) || isa<CmpInst>(I) ||
|
||||||
isa<InsertElementInst>(I) || isa<ExtractElementInst>(I) ||
|
isa<InsertElementInst>(I) || isa<ExtractElementInst>(I) ||
|
||||||
isa<ShuffleVectorInst>(I) || isa<ExtractValueInst>(I) ||
|
isa<ShuffleVectorInst>(I) || isa<ExtractValueInst>(I) ||
|
||||||
isa<InsertValueInst>(I));
|
isa<InsertValueInst>(I) || isa<FreezeInst>(I));
|
||||||
}
|
}
|
||||||
/// Return true if all of the alias sets within this AST are known not to
|
/// Return true if all of the alias sets within this AST are known not to
|
||||||
/// contain a Mod, or if MSSA knows thare are no MemoryDefs in the loop.
|
/// contain a Mod, or if MSSA knows thare are no MemoryDefs in the loop.
|
||||||
|
|
|
@ -0,0 +1,43 @@
|
||||||
|
; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
|
||||||
|
; RUN: opt -licm -S < %s | FileCheck %s
|
||||||
|
|
||||||
|
define void @hoist(i1 %a) {
|
||||||
|
; CHECK-LABEL: @hoist(
|
||||||
|
; CHECK-NEXT: entry:
|
||||||
|
; CHECK-NEXT: [[B:%.*]] = freeze i1 [[A:%.*]]
|
||||||
|
; CHECK-NEXT: br label [[LOOP:%.*]]
|
||||||
|
; CHECK: loop:
|
||||||
|
; CHECK-NEXT: call void @use(i1 [[B]])
|
||||||
|
; CHECK-NEXT: br label [[LOOP]]
|
||||||
|
;
|
||||||
|
entry:
|
||||||
|
br label %loop
|
||||||
|
loop:
|
||||||
|
%b = freeze i1 %a
|
||||||
|
call void @use(i1 %b)
|
||||||
|
br label %loop
|
||||||
|
}
|
||||||
|
|
||||||
|
define i1 @sink(i1 %a) {
|
||||||
|
; CHECK-LABEL: @sink(
|
||||||
|
; CHECK-NEXT: entry:
|
||||||
|
; CHECK-NEXT: br label [[LOOP:%.*]]
|
||||||
|
; CHECK: loop:
|
||||||
|
; CHECK-NEXT: [[C:%.*]] = call i1 @cond()
|
||||||
|
; CHECK-NEXT: br i1 [[C]], label [[LOOP]], label [[EXIT:%.*]]
|
||||||
|
; CHECK: exit:
|
||||||
|
; CHECK-NEXT: [[FR_LE:%.*]] = freeze i1 [[A:%.*]]
|
||||||
|
; CHECK-NEXT: ret i1 [[FR_LE]]
|
||||||
|
;
|
||||||
|
entry:
|
||||||
|
br label %loop
|
||||||
|
loop:
|
||||||
|
%fr = freeze i1 %a
|
||||||
|
%c = call i1 @cond()
|
||||||
|
br i1 %c, label %loop, label %exit
|
||||||
|
exit:
|
||||||
|
ret i1 %fr
|
||||||
|
}
|
||||||
|
|
||||||
|
declare i1 @cond()
|
||||||
|
declare void @use(i1)
|
Loading…
Reference in New Issue