LLVM  14.0.0git
MemDepPrinter.cpp
Go to the documentation of this file.
1 //===- MemDepPrinter.cpp - Printer for MemoryDependenceAnalysis -----------===//
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 //
10 //===----------------------------------------------------------------------===//
11 
12 #include "llvm/ADT/SetVector.h"
15 #include "llvm/Analysis/Passes.h"
16 #include "llvm/IR/InstIterator.h"
17 #include "llvm/IR/Instructions.h"
18 #include "llvm/IR/LLVMContext.h"
19 #include "llvm/InitializePasses.h"
22 
23 using namespace llvm;
24 
25 namespace {
26  struct MemDepPrinter : public FunctionPass {
27  const Function *F;
28 
29  enum DepType {
30  Clobber = 0,
31  Def,
32  NonFuncLocal,
33  Unknown
34  };
35 
36  static const char *const DepTypeStr[];
37 
39  typedef std::pair<InstTypePair, const BasicBlock *> Dep;
40  typedef SmallSetVector<Dep, 4> DepSet;
41  typedef DenseMap<const Instruction *, DepSet> DepSetMap;
42  DepSetMap Deps;
43 
44  static char ID; // Pass identifcation, replacement for typeid
45  MemDepPrinter() : FunctionPass(ID) {
47  }
48 
49  bool runOnFunction(Function &F) override;
50 
51  void print(raw_ostream &OS, const Module * = nullptr) const override;
52 
53  void getAnalysisUsage(AnalysisUsage &AU) const override {
56  AU.setPreservesAll();
57  }
58 
59  void releaseMemory() override {
60  Deps.clear();
61  F = nullptr;
62  }
63 
64  private:
65  static InstTypePair getInstTypePair(MemDepResult dep) {
66  if (dep.isClobber())
67  return InstTypePair(dep.getInst(), Clobber);
68  if (dep.isDef())
69  return InstTypePair(dep.getInst(), Def);
70  if (dep.isNonFuncLocal())
71  return InstTypePair(dep.getInst(), NonFuncLocal);
72  assert(dep.isUnknown() && "unexpected dependence type");
73  return InstTypePair(dep.getInst(), Unknown);
74  }
75  };
76 }
77 
78 char MemDepPrinter::ID = 0;
79 INITIALIZE_PASS_BEGIN(MemDepPrinter, "print-memdeps",
80  "Print MemDeps of function", false, true)
83  "Print MemDeps of function", false, true)
84 
86  return new MemDepPrinter();
87 }
88 
89 const char *const MemDepPrinter::DepTypeStr[]
90  = {"Clobber", "Def", "NonFuncLocal", "Unknown"};
91 
93  this->F = &F;
94  MemoryDependenceResults &MDA = getAnalysis<MemoryDependenceWrapperPass>().getMemDep();
95 
96  // All this code uses non-const interfaces because MemDep is not
97  // const-friendly, though nothing is actually modified.
98  for (auto &I : instructions(F)) {
99  Instruction *Inst = &I;
100 
101  if (!Inst->mayReadFromMemory() && !Inst->mayWriteToMemory())
102  continue;
103 
104  MemDepResult Res = MDA.getDependency(Inst);
105  if (!Res.isNonLocal()) {
106  Deps[Inst].insert(std::make_pair(getInstTypePair(Res),
107  static_cast<BasicBlock *>(nullptr)));
108  } else if (auto *Call = dyn_cast<CallBase>(Inst)) {
110  MDA.getNonLocalCallDependency(Call);
111 
112  DepSet &InstDeps = Deps[Inst];
113  for (const NonLocalDepEntry &I : NLDI) {
114  const MemDepResult &Res = I.getResult();
115  InstDeps.insert(std::make_pair(getInstTypePair(Res), I.getBB()));
116  }
117  } else {
119  assert( (isa<LoadInst>(Inst) || isa<StoreInst>(Inst) ||
120  isa<VAArgInst>(Inst)) && "Unknown memory instruction!");
121  MDA.getNonLocalPointerDependency(Inst, NLDI);
122 
123  DepSet &InstDeps = Deps[Inst];
124  for (const NonLocalDepResult &I : NLDI) {
125  const MemDepResult &Res = I.getResult();
126  InstDeps.insert(std::make_pair(getInstTypePair(Res), I.getBB()));
127  }
128  }
129  }
130 
131  return false;
132 }
133 
134 void MemDepPrinter::print(raw_ostream &OS, const Module *M) const {
135  for (const auto &I : instructions(*F)) {
136  const Instruction *Inst = &I;
137 
138  DepSetMap::const_iterator DI = Deps.find(Inst);
139  if (DI == Deps.end())
140  continue;
141 
142  const DepSet &InstDeps = DI->second;
143 
144  for (const auto &I : InstDeps) {
145  const Instruction *DepInst = I.first.getPointer();
146  DepType type = I.first.getInt();
147  const BasicBlock *DepBB = I.second;
148 
149  OS << " ";
150  OS << DepTypeStr[type];
151  if (DepBB) {
152  OS << " in block ";
153  DepBB->printAsOperand(OS, /*PrintType=*/false, M);
154  }
155  if (DepInst) {
156  OS << " from: ";
157  DepInst->print(OS);
158  }
159  OS << "\n";
160  }
161 
162  Inst->print(OS);
163  OS << "\n\n";
164  }
165 }
llvm
---------------------— PointerInfo ------------------------------------—
Definition: AllocatorList.h:23
llvm::tgtok::Def
@ Def
Definition: TGLexer.h:50
llvm::NonLocalDepEntry
This is an entry in the NonLocalDepInfo cache.
Definition: MemoryDependenceAnalysis.h:198
type
print
static void print(raw_ostream &Out, object::Archive::Kind Kind, T Val)
Definition: ArchiveWriter.cpp:147
InstIterator.h
llvm::Function
Definition: Function.h:61
llvm::SmallVector
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
Definition: SmallVector.h:1168
ErrorHandling.h
llvm::MemDepResult
A memory dependence query can return one of three different answers.
Definition: MemoryDependenceAnalysis.h:37
memdeps
print memdeps
Definition: MemDepPrinter.cpp:82
INITIALIZE_PASS_BEGIN
INITIALIZE_PASS_BEGIN(MemDepPrinter, "print-memdeps", "Print MemDeps of function", false, true) INITIALIZE_PASS_END(MemDepPrinter
MemoryDependenceAnalysis.h
F
#define F(x, y, z)
Definition: MD5.cpp:56
llvm::BasicBlock
LLVM Basic Block Representation.
Definition: BasicBlock.h:58
AliasAnalysis.h
llvm::PassRegistry::getPassRegistry
static PassRegistry * getPassRegistry()
getPassRegistry - Access the global registry object, which is automatically initialized at applicatio...
Definition: PassRegistry.cpp:31
llvm::AnalysisUsage
Represent the analysis usage information of a pass.
Definition: PassAnalysisSupport.h:47
false
Definition: StackSlotColoring.cpp:142
llvm::Instruction
Definition: Instruction.h:45
llvm::raw_ostream
This class implements an extremely fast bulk output stream that can only output to a stream.
Definition: raw_ostream.h:53
llvm::NonLocalDepResult
This is a result from a NonLocal dependence query.
Definition: MemoryDependenceAnalysis.h:223
llvm::Instruction::mayWriteToMemory
bool mayWriteToMemory() const
Return true if this instruction may modify memory.
Definition: Instruction.cpp:584
llvm::MemDepResult::isNonFuncLocal
bool isNonFuncLocal() const
Tests if this MemDepResult represents a query that is transparent to the start of the function.
Definition: MemoryDependenceAnalysis.h:153
INITIALIZE_PASS_END
#define INITIALIZE_PASS_END(passName, arg, name, cfg, analysis)
Definition: PassSupport.h:58
llvm::MemDepResult::getInst
Instruction * getInst() const
If this is a normal dependency, returns the instruction that is depended on.
Definition: MemoryDependenceAnalysis.h:165
llvm::instructions
inst_range instructions(Function *F)
Definition: InstIterator.h:133
type
AMD64 Optimization Manual has some nice information about optimizing integer multiplication by a constant How much of it applies to Intel s X86 implementation There are definite trade offs to xmm0 cvttss2siq rdx jb L3 subss xmm0 rax cvttss2siq rdx xorq rdx rax ret instead of xmm1 cvttss2siq rcx movaps xmm2 subss xmm2 cvttss2siq rax rdx xorq rax ucomiss xmm0 cmovb rax ret Seems like the jb branch has high likelihood of being taken It would have saved a few instructions It s not possible to reference and DH registers in an instruction requiring REX prefix divb and mulb both produce results in AH If isel emits a CopyFromReg which gets turned into a movb and that can be allocated a r8b r15b To get around isel emits a CopyFromReg from AX and then right shift it down by and truncate it It s not pretty but it works We need some register allocation magic to make the hack go which would often require a callee saved register Callees usually need to keep this value live for most of their body so it doesn t add a significant burden on them We currently implement this in however this is suboptimal because it means that it would be quite awkward to implement the optimization for callers A better implementation would be to relax the LLVM IR rules for sret arguments to allow a function with an sret argument to have a non void return type
Definition: README-X86-64.txt:70
llvm::pdb::Unknown
@ Unknown
Definition: PDBTypes.h:395
INITIALIZE_PASS_DEPENDENCY
INITIALIZE_PASS_DEPENDENCY(DominatorTreeWrapperPass)
llvm::DenseMap
Definition: DenseMap.h:714
I
#define I(x, y, z)
Definition: MD5.cpp:59
llvm::MemDepResult::isClobber
bool isClobber() const
Tests if this MemDepResult represents a query that is an instruction clobber dependency.
Definition: MemoryDependenceAnalysis.h:139
llvm::MemoryDependenceResults::getNonLocalCallDependency
const NonLocalDepInfo & getNonLocalCallDependency(CallBase *QueryCall)
Perform a full dependency query for the specified call, returning the set of blocks that the value is...
Definition: MemoryDependenceAnalysis.cpp:716
llvm::Value::print
void print(raw_ostream &O, bool IsForDebug=false) const
Implement operator<< on Value.
Definition: AsmWriter.cpp:4588
assert
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
function
print Print MemDeps of function
Definition: MemDepPrinter.cpp:83
llvm::Module
A Module instance is used to store all the information related to an LLVM module.
Definition: Module.h:67
llvm::Value::printAsOperand
void printAsOperand(raw_ostream &O, bool PrintType=true, const Module *M=nullptr) const
Print the name of this Value out to the specified raw_ostream.
Definition: AsmWriter.cpp:4665
llvm::MemoryDependenceResults::getDependency
MemDepResult getDependency(Instruction *QueryInst)
Returns the instruction on which a memory operation depends.
Definition: MemoryDependenceAnalysis.cpp:645
llvm::Instruction::mayReadFromMemory
bool mayReadFromMemory() const
Return true if this instruction may read memory.
Definition: Instruction.cpp:564
llvm::initializeMemDepPrinterPass
void initializeMemDepPrinterPass(PassRegistry &)
runOnFunction
static bool runOnFunction(Function &F, bool PostInlining)
Definition: EntryExitInstrumenter.cpp:69
llvm::MemoryDependenceResults
Provides a lazy, caching interface for making common memory aliasing information queries,...
Definition: MemoryDependenceAnalysis.h:264
llvm::AnalysisUsage::setPreservesAll
void setPreservesAll()
Set by analyses that do not transform their input at all.
Definition: PassAnalysisSupport.h:130
llvm::MemoryDependenceWrapperPass
A wrapper analysis pass for the legacy pass manager that exposes a MemoryDepnedenceResults instance.
Definition: MemoryDependenceAnalysis.h:525
llvm::MemoryDependenceResults::getNonLocalPointerDependency
void getNonLocalPointerDependency(Instruction *QueryInst, SmallVectorImpl< NonLocalDepResult > &Result)
Perform a full dependency query for an access to the QueryInst's specified memory location,...
Definition: MemoryDependenceAnalysis.cpp:842
Instructions.h
llvm::PointerIntPair
PointerIntPair - This class implements a pair of a pointer and small integer.
Definition: PointerIntPair.h:45
llvm::MemoryDependenceResults::NonLocalDepInfo
std::vector< NonLocalDepEntry > NonLocalDepInfo
Definition: MemoryDependenceAnalysis.h:270
llvm::AAResultsWrapperPass
A wrapper pass to provide the legacy pass manager access to a suitably prepared AAResults object.
Definition: AliasAnalysis.h:1336
llvm::createMemDepPrinter
FunctionPass * createMemDepPrinter()
Definition: MemDepPrinter.cpp:85
llvm::AnalysisUsage::addRequiredTransitive
AnalysisUsage & addRequiredTransitive()
Definition: PassAnalysisSupport.h:81
llvm::SmallSetVector
A SetVector that performs no allocations if smaller than a certain size.
Definition: SetVector.h:307
llvm::FunctionPass
FunctionPass class - This class is used to implement most global optimizations.
Definition: Pass.h:298
LLVMContext.h
llvm::MemDepResult::isUnknown
bool isUnknown() const
Tests if this MemDepResult represents a query which cannot and/or will not be computed.
Definition: MemoryDependenceAnalysis.h:159
raw_ostream.h
true
basic Basic Alias true
Definition: BasicAliasAnalysis.cpp:1853
InitializePasses.h
llvm::MemDepResult::isNonLocal
bool isNonLocal() const
Tests if this MemDepResult represents a query that is transparent to the start of the block,...
Definition: MemoryDependenceAnalysis.h:147
SetVector.h
of
Add support for conditional and other related patterns Instead of
Definition: README.txt:134
Passes.h
llvm::Intrinsic::ID
unsigned ID
Definition: TargetTransformInfo.h:37
llvm::MemDepResult::isDef
bool isDef() const
Tests if this MemDepResult represents a query that is an instruction definition dependency.
Definition: MemoryDependenceAnalysis.h:143