blob: 020a8c77ccc221802b24d5ecc2a0623df1c2a462 [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 Bolkafc8a04a2009-06-29 18:51:11 +000039static inline bool IsMemRefInstr(const Value *V) {
40 const Instruction *I = dyn_cast<const Instruction>(V);
41 return I && (I->mayReadFromMemory() || I->mayWriteToMemory());
Andreas Bolkaf17ab7f2009-06-28 00:21:21 +000042}
43
Andreas Bolka88a17f02009-06-29 00:50:26 +000044static void GetMemRefInstrs(
Andreas Bolka158c5902009-06-28 00:35:22 +000045 const Loop *L, SmallVectorImpl<Instruction*> &memrefs) {
46 for (Loop::block_iterator b = L->block_begin(), be = L->block_end();
47 b != be; ++b)
48 for (BasicBlock::iterator i = (*b)->begin(), ie = (*b)->end();
49 i != ie; ++i)
Andreas Bolka88a17f02009-06-29 00:50:26 +000050 if (IsMemRefInstr(i))
Andreas Bolka158c5902009-06-28 00:35:22 +000051 memrefs.push_back(i);
52}
53
Andreas Bolkaf17ab7f2009-06-28 00:21:21 +000054//===----------------------------------------------------------------------===//
55// Dependence Testing
56//===----------------------------------------------------------------------===//
57
58bool LoopDependenceAnalysis::isDependencePair(const Value *x,
59 const Value *y) const {
Andreas Bolkafc8a04a2009-06-29 18:51:11 +000060 return IsMemRefInstr(x) &&
61 IsMemRefInstr(y) &&
62 (cast<const Instruction>(x)->mayWriteToMemory() ||
63 cast<const Instruction>(y)->mayWriteToMemory());
Andreas Bolkaf17ab7f2009-06-28 00:21:21 +000064}
65
66bool LoopDependenceAnalysis::depends(Value *src, Value *dst) {
67 assert(isDependencePair(src, dst) && "Values form no dependence pair!");
68 return true;
69}
70
71//===----------------------------------------------------------------------===//
Andreas Bolka306b5b22009-06-24 21:29:13 +000072// LoopDependenceAnalysis Implementation
73//===----------------------------------------------------------------------===//
74
75bool LoopDependenceAnalysis::runOnLoop(Loop *L, LPPassManager &) {
76 this->L = L;
77 SE = &getAnalysis<ScalarEvolution>();
78 return false;
79}
80
81void LoopDependenceAnalysis::getAnalysisUsage(AnalysisUsage &AU) const {
82 AU.setPreservesAll();
Andreas Bolkab88ee912009-06-28 00:16:08 +000083 AU.addRequiredTransitive<ScalarEvolution>();
84}
85
86static void PrintLoopInfo(
Andreas Bolka158c5902009-06-28 00:35:22 +000087 raw_ostream &OS, LoopDependenceAnalysis *LDA, const Loop *L) {
Andreas Bolkab88ee912009-06-28 00:16:08 +000088 if (!L->empty()) return; // ignore non-innermost loops
89
90 OS << "Loop at depth " << L->getLoopDepth() << ", header block: ";
91 WriteAsOperand(OS, L->getHeader(), false);
92 OS << "\n";
Andreas Bolka158c5902009-06-28 00:35:22 +000093
94 SmallVector<Instruction*, 8> memrefs;
Andreas Bolkab2662e42009-06-29 00:53:49 +000095 GetMemRefInstrs(L, memrefs);
Andreas Bolka158c5902009-06-28 00:35:22 +000096 OS << " Load/store instructions: " << memrefs.size() << "\n";
97 OS << " Pairwise dependence results:\n";
98 for (SmallVector<Instruction*, 8>::const_iterator x = memrefs.begin(),
99 end = memrefs.end(); x != end; ++x)
100 for (SmallVector<Instruction*, 8>::const_iterator y = x + 1;
101 y != end; ++y)
102 if (LDA->isDependencePair(*x, *y))
103 OS << "\t" << (x - memrefs.begin()) << "," << (y - memrefs.begin())
104 << ": " << (LDA->depends(*x, *y) ? "dependent" : "independent")
105 << "\n";
Andreas Bolkab88ee912009-06-28 00:16:08 +0000106}
107
108void LoopDependenceAnalysis::print(raw_ostream &OS, const Module*) const {
Andreas Bolka158c5902009-06-28 00:35:22 +0000109 // TODO: doc why const_cast is safe
110 PrintLoopInfo(OS, const_cast<LoopDependenceAnalysis*>(this), this->L);
Andreas Bolkab88ee912009-06-28 00:16:08 +0000111}
112
113void LoopDependenceAnalysis::print(std::ostream &OS, const Module *M) const {
114 raw_os_ostream os(OS);
115 print(os, M);
Andreas Bolka306b5b22009-06-24 21:29:13 +0000116}