]> granicus.if.org Git - llvm/commitdiff
[CVP] Use LVI to constant fold deopt operands
authorPhilip Reames <listmail@philipreames.com>
Tue, 22 Jan 2019 01:34:33 +0000 (01:34 +0000)
committerPhilip Reames <listmail@philipreames.com>
Tue, 22 Jan 2019 01:34:33 +0000 (01:34 +0000)
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
lib/Transforms/Scalar/CorrelatedValuePropagation.cpp
test/Transforms/CorrelatedValuePropagation/deopt.ll

index 8943c31e290d229e434b340936434b68018e2238..03df953f24e7fd292f24fbfb3d209415b37771af 100644 (file)
@@ -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<Intrinsic::experimental_guard>(m_Value(Cond))))
index a51b86d34a8f4cef03f8532aa791806d25495606..0a33ea6e195ed6d5a23f95f989454966bf6e0fec 100644 (file)
@@ -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<Use&>(ConstU);
+      Value *V = U.get();
+      if (V->getType()->isVectorTy()) continue;
+      if (isa<Constant>(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<PointerType>(V->getType());
     // Try to mark pointer typed parameters as non-null.  We skip the
index cb1f72221bc7bfc9ea7b0c11f458c2a74b0b0690..6dab3aaf2438b075cc8b61df334896a7fece1870 100644 (file)
@@ -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)]