25#define DEBUG_TYPE "x86-discriminate-memops"
29 cl::desc(
"Generate unique debug info for each instruction with a memory "
30 "operand. Should be enabled for profile-driven cache prefetching, "
31 "both in the build of the binary being profiled, as well as in "
32 "the build of the binary consuming the profile."),
36 "x86-bypass-prefetch-instructions",
cl::init(
true),
37 cl::desc(
"When discriminating instructions with memory operands, ignore "
38 "prefetch instructions. This ensures the other memory operand "
39 "instructions have the same identifiers after inserting "
40 "prefetches, allowing for successive insertions."),
45using Location = std::pair<StringRef, unsigned>;
48 return std::make_pair(Loc->getFilename(), Loc->getLine());
61 return "X86 Discriminate Memory Operands";
68 X86DiscriminateMemOps();
71bool IsPrefetchOpcode(
unsigned Opcode) {
72 return Opcode == X86::PREFETCHNTA || Opcode == X86::PREFETCHT0 ||
73 Opcode == X86::PREFETCHT1 || Opcode == X86::PREFETCHT2 ||
74 Opcode == X86::PREFETCHIT0 || Opcode == X86::PREFETCHIT1 ||
75 Opcode == X86::PREFETCHRST2;
83char X86DiscriminateMemOps::ID = 0;
93 if (!FDI || !FDI->getUnit()->getDebugInfoForProfiling())
99 DILocation::get(FDI->
getContext(), FDI->getLine(), 0, FDI);
100 assert(ReferenceDI &&
"ReferenceDI should not be nullptr");
102 MemOpDiscriminators[diToLocation(ReferenceDI)] = 0;
108 for (
auto &
MBB : MF) {
109 for (
auto &
MI :
MBB) {
110 const auto &DI =
MI.getDebugLoc();
116 MemOpDiscriminators[Loc] =
117 std::max(MemOpDiscriminators[Loc], DI->getBaseDiscriminator());
126 bool Changed =
false;
127 for (
auto &
MBB : MF) {
128 for (
auto &
MI :
MBB) {
140 const std::pair<DenseSet<unsigned>::iterator,
bool> TryInsert =
142 if (!TryInsert.second || !HasDebug) {
143 unsigned BF,
DF, CI = 0;
145 std::optional<unsigned> EncodedDiscriminator =
148 if (!EncodedDiscriminator) {
154 "for instruction with memory operand in: "
155 << DI->getFilename() <<
" Line: " << DI->getLine()
156 <<
" Column: " << DI->getColumn()
157 <<
". This is likely due to a large macro expansion. \n");
161 ++MemOpDiscriminators[
L];
163 assert(DI &&
"DI should not be nullptr");
164 updateDebugInfo(&
MI, DI);
166 std::pair<DenseSet<unsigned>::iterator,
bool> MustInsert =
169 assert(MustInsert.second &&
"New discriminator shouldn't be present in set");
183 return new X86DiscriminateMemOps();
MachineBasicBlock MachineBasicBlock::iterator DebugLoc DL
static RegisterPass< DebugifyFunctionPass > DF("debugify-function", "Attach debug info to a function")
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
static cl::opt< bool > EnableDiscriminateMemops(DEBUG_TYPE, cl::init(false), cl::desc("Generate unique debug info for each instruction with a memory " "operand. Should be enabled for profile-driven cache prefetching, " "both in the build of the binary being profiled, as well as in " "the build of the binary consuming the profile."), cl::Hidden)
static cl::opt< bool > BypassPrefetchInstructions("x86-bypass-prefetch-instructions", cl::init(true), cl::desc("When discriminating instructions with memory operands, ignore " "prefetch instructions. This ensures the other memory operand " "instructions have the same identifiers after inserting " "prefetches, allowing for successive insertions."), cl::Hidden)
static std::optional< unsigned > encodeDiscriminator(unsigned BD, unsigned DF, unsigned CI)
Raw encoding of the discriminator.
static void decodeDiscriminator(unsigned D, unsigned &BD, unsigned &DF, unsigned &CI)
Raw decoder for values in an encoded discriminator D.
unsigned getBaseDiscriminator() const
Returns the base discriminator stored in the discriminator.
const DILocation * cloneWithDiscriminator(unsigned Discriminator) const
Returns a new DILocation with updated Discriminator.
Implements a dense probed hash-table based set.
FunctionPass class - This class is used to implement most global optimizations.
DISubprogram * getSubprogram() const
Get the attached subprogram.
LLVMContext & getContext() const
MachineFunctionPass - This class adapts the FunctionPass interface to allow convenient creation of pa...
virtual bool runOnMachineFunction(MachineFunction &MF)=0
runOnMachineFunction - This method must be overloaded to perform the desired machine code transformat...
Function & getFunction()
Return the LLVM function that this machine code represents.
Representation of each machine instruction.
virtual StringRef getPassName() const
getPassName - Return a nice clean name for a pass.
StringRef - Represent a constant reference to a string, i.e.
unsigned ID
LLVM IR allows to use arbitrary numbers as calling convention identifiers.
int getMemoryOperandNo(uint64_t TSFlags)
initializer< Ty > init(const Ty &Val)
This is an optimization pass for GlobalISel generic memory operations.
raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
FunctionPass * createX86DiscriminateMemOpsPass()
This pass ensures instructions featuring a memory operand have distinctive <LineNumber,...