From 27ae9060d2d08a45465001eadef4a131b2928d04 Mon Sep 17 00:00:00 2001 From: Philip Reames Date: Tue, 22 Jan 2019 01:34:33 +0000 Subject: [PATCH] [CVP] Use LVI to constant fold deopt operands Deopt operands are generally intended to record information about a site in code with minimal perturbation of the surrounding code. Idiomatically, they also tend to appear down rare paths. Putting these together, we have an obvious case for extending CVP w/deopt operand constant folding. Arguably, we should be doing this for all operands on all instructions, but that's definitely a much larger and risky change. Differential Revision: https://reviews.llvm.org/D55678 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@351774 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/Analysis/LazyValueInfo.cpp | 4 +++- .../Scalar/CorrelatedValuePropagation.cpp | 24 +++++++++++++++++++ .../CorrelatedValuePropagation/deopt.ll | 16 ++++++------- 3 files changed, 35 insertions(+), 9 deletions(-) diff --git a/lib/Analysis/LazyValueInfo.cpp b/lib/Analysis/LazyValueInfo.cpp index 8943c31e290..03df953f24e 100644 --- a/lib/Analysis/LazyValueInfo.cpp +++ b/lib/Analysis/LazyValueInfo.cpp @@ -823,7 +823,9 @@ void LazyValueInfoImpl::intersectAssumeOrGuardBlockValueConstantRange( if (!GuardDecl || GuardDecl->use_empty()) return; - for (Instruction &I : make_range(BBI->getIterator().getReverse(), + if (BBI->getIterator() == BBI->getParent()->begin()) + return; + for (Instruction &I : make_range(std::next(BBI->getIterator().getReverse()), BBI->getParent()->rend())) { Value *Cond = nullptr; if (match(&I, m_Intrinsic(m_Value(Cond)))) diff --git a/lib/Transforms/Scalar/CorrelatedValuePropagation.cpp b/lib/Transforms/Scalar/CorrelatedValuePropagation.cpp index a51b86d34a8..0a33ea6e195 100644 --- a/lib/Transforms/Scalar/CorrelatedValuePropagation.cpp +++ b/lib/Transforms/Scalar/CorrelatedValuePropagation.cpp @@ -462,6 +462,30 @@ static bool processCallSite(CallSite CS, LazyValueInfo *LVI) { } } + // Deopt bundle operands are intended to capture state with minimal + // perturbance of the code otherwise. If we can find a constant value for + // any such operand and remove a use of the original value, that's + // desireable since it may allow further optimization of that value (e.g. via + // single use rules in instcombine). Since deopt uses tend to, + // idiomatically, appear along rare conditional paths, it's reasonable likely + // we may have a conditional fact with which LVI can fold. + if (auto DeoptBundle = CS.getOperandBundle(LLVMContext::OB_deopt)) { + bool Progress = false; + for (const Use &ConstU : DeoptBundle->Inputs) { + Use &U = const_cast(ConstU); + Value *V = U.get(); + if (V->getType()->isVectorTy()) continue; + if (isa(V)) continue; + + Constant *C = LVI->getConstant(V, CS.getParent(), CS.getInstruction()); + if (!C) continue; + U.set(C); + Progress = true; + } + if (Progress) + return true; + } + for (Value *V : CS.args()) { PointerType *Type = dyn_cast(V->getType()); // Try to mark pointer typed parameters as non-null. We skip the diff --git a/test/Transforms/CorrelatedValuePropagation/deopt.ll b/test/Transforms/CorrelatedValuePropagation/deopt.ll index cb1f72221bc..6dab3aaf243 100644 --- a/test/Transforms/CorrelatedValuePropagation/deopt.ll +++ b/test/Transforms/CorrelatedValuePropagation/deopt.ll @@ -11,7 +11,7 @@ define void @test1(i1 %c, i1 %c2) { ; CHECK-NEXT: [[CMP:%.*]] = icmp sgt i64 [[SEL2]], 0 ; CHECK-NEXT: br i1 [[CMP]], label [[TAKEN:%.*]], label [[UNTAKEN:%.*]] ; CHECK: taken: -; CHECK-NEXT: call void @use() [ "deopt"(i64 [[SEL2]]) ] +; CHECK-NEXT: call void @use() [ "deopt"(i64 1) ] ; CHECK-NEXT: ret void ; CHECK: untaken: ; CHECK-NEXT: ret void @@ -37,7 +37,7 @@ define void @test1_assume(i1 %c, i1 %c2) { ; CHECK-NEXT: [[SEL2:%.*]] = select i1 [[C2:%.*]], i64 [[SEL]], i64 0 ; CHECK-NEXT: [[CMP:%.*]] = icmp sgt i64 [[SEL2]], 0 ; CHECK-NEXT: call void @llvm.assume(i1 [[CMP]]) -; CHECK-NEXT: call void @use() [ "deopt"(i64 [[SEL2]]) ] +; CHECK-NEXT: call void @use() [ "deopt"(i64 1) ] ; CHECK-NEXT: ret void ; %sel = select i1 %c, i64 -1, i64 1 @@ -55,7 +55,7 @@ define void @test1_guard(i1 %c, i1 %c2) { ; CHECK-NEXT: [[SEL2:%.*]] = select i1 [[C2:%.*]], i64 [[SEL]], i64 0 ; CHECK-NEXT: [[CMP:%.*]] = icmp sgt i64 [[SEL2]], 0 ; CHECK-NEXT: call void (i1, ...) @llvm.experimental.guard(i1 [[CMP]]) [ "deopt"(i64 [[SEL2]]) ] -; CHECK-NEXT: call void @use() [ "deopt"(i64 [[SEL2]]) ] +; CHECK-NEXT: call void @use() [ "deopt"(i64 1) ] ; CHECK-NEXT: ret void ; %sel = select i1 %c, i64 -1, i64 1 @@ -76,7 +76,7 @@ define void @test2(i1 %c, i1 %c2) { ; CHECK-NEXT: [[CMP:%.*]] = icmp sgt i64 [[SEL2]], 0 ; CHECK-NEXT: br i1 [[CMP]], label [[TAKEN:%.*]], label [[UNTAKEN:%.*]] ; CHECK: taken: -; CHECK-NEXT: call void @use() [ "deopt"(i64 [[SEL2]]) ] +; CHECK-NEXT: call void @use() [ "deopt"(i64 1) ] ; CHECK-NEXT: ret void ; CHECK: untaken: ; CHECK-NEXT: ret void @@ -98,7 +98,7 @@ define void @test3(i1 %c, i1 %c2) { ; CHECK-NEXT: [[CMP:%.*]] = icmp sgt i64 [[SEL2]], 1 ; CHECK-NEXT: br i1 [[CMP]], label [[TAKEN:%.*]], label [[UNTAKEN:%.*]] ; CHECK: taken: -; CHECK-NEXT: call void @use() [ "deopt"(i64 [[SEL2]]) ] +; CHECK-NEXT: call void @use() [ "deopt"(i64 2) ] ; CHECK-NEXT: ret void ; CHECK: untaken: ; CHECK-NEXT: ret void @@ -120,10 +120,10 @@ define void @test4(i1 %c, i1 %c2) { ; CHECK-NEXT: [[SEL2:%.*]] = select i1 [[C2:%.*]], i64 0, i64 1 ; CHECK-NEXT: [[ADD1:%.*]] = add i64 0, [[SEL]] ; CHECK-NEXT: [[ADD2:%.*]] = add i64 [[ADD1]], [[SEL2]] -; CHECK-NEXT: [[CMP:%.*]] = icmp sgt i64 [[ADD2]], 0 +; CHECK-NEXT: [[CMP:%.*]] = icmp sgt i64 [[ADD2]], 1 ; CHECK-NEXT: br i1 [[CMP]], label [[TAKEN:%.*]], label [[UNTAKEN:%.*]] ; CHECK: taken: -; CHECK-NEXT: call void @use() [ "deopt"(i64 [[ADD2]]) ] +; CHECK-NEXT: call void @use() [ "deopt"(i64 2) ] ; CHECK-NEXT: ret void ; CHECK: untaken: ; CHECK-NEXT: ret void @@ -132,7 +132,7 @@ define void @test4(i1 %c, i1 %c2) { %sel2 = select i1 %c2, i64 0, i64 1 %add1 = add i64 0, %sel %add2 = add i64 %add1, %sel2 - %cmp = icmp sgt i64 %add2, 0 + %cmp = icmp sgt i64 %add2, 1 br i1 %cmp, label %taken, label %untaken taken: call void @use() ["deopt" (i64 %add2)] -- 2.50.1