]> granicus.if.org Git - llvm/commitdiff
Invalidate assumption cache before outlining.
authorAditya Kumar <hiraditya@msn.com>
Fri, 4 Oct 2019 22:46:42 +0000 (22:46 +0000)
committerAditya Kumar <hiraditya@msn.com>
Fri, 4 Oct 2019 22:46:42 +0000 (22:46 +0000)
Subscribers: llvm-commits

Tags: #llvm

Reviewers: compnerd, vsk, sebpop, fhahn, tejohnson

Reviewed by: vsk

Differential Revision: https://reviews.llvm.org/D68478

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@373807 91177308-0d34-0410-b5e6-96231b3b80d8

include/llvm/Transforms/Utils/CodeExtractor.h
lib/Transforms/IPO/HotColdSplitting.cpp
lib/Transforms/Utils/CodeExtractor.cpp
test/Transforms/HotColdSplit/assumption-cache-invalidation.ll

index 8ff51723393266f55d7daef706a43023a96ffb01..74584bce910a72b126d1790b7d18bb34d22701ab 100644 (file)
@@ -106,6 +106,11 @@ class Value;
     /// returns false.
     Function *extractCodeRegion();
 
+    /// Verify that assumption cache isn't stale after a region is extracted.
+    /// Returns false when verifier finds errors. AssumptionCache is passed as
+    /// parameter to make this function stateless.
+    static bool verifyAssumptionCache(const Function& F, AssumptionCache *AC);
+
     /// Test whether this code extractor is eligible.
     ///
     /// Based on the blocks used when constructing the code extractor,
index 31571c4a20a87fc5a54a805bc04ad4adfefe8956..bd641da37f55232586c12c9315d2e8d7d6d9bae8 100644 (file)
@@ -628,11 +628,6 @@ bool HotColdSplitting::outlineColdRegions(Function &F, bool HasProfileSummary) {
     } while (!Region.empty());
   }
 
-  // We need to explicitly clear the assumption cache since the value tracking
-  // may now be invalid as part of the function has changed.
-  if (Changed)
-    if (AssumptionCache *AC = LookupAC(F))
-      AC->clear();
   return Changed;
 }
 
index fcacc3a68002ca38ed9a25b39ee1243c5e250b3c..1fe520b161020f8e26ee4cff69ff4daf0099c633 100644 (file)
@@ -1301,13 +1301,6 @@ void CodeExtractor::moveCodeToFunction(Function *newFunction) {
 
     // Insert this basic block into the new function
     newBlocks.push_back(Block);
-
-    // Remove @llvm.assume calls that were moved to the new function from the
-    // old function's assumption cache.
-    if (AC)
-      for (auto &I : *Block)
-        if (match(&I, m_Intrinsic<Intrinsic::assume>()))
-          AC->unregisterAssumption(cast<CallInst>(&I));
   }
 }
 
@@ -1378,6 +1371,15 @@ Function *CodeExtractor::extractCodeRegion() {
     }
   }
 
+  if (AC) {
+    // Remove @llvm.assume calls that were moved to the new function from the
+    // old function's assumption cache.
+    for (BasicBlock *Block : Blocks)
+      for (auto &I : *Block)
+        if (match(&I, m_Intrinsic<Intrinsic::assume>()))
+          AC->unregisterAssumption(cast<CallInst>(&I));
+  }
+
   // If we have any return instructions in the region, split those blocks so
   // that the return is not in the region.
   splitReturnBlocks();
@@ -1568,5 +1570,17 @@ Function *CodeExtractor::extractCodeRegion() {
   });
   LLVM_DEBUG(if (verifyFunction(*oldFunction))
              report_fatal_error("verification of oldFunction failed!"));
+  LLVM_DEBUG(if (AC && verifyAssumptionCache(*oldFunction, AC))
+             report_fatal_error("Stale Asumption cache for old Function!"));
   return newFunction;
 }
+
+bool CodeExtractor::verifyAssumptionCache(const Function& F,
+                                          AssumptionCache *AC) {
+  for (auto AssumeVH : AC->assumptions()) {
+    CallInst *I = cast<CallInst>(AssumeVH);
+    if (I->getFunction() != &F)
+      return true;
+  }
+  return false;
+}
index 811b50783a5c5b8271059ea42da7675549acf536..fbf2061ff650ad7f0e3147d758c597bc6127cc14 100644 (file)
@@ -1,3 +1,5 @@
+; REQUIRES: asserts
+; RUN: opt -S -instsimplify -hotcoldsplit -debug < %s 2>&1 | FileCheck %s
 ; RUN: opt -instcombine -hotcoldsplit -instsimplify %s -o /dev/null
 
 target datalayout = "e-m:e-i8:8:32-i16:16:32-i64:64-i128:128-n32:64-S128"
@@ -6,6 +8,16 @@ target triple = "aarch64"
 %a = type { i64, i64 }
 %b = type { i64 }
 
+; CHECK: @f
+; CHECK-LABEL: codeRepl:
+; CHECK-NOT: @llvm.assume
+; CHECK: }
+; CHECK: declare {{.*}}@llvm.assume
+; CHECK: define {{.*}}@f.cold.1(i64 %0)
+; CHECK-LABEL: newFuncRoot:
+; CHECK: %1 = icmp eq i64 %0, 0
+; CHECK: call void @llvm.assume(i1 %1)
+
 define void @f() {
 entry:
   %0 = getelementptr inbounds %a, %a* null, i64 0, i32 1