LLVM  16.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/InitializePasses.h"
21 
22 using namespace llvm;
23 
24 namespace {
25  struct MemDepPrinter : public FunctionPass {
26  const Function *F;
27 
28  enum DepType {
29  Clobber = 0,
30  Def,
31  NonFuncLocal,
32  Unknown
33  };
34 
35  static const char *const DepTypeStr[];
36 
38  typedef std::pair<InstTypePair, const BasicBlock *> Dep;
39  typedef SmallSetVector<Dep, 4> DepSet;
40  typedef DenseMap<const Instruction *, DepSet> DepSetMap;
41  DepSetMap Deps;
42 
43  static char ID; // Pass identifcation, replacement for typeid
44  MemDepPrinter() : FunctionPass(ID) {
46  }
47 
48  bool runOnFunction(Function &F) override;
49 
50  void print(raw_ostream &OS, const Module * = nullptr) const override;
51 
52  void getAnalysisUsage(AnalysisUsage &AU) const override {
55  AU.setPreservesAll();
56  }
57 
58  void releaseMemory() override {
59  Deps.clear();
60  F = nullptr;
61  }
62 
63  private:
64  static InstTypePair getInstTypePair(MemDepResult dep) {
65  if (dep.isClobber())
66  return InstTypePair(dep.getInst(), Clobber);
67  if (dep.isDef())
68  return InstTypePair(dep.getInst(), Def);
69  if (dep.isNonFuncLocal())
70  return InstTypePair(dep.getInst(), NonFuncLocal);
71  assert(dep.isUnknown() && "unexpected dependence type");
72  return InstTypePair(dep.getInst(), Unknown);
73  }
74  };
75 }
76 
77 char MemDepPrinter::ID = 0;
78 INITIALIZE_PASS_BEGIN(MemDepPrinter, "print-memdeps",
79  "Print MemDeps of function", false, true)
82  "Print MemDeps of function", false, true)
83 
85  return new MemDepPrinter();
86 }
87 
88 const char *const MemDepPrinter::DepTypeStr[]
89  = {"Clobber", "Def", "NonFuncLocal", "Unknown"};
90 
92  this->F = &F;
93  MemoryDependenceResults &MDA = getAnalysis<MemoryDependenceWrapperPass>().getMemDep();
94 
95  // All this code uses non-const interfaces because MemDep is not
96  // const-friendly, though nothing is actually modified.
97  for (auto &I : instructions(F)) {
98  Instruction *Inst = &I;
99 
100  if (!Inst->mayReadFromMemory() && !Inst->mayWriteToMemory())
101  continue;
102 
103  MemDepResult Res = MDA.getDependency(Inst);
104  if (!Res.isNonLocal()) {
105  Deps[Inst].insert(std::make_pair(getInstTypePair(Res),
106  static_cast<BasicBlock *>(nullptr)));
107  } else if (auto *Call = dyn_cast<CallBase>(Inst)) {
109  MDA.getNonLocalCallDependency(Call);
110 
111  DepSet &InstDeps = Deps[Inst];
112  for (const NonLocalDepEntry &I : NLDI) {
113  const MemDepResult &Res = I.getResult();
114  InstDeps.insert(std::make_pair(getInstTypePair(Res), I.getBB()));
115  }
116  } else {
118  assert( (isa<LoadInst>(Inst) || isa<StoreInst>(Inst) ||
119  isa<VAArgInst>(Inst)) && "Unknown memory instruction!");
120  MDA.getNonLocalPointerDependency(Inst, NLDI);
121 
122  DepSet &InstDeps = Deps[Inst];
123  for (const NonLocalDepResult &I : NLDI) {
124  const MemDepResult &Res = I.getResult();
125  InstDeps.insert(std::make_pair(getInstTypePair(Res), I.getBB()));
126  }
127  }
128  }
129 
130  return false;
131 }
132 
133 void MemDepPrinter::print(raw_ostream &OS, const Module *M) const {
134  for (const auto &I : instructions(*F)) {
135  const Instruction *Inst = &I;
136 
137  DepSetMap::const_iterator DI = Deps.find(Inst);
138  if (DI == Deps.end())
139  continue;
140 
141  const DepSet &InstDeps = DI->second;
142 
143  for (const auto &I : InstDeps) {
144  const Instruction *DepInst = I.first.getPointer();
145  DepType type = I.first.getInt();
146  const BasicBlock *DepBB = I.second;
147 
148  OS << " ";
149  OS << DepTypeStr[type];
150  if (DepBB) {
151  OS << " in block ";
152  DepBB->printAsOperand(OS, /*PrintType=*/false, M);
153  }
154  if (DepInst) {
155  OS << " from: ";
156  DepInst->print(OS);
157  }
158  OS << "\n";
159  }
160 
161  Inst->print(OS);
162  OS << "\n\n";
163  }
164 }
llvm
This is an optimization pass for GlobalISel generic memory operations.
Definition: AddressRanges.h:18
llvm::tgtok::Def
@ Def
Definition: TGLexer.h:50
llvm::NonLocalDepEntry
This is an entry in the NonLocalDepInfo cache.
Definition: MemoryDependenceAnalysis.h:199
llvm::AArch64PACKey::ID
ID
Definition: AArch64BaseInfo.h:818
print
static void print(raw_ostream &Out, object::Archive::Kind Kind, T Val)
Definition: ArchiveWriter.cpp:189
InstIterator.h
llvm::Function
Definition: Function.h:60
llvm::SmallVector
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
Definition: SmallVector.h:1199
ErrorHandling.h
true
basic Basic Alias true
Definition: BasicAliasAnalysis.cpp:1793
llvm::Instruction::mayWriteToMemory
bool mayWriteToMemory() const LLVM_READONLY
Return true if this instruction may modify memory.
Definition: Instruction.cpp:626
llvm::MemDepResult
A memory dependence query can return one of three different answers.
Definition: MemoryDependenceAnalysis.h:38
memdeps
print memdeps
Definition: MemDepPrinter.cpp:81
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:55
llvm::BasicBlock
LLVM Basic Block Representation.
Definition: BasicBlock.h:55
AliasAnalysis.h
llvm::Instruction::mayReadFromMemory
bool mayReadFromMemory() const LLVM_READONLY
Return true if this instruction may read memory.
Definition: Instruction.cpp:606
llvm::PassRegistry::getPassRegistry
static PassRegistry * getPassRegistry()
getPassRegistry - Access the global registry object, which is automatically initialized at applicatio...
Definition: PassRegistry.cpp:24
llvm::AnalysisUsage
Represent the analysis usage information of a pass.
Definition: PassAnalysisSupport.h:47
false
Definition: StackSlotColoring.cpp:141
llvm::Instruction
Definition: Instruction.h:42
llvm::raw_ostream
This class implements an extremely fast bulk output stream that can only output to a stream.
Definition: raw_ostream.h:52
llvm::NonLocalDepResult
This is a result from a NonLocal dependence query.
Definition: MemoryDependenceAnalysis.h:224
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:154
llvm::CallingConv::ID
unsigned ID
LLVM IR allows to use arbitrary numbers as calling convention identifiers.
Definition: CallingConv.h:24
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:166
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:396
INITIALIZE_PASS_DEPENDENCY
INITIALIZE_PASS_DEPENDENCY(DominatorTreeWrapperPass)
llvm::DenseMap
Definition: DenseMap.h:714
I
#define I(x, y, z)
Definition: MD5.cpp:58
llvm::MemDepResult::isClobber
bool isClobber() const
Tests if this MemDepResult represents a query that is an instruction clobber dependency.
Definition: MemoryDependenceAnalysis.h:140
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:709
llvm::Value::print
void print(raw_ostream &O, bool IsForDebug=false) const
Implement operator<< on Value.
Definition: AsmWriter.cpp:4676
assert
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
function
print Print MemDeps of function
Definition: MemDepPrinter.cpp:82
llvm::Module
A Module instance is used to store all the information related to an LLVM module.
Definition: Module.h:65
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:4759
llvm::print
Printable print(const GCNRegPressure &RP, const GCNSubtarget *ST=nullptr)
Definition: GCNRegPressure.cpp:138
llvm::MemoryDependenceResults::getDependency
MemDepResult getDependency(Instruction *QueryInst)
Returns the instruction on which a memory operation depends.
Definition: MemoryDependenceAnalysis.cpp:638
llvm::rdf::Print
Print(const T &, const DataFlowGraph &) -> Print< T >
llvm::initializeMemDepPrinterPass
void initializeMemDepPrinterPass(PassRegistry &)
runOnFunction
static bool runOnFunction(Function &F, bool PostInlining)
Definition: EntryExitInstrumenter.cpp:85
llvm::MemoryDependenceResults
Provides a lazy, caching interface for making common memory aliasing information queries,...
Definition: MemoryDependenceAnalysis.h:265
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:526
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:833
Instructions.h
llvm::PointerIntPair
PointerIntPair - This class implements a pair of a pointer and small integer.
Definition: PointerIntPair.h:46
llvm::MemoryDependenceResults::NonLocalDepInfo
std::vector< NonLocalDepEntry > NonLocalDepInfo
Definition: MemoryDependenceAnalysis.h:271
llvm::AAResultsWrapperPass
A wrapper pass to provide the legacy pass manager access to a suitably prepared AAResults object.
Definition: AliasAnalysis.h:924
llvm::createMemDepPrinter
FunctionPass * createMemDepPrinter()
Definition: MemDepPrinter.cpp:84
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:308
llvm::MemDepResult::isUnknown
bool isUnknown() const
Tests if this MemDepResult represents a query which cannot and/or will not be computed.
Definition: MemoryDependenceAnalysis.h:160
raw_ostream.h
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:148
SetVector.h
of
Add support for conditional and other related patterns Instead of
Definition: README.txt:134
Passes.h
llvm::MemDepResult::isDef
bool isDef() const
Tests if this MemDepResult represents a query that is an instruction definition dependency.
Definition: MemoryDependenceAnalysis.h:144