LLVM  15.0.0git
ReplayInlineAdvisor.cpp
Go to the documentation of this file.
1 //===- ReplayInlineAdvisor.cpp - Replay InlineAdvisor ---------------------===//
2 //
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
6 //
7 //===----------------------------------------------------------------------===//
8 //
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
12 // inlining steady.
13 //
14 //===----------------------------------------------------------------------===//
15 
20 #include <memory>
21 
22 using namespace llvm;
23 
24 #define DEBUG_TYPE "replay-inline"
25 
28  std::unique_ptr<InlineAdvisor> OriginalAdvisor,
29  const ReplayInlinerSettings &ReplaySettings, bool EmitRemarks,
30  InlineContext IC)
31  : InlineAdvisor(M, FAM, IC), OriginalAdvisor(std::move(OriginalAdvisor)),
32  ReplaySettings(ReplaySettings), EmitRemarks(EmitRemarks) {
33 
34  auto BufferOrErr = MemoryBuffer::getFileOrSTDIN(ReplaySettings.ReplayFile);
35  std::error_code EC = BufferOrErr.getError();
36  if (EC) {
37  Context.emitError("Could not open remarks file: " + EC.message());
38  return;
39  }
40 
41  // Example for inline remarks to parse:
42  // main:3:1.1: '_Z3subii' inlined into 'main' at callsite sum:1 @
43  // main:3:1.1;
44  // We use the callsite string after `at callsite` to replay inlining.
45  line_iterator LineIt(*BufferOrErr.get(), /*SkipBlanks=*/true);
46  const std::string PositiveRemark = "' inlined into '";
47  const std::string NegativeRemark = "' will not be inlined into '";
48 
49  for (; !LineIt.is_at_eof(); ++LineIt) {
50  StringRef Line = *LineIt;
51  auto Pair = Line.split(" at callsite ");
52 
53  bool IsPositiveRemark = true;
54  if (Pair.first.contains(NegativeRemark))
55  IsPositiveRemark = false;
56 
57  auto CalleeCaller =
58  Pair.first.split(IsPositiveRemark ? PositiveRemark : NegativeRemark);
59 
60  StringRef Callee = CalleeCaller.first.rsplit(": '").second;
61  StringRef Caller = CalleeCaller.second.rsplit("'").first;
62 
63  auto CallSite = Pair.second.split(";").first;
64 
65  if (Callee.empty() || Caller.empty() || CallSite.empty()) {
66  Context.emitError("Invalid remark format: " + Line);
67  return;
68  }
69 
70  std::string Combined = (Callee + CallSite).str();
71  InlineSitesFromRemarks[Combined] = IsPositiveRemark;
73  CallersToReplay.insert(Caller);
74  }
75 
76  HasReplayRemarks = true;
77 }
78 
79 std::unique_ptr<InlineAdvisor>
82  std::unique_ptr<InlineAdvisor> OriginalAdvisor,
83  const ReplayInlinerSettings &ReplaySettings,
84  bool EmitRemarks, InlineContext IC) {
85  auto Advisor = std::make_unique<ReplayInlineAdvisor>(
86  M, FAM, Context, std::move(OriginalAdvisor), ReplaySettings, EmitRemarks,
87  IC);
88  if (!Advisor->areReplayRemarksLoaded())
89  Advisor.reset();
90  return Advisor;
91 }
92 
93 std::unique_ptr<InlineAdvice> ReplayInlineAdvisor::getAdviceImpl(CallBase &CB) {
94  assert(HasReplayRemarks);
95 
96  Function &Caller = *CB.getCaller();
97  auto &ORE = FAM.getResult<OptimizationRemarkEmitterAnalysis>(Caller);
98 
99  // Decision not made by replay system
100  if (!hasInlineAdvice(*CB.getFunction())) {
101  // If there's a registered original advisor, return its decision
102  if (OriginalAdvisor)
103  return OriginalAdvisor->getAdvice(CB);
104 
105  // If no decision is made above, return non-decision
106  return {};
107  }
108 
109  std::string CallSiteLoc =
110  formatCallSiteLocation(CB.getDebugLoc(), ReplaySettings.ReplayFormat);
112  std::string Combined = (Callee + CallSiteLoc).str();
113 
114  // Replay decision, if it has one
115  auto Iter = InlineSitesFromRemarks.find(Combined);
116  if (Iter != InlineSitesFromRemarks.end()) {
117  if (InlineSitesFromRemarks[Combined]) {
118  LLVM_DEBUG(dbgs() << "Replay Inliner: Inlined " << Callee << " @ "
119  << CallSiteLoc << "\n");
120  return std::make_unique<DefaultInlineAdvice>(
121  this, CB, llvm::InlineCost::getAlways("previously inlined"), ORE,
122  EmitRemarks);
123  } else {
124  LLVM_DEBUG(dbgs() << "Replay Inliner: Not Inlined " << Callee << " @ "
125  << CallSiteLoc << "\n");
126  // A negative inline is conveyed by "None" Optional<InlineCost>
127  return std::make_unique<DefaultInlineAdvice>(this, CB, None, ORE,
128  EmitRemarks);
129  }
130  }
131 
132  // Fallback decisions
133  if (ReplaySettings.ReplayFallback ==
135  return std::make_unique<DefaultInlineAdvice>(
136  this, CB, llvm::InlineCost::getAlways("AlwaysInline Fallback"), ORE,
137  EmitRemarks);
138  else if (ReplaySettings.ReplayFallback ==
140  // A negative inline is conveyed by "None" Optional<InlineCost>
141  return std::make_unique<DefaultInlineAdvice>(this, CB, None, ORE,
142  EmitRemarks);
143  else {
144  assert(ReplaySettings.ReplayFallback ==
146  // If there's a registered original advisor, return its decision
147  if (OriginalAdvisor)
148  return OriginalAdvisor->getAdvice(CB);
149  }
150 
151  // If no decision is made above, return non-decision
152  return {};
153 }
MemoryBuffer.h
llvm
This is an optimization pass for GlobalISel generic memory operations.
Definition: AddressRanges.h:17
llvm::LLVMContext::emitError
void emitError(uint64_t LocCookie, const Twine &ErrorStr)
emitError - Emit an error message to the currently installed error handler with optional location inf...
Definition: LLVMContext.cpp:266
M
We currently emits eax Perhaps this is what we really should generate is Is imull three or four cycles eax eax The current instruction priority is based on pattern complexity The former is more complex because it folds a load so the latter will not be emitted Perhaps we should use AddedComplexity to give LEA32r a higher priority We should always try to match LEA first since the LEA matching code does some estimate to determine whether the match is profitable if we care more about code then imull is better It s two bytes shorter than movl leal On a Pentium M
Definition: README.txt:252
llvm::ReplayInlinerSettings::ReplayFormat
CallSiteFormat ReplayFormat
Definition: ReplayInlineAdvisor.h:50
llvm::line_iterator
A forward iterator which reads text lines from a buffer.
Definition: LineIterator.h:33
llvm::AnalysisManager::getResult
PassT::Result & getResult(IRUnitT &IR, ExtraArgTs... ExtraArgs)
Get the result of an analysis pass for a given IR unit.
Definition: PassManager.h:780
llvm::Function
Definition: Function.h:60
llvm::ReplayInlineAdvisor::ReplayInlineAdvisor
ReplayInlineAdvisor(Module &M, FunctionAnalysisManager &FAM, LLVMContext &Context, std::unique_ptr< InlineAdvisor > OriginalAdvisor, const ReplayInlinerSettings &ReplaySettings, bool EmitRemarks, InlineContext IC)
Definition: ReplayInlineAdvisor.cpp:26
OptimizationRemarkEmitter.h
FAM
FunctionAnalysisManager FAM
Definition: PassBuilderBindings.cpp:59
llvm::StringMap::end
iterator end()
Definition: StringMap.h:204
llvm::InlineCost::getAlways
static InlineCost getAlways(const char *Reason, Optional< CostBenefitPair > CostBenefit=None)
Definition: InlineCost.h:117
llvm::StringSet::insert
std::pair< typename Base::iterator, bool > insert(StringRef key)
Definition: StringSet.h:34
llvm::StringMap::find
iterator find(StringRef Key)
Definition: StringMap.h:217
llvm::ReplayInlinerSettings::Fallback::Original
@ Original
LLVM_DEBUG
#define LLVM_DEBUG(X)
Definition: Debug.h:101
Context
LLVMContext & Context
Definition: NVVMIntrRange.cpp:66
llvm::dbgs
raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
Definition: Debug.cpp:163
llvm::StringRef::split
LLVM_NODISCARD std::pair< StringRef, StringRef > split(char Separator) const
Split into two substrings around the first occurrence of a separator character.
Definition: StringRef.h:753
llvm::CallBase::getCalledFunction
Function * getCalledFunction() const
Returns the function called, or null if this is an indirect function invocation or the function signa...
Definition: InstrTypes.h:1396
LineIterator.h
llvm::ReplayInlinerSettings::Fallback::NeverInline
@ NeverInline
llvm::InlineContext
Provides context on when an inline advisor is constructed in the pipeline (e.g., link phase,...
Definition: InlineAdvisor.h:58
llvm::None
const NoneType None
Definition: None.h:24
llvm::CallBase::getCaller
Function * getCaller()
Helper to get the caller (the parent function).
Definition: Instructions.cpp:282
llvm::formatCallSiteLocation
std::string formatCallSiteLocation(DebugLoc DLoc, const CallSiteFormat &Format)
Get call site location as a string with the given format.
Definition: InlineAdvisor.cpp:428
llvm::ReplayInlinerSettings::ReplayFile
StringRef ReplayFile
Definition: ReplayInlineAdvisor.h:47
ReplayInlineAdvisor.h
move
compiles ldr LCPI1_0 ldr ldr mov lsr tst moveq r1 ldr LCPI1_1 and r0 bx lr It would be better to do something like to fold the shift into the conditional move
Definition: README.txt:546
llvm::LLVMContext
This is an important class for using LLVM in a threaded context.
Definition: LLVMContext.h:68
llvm::MemoryBuffer::getFileOrSTDIN
static ErrorOr< std::unique_ptr< MemoryBuffer > > getFileOrSTDIN(const Twine &Filename, bool IsText=false, bool RequiresNullTerminator=true)
Open the specified file as a MemoryBuffer, or open stdin if the Filename is "-".
Definition: MemoryBuffer.cpp:146
llvm::ReplayInlinerSettings::ReplayScope
Scope ReplayScope
Definition: ReplayInlineAdvisor.h:48
assert
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
llvm::move
OutputIt move(R &&Range, OutputIt Out)
Provide wrappers to std::move which take ranges instead of having to pass begin/end explicitly.
Definition: STLExtras.h:1675
llvm::Module
A Module instance is used to store all the information related to an LLVM module.
Definition: Module.h:65
llvm::ReplayInlinerSettings::ReplayFallback
Fallback ReplayFallback
Definition: ReplayInlineAdvisor.h:49
llvm::StringRef
StringRef - Represent a constant reference to a string, i.e.
Definition: StringRef.h:58
llvm::InlineAdvisor
Interface for deciding whether to inline a call site or not.
Definition: InlineAdvisor.h:163
llvm::Instruction::getFunction
const Function * getFunction() const
Return the function this instruction belongs to.
Definition: Instruction.cpp:69
llvm::Value::getName
StringRef getName() const
Return a constant reference to the value's name.
Definition: Value.cpp:305
Callee
amdgpu Simplify well known AMD library false FunctionCallee Callee
Definition: AMDGPULibCalls.cpp:186
llvm::InlineAdvisor::FAM
FunctionAnalysisManager & FAM
Definition: InlineAdvisor.h:209
std
Definition: BitVector.h:851
llvm::line_iterator::is_at_eof
bool is_at_eof() const
Return true if we've reached EOF or are an "end" iterator.
Definition: LineIterator.h:60
llvm::Instruction::getDebugLoc
const DebugLoc & getDebugLoc() const
Return the debug location for this node as a DebugLoc.
Definition: Instruction.h:352
llvm::ReplayInlinerSettings::Scope::Function
@ Function
llvm::ReplayInlineAdvisor::getAdviceImpl
std::unique_ptr< InlineAdvice > getAdviceImpl(CallBase &CB) override
Definition: ReplayInlineAdvisor.cpp:93
llvm::CallBase
Base class for all callable instructions (InvokeInst and CallInst) Holds everything related to callin...
Definition: InstrTypes.h:1174
llvm::AnalysisManager
A container for analyses that lazily runs them and caches their results.
Definition: InstructionSimplify.h:42
llvm::ReplayInlinerSettings::Fallback::AlwaysInline
@ AlwaysInline
llvm::OptimizationRemarkEmitterAnalysis
Definition: OptimizationRemarkEmitter.h:164
llvm::ReplayInlinerSettings
Replay Inliner Setup.
Definition: ReplayInlineAdvisor.h:43
llvm::getReplayInlineAdvisor
std::unique_ptr< InlineAdvisor > getReplayInlineAdvisor(Module &M, FunctionAnalysisManager &FAM, LLVMContext &Context, std::unique_ptr< InlineAdvisor > OriginalAdvisor, const ReplayInlinerSettings &ReplaySettings, bool EmitRemarks, InlineContext IC)
Definition: ReplayInlineAdvisor.cpp:80