LLVM  14.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 
18 #include "llvm/IR/Instructions.h"
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  : InlineAdvisor(M, FAM), OriginalAdvisor(std::move(OriginalAdvisor)),
31  HasReplayRemarks(false), ReplaySettings(ReplaySettings),
32  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> llvm::getReplayInlineAdvisor(
81  std::unique_ptr<InlineAdvisor> OriginalAdvisor,
82  const ReplayInlinerSettings &ReplaySettings, bool EmitRemarks) {
83  auto Advisor = std::make_unique<ReplayInlineAdvisor>(
84  M, FAM, Context, std::move(OriginalAdvisor), ReplaySettings, EmitRemarks);
85  if (!Advisor->areReplayRemarksLoaded())
86  Advisor.reset();
87  return Advisor;
88 }
89 
90 std::unique_ptr<InlineAdvice> ReplayInlineAdvisor::getAdviceImpl(CallBase &CB) {
91  assert(HasReplayRemarks);
92 
93  Function &Caller = *CB.getCaller();
94  auto &ORE = FAM.getResult<OptimizationRemarkEmitterAnalysis>(Caller);
95 
96  // Decision not made by replay system
97  if (!hasInlineAdvice(*CB.getFunction())) {
98  // If there's a registered original advisor, return its decision
99  if (OriginalAdvisor)
100  return OriginalAdvisor->getAdvice(CB);
101 
102  // If no decision is made above, return non-decision
103  return {};
104  }
105 
106  std::string CallSiteLoc =
107  formatCallSiteLocation(CB.getDebugLoc(), ReplaySettings.ReplayFormat);
109  std::string Combined = (Callee + CallSiteLoc).str();
110 
111  // Replay decision, if it has one
112  auto Iter = InlineSitesFromRemarks.find(Combined);
113  if (Iter != InlineSitesFromRemarks.end()) {
114  if (InlineSitesFromRemarks[Combined]) {
115  LLVM_DEBUG(dbgs() << "Replay Inliner: Inlined " << Callee << " @ "
116  << CallSiteLoc << "\n");
117  return std::make_unique<DefaultInlineAdvice>(
118  this, CB, llvm::InlineCost::getAlways("previously inlined"), ORE,
119  EmitRemarks);
120  } else {
121  LLVM_DEBUG(dbgs() << "Replay Inliner: Not Inlined " << Callee << " @ "
122  << CallSiteLoc << "\n");
123  // A negative inline is conveyed by "None" Optional<InlineCost>
124  return std::make_unique<DefaultInlineAdvice>(this, CB, None, ORE,
125  EmitRemarks);
126  }
127  }
128 
129  // Fallback decisions
130  if (ReplaySettings.ReplayFallback ==
132  return std::make_unique<DefaultInlineAdvice>(
133  this, CB, llvm::InlineCost::getAlways("AlwaysInline Fallback"), ORE,
134  EmitRemarks);
135  else if (ReplaySettings.ReplayFallback ==
137  // A negative inline is conveyed by "None" Optional<InlineCost>
138  return std::make_unique<DefaultInlineAdvice>(this, CB, None, ORE,
139  EmitRemarks);
140  else {
141  assert(ReplaySettings.ReplayFallback ==
143  // If there's a registered original advisor, return its decision
144  if (OriginalAdvisor)
145  return OriginalAdvisor->getAdvice(CB);
146  }
147 
148  // If no decision is made above, return non-decision
149  return {};
150 }
llvm::ReplayInlineAdvisor::ReplayInlineAdvisor
ReplayInlineAdvisor(Module &M, FunctionAnalysisManager &FAM, LLVMContext &Context, std::unique_ptr< InlineAdvisor > OriginalAdvisor, const ReplayInlinerSettings &ReplaySettings, bool EmitRemarks)
Definition: ReplayInlineAdvisor.cpp:26
llvm::getReplayInlineAdvisor
std::unique_ptr< InlineAdvisor > getReplayInlineAdvisor(Module &M, FunctionAnalysisManager &FAM, LLVMContext &Context, std::unique_ptr< InlineAdvisor > OriginalAdvisor, const ReplayInlinerSettings &ReplaySettings, bool EmitRemarks)
Definition: ReplayInlineAdvisor.cpp:79
llvm
This is an optimization pass for GlobalISel generic memory operations.
Definition: AllocatorList.h:23
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:783
DebugInfoMetadata.h
llvm::Function
Definition: Function.h:62
FAM
FunctionAnalysisManager FAM
Definition: PassBuilderBindings.cpp:59
llvm::StringMap::end
iterator end()
Definition: StringMap.h:203
llvm::InlineCost::getAlways
static InlineCost getAlways(const char *Reason, Optional< CostBenefitPair > CostBenefit=None)
Definition: InlineCost.h:111
llvm::StringSet::insert
std::pair< typename Base::iterator, bool > insert(StringRef key)
Definition: StringSet.h:33
llvm::StringMap::find
iterator find(StringRef Key)
Definition: StringMap.h:216
llvm::ReplayInlinerSettings::Fallback::Original
@ Original
LLVM_DEBUG
#define LLVM_DEBUG(X)
Definition: Debug.h:101
Context
ManagedStatic< detail::RecordContext > Context
Definition: Record.cpp:96
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:748
llvm::CallBase::getCalledFunction
Function * getCalledFunction() const
Returns the function called, or null if this is an indirect function invocation.
Definition: InstrTypes.h:1398
false
Definition: StackSlotColoring.cpp:142
LineIterator.h
llvm::ReplayInlinerSettings::Fallback::NeverInline
@ NeverInline
llvm::None
const NoneType None
Definition: None.h:23
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:416
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:67
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:144
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:1707
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:57
llvm::InlineAdvisor
Interface for deciding whether to inline a call site or not.
Definition: InlineAdvisor.h:140
llvm::Instruction::getFunction
const Function * getFunction() const
Return the function this instruction belongs to.
Definition: Instruction.cpp:70
llvm::Value::getName
StringRef getName() const
Return a constant reference to the value's name.
Definition: Value.cpp:309
Callee
amdgpu Simplify well known AMD library false FunctionCallee Callee
Definition: AMDGPULibCalls.cpp:185
llvm::InlineAdvisor::FAM
FunctionAnalysisManager & FAM
Definition: InlineAdvisor.h:180
std
Definition: BitVector.h:838
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
Instructions.h
llvm::Instruction::getDebugLoc
const DebugLoc & getDebugLoc() const
Return the debug location for this node as a DebugLoc.
Definition: Instruction.h:370
llvm::ReplayInlinerSettings::Scope::Function
@ Function
llvm::ReplayInlineAdvisor::getAdviceImpl
std::unique_ptr< InlineAdvice > getAdviceImpl(CallBase &CB) override
Definition: ReplayInlineAdvisor.cpp:90
llvm::CallBase
Base class for all callable instructions (InvokeInst and CallInst) Holds everything related to callin...
Definition: InstrTypes.h:1176
llvm::AnalysisManager
A container for analyses that lazily runs them and caches their results.
Definition: InstructionSimplify.h:44
llvm::ReplayInlinerSettings::Fallback::AlwaysInline
@ AlwaysInline
llvm::OptimizationRemarkEmitterAnalysis
Definition: OptimizationRemarkEmitter.h:164
llvm::ReplayInlinerSettings
Replay Inliner Setup.
Definition: ReplayInlineAdvisor.h:43