From: Aditya Kumar Date: Fri, 4 Oct 2019 22:46:42 +0000 (+0000) Subject: Invalidate assumption cache before outlining. X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=83e4df01a8973f9039582e9ced6555f519394b65;p=llvm Invalidate assumption cache before outlining. 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 --- diff --git a/include/llvm/Transforms/Utils/CodeExtractor.h b/include/llvm/Transforms/Utils/CodeExtractor.h index 8ff51723393..74584bce910 100644 --- a/include/llvm/Transforms/Utils/CodeExtractor.h +++ b/include/llvm/Transforms/Utils/CodeExtractor.h @@ -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, diff --git a/lib/Transforms/IPO/HotColdSplitting.cpp b/lib/Transforms/IPO/HotColdSplitting.cpp index 31571c4a20a..bd641da37f5 100644 --- a/lib/Transforms/IPO/HotColdSplitting.cpp +++ b/lib/Transforms/IPO/HotColdSplitting.cpp @@ -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; } diff --git a/lib/Transforms/Utils/CodeExtractor.cpp b/lib/Transforms/Utils/CodeExtractor.cpp index fcacc3a6800..1fe520b1610 100644 --- a/lib/Transforms/Utils/CodeExtractor.cpp +++ b/lib/Transforms/Utils/CodeExtractor.cpp @@ -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())) - AC->unregisterAssumption(cast(&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())) + AC->unregisterAssumption(cast(&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(AssumeVH); + if (I->getFunction() != &F) + return true; + } + return false; +} diff --git a/test/Transforms/HotColdSplit/assumption-cache-invalidation.ll b/test/Transforms/HotColdSplit/assumption-cache-invalidation.ll index 811b50783a5..fbf2061ff65 100644 --- a/test/Transforms/HotColdSplit/assumption-cache-invalidation.ll +++ b/test/Transforms/HotColdSplit/assumption-cache-invalidation.ll @@ -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