36 cl::desc(
"Path to the prefetch hints profile. See also "
37 "-x86-discriminate-memops"),
43 bool doInitialization(
Module &)
override;
47 unsigned InstructionID;
50 typedef SmallVectorImpl<PrefetchInfo> Prefetches;
51 bool findPrefetchInfo(
const FunctionSamples *Samples,
const MachineInstr &
MI,
52 Prefetches &prefetches)
const;
56 X86InsertPrefetch(
const std::string &PrefetchHintsFilename);
57 StringRef getPassName()
const override {
58 return "X86 Insert Cache Prefetches";
63 std::unique_ptr<SampleProfileReader> Reader;
72 if (
const auto &
Loc =
MI.getDebugLoc())
75 Loc->getBaseDiscriminator());
76 return std::error_code();
84 return (BaseReg == 0 ||
85 X86MCRegisterClasses[X86::GR64RegClassID].
contains(BaseReg) ||
86 X86MCRegisterClasses[X86::GR32RegClassID].
contains(BaseReg)) &&
88 X86MCRegisterClasses[X86::GR64RegClassID].contains(IndexReg) ||
89 X86MCRegisterClasses[X86::GR32RegClassID].
contains(IndexReg));
98char X86InsertPrefetch::ID = 0;
100X86InsertPrefetch::X86InsertPrefetch(
const std::string &PrefetchHintsFilename)
106bool X86InsertPrefetch::findPrefetchInfo(
const FunctionSamples *TopSamples,
108 Prefetches &Prefetches)
const {
109 assert(Prefetches.empty() &&
110 "Expected caller passed empty PrefetchInfo vector.");
116 static constexpr std::pair<StringLiteral, unsigned> HintTypes[] = {
117 {
"_nta_", X86::PREFETCHNTA},
118 {
"_t0_", X86::PREFETCHT0},
119 {
"_t1_", X86::PREFETCHT1},
120 {
"_t2_", X86::PREFETCHT2},
122 static const char *SerializedPrefetchPrefix =
"__prefetch";
124 auto T = getPrefetchHints(TopSamples,
MI);
127 int16_t max_index = -1;
130 for (
const auto &S_V : *
T) {
131 StringRef
Name = S_V.first.stringRef();
132 if (
Name.consume_front(SerializedPrefetchPrefix)) {
133 int64_t
D =
static_cast<int64_t
>(S_V.second);
135 for (
const auto &HintType : HintTypes) {
136 if (
Name.consume_front(HintType.first)) {
137 IID = HintType.second;
144 Name.consumeInteger(10, index);
146 if (index >= Prefetches.size())
147 Prefetches.resize(index + 1);
148 Prefetches[index] = {IID,
D};
149 max_index = std::max(max_index,
static_cast<int16_t
>(index));
152 assert(max_index + 1 >= 0 &&
153 "Possible overflow: max_index + 1 should be positive.");
154 assert(
static_cast<size_t>(max_index + 1) == Prefetches.size() &&
155 "The number of prefetch hints received should match the number of "
156 "PrefetchInfo objects returned");
157 return !Prefetches.empty();
160bool X86InsertPrefetch::doInitialization(
Module &M) {
161 if (Filename.empty())
164 LLVMContext &Ctx =
M.getContext();
167 ErrorOr<std::unique_ptr<SampleProfileReader>> ReaderOrErr =
169 if (std::error_code EC = ReaderOrErr.
getError()) {
170 std::string Msg =
"Could not open profile: " +
EC.message();
171 Ctx.
diagnose(DiagnosticInfoSampleProfile(Filename, Msg,
172 DiagnosticSeverity::DS_Warning));
175 Reader = std::move(ReaderOrErr.
get());
180void X86InsertPrefetch::getAnalysisUsage(AnalysisUsage &AU)
const {
185bool X86InsertPrefetch::runOnMachineFunction(MachineFunction &MF) {
188 const FunctionSamples *Samples = Reader->getSamplesFor(MF.
getFunction());
196 for (
auto &
MBB : MF) {
205 int MemOpOffset =
Offset + Bias;
207 if (!IsMemOpCompatibleWithPrefetch(*Current, MemOpOffset))
210 if (!findPrefetchInfo(Samples, *Current, Prefetches))
213 "The Prefetches vector should contain at least a value if "
214 "findPrefetchInfo returned true.");
215 for (
auto &PrefInfo : Prefetches) {
216 unsigned PFetchInstrID = PrefInfo.InstructionID;
217 int64_t Delta = PrefInfo.Delta;
218 const MCInstrDesc &
Desc =
TII->get(PFetchInstrID);
219 MachineInstr *PFetch =
220 MF.CreateMachineInstr(
Desc, Current->getDebugLoc(),
true);
221 MachineInstrBuilder MIB(MF, PFetch);
226 "Unexpected change in X86 operand offset order.");
236 .addImm(Current->getOperand(MemOpOffset +
X86::AddrDisp).getImm() +
241 if (!Current->memoperands_empty()) {
242 MachineMemOperand *CurrentOp = *(Current->memoperands_begin());
243 MIB.addMemOperand(MF.getMachineMemOperand(
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
static GCRegistry::Add< StatepointGC > D("statepoint-example", "an example strategy for statepoint")
const HexagonInstrInfo * TII
Module.h This file contains the declarations for the Module class.
Machine Check Debug Module
This file provides the interface for the sampled PGO loader pass.
static bool contains(SmallPtrSetImpl< ConstantExpr * > &Cache, ConstantExpr *Expr, Constant *C)
Defines the virtual file system interface vfs::FileSystem.
static cl::opt< std::string > PrefetchHintsFile("prefetch-hints-file", cl::desc("Path to the prefetch hints profile. See also " "-x86-discriminate-memops"), cl::Hidden)
Represent the analysis usage information of a pass.
void setPreservesAll()
Set by analyses that do not transform their input at all.
Represents either an error or a value T.
std::error_code getError() const
FunctionPass class - This class is used to implement most global optimizations.
LLVM_ABI void diagnose(const DiagnosticInfo &DI)
Report a message to the currently installed diagnostic handler.
instr_iterator instr_begin()
LLVM_ABI instr_iterator insert(instr_iterator I, MachineInstr *M)
Insert MI into the instruction list before I, possibly inside a bundle.
instr_iterator instr_end()
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.
Function & getFunction()
Return the LLVM function that this machine code represents.
Representation of each machine instruction.
LocationSize getSize() const
Return the size in bytes of the memory reference.
int64_t getOffset() const
For normal values, this is a byte offset added to the base address.
A Module instance is used to store all the information related to an LLVM module.
Wrapper class representing virtual and physical registers.
virtual const TargetInstrInfo * getInstrInfo() const
Representation of the samples collected for a function.
LLVM_ABI const FunctionSamples * findFunctionSamples(const DILocation *DIL, SampleProfileReaderItaniumRemapper *Remapper=nullptr, const HashKeyMap< std::unordered_map, FunctionId, FunctionId > *FuncNameToProfNameMap=nullptr) const
Get the FunctionSamples of the inline instance where DIL originates from.
static LLVM_ABI unsigned getOffset(const DILocation *DIL)
Returns the line offset to the start line of the subprogram.
static LLVM_ABI bool UseMD5
Whether the profile uses MD5 to represent string.
static LLVM_ABI ErrorOr< std::unique_ptr< SampleProfileReader > > create(StringRef Filename, LLVMContext &C, vfs::FileSystem &FS, FSDiscriminatorPass P=FSDiscriminatorPass::Base, StringRef RemapFilename="")
Create a sample profile reader appropriate to the file format.
std::unordered_map< FunctionId, uint64_t > CallTargetMap
unsigned ID
LLVM IR allows to use arbitrary numbers as calling convention identifiers.
int getMemoryOperandNo(uint64_t TSFlags)
unsigned getOperandBias(const MCInstrDesc &Desc)
Compute whether all of the def operands are repeated in the uses and therefore should be skipped.
BaseReg
Stack frame base register. Bit 0 of FREInfo.Info.
LLVM_ABI IntrusiveRefCntPtr< FileSystem > getRealFileSystem()
Gets an vfs::FileSystem for the 'real' file system, as seen by the operating system.
This is an optimization pass for GlobalISel generic memory operations.
FunctionPass * createX86InsertPrefetchPass()
This pass applies profiling information to insert cache prefetches.
class LLVM_GSL_OWNER SmallVector
Forward declaration of SmallVector so that calculateSmallVectorDefaultInlinedElements can reference s...
DWARFExpression::Operation Op