blob: ec1d2f1f2ec83b223963f8397297e2ec7ecfc3fa [file] [log] [blame]
Andreas Bolka306b5b22009-06-24 21:29:13 +00001//===- LoopDependenceAnalysis.cpp - LDA Implementation ----------*- C++ -*-===//
2//
3// The LLVM Compiler Infrastructure
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9//
10// This is the (beginning) of an implementation of a loop dependence analysis
11// framework, which is used to detect dependences in memory accesses in loops.
12//
13// Please note that this is work in progress and the interface is subject to
14// change.
15//
16// TODO: adapt as implementation progresses.
17//
18//===----------------------------------------------------------------------===//
19
20#define DEBUG_TYPE "lda"
21#include "llvm/Analysis/LoopDependenceAnalysis.h"
22#include "llvm/Analysis/LoopPass.h"
23#include "llvm/Analysis/ScalarEvolution.h"
Andreas Bolkaf17ab7f2009-06-28 00:21:21 +000024#include "llvm/Instructions.h"
Andreas Bolka306b5b22009-06-24 21:29:13 +000025using namespace llvm;
26
27LoopPass *llvm::createLoopDependenceAnalysisPass() {
28 return new LoopDependenceAnalysis();
29}
30
31static RegisterPass<LoopDependenceAnalysis>
32R("lda", "Loop Dependence Analysis", false, true);
33char LoopDependenceAnalysis::ID = 0;
34
35//===----------------------------------------------------------------------===//
Andreas Bolkaf17ab7f2009-06-28 00:21:21 +000036// Utility Functions
37//===----------------------------------------------------------------------===//
38
Andreas Bolka88a17f02009-06-29 00:50:26 +000039static inline bool IsMemRefInstr(const Value *I) {
Andreas Bolkaf17ab7f2009-06-28 00:21:21 +000040 return isa<LoadInst>(I) || isa<StoreInst>(I);
41}
42
Andreas Bolka88a17f02009-06-29 00:50:26 +000043static void GetMemRefInstrs(
Andreas Bolka158c5902009-06-28 00:35:22 +000044 const Loop *L, SmallVectorImpl<Instruction*> &memrefs) {
45 for (Loop::block_iterator b = L->block_begin(), be = L->block_end();
46 b != be; ++b)
47 for (BasicBlock::iterator i = (*b)->begin(), ie = (*b)->end();
48 i != ie; ++i)
Andreas Bolka88a17f02009-06-29 00:50:26 +000049 if (IsMemRefInstr(i))
Andreas Bolka158c5902009-06-28 00:35:22 +000050 memrefs.push_back(i);
51}
52
Andreas Bolkaf17ab7f2009-06-28 00:21:21 +000053//===----------------------------------------------------------------------===//
54// Dependence Testing
55//===----------------------------------------------------------------------===//
56
57bool LoopDependenceAnalysis::isDependencePair(const Value *x,
58 const Value *y) const {
Andreas Bolka88a17f02009-06-29 00:50:26 +000059 return IsMemRefInstr(x) && IsMemRefInstr(y)
Andreas Bolkaf17ab7f2009-06-28 00:21:21 +000060 && (isa<StoreInst>(x) || isa<StoreInst>(y));
61}
62
63bool LoopDependenceAnalysis::depends(Value *src, Value *dst) {
64 assert(isDependencePair(src, dst) && "Values form no dependence pair!");
65 return true;
66}
67
68//===----------------------------------------------------------------------===//
Andreas Bolka306b5b22009-06-24 21:29:13 +000069// LoopDependenceAnalysis Implementation
70//===----------------------------------------------------------------------===//
71
72bool LoopDependenceAnalysis::runOnLoop(Loop *L, LPPassManager &) {
73 this->L = L;
74 SE = &getAnalysis<ScalarEvolution>();
75 return false;
76}
77
78void LoopDependenceAnalysis::getAnalysisUsage(AnalysisUsage &AU) const {
79 AU.setPreservesAll();
Andreas Bolkab88ee912009-06-28 00:16:08 +000080 AU.addRequiredTransitive<ScalarEvolution>();
81}
82
83static void PrintLoopInfo(
Andreas Bolka158c5902009-06-28 00:35:22 +000084 raw_ostream &OS, LoopDependenceAnalysis *LDA, const Loop *L) {
Andreas Bolkab88ee912009-06-28 00:16:08 +000085 if (!L->empty()) return; // ignore non-innermost loops
86
87 OS << "Loop at depth " << L->getLoopDepth() << ", header block: ";
88 WriteAsOperand(OS, L->getHeader(), false);
89 OS << "\n";
Andreas Bolka158c5902009-06-28 00:35:22 +000090
91 SmallVector<Instruction*, 8> memrefs;
92 getMemRefInstrs(L, memrefs);
93 OS << " Load/store instructions: " << memrefs.size() << "\n";
94 OS << " Pairwise dependence results:\n";
95 for (SmallVector<Instruction*, 8>::const_iterator x = memrefs.begin(),
96 end = memrefs.end(); x != end; ++x)
97 for (SmallVector<Instruction*, 8>::const_iterator y = x + 1;
98 y != end; ++y)
99 if (LDA->isDependencePair(*x, *y))
100 OS << "\t" << (x - memrefs.begin()) << "," << (y - memrefs.begin())
101 << ": " << (LDA->depends(*x, *y) ? "dependent" : "independent")
102 << "\n";
Andreas Bolkab88ee912009-06-28 00:16:08 +0000103}
104
105void LoopDependenceAnalysis::print(raw_ostream &OS, const Module*) const {
Andreas Bolka158c5902009-06-28 00:35:22 +0000106 // TODO: doc why const_cast is safe
107 PrintLoopInfo(OS, const_cast<LoopDependenceAnalysis*>(this), this->L);
Andreas Bolkab88ee912009-06-28 00:16:08 +0000108}
109
110void LoopDependenceAnalysis::print(std::ostream &OS, const Module *M) const {
111 raw_os_ostream os(OS);
112 print(os, M);
Andreas Bolka306b5b22009-06-24 21:29:13 +0000113}