Go to the documentation of this file.
33 using namespace sampleprof;
37 cl::desc(
"Path to the prefetch hints profile. See also "
38 "-x86-discriminate-memops"),
44 bool doInitialization(
Module &)
override;
48 unsigned InstructionID;
53 Prefetches &prefetches)
const;
57 X86InsertPrefetch(
const std::string &PrefetchHintsFilename);
59 return "X86 Insert Cache Prefetches";
64 std::unique_ptr<SampleProfileReader> Reader;
73 if (
const auto &Loc =
MI.getDebugLoc())
76 Loc->getBaseDiscriminator());
77 return std::error_code();
85 return (BaseReg == 0 ||
86 X86MCRegisterClasses[X86::GR64RegClassID].
contains(BaseReg) ||
87 X86MCRegisterClasses[X86::GR32RegClassID].
contains(BaseReg)) &&
89 X86MCRegisterClasses[X86::GR64RegClassID].contains(IndexReg) ||
90 X86MCRegisterClasses[X86::GR32RegClassID].contains(IndexReg));
101 X86InsertPrefetch::X86InsertPrefetch(
const std::string &PrefetchHintsFilename)
107 bool X86InsertPrefetch::findPrefetchInfo(
const FunctionSamples *TopSamples,
109 Prefetches &Prefetches)
const {
110 assert(Prefetches.empty() &&
111 "Expected caller passed empty PrefetchInfo vector.");
112 static constexpr std::pair<StringLiteral, unsigned> HintTypes[] = {
113 {
"_nta_", X86::PREFETCHNTA},
114 {
"_t0_", X86::PREFETCHT0},
115 {
"_t1_", X86::PREFETCHT1},
116 {
"_t2_", X86::PREFETCHT2},
118 static const char *SerializedPrefetchPrefix =
"__prefetch";
123 int16_t max_index = -1;
126 for (
const auto &S_V : *
T) {
128 if (
Name.consume_front(SerializedPrefetchPrefix)) {
129 int64_t
D =
static_cast<int64_t
>(S_V.second);
131 for (
const auto &HintType : HintTypes) {
132 if (
Name.startswith(HintType.first)) {
133 Name =
Name.drop_front(HintType.first.size());
134 IID = HintType.second;
143 if (
index >= Prefetches.size())
144 Prefetches.resize(
index + 1);
145 Prefetches[
index] = {IID,
D};
146 max_index =
std::max(max_index,
static_cast<int16_t
>(
index));
149 assert(max_index + 1 >= 0 &&
150 "Possible overflow: max_index + 1 should be positive.");
151 assert(
static_cast<size_t>(max_index + 1) == Prefetches.size() &&
152 "The number of prefetch hints received should match the number of "
153 "PrefetchInfo objects returned");
154 return !Prefetches.empty();
157 bool X86InsertPrefetch::doInitialization(
Module &
M) {
158 if (Filename.empty())
163 SampleProfileReader::create(Filename, Ctx);
164 if (std::error_code EC = ReaderOrErr.
getError()) {
165 std::string
Msg =
"Could not open profile: " +
EC.message();
175 void X86InsertPrefetch::getAnalysisUsage(
AnalysisUsage &AU)
const {
177 MachineFunctionPass::getAnalysisUsage(AU);
187 bool Changed =
false;
191 for (
auto &
MBB : MF) {
202 if (!IsMemOpCompatibleWithPrefetch(*Current, MemOpOffset))
205 if (!findPrefetchInfo(Samples, *Current, Prefetches))
207 assert(!Prefetches.empty() &&
208 "The Prefetches vector should contain at least a value if "
209 "findPrefetchInfo returned true.");
210 for (
auto &PrefInfo : Prefetches) {
211 unsigned PFetchInstrID = PrefInfo.InstructionID;
212 int64_t Delta = PrefInfo.Delta;
215 MF.CreateMachineInstr(Desc, Current->getDebugLoc(),
true);
221 "Unexpected change in X86 operand offset order.");
231 .addImm(Current->getOperand(MemOpOffset +
X86::AddrDisp).getImm() +
236 if (!Current->memoperands_empty()) {
238 MIB.addMemOperand(MF.getMachineMemOperand(
This is an optimization pass for GlobalISel generic memory operations.
int getMemoryOperandNo(uint64_t TSFlags)
The function returns the MCInst operand # for the first field of the memory operand.
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
@ AddrSegmentReg
AddrSegmentReg - The operand # of the segment in the memory operand.
virtual const TargetInstrInfo * getInstrInfo() const
return AArch64::GPR64RegClass contains(Reg)
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
int64_t getOffset() const
For normal values, this is a byte offset added to the base address.
MachineFunctionPass - This class adapts the FunctionPass interface to allow convenient creation of pa...
A description of a memory reference used in the backend.
Expected< ExpressionValue > max(const ExpressionValue &Lhs, const ExpressionValue &Rhs)
TargetInstrInfo - Interface to description of machine instruction set.
Represent the analysis usage information of a pass.
std::error_code getError() const
const HexagonInstrInfo * TII
Describe properties that are true of each instruction in the target description file.
unsigned ID
LLVM IR allows to use arbitrary numbers as calling convention identifiers.
const TargetSubtargetInfo & getSubtarget() const
getSubtarget - Return the subtarget for which this machine code is being compiled.
unsigned getOperandBias(const MCInstrDesc &Desc)
Compute whether all of the def operands are repeated in the uses and therefore should be skipped.
Representation of each machine instruction.
static GCRegistry::Add< StatepointGC > D("statepoint-example", "an example strategy for statepoint")
Representation of the samples collected for a function.
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
This is an important class for using LLVM in a threaded context.
FunctionPass * createX86InsertPrefetchPass()
This pass applies profiling information to insert cache prefetches.
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
A Module instance is used to store all the information related to an LLVM module.
instr_iterator instr_begin()
static unsigned getOffset(const DILocation *DIL)
Returns the line offset to the start line of the subprogram.
instr_iterator instr_end()
Diagnostic information for the sample profiler.
StringRef - Represent a constant reference to a string, i.e.
StringMap< uint64_t > CallTargetMap
Wrapper class representing virtual and physical registers.
const CustomOperand< const MCSubtargetInfo & > Msg[]
void diagnose(const DiagnosticInfo &DI)
Report a message to the currently installed diagnostic handler.
Function & getFunction()
Return the LLVM function that this machine code represents.
void setPreservesAll()
Set by analyses that do not transform their input at all.
instr_iterator insert(instr_iterator I, MachineInstr *M)
Insert MI into the instruction list before I, possibly inside a bundle.
uint64_t getSize() const
Return the size in bytes of the memory reference.
static cl::opt< std::string > PrefetchHintsFile("prefetch-hints-file", cl::desc("Path to the prefetch hints profile. See also " "-x86-discriminate-memops"), cl::Hidden)
Represents either an error or a value T.
This class consists of common code factored out of the SmallVector class to reduce code duplication b...
FunctionPass class - This class is used to implement most global optimizations.
const FunctionSamples * findFunctionSamples(const DILocation *DIL, SampleProfileReaderItaniumRemapper *Remapper=nullptr) const
Get the FunctionSamples of the inline instance where DIL originates from.