//
//===----------------------------------------------------------------------===//
-#include "llvm/Analysis/MemoryDependenceAnalysis.h"
#include "llvm/Analysis/Passes.h"
-#include "llvm/Assembly/Writer.h"
-#include "llvm/Support/CallSite.h"
-#include "llvm/Support/InstIterator.h"
+#include "llvm/ADT/SetVector.h"
+#include "llvm/Analysis/MemoryDependenceAnalysis.h"
+#include "llvm/IR/CallSite.h"
+#include "llvm/IR/InstIterator.h"
+#include "llvm/IR/LLVMContext.h"
#include "llvm/Support/ErrorHandling.h"
#include "llvm/Support/raw_ostream.h"
-#include "llvm/ADT/SetVector.h"
using namespace llvm;
namespace {
struct MemDepPrinter : public FunctionPass {
const Function *F;
- typedef PointerIntPair<const Instruction *, 1> InstAndClobberFlag;
- typedef std::pair<InstAndClobberFlag, const BasicBlock *> Dep;
+ enum DepType {
+ Clobber = 0,
+ Def,
+ NonFuncLocal,
+ Unknown
+ };
+
+ static const char *const DepTypeStr[];
+
+ typedef PointerIntPair<const Instruction *, 2, DepType> InstTypePair;
+ typedef std::pair<InstTypePair, const BasicBlock *> Dep;
typedef SmallSetVector<Dep, 4> DepSet;
typedef DenseMap<const Instruction *, DepSet> DepSetMap;
DepSetMap Deps;
initializeMemDepPrinterPass(*PassRegistry::getPassRegistry());
}
- virtual bool runOnFunction(Function &F);
+ bool runOnFunction(Function &F) override;
- void print(raw_ostream &OS, const Module * = 0) const;
+ void print(raw_ostream &OS, const Module * = nullptr) const override;
- virtual void getAnalysisUsage(AnalysisUsage &AU) const {
- AU.addRequired<MemoryDependenceAnalysis>();
+ void getAnalysisUsage(AnalysisUsage &AU) const override {
+ AU.addRequiredTransitive<AliasAnalysis>();
+ AU.addRequiredTransitive<MemoryDependenceAnalysis>();
AU.setPreservesAll();
}
- virtual void releaseMemory() {
+ void releaseMemory() override {
Deps.clear();
- F = 0;
+ F = nullptr;
+ }
+
+ private:
+ static InstTypePair getInstTypePair(MemDepResult dep) {
+ if (dep.isClobber())
+ return InstTypePair(dep.getInst(), Clobber);
+ if (dep.isDef())
+ return InstTypePair(dep.getInst(), Def);
+ if (dep.isNonFuncLocal())
+ return InstTypePair(dep.getInst(), NonFuncLocal);
+ assert(dep.isUnknown() && "unexpected dependence type");
+ return InstTypePair(dep.getInst(), Unknown);
+ }
+ static InstTypePair getInstTypePair(const Instruction* inst, DepType type) {
+ return InstTypePair(inst, type);
}
};
}
return new MemDepPrinter();
}
+const char *const MemDepPrinter::DepTypeStr[]
+ = {"Clobber", "Def", "NonFuncLocal", "Unknown"};
+
bool MemDepPrinter::runOnFunction(Function &F) {
this->F = &F;
MemoryDependenceAnalysis &MDA = getAnalysis<MemoryDependenceAnalysis>();
// All this code uses non-const interfaces because MemDep is not
// const-friendly, though nothing is actually modified.
- for (inst_iterator I = inst_begin(F), E = inst_end(F); I != E; ++I) {
- Instruction *Inst = &*I;
+ for (auto &I: inst_range(F)) {
+ Instruction *Inst = &I;
if (!Inst->mayReadFromMemory() && !Inst->mayWriteToMemory())
continue;
MemDepResult Res = MDA.getDependency(Inst);
if (!Res.isNonLocal()) {
- assert(Res.isClobber() != Res.isDef() &&
- "Local dep should be def or clobber!");
- Deps[Inst].insert(std::make_pair(InstAndClobberFlag(Res.getInst(),
- Res.isClobber()),
- static_cast<BasicBlock *>(0)));
+ Deps[Inst].insert(std::make_pair(getInstTypePair(Res),
+ static_cast<BasicBlock *>(nullptr)));
} else if (CallSite CS = cast<Value>(Inst)) {
const MemoryDependenceAnalysis::NonLocalDepInfo &NLDI =
MDA.getNonLocalCallDependency(CS);
for (MemoryDependenceAnalysis::NonLocalDepInfo::const_iterator
I = NLDI.begin(), E = NLDI.end(); I != E; ++I) {
const MemDepResult &Res = I->getResult();
- assert(Res.isClobber() != Res.isDef() &&
- "Resolved non-local call dep should be def or clobber!");
- InstDeps.insert(std::make_pair(InstAndClobberFlag(Res.getInst(),
- Res.isClobber()),
- I->getBB()));
+ InstDeps.insert(std::make_pair(getInstTypePair(Res), I->getBB()));
}
} else {
SmallVector<NonLocalDepResult, 4> NLDI;
- if (LoadInst *LI = dyn_cast<LoadInst>(Inst)) {
- // FIXME: Volatile is not handled properly here.
- MDA.getNonLocalPointerDependency(LI->getPointerOperand(), !LI->isVolatile(),
- LI->getParent(), NLDI);
- } else if (StoreInst *SI = dyn_cast<StoreInst>(Inst)) {
- // FIXME: Volatile is not handled properly here.
- MDA.getNonLocalPointerDependency(SI->getPointerOperand(), false,
- SI->getParent(), NLDI);
- } else if (VAArgInst *VI = dyn_cast<VAArgInst>(Inst)) {
- MDA.getNonLocalPointerDependency(VI->getPointerOperand(), false,
- VI->getParent(), NLDI);
- } else {
- llvm_unreachable("Unknown memory instruction!");
- }
+ assert( (isa<LoadInst>(Inst) || isa<StoreInst>(Inst) ||
+ isa<VAArgInst>(Inst)) && "Unknown memory instruction!");
+ MDA.getNonLocalPointerDependency(Inst, NLDI);
DepSet &InstDeps = Deps[Inst];
for (SmallVectorImpl<NonLocalDepResult>::const_iterator
I = NLDI.begin(), E = NLDI.end(); I != E; ++I) {
const MemDepResult &Res = I->getResult();
- assert(Res.isClobber() != Res.isDef() &&
- "Resolved non-local pointer dep should be def or clobber!");
- InstDeps.insert(std::make_pair(InstAndClobberFlag(Res.getInst(),
- Res.isClobber()),
- I->getBB()));
+ InstDeps.insert(std::make_pair(getInstTypePair(Res), I->getBB()));
}
}
}
}
void MemDepPrinter::print(raw_ostream &OS, const Module *M) const {
- for (const_inst_iterator I = inst_begin(*F), E = inst_end(*F); I != E; ++I) {
- const Instruction *Inst = &*I;
+ for (auto &I: inst_range(*F)) {
+ const Instruction *Inst = &I;
DepSetMap::const_iterator DI = Deps.find(Inst);
if (DI == Deps.end())
const DepSet &InstDeps = DI->second;
- for (DepSet::const_iterator I = InstDeps.begin(), E = InstDeps.end();
- I != E; ++I) {
- const Instruction *DepInst = I->first.getPointer();
- bool isClobber = I->first.getInt();
- const BasicBlock *DepBB = I->second;
+ for (auto &I: InstDeps) {
+ const Instruction *DepInst = I.first.getPointer();
+ DepType type = I.first.getInt();
+ const BasicBlock *DepBB = I.second;
- OS << " " << (isClobber ? "Clobber" : " Def");
+ OS << " ";
+ OS << DepTypeStr[type];
if (DepBB) {
OS << " in block ";
- WriteAsOperand(OS, DepBB, /*PrintType=*/false, M);
+ DepBB->printAsOperand(OS, /*PrintType=*/false, M);
}
- OS << " from: ";
- if (DepInst == Inst)
- OS << "<unspecified>";
- else
+ if (DepInst) {
+ OS << " from: ";
DepInst->print(OS);
+ }
OS << "\n";
}