[llvm] 37e06e8 - [InlineCost] InlineCostAnnotationWriterPass introduced

Kirill Naumov via llvm-commits llvm-commits at lists.llvm.org
Wed Jun 17 06:41:05 PDT 2020


Author: Kirill Naumov
Date: 2020-06-17T13:40:17Z
New Revision: 37e06e8f5c6ee39a1d7cbaf7d5f5a3ebfa1b4e15

URL: https://github.com/llvm/llvm-project/commit/37e06e8f5c6ee39a1d7cbaf7d5f5a3ebfa1b4e15
DIFF: https://github.com/llvm/llvm-project/commit/37e06e8f5c6ee39a1d7cbaf7d5f5a3ebfa1b4e15.diff

LOG: [InlineCost] InlineCostAnnotationWriterPass introduced

This class allows to see the inliner's decisions for better
optimization verifications and tests. To use, use flag
"-passes="print<inline-cost>"".

Reviewers: apilipenko, mtrofin, davidxl, fedor.sergeev

Reviewed By: mtrofin

Differential revision: https://reviews.llvm.org/D81743

Added: 
    llvm/test/Transforms/Inline/inline-cost-annotation-pass.ll

Modified: 
    llvm/include/llvm/Analysis/InlineCost.h
    llvm/lib/Analysis/InlineCost.cpp
    llvm/lib/Passes/PassRegistry.def
    llvm/test/Transforms/Inline/debuginline-cost-delta.ll

Removed: 
    llvm/test/Transforms/Inline/print-instructions-deltas-unfinished.ll


################################################################################
diff  --git a/llvm/include/llvm/Analysis/InlineCost.h b/llvm/include/llvm/Analysis/InlineCost.h
index a1f49d45789c..c697e01d4600 100644
--- a/llvm/include/llvm/Analysis/InlineCost.h
+++ b/llvm/include/llvm/Analysis/InlineCost.h
@@ -269,6 +269,18 @@ Optional<int> getInliningCostEstimate(
 
 /// Minimal filter to detect invalid constructs for inlining.
 InlineResult isInlineViable(Function &Callee);
+
+// This pass is used to annotate instructions during the inline process for
+// debugging and analysis. The main purpose of the pass is to see and test
+// inliner's decisions when creating new optimizations to InlineCost.
+struct InlineCostAnnotationPrinterPass
+    : PassInfoMixin<InlineCostAnnotationPrinterPass> {
+  raw_ostream &OS;
+
+public:
+  explicit InlineCostAnnotationPrinterPass(raw_ostream &OS) : OS(OS) {}
+  PreservedAnalyses run(Function &F, FunctionAnalysisManager &FAM);
+};
 } // namespace llvm
 
 #endif

diff  --git a/llvm/lib/Analysis/InlineCost.cpp b/llvm/lib/Analysis/InlineCost.cpp
index ba327ca6ce2d..fd4e7c765e51 100644
--- a/llvm/lib/Analysis/InlineCost.cpp
+++ b/llvm/lib/Analysis/InlineCost.cpp
@@ -2509,3 +2509,40 @@ InlineParams llvm::getInlineParams(unsigned OptLevel, unsigned SizeOptLevel) {
     Params.LocallyHotCallSiteThreshold = LocallyHotCallSiteThreshold;
   return Params;
 }
+
+PreservedAnalyses
+InlineCostAnnotationPrinterPass::run(Function &F,
+                                     FunctionAnalysisManager &FAM) {
+  PrintInstructionComments = true;
+  std::function<AssumptionCache &(Function &)> GetAssumptionCache = [&](
+      Function &F) -> AssumptionCache & {
+    return FAM.getResult<AssumptionAnalysis>(F);
+  };
+  Module *M = F.getParent();
+  ProfileSummaryInfo PSI(*M);
+  DataLayout DL(M);
+  TargetTransformInfo TTI(DL);
+  // FIXME: Redesign the usage of InlineParams to expand the scope of this pass.
+  // In the current implementation, the type of InlineParams doesn't matter as
+  // the pass serves only for verification of inliner's decisions.
+  // We can add a flag which determines InlineParams for this run. Right now,
+  // the default InlineParams are used.
+  const InlineParams Params = llvm::getInlineParams();
+    for (BasicBlock &BB : F) {
+    for (Instruction &I : BB) {
+      if (CallInst *CI = dyn_cast<CallInst>(&I)) {
+        Function *CalledFunction = CI->getCalledFunction();
+        if (!CalledFunction || CalledFunction->isDeclaration())
+          continue;
+        OptimizationRemarkEmitter ORE(CalledFunction);
+        InlineCostCallAnalyzer ICCA(*CalledFunction, *CI, Params, TTI,
+                                    GetAssumptionCache, nullptr, &PSI, &ORE);
+        ICCA.analyze();
+        OS << "      Analyzing call of " << CalledFunction->getName()
+           << "... (caller:" << CI->getCaller()->getName() << ")\n";
+        ICCA.dump();
+      }
+    }
+  }
+  return PreservedAnalyses::all();
+}
\ No newline at end of file

