LLVM 23.0.0git
InsertCodePrefetch.cpp
Go to the documentation of this file.
1//===-- InsertCodePrefetch.cpp ---=========--------------------------------===//
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/// \file
10/// Code Prefetch Insertion Pass.
11//===----------------------------------------------------------------------===//
12/// This pass inserts code prefetch instructions according to the prefetch
13/// directives in the basic block section profile. The target of a prefetch can
14/// be the beginning of any dynamic basic block, that is the beginning of a
15/// machine basic block, or immediately after a callsite. A global symbol is
16/// emitted at the position of the target so it can be addressed from the
17/// prefetch instruction from any module. In order to insert prefetch hints,
18/// `TargetInstrInfo::insertCodePrefetchInstr` must be implemented by the
19/// target.
20//===----------------------------------------------------------------------===//
21
23
24#include "llvm/ADT/DenseMap.h"
27#include "llvm/ADT/StringRef.h"
33#include "llvm/CodeGen/Passes.h"
36#include "llvm/MC/MCContext.h"
37#include "llvm/MC/MCSymbolELF.h"
39
40using namespace llvm;
41#define DEBUG_TYPE "insert-code-prefetch"
42
44 const UniqueBBID &BBID,
45 unsigned CallsiteIndex) {
46 SmallString<128> R("__llvm_prefetch_target_");
47 R += FunctionName;
48 R += "_";
49 R += utostr(BBID.BaseID);
50 R += "_";
52 return R;
53}
54
55namespace {
56class InsertCodePrefetch : public MachineFunctionPass {
57public:
58 static char ID;
59
60 InsertCodePrefetch() : MachineFunctionPass(ID) {}
61
62 StringRef getPassName() const override {
63 return "Code Prefetch Inserter Pass";
64 }
65
66 void getAnalysisUsage(AnalysisUsage &AU) const override;
67
68 // Sets prefetch targets based on the bb section profile.
69 bool runOnMachineFunction(MachineFunction &MF) override;
70};
71
72} // end anonymous namespace
73
74//===----------------------------------------------------------------------===//
75// Implementation
76//===----------------------------------------------------------------------===//
77
78char InsertCodePrefetch::ID = 0;
79INITIALIZE_PASS_BEGIN(InsertCodePrefetch, DEBUG_TYPE, "Code prefetch insertion",
80 true, false)
82INITIALIZE_PASS_END(InsertCodePrefetch, DEBUG_TYPE, "Code prefetch insertion",
84
86 const SmallVector<CallsiteID> &PrefetchTargets) {
87 if (PrefetchTargets.empty())
88 return false;
89 // Set each block's prefetch targets so AsmPrinter can emit a special symbol
90 // there.
91 DenseMap<UniqueBBID, SmallVector<unsigned>> PrefetchTargetsByBBID;
92 for (const auto &Target : PrefetchTargets)
93 PrefetchTargetsByBBID[Target.BBID].push_back(Target.CallsiteIndex);
94 // Sort and uniquify the callsite indices for every block.
95 for (auto &[K, V] : PrefetchTargetsByBBID) {
96 llvm::sort(V);
97 V.erase(llvm::unique(V), V.end());
98 }
99 MF.setPrefetchTargets(PrefetchTargetsByBBID);
100 return true;
101}
102
103static bool
105 const SmallVector<PrefetchHint> &PrefetchHints) {
106 bool PrefetchInserted = false;
107 bool IsELF = MF.getTarget().getTargetTriple().isOSBinFormatELF();
108 const Module *M = MF.getFunction().getParent();
109 DenseMap<UniqueBBID, SmallVector<PrefetchHint>> PrefetchHintsBySiteBBID;
110 for (const auto &H : PrefetchHints)
111 PrefetchHintsBySiteBBID[H.SiteID.BBID].push_back(H);
112 // Sort prefetch hints by their callsite index so we can insert them by one
113 // pass over the block's instructions.
114 for (auto &[SiteBBID, Hints] : PrefetchHintsBySiteBBID) {
115 llvm::sort(Hints, [](const PrefetchHint &H1, const PrefetchHint &H2) {
117 });
118 }
119 auto PtrTy =
122 for (auto &BB : MF) {
123 auto It = PrefetchHintsBySiteBBID.find(*BB.getBBID());
124 if (It == PrefetchHintsBySiteBBID.end())
125 continue;
126 const auto &BBHints = It->second;
127 unsigned NumCallsInBB = 0;
128 auto InstrIt = BB.begin();
129 for (auto HintIt = BBHints.begin(); HintIt != BBHints.end();) {
130 auto NextInstrIt = InstrIt == BB.end() ? BB.end() : std::next(InstrIt);
131 // Insert all the prefetch hints which must be placed after this call (or
132 // at the beginning of the block if `NumCallsInBB` is zero.
133 while (HintIt != BBHints.end() &&
134 HintIt->SiteID.CallsiteIndex == NumCallsInBB) {
135 bool TargetFunctionDefined = false;
136 if (Function *TargetFunction = M->getFunction(HintIt->TargetFunction))
137 TargetFunctionDefined = !TargetFunction->isDeclaration();
138
139 auto TargetSymbolName = getPrefetchTargetSymbolName(
140 HintIt->TargetFunction, HintIt->TargetID.BBID,
141 HintIt->TargetID.CallsiteIndex);
142 auto *GV = MF.getFunction().getParent()->getOrInsertGlobal(
143 TargetSymbolName, PtrTy);
144 MachineInstr *PrefetchInstr =
145 TII->insertCodePrefetchInstr(BB, InstrIt, GV);
146 if (!TargetFunctionDefined && IsELF) {
147 // If the target function is not defined in this module, we guard
148 // against undefined prefetch target symbol by emitting a fallback
149 // symbol with weak linkage right after the prefetch instruction. If
150 // there is no strong symbol, the fallback will be used and we
151 // prefetch the next address:
152 //
153 // prefetchit1 __llvm_prefetch_target_foo_x_y(%rip)
154 // .weak __llvm_prefetch_target_foo_x_y
155 // __llvm_prefetch_target_foo_x_y:
156 MCSymbolELF *WeakFallbackSym = static_cast<MCSymbolELF *>(
157 MF.getContext().getOrCreateSymbol(TargetSymbolName));
158 WeakFallbackSym->setBinding(ELF::STB_WEAK);
159 PrefetchInstr->setPostInstrSymbol(MF, WeakFallbackSym);
160 }
161 PrefetchInserted = true;
162 ++HintIt;
163 }
164 if (InstrIt == BB.end())
165 break;
166 if (InstrIt->isCall())
167 ++NumCallsInBB;
168 InstrIt = NextInstrIt;
169 }
170 }
171 return PrefetchInserted;
172}
173
174bool InsertCodePrefetch::runOnMachineFunction(MachineFunction &MF) {
175 assert(MF.getTarget().getBBSectionsType() == BasicBlockSection::List &&
176 "BB Sections list not enabled!");
178 return false;
179
180 auto &ProfileReader =
181 getAnalysis<BasicBlockSectionsProfileReaderWrapperPass>();
182 bool R = setPrefetchTargets(
183 MF, ProfileReader.getPrefetchTargetsForFunction(MF.getName()));
184 bool S = insertPrefetchHints(
185 MF, ProfileReader.getPrefetchHintsForFunction(MF.getName()));
186 return R || S;
187}
188
189void InsertCodePrefetch::getAnalysisUsage(AnalysisUsage &AU) const {
190 AU.setPreservesAll();
191 AU.addRequired<BasicBlockSectionsProfileReaderWrapperPass>();
193}
194
196 return new InsertCodePrefetch();
197}
for(const MachineOperand &MO :llvm::drop_begin(OldMI.operands(), Desc.getNumOperands()))
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
aarch64 promote const
This file defines the DenseMap class.
#define DEBUG_TYPE
const HexagonInstrInfo * TII
static bool insertPrefetchHints(MachineFunction &MF, const SmallVector< PrefetchHint > &PrefetchHints)
Code prefetch static false bool setPrefetchTargets(MachineFunction &MF, const SmallVector< CallsiteID > &PrefetchTargets)
This file contains common utilities for code prefetch insertion.
#define H(x, y, z)
Definition MD5.cpp:56
#define INITIALIZE_PASS_DEPENDENCY(depName)
Definition PassSupport.h:42
#define INITIALIZE_PASS_END(passName, arg, name, cfg, analysis)
Definition PassSupport.h:44
#define INITIALIZE_PASS_BEGIN(passName, arg, name, cfg, analysis)
Definition PassSupport.h:39
This file defines the SmallVector class.
This file contains some functions that are useful when dealing with strings.
AnalysisUsage & addRequired()
void setPreservesAll()
Set by analyses that do not transform their input at all.
iterator find(const_arg_type_t< KeyT > Val)
Definition DenseMap.h:178
iterator end()
Definition DenseMap.h:81
const Function & getFunction() const
Definition Function.h:166
Module * getParent()
Get the module that this global value is contained inside of...
void setBinding(unsigned Binding) const
MachineFunctionPass - This class adapts the FunctionPass interface to allow convenient creation of pa...
void getAnalysisUsage(AnalysisUsage &AU) const override
getAnalysisUsage - Subclasses that override getAnalysisUsage must call this.
const TargetSubtargetInfo & getSubtarget() const
getSubtarget - Return the subtarget for which this machine code is being compiled.
StringRef getName() const
getName - Return the name of the corresponding LLVM function.
MCContext & getContext() const
Function & getFunction()
Return the LLVM function that this machine code represents.
const TargetMachine & getTarget() const
getTarget - Return the target machine this machine code is compiled with
Representation of each machine instruction.
LLVM_ABI void setPostInstrSymbol(MachineFunction &MF, MCSymbol *Symbol)
Set a symbol that will be emitted just after the instruction itself.
A Module instance is used to store all the information related to an LLVM module.
Definition Module.h:67
LLVMContext & getContext() const
Get the global data context.
Definition Module.h:285
GlobalVariable * getOrInsertGlobal(StringRef Name, Type *Ty, function_ref< GlobalVariable *()> CreateGlobalCallback)
Look up the specified global in the module symbol table.
Definition Module.cpp:262
static PointerType * getUnqual(Type *ElementType)
This constructs a pointer to an object of the specified type in the default address space (address sp...
SmallString - A SmallString is just a SmallVector with methods and accessors that make it work better...
Definition SmallString.h:26
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
StringRef - Represent a constant reference to a string, i.e.
Definition StringRef.h:55
TargetInstrInfo - Interface to description of machine instruction set.
const Triple & getTargetTriple() const
llvm::BasicBlockSection getBBSectionsType() const
If basic blocks should be emitted into their own section, corresponding to -fbasic-block-sections.
virtual const TargetInstrInfo * getInstrInfo() const
Target - Wrapper for Target specific information.
bool isOSBinFormatELF() const
Tests whether the OS uses the ELF binary format.
Definition Triple.h:810
unsigned ID
LLVM IR allows to use arbitrary numbers as calling convention identifiers.
Definition CallingConv.h:24
@ STB_WEAK
Definition ELF.h:1407
This is an optimization pass for GlobalISel generic memory operations.
std::string utostr(uint64_t X, bool isNeg=false)
auto unique(Range &&R, Predicate P)
Definition STLExtras.h:2134
void sort(IteratorTy Start, IteratorTy End)
Definition STLExtras.h:1636
SmallString< 128 > getPrefetchTargetSymbolName(StringRef FunctionName, const UniqueBBID &BBID, unsigned CallsiteIndex)
bool hasInstrProfHashMismatch(MachineFunction &MF)
This checks if the source of this function has drifted since this binary was profiled previously.
LLVM_ABI MachineFunctionPass * createInsertCodePrefetchPass()
createInsertCodePrefetchPass - This pass enables inserting code prefetch hints based on the basic blo...
unsigned CallsiteIndex
Definition UniqueBBID.h:33
CallsiteID SiteID
Definition UniqueBBID.h:39
unsigned BaseID
Definition UniqueBBID.h:24