forked from OSchip/llvm-project
[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
This commit is contained in:
parent
ccd127008a
commit
37e06e8f5c
|
@ -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
|
||||
|
|
|
@ -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();
|
||||
}
|
|
@ -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()))
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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
|
||||
}
|
|
@ -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
|
||||
}
|
Loading…
Reference in New Issue