diff --git a/llvm/include/llvm/Analysis/InlineSizeEstimatorAnalysis.h b/llvm/include/llvm/Analysis/InlineSizeEstimatorAnalysis.h --- a/llvm/include/llvm/Analysis/InlineSizeEstimatorAnalysis.h +++ b/llvm/include/llvm/Analysis/InlineSizeEstimatorAnalysis.h @@ -31,5 +31,15 @@ private: std::unique_ptr Evaluator; }; + +class InlineSizeEstimatorAnalysisPrinterPass + : public PassInfoMixin { + raw_ostream &OS; + +public: + explicit InlineSizeEstimatorAnalysisPrinterPass(raw_ostream &OS) : OS(OS) {} + + PreservedAnalyses run(Function &F, FunctionAnalysisManager &AM); +}; } // namespace llvm #endif // LLVM_ANALYSIS_INLINESIZEESTIMATORANALYSIS_H \ No newline at end of file diff --git a/llvm/lib/Analysis/InlineSizeEstimatorAnalysis.cpp b/llvm/lib/Analysis/InlineSizeEstimatorAnalysis.cpp --- a/llvm/lib/Analysis/InlineSizeEstimatorAnalysis.cpp +++ b/llvm/lib/Analysis/InlineSizeEstimatorAnalysis.cpp @@ -296,4 +296,12 @@ return None; } bool InlineSizeEstimatorAnalysis::isEvaluatorRequested() { return false; } -#endif \ No newline at end of file +#endif + +PreservedAnalyses +InlineSizeEstimatorAnalysisPrinterPass::run(Function &F, + FunctionAnalysisManager &AM) { + OS << "[InlineSizeEstimatorAnalysis] size estimate for " << F.getName() + << ": " << AM.getResult(F) << "\n"; + return PreservedAnalyses::all(); +} diff --git a/llvm/lib/Passes/PassRegistry.def b/llvm/lib/Passes/PassRegistry.def --- a/llvm/lib/Passes/PassRegistry.def +++ b/llvm/lib/Passes/PassRegistry.def @@ -235,6 +235,8 @@ FUNCTION_PASS("print", DemandedBitsPrinterPass(dbgs())) FUNCTION_PASS("print", DominanceFrontierPrinterPass(dbgs())) FUNCTION_PASS("print", InlineCostAnnotationPrinterPass(dbgs())) +FUNCTION_PASS("print", + InlineSizeEstimatorAnalysisPrinterPass(dbgs())) FUNCTION_PASS("print", LoopPrinterPass(dbgs())) FUNCTION_PASS("print", MemorySSAPrinterPass(dbgs())) FUNCTION_PASS("print", PhiValuesPrinterPass(dbgs())) diff --git a/llvm/test/CMakeLists.txt b/llvm/test/CMakeLists.txt --- a/llvm/test/CMakeLists.txt +++ b/llvm/test/CMakeLists.txt @@ -16,6 +16,7 @@ LLVM_ENABLE_PLUGINS LLVM_BYE_LINK_INTO_TOOLS LLVM_HAVE_TF_AOT + LLVM_HAVE_TF_API ) configure_lit_site_cfg( diff --git a/llvm/test/Transforms/Inline/ML/Inputs/size-estimator.ll b/llvm/test/Transforms/Inline/ML/Inputs/size-estimator.ll new file mode 100644 --- /dev/null +++ b/llvm/test/Transforms/Inline/ML/Inputs/size-estimator.ll @@ -0,0 +1,28 @@ +target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128" +target triple = "x86_64-pc-linux-gnu" + +declare i32 @f1(i32) +declare i32 @f2(i32) + +define i32 @branches(i32) { + %cond = icmp slt i32 %0, 3 + br i1 %cond, label %then, label %else + +then: + %ret.1 = call i32 @f1(i32 %0) + br label %last.block + +else: + %ret.2 = call i32 @f2(i32 %0) + br label %last.block + +last.block: + %ret = phi i32 [%ret.1, %then], [%ret.2, %else] + ret i32 %ret +} + +define internal i32 @top() { + %1 = call i32 @branches(i32 2) + %2 = call i32 @f1(i32 %1) + ret i32 %2 +} \ No newline at end of file diff --git a/llvm/test/Transforms/Inline/ML/size-estimator-default.ll b/llvm/test/Transforms/Inline/ML/size-estimator-default.ll new file mode 100644 --- /dev/null +++ b/llvm/test/Transforms/Inline/ML/size-estimator-default.ll @@ -0,0 +1,4 @@ +; REQUIRES: !have_tf_api +; RUN: opt -passes='print' -S < %S/Inputs/size-estimator.ll 2>&1 | FileCheck %s + +; CHECK: [InlineSizeEstimatorAnalysis] size estimate for branches: None \ No newline at end of file diff --git a/llvm/test/Transforms/Inline/ML/size-estimator-training.ll b/llvm/test/Transforms/Inline/ML/size-estimator-training.ll new file mode 100644 --- /dev/null +++ b/llvm/test/Transforms/Inline/ML/size-estimator-training.ll @@ -0,0 +1,6 @@ +; REQUIRES: have_tf_api +; RUN: opt -passes='print' -S < %S/Inputs/size-estimator.ll 2>&1 | FileCheck %s --check-prefix=DEFAULT +; RUN: opt -passes='print' -ml-inliner-ir2native-model=%S/../../../../unittests/Analysis/Inputs/ir2native_x86_64_model -S < %S/Inputs/size-estimator.ll 2>&1 | FileCheck %s + +; DEFAULT: [InlineSizeEstimatorAnalysis] size estimate for branches: None +; CHECK: [InlineSizeEstimatorAnalysis] size estimate for branches: 28 \ No newline at end of file diff --git a/llvm/test/lit.cfg.py b/llvm/test/lit.cfg.py --- a/llvm/test/lit.cfg.py +++ b/llvm/test/lit.cfg.py @@ -222,6 +222,9 @@ if config.have_tf_aot: config.available_features.add("have_tf_aot") +if config.have_tf_api: + config.available_features.add("have_tf_api") + def have_cxx_shared_library(): readobj_exe = lit.util.which('llvm-readobj', config.llvm_tools_dir) if not readobj_exe: diff --git a/llvm/test/lit.site.cfg.py.in b/llvm/test/lit.site.cfg.py.in --- a/llvm/test/lit.site.cfg.py.in +++ b/llvm/test/lit.site.cfg.py.in @@ -49,6 +49,7 @@ config.has_plugins = @LLVM_ENABLE_PLUGINS@ config.linked_bye_extension = @LLVM_BYE_LINK_INTO_TOOLS@ config.have_tf_aot = @LLVM_HAVE_TF_AOT@ +config.have_tf_api = @LLVM_HAVE_TF_API@ # Support substitution of the tools_dir with user parameters. This is # used when we can't determine the tool dir at configuration time. diff --git a/llvm/unittests/Analysis/CMakeLists.txt b/llvm/unittests/Analysis/CMakeLists.txt --- a/llvm/unittests/Analysis/CMakeLists.txt +++ b/llvm/unittests/Analysis/CMakeLists.txt @@ -28,7 +28,6 @@ DomTreeUpdaterTest.cpp GlobalsModRefTest.cpp InlineFeaturesAnalysisTest.cpp - InlineSizeEstimatorAnalysisTest.cpp IVDescriptorsTest.cpp LazyCallGraphTest.cpp LoadsTest.cpp diff --git a/llvm/unittests/Analysis/InlineSizeEstimatorAnalysisTest.cpp b/llvm/unittests/Analysis/InlineSizeEstimatorAnalysisTest.cpp deleted file mode 100644 --- a/llvm/unittests/Analysis/InlineSizeEstimatorAnalysisTest.cpp +++ /dev/null @@ -1,101 +0,0 @@ -//===- InlineSizeEstimatorAnalysisTest.cpp - test for ir2native -----------===// -// -// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. -// See https://llvm.org/LICENSE.txt for license information. -// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception -// -//===----------------------------------------------------------------------===// - -#include "llvm/Analysis/InlineSizeEstimatorAnalysis.h" -#include "llvm/Analysis/LoopInfo.h" -#include "llvm/Analysis/TargetLibraryInfo.h" -#include "llvm/Analysis/TargetTransformInfo.h" -#include "llvm/AsmParser/Parser.h" -#include "llvm/IR/Dominators.h" -#include "llvm/IR/Instructions.h" -#include "llvm/IR/LLVMContext.h" -#include "llvm/IR/Module.h" -#include "llvm/Support/CommandLine.h" -#include "llvm/Support/Path.h" -#include "llvm/Support/SourceMgr.h" -#include "llvm/Testing/Support/SupportHelpers.h" -#include "gtest/gtest.h" - -using namespace llvm; - -extern const char *TestMainArgv0; -extern cl::opt TFIR2NativeModelPath; - -#ifdef LLVM_HAVE_TF_API -static std::string getModelPath() { - SmallString<128> InputsDir = unittest::getInputFileDirectory(TestMainArgv0); - llvm::sys::path::append(InputsDir, "ir2native_x86_64_model"); - return std::string(InputsDir); -} -#endif - -static std::unique_ptr parseIR(LLVMContext &C, const char *IR) { - SMDiagnostic Err; - std::unique_ptr Mod = parseAssemblyString(IR, Err, C); - if (!Mod) - Err.print("MLAnalysisTests", errs()); - return Mod; -} - -static FunctionAnalysisManager buildFAM() { - FunctionAnalysisManager FAM; - FAM.registerPass([&] { return DominatorTreeAnalysis(); }); - FAM.registerPass([&] { return PassInstrumentationAnalysis(); }); - FAM.registerPass([&] { return TargetIRAnalysis(); }); - FAM.registerPass([&] { return LoopAnalysis(); }); - return FAM; -} - -// Test model loading and evaluation. -TEST(InlineSizeEstimatorAnalysis, SizeIsValidTest) { - LLVMContext C; - std::unique_ptr M = parseIR(C, - R"IR( -target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128" -target triple = "x86_64-pc-linux-gnu" - -declare i32 @f1(i32) -declare i32 @f2(i32) - -define i32 @branches(i32) { - %cond = icmp slt i32 %0, 3 - br i1 %cond, label %then, label %else - -then: - %ret.1 = call i32 @f1(i32 %0) - br label %last.block - -else: - %ret.2 = call i32 @f2(i32 %0) - br label %last.block - -last.block: - %ret = phi i32 [%ret.1, %then], [%ret.2, %else] - ret i32 %ret -} - -define internal i32 @top() { - %1 = call i32 @branches(i32 2) - %2 = call i32 @f1(i32 %1) - ret i32 %2 -} -)IR"); - - FunctionAnalysisManager FAM = buildFAM(); -#ifdef LLVM_HAVE_TF_API - TFIR2NativeModelPath = getModelPath(); -#endif - - InlineSizeEstimatorAnalysis FA; - auto SizeEstimate = FA.run(*M->getFunction("branches"), FAM); -#ifdef LLVM_HAVE_TF_API - EXPECT_GT(*SizeEstimate, 0); -#else - EXPECT_FALSE(SizeEstimate.hasValue()); -#endif -}