diff  --git a/llvm/lib/Passes/PassRegistry.def b/llvm/lib/Passes/PassRegistry.def
index dc037ff1d3ec..06fcdcdcec77 100644
--- a/llvm/lib/Passes/PassRegistry.def
+++ b/llvm/lib/Passes/PassRegistry.def
@@ -233,6 +233,7 @@ FUNCTION_PASS("print<domtree>", DominatorTreePrinterPass(dbgs()))
 FUNCTION_PASS("print<postdomtree>", PostDominatorTreePrinterPass(dbgs()))
 FUNCTION_PASS("print<demanded-bits>", DemandedBitsPrinterPass(dbgs()))
 FUNCTION_PASS("print<domfrontier>", DominanceFrontierPrinterPass(dbgs()))
+FUNCTION_PASS("print<inline-cost>", InlineCostAnnotationPrinterPass(dbgs()))
 FUNCTION_PASS("print<loops>", LoopPrinterPass(dbgs()))
 FUNCTION_PASS("print<memoryssa>", MemorySSAPrinterPass(dbgs()))
 FUNCTION_PASS("print<phi-values>", PhiValuesPrinterPass(dbgs()))

diff  --git a/llvm/test/Transforms/Inline/debuginline-cost-delta.ll b/llvm/test/Transforms/Inline/debuginline-cost-delta.ll
index 2ef604d05bc3..2e6a8f452079 100644
--- a/llvm/test/Transforms/Inline/debuginline-cost-delta.ll
+++ b/llvm/test/Transforms/Inline/debuginline-cost-delta.ll
@@ -1,32 +1,16 @@
-; Require asserts for -debug-only
-; REQUIRES: asserts
-
-; RUN: opt < %s -inline -debug-only=inline-cost -disable-output -print-instruction-comments 2>&1 | FileCheck %s
+; RUN: opt < %s -passes="print<inline-cost>" 2>&1 | FileCheck %s
 
 ; CHECK:       Analyzing call of callee1... (caller:foo)
