1 //===- ReplayInlineAdvisor.cpp - Replay InlineAdvisor ---------------------===//
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
7 //===----------------------------------------------------------------------===//
9 // This file implements ReplayInlineAdvisor that replays inline decisions based
10 // on previous inline remarks from optimization remark log. This is a best
11 // effort approach useful for testing compiler/source changes while holding
14 //===----------------------------------------------------------------------===//
16 #include "llvm/Analysis/ReplayInlineAdvisor.h"
17 #include "llvm/IR/DebugInfoMetadata.h"
18 #include "llvm/IR/Instructions.h"
19 #include "llvm/Support/LineIterator.h"
23 #define DEBUG_TYPE "inline-replay"
25 ReplayInlineAdvisor::ReplayInlineAdvisor(
26 Module
&M
, FunctionAnalysisManager
&FAM
, LLVMContext
&Context
,
27 std::unique_ptr
<InlineAdvisor
> OriginalAdvisor
, StringRef RemarksFile
,
29 : InlineAdvisor(M
, FAM
), OriginalAdvisor(std::move(OriginalAdvisor
)),
30 HasReplayRemarks(false), EmitRemarks(EmitRemarks
) {
31 auto BufferOrErr
= MemoryBuffer::getFileOrSTDIN(RemarksFile
);
32 std::error_code EC
= BufferOrErr
.getError();
34 Context
.emitError("Could not open remarks file: " + EC
.message());
38 // Example for inline remarks to parse:
39 // main:3:1.1: '_Z3subii' inlined into 'main' at callsite sum:1 @ main:3:1.1
40 // We use the callsite string after `at callsite` to replay inlining.
41 line_iterator
LineIt(*BufferOrErr
.get(), /*SkipBlanks=*/true);
42 for (; !LineIt
.is_at_eof(); ++LineIt
) {
43 StringRef Line
= *LineIt
;
44 auto Pair
= Line
.split(" at callsite ");
46 StringRef Callee
= Pair
.first
.split(" inlined into")
49 auto CallSite
= Pair
.second
.split(";").first
;
51 if (Callee
.empty() || CallSite
.empty())
54 std::string Combined
= (Callee
+ CallSite
).str();
55 InlineSitesFromRemarks
.insert(Combined
);
58 HasReplayRemarks
= true;
61 std::unique_ptr
<InlineAdvice
> ReplayInlineAdvisor::getAdviceImpl(CallBase
&CB
) {
62 assert(HasReplayRemarks
);
64 Function
&Caller
= *CB
.getCaller();
65 auto &ORE
= FAM
.getResult
<OptimizationRemarkEmitterAnalysis
>(Caller
);
67 if (InlineSitesFromRemarks
.empty())
68 return std::make_unique
<DefaultInlineAdvice
>(this, CB
, None
, ORE
,
71 std::string CallSiteLoc
= getCallSiteLocation(CB
.getDebugLoc());
72 StringRef Callee
= CB
.getCalledFunction()->getName();
73 std::string Combined
= (Callee
+ CallSiteLoc
).str();
74 auto Iter
= InlineSitesFromRemarks
.find(Combined
);
76 Optional
<InlineCost
> InlineRecommended
= None
;
77 if (Iter
!= InlineSitesFromRemarks
.end()) {
78 InlineRecommended
= llvm::InlineCost::getAlways("found in replay");
81 return std::make_unique
<DefaultInlineAdvice
>(this, CB
, InlineRecommended
, ORE
,