diff --git a/llvm/include/llvm/Analysis/FunctionPropertiesAnalysis.h b/llvm/include/llvm/Analysis/FunctionPropertiesAnalysis.h --- a/llvm/include/llvm/Analysis/FunctionPropertiesAnalysis.h +++ b/llvm/include/llvm/Analysis/FunctionPropertiesAnalysis.h @@ -20,6 +20,7 @@ #include "llvm/IR/PassManager.h" namespace llvm { +class DominatorTree; class Function; class LoopInfo; @@ -31,7 +32,11 @@ public: static FunctionPropertiesInfo - getFunctionPropertiesInfo(const Function &F, FunctionAnalysisManager &FAM); + getFunctionPropertiesInfo(const Function &F, const DominatorTree &DT, + const LoopInfo &LI); + + static FunctionPropertiesInfo + getFunctionPropertiesInfo(Function &F, FunctionAnalysisManager &FAM); bool operator==(const FunctionPropertiesInfo &FPI) const { return std::memcmp(this, &FPI, sizeof(FunctionPropertiesInfo)) == 0; @@ -109,14 +114,21 @@ /// inlining. class FunctionPropertiesUpdater { public: - FunctionPropertiesUpdater(FunctionPropertiesInfo &FPI, const CallBase &CB); + FunctionPropertiesUpdater(FunctionPropertiesInfo &FPI, CallBase &CB); void finish(FunctionAnalysisManager &FAM) const; + bool finishAndTest(FunctionAnalysisManager &FAM) const { + finish(FAM); + return isUpdateValid(Caller, FPI, FAM); + } private: FunctionPropertiesInfo &FPI; - const BasicBlock &CallSiteBB; - const Function &Caller; + BasicBlock &CallSiteBB; + Function &Caller; + + static bool isUpdateValid(Function &F, const FunctionPropertiesInfo &FPI, + FunctionAnalysisManager &FAM); DenseSet Successors; }; diff --git a/llvm/lib/Analysis/FunctionPropertiesAnalysis.cpp b/llvm/lib/Analysis/FunctionPropertiesAnalysis.cpp --- a/llvm/lib/Analysis/FunctionPropertiesAnalysis.cpp +++ b/llvm/lib/Analysis/FunctionPropertiesAnalysis.cpp @@ -82,13 +82,15 @@ } FunctionPropertiesInfo FunctionPropertiesInfo::getFunctionPropertiesInfo( - const Function &F, FunctionAnalysisManager &FAM) { + Function &F, FunctionAnalysisManager &FAM) { + return getFunctionPropertiesInfo(F, FAM.getResult(F), + FAM.getResult(F)); +} + +FunctionPropertiesInfo FunctionPropertiesInfo::getFunctionPropertiesInfo( + const Function &F, const DominatorTree &DT, const LoopInfo &LI) { FunctionPropertiesInfo FPI; - // The const casts are due to the getResult API - there's no mutation of F. - const auto &LI = FAM.getResult(const_cast(F)); - const auto &DT = - FAM.getResult(const_cast(F)); for (const auto &BB : F) if (DT.isReachableFromEntry(&BB)) FPI.reIncludeBB(BB); @@ -127,7 +129,7 @@ } FunctionPropertiesUpdater::FunctionPropertiesUpdater( - FunctionPropertiesInfo &FPI, const CallBase &CB) + FunctionPropertiesInfo &FPI, CallBase &CB) : FPI(FPI), CallSiteBB(*CB.getParent()), Caller(*CallSiteBB.getParent()) { assert(isa(CB) || isa(CB)); // For BBs that are likely to change, we subtract from feature totals their @@ -247,5 +249,13 @@ const auto &LI = FAM.getResult(const_cast(Caller)); FPI.updateAggregateStats(Caller, LI); - assert(FPI == FunctionPropertiesInfo::getFunctionPropertiesInfo(Caller, FAM)); } + +bool FunctionPropertiesUpdater::isUpdateValid(Function &F, + const FunctionPropertiesInfo &FPI, + FunctionAnalysisManager &FAM) { + DominatorTree DT(F); + LoopInfo LI(DT); + auto Fresh = FunctionPropertiesInfo::getFunctionPropertiesInfo(F, DT, LI); + return FPI == Fresh; +} \ No newline at end of file diff --git a/llvm/unittests/Analysis/FunctionPropertiesAnalysisTest.cpp b/llvm/unittests/Analysis/FunctionPropertiesAnalysisTest.cpp --- a/llvm/unittests/Analysis/FunctionPropertiesAnalysisTest.cpp +++ b/llvm/unittests/Analysis/FunctionPropertiesAnalysisTest.cpp @@ -158,7 +158,7 @@ auto IR = llvm::InlineFunction(*CB, IFI); EXPECT_TRUE(IR.isSuccess()); invalidate(*F1); - FPU.finish(FAM); + EXPECT_TRUE(FPU.finishAndTest(FAM)); EXPECT_EQ(FPI, ExpectedFinal); } @@ -212,7 +212,7 @@ auto IR = llvm::InlineFunction(*CB, IFI); EXPECT_TRUE(IR.isSuccess()); invalidate(*F1); - FPU.finish(FAM); + EXPECT_TRUE(FPU.finishAndTest(FAM)); EXPECT_EQ(FPI, ExpectedFinal); } @@ -279,7 +279,7 @@ auto IR = llvm::InlineFunction(*CB, IFI); EXPECT_TRUE(IR.isSuccess()); invalidate(*F1); - FPU.finish(FAM); + EXPECT_TRUE(FPU.finishAndTest(FAM)); EXPECT_EQ(FPI, ExpectedFinal); } @@ -324,7 +324,7 @@ auto IR = llvm::InlineFunction(*CB, IFI); EXPECT_TRUE(IR.isSuccess()); invalidate(*F1); - FPU.finish(FAM); + EXPECT_TRUE(FPU.finishAndTest(FAM)); EXPECT_EQ(static_cast(FPI.BasicBlockCount), F1->size()); EXPECT_EQ(static_cast(FPI.TotalInstructionCount), F1->getInstructionCount()); @@ -377,7 +377,7 @@ auto IR = llvm::InlineFunction(*CB, IFI); EXPECT_TRUE(IR.isSuccess()); invalidate(*F1); - FPU.finish(FAM); + EXPECT_TRUE(FPU.finishAndTest(FAM)); EXPECT_EQ(static_cast(FPI.BasicBlockCount), F1->size() - 1); EXPECT_EQ(static_cast(FPI.TotalInstructionCount), F1->getInstructionCount() - 2); @@ -431,7 +431,7 @@ auto IR = llvm::InlineFunction(*CB, IFI); EXPECT_TRUE(IR.isSuccess()); invalidate(*F1); - FPU.finish(FAM); + EXPECT_TRUE(FPU.finishAndTest(FAM)); EXPECT_EQ(static_cast(FPI.BasicBlockCount), F1->size() - 1); EXPECT_EQ(static_cast(FPI.TotalInstructionCount), F1->getInstructionCount() - 2); @@ -483,7 +483,7 @@ auto IR = llvm::InlineFunction(*CB, IFI); EXPECT_TRUE(IR.isSuccess()); invalidate(*F1); - FPU.finish(FAM); + EXPECT_TRUE(FPU.finishAndTest(FAM)); EXPECT_EQ(static_cast(FPI.BasicBlockCount), F1->size() - 1); EXPECT_EQ(static_cast(FPI.TotalInstructionCount), F1->getInstructionCount() - 2); @@ -539,7 +539,7 @@ auto IR = llvm::InlineFunction(*CB, IFI); EXPECT_TRUE(IR.isSuccess()); invalidate(*F1); - FPU.finish(FAM); + EXPECT_TRUE(FPU.finishAndTest(FAM)); EXPECT_EQ(static_cast(FPI.BasicBlockCount), F1->size() - 1); EXPECT_EQ(static_cast(FPI.TotalInstructionCount), F1->getInstructionCount() - 2); @@ -610,7 +610,7 @@ auto IR = llvm::InlineFunction(*CB, IFI); EXPECT_TRUE(IR.isSuccess()); invalidate(*F1); - FPU.finish(FAM); + EXPECT_TRUE(FPU.finishAndTest(FAM)); EXPECT_EQ(FPI, ExpectedFinal); } @@ -677,7 +677,7 @@ auto IR = llvm::InlineFunction(*CB, IFI); EXPECT_TRUE(IR.isSuccess()); invalidate(*F1); - FPU.finish(FAM); + EXPECT_TRUE(FPU.finishAndTest(FAM)); EXPECT_EQ(FPI, ExpectedFinal); } @@ -737,7 +737,7 @@ auto IR = llvm::InlineFunction(*CB, IFI); EXPECT_TRUE(IR.isSuccess()); invalidate(*F1); - FPU.finish(FAM); + EXPECT_TRUE(FPU.finishAndTest(FAM)); EXPECT_EQ(FPI, ExpectedFinal); } } // end anonymous namespace