-; CHECK: define i32 @callee1(i32 %x) {
-; CHECK: ; cost before = {{.*}}, cost after = {{.*}}, threshold before = {{.*}}, threshold after = {{.*}}, cost delta = 5
-; CHECK:   %x1 = add i32 %x, 1
-; CHECK: ; cost before = {{.*}}, cost after = {{.*}}, threshold before = {{.*}}, threshold after = {{.*}}, cost delta = 5
-; CHECK:   %x2 = add i32 %x1, 1
-; CHECK: ; cost before = {{.*}}, cost after = {{.*}}, threshold before = {{.*}}, threshold after = {{.*}}, cost delta = 5
-; CHECK:   %x3 = add i32 %x2, 1
-; CHECK: ; cost before = {{.*}}, cost after = {{.*}}, threshold before = {{.*}}, threshold after = {{.*}}, cost delta = 0
-; CHECK:   ret i32 %x3
-; CHECK: }
-; CHECK:      NumConstantArgs: 0
-; CHECK:      NumConstantOffsetPtrArgs: 0
-; CHECK:      NumAllocaArgs: 0
-; CHECK:      NumConstantPtrCmps: 0
-; CHECK:      NumConstantPtrDiffs: 0
-; CHECK:      NumInstructionsSimplified: 1
-; CHECK:      NumInstructions: 4
-; CHECK:      SROACostSavings: 0
-; CHECK:      SROACostSavingsLost: 0
-; CHECK:      LoadEliminationCost: 0
-; CHECK:      ContainsNoDuplicateCall: 0
-; CHECK:      Cost: {{.*}}
-; CHECK:      Threshold: {{.*}}
+; CHECK-NEXT: define i32 @callee1(i32 %x) {
+; CHECK-NEXT: cost before = {{.*}}, cost after = {{.*}}, threshold before = {{.*}}, threshold after = {{.*}}, cost delta = {{.*}}
+; CHECK-NEXT:   %x1 = add i32 %x, 1
+; CHECK-NEXT: cost before = {{.*}}, cost after = {{.*}}, threshold before = {{.*}}, threshold after = {{.*}}, cost delta = {{.*}}
+; CHECK-NEXT:   %x2 = add i32 %x1, 1
+; CHECK-NEXT: cost before = {{.*}}, cost after = {{.*}}, threshold before = {{.*}}, threshold after = {{.*}}, cost delta = {{.*}}
+; CHECK-NEXT:   %x3 = add i32 %x2, 1
+; CHECK-NEXT: cost before = {{.*}}, cost after = {{.*}}, threshold before = {{.*}}, threshold after = {{.*}}, cost delta = {{.*}}
+; CHECK-NEXT:   ret i32 %x3
+; CHECK-NEXT: }
 
 define i32 @foo(i32 %y) {
   %x = call i32 @callee1(i32 %y)

diff  --git a/llvm/test/Transforms/Inline/inline-cost-annotation-pass.ll b/llvm/test/Transforms/Inline/inline-cost-annotation-pass.ll
new file mode 100644
index 000000000000..73b8a0bb0c0b
--- /dev/null
+++ b/llvm/test/Transforms/Inline/inline-cost-annotation-pass.ll
@@ -0,0 +1,32 @@
+; RUN: opt < %s -passes="print<inline-cost>" 2>&1 | FileCheck %s
+
+; CHECK:       Analyzing call of foo... (caller:main)
+; CHECK: define i8 addrspace(1)** @foo() {
+; CHECK:  cost before = {{.*}}, cost after = {{.*}}, threshold before = {{.*}}, threshold after = {{.*}}, cost delta = {{.*}}
+; CHECK:  %1 = inttoptr i64 754974720 to i8 addrspace(1)**
+; CHECK:  cost before = {{.*}}, cost after = {{.*}}, threshold before = {{.*}}, threshold after = {{.*}}, cost delta = {{.*}}
+; CHECK:  ret i8 addrspace(1)** %1
+; CHECK: }
+; CHECK:       NumConstantArgs: {{.*}}
+; CHECK:       NumConstantOffsetPtrArgs: {{.*}}
+; CHECK:       NumAllocaArgs: {{.*}}
+; CHECK:       NumConstantPtrCmps: {{.*}}
+; CHECK:       NumConstantPtrDiffs: {{.*}}
+; CHECK:       NumInstructionsSimplified: {{.*}}
+; CHECK:       NumInstructions: {{.*}}
+; CHECK:       SROACostSavings: {{.*}}
+; CHECK:       SROACostSavingsLost: {{.*}}
+; CHECK:       LoadEliminationCost: {{.*}}
+; CHECK:       ContainsNoDuplicateCall: {{.*}}
+; CHECK:       Cost: {{.*}}
+; CHECK:       Threshold: {{.*}}
+
+define i8 addrspace(1)** @foo() {
+  %1 = inttoptr i64 754974720 to i8 addrspace(1)**
+  ret i8 addrspace(1)** %1
+}
+
+define i8 addrspace(1)** @main() {
+  %1 = call i8 addrspace(1)** @foo()
+  ret i8 addrspace(1)** %1
+}

diff  --git a/llvm/test/Transforms/Inline/print-instructions-deltas-unfinished.ll b/llvm/test/Transforms/Inline/print-instructions-deltas-unfinished.ll
deleted file mode 100644
index 70e223c951e3..000000000000
--- a/llvm/test/Transforms/Inline/print-instructions-deltas-unfinished.ll
+++ /dev/null
@@ -1,22 +0,0 @@
-; Require asserts for -debug-only
-; REQUIRES: asserts
-
-; This test ensures that the hadling of instructions which were not analyzed by
-; '-print-instruction-deltas' flag due to the early exit was done correctly.
-
-; RUN: opt < %s -inline -debug-only=inline-cost -disable-output -print-instruction-comments -inline-threshold=0 2>&1 | FileCheck %s
-
-; CHECK: No analysis for the instruction
-; CHECK:   ret void
-
-declare void @callee1()
-
-define void @bar() {
-  call void @callee1()
-  ret void
-}
-
-define void @foo() {
-  call void @bar()
-  ret void
-}


        


More information about the llvm-commits mailing list