blob: a49f18166dc410fbb0e9038ecff3d0769516c1ff [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"
Andreas Bolka8f9cd692009-07-01 21:45:23 +000021#include "llvm/Analysis/AliasAnalysis.h"
Andreas Bolka306b5b22009-06-24 21:29:13 +000022#include "llvm/Analysis/LoopDependenceAnalysis.h"
23#include "llvm/Analysis/LoopPass.h"
24#include "llvm/Analysis/ScalarEvolution.h"
Andreas Bolkaf17ab7f2009-06-28 00:21:21 +000025#include "llvm/Instructions.h"
Andreas Bolka5771ed92009-06-30 02:12:10 +000026#include "llvm/Support/Debug.h"
Andreas Bolka8f9cd692009-07-01 21:45:23 +000027#include "llvm/Target/TargetData.h"
Andreas Bolka306b5b22009-06-24 21:29:13 +000028using namespace llvm;
29
30LoopPass *llvm::createLoopDependenceAnalysisPass() {
31 return new LoopDependenceAnalysis();
32}
33
34static RegisterPass<LoopDependenceAnalysis>
35R("lda", "Loop Dependence Analysis", false, true);
36char LoopDependenceAnalysis::ID = 0;
37
38//===----------------------------------------------------------------------===//
Andreas Bolkaf17ab7f2009-06-28 00:21:21 +000039// Utility Functions
40//===----------------------------------------------------------------------===//
41
Andreas Bolkafc8a04a2009-06-29 18:51:11 +000042static inline bool IsMemRefInstr(const Value *V) {
43 const Instruction *I = dyn_cast<const Instruction>(V);
44 return I && (I->mayReadFromMemory() || I->mayWriteToMemory());
Andreas Bolkaf17ab7f2009-06-28 00:21:21 +000045}
46
Andreas Bolka88a17f02009-06-29 00:50:26 +000047static void GetMemRefInstrs(
Andreas Bolka158c5902009-06-28 00:35:22 +000048 const Loop *L, SmallVectorImpl<Instruction*> &memrefs) {
49 for (Loop::block_iterator b = L->block_begin(), be = L->block_end();
50 b != be; ++b)
51 for (BasicBlock::iterator i = (*b)->begin(), ie = (*b)->end();
52 i != ie; ++i)
Andreas Bolka88a17f02009-06-29 00:50:26 +000053 if (IsMemRefInstr(i))
Andreas Bolka158c5902009-06-28 00:35:22 +000054 memrefs.push_back(i);
55}
56
Andreas Bolka5771ed92009-06-30 02:12:10 +000057static bool IsLoadOrStoreInst(Value *I) {
58 return isa<LoadInst>(I) || isa<StoreInst>(I);
59}
60
61static Value *GetPointerOperand(Value *I) {
62 if (LoadInst *i = dyn_cast<LoadInst>(I))
63 return i->getPointerOperand();
64 if (StoreInst *i = dyn_cast<StoreInst>(I))
65 return i->getPointerOperand();
66 assert(0 && "Value is no load or store instruction!");
67 // Never reached.
68 return 0;
69}
70
Andreas Bolkaf17ab7f2009-06-28 00:21:21 +000071//===----------------------------------------------------------------------===//
72// Dependence Testing
73//===----------------------------------------------------------------------===//
74
75bool LoopDependenceAnalysis::isDependencePair(const Value *x,
76 const Value *y) const {
Andreas Bolkafc8a04a2009-06-29 18:51:11 +000077 return IsMemRefInstr(x) &&
78 IsMemRefInstr(y) &&
79 (cast<const Instruction>(x)->mayWriteToMemory() ||
80 cast<const Instruction>(y)->mayWriteToMemory());
Andreas Bolkaf17ab7f2009-06-28 00:21:21 +000081}
82
83bool LoopDependenceAnalysis::depends(Value *src, Value *dst) {
84 assert(isDependencePair(src, dst) && "Values form no dependence pair!");
Andreas Bolka5771ed92009-06-30 02:12:10 +000085 DOUT << "== LDA test ==\n" << *src << *dst;
86
87 // We only analyse loads and stores; for possible memory accesses by e.g.
88 // free, call, or invoke instructions we conservatively assume dependence.
89 if (!IsLoadOrStoreInst(src) || !IsLoadOrStoreInst(dst))
90 return true;
91
92 Value *srcPtr = GetPointerOperand(src);
93 Value *dstPtr = GetPointerOperand(dst);
94 const Value *srcObj = srcPtr->getUnderlyingObject();
95 const Value *dstObj = dstPtr->getUnderlyingObject();
Andreas Bolka8f9cd692009-07-01 21:45:23 +000096 AliasAnalysis::AliasResult alias = AA->alias(
97 srcObj, AA->getTargetData().getTypeStoreSize(srcObj->getType()),
98 dstObj, AA->getTargetData().getTypeStoreSize(dstObj->getType()));
Andreas Bolka5771ed92009-06-30 02:12:10 +000099
Andreas Bolka8f9cd692009-07-01 21:45:23 +0000100 // If we don't know whether or not the two objects alias, assume dependence.
101 if (alias == AliasAnalysis::MayAlias)
Andreas Bolka5771ed92009-06-30 02:12:10 +0000102 return true;
103
Andreas Bolka8f9cd692009-07-01 21:45:23 +0000104 // If the objects noalias, they are distinct, accesses are independent.
105 if (alias == AliasAnalysis::NoAlias)
Andreas Bolka5771ed92009-06-30 02:12:10 +0000106 return false;
107
Andreas Bolka8f9cd692009-07-01 21:45:23 +0000108 // TODO: the underlying objects MustAlias, test for dependence
109
Andreas Bolka5771ed92009-06-30 02:12:10 +0000110 // We couldn't establish a more precise result, so we have to conservatively
111 // assume full dependence.
Andreas Bolkaf17ab7f2009-06-28 00:21:21 +0000112 return true;
113}
114
115//===----------------------------------------------------------------------===//
Andreas Bolka306b5b22009-06-24 21:29:13 +0000116// LoopDependenceAnalysis Implementation
117//===----------------------------------------------------------------------===//
118
119bool LoopDependenceAnalysis::runOnLoop(Loop *L, LPPassManager &) {
120 this->L = L;
Andreas Bolka8f9cd692009-07-01 21:45:23 +0000121 AA = &getAnalysis<AliasAnalysis>();
Andreas Bolka306b5b22009-06-24 21:29:13 +0000122 SE = &getAnalysis<ScalarEvolution>();
123 return false;
124}
125
126void LoopDependenceAnalysis::getAnalysisUsage(AnalysisUsage &AU) const {
127 AU.setPreservesAll();
Andreas Bolka8f9cd692009-07-01 21:45:23 +0000128 AU.addRequiredTransitive<AliasAnalysis>();
Andreas Bolkab88ee912009-06-28 00:16:08 +0000129 AU.addRequiredTransitive<ScalarEvolution>();
130}
131
132static void PrintLoopInfo(
Andreas Bolka158c5902009-06-28 00:35:22 +0000133 raw_ostream &OS, LoopDependenceAnalysis *LDA, const Loop *L) {
Andreas Bolkab88ee912009-06-28 00:16:08 +0000134 if (!L->empty()) return; // ignore non-innermost loops
135
136 OS << "Loop at depth " << L->getLoopDepth() << ", header block: ";
137 WriteAsOperand(OS, L->getHeader(), false);
138 OS << "\n";
Andreas Bolka158c5902009-06-28 00:35:22 +0000139
140 SmallVector<Instruction*, 8> memrefs;
Andreas Bolkab2662e42009-06-29 00:53:49 +0000141 GetMemRefInstrs(L, memrefs);
Andreas Bolka158c5902009-06-28 00:35:22 +0000142 OS << " Load/store instructions: " << memrefs.size() << "\n";
143 OS << " Pairwise dependence results:\n";
144 for (SmallVector<Instruction*, 8>::const_iterator x = memrefs.begin(),
145 end = memrefs.end(); x != end; ++x)
146 for (SmallVector<Instruction*, 8>::const_iterator y = x + 1;
147 y != end; ++y)
148 if (LDA->isDependencePair(*x, *y))
149 OS << "\t" << (x - memrefs.begin()) << "," << (y - memrefs.begin())
150 << ": " << (LDA->depends(*x, *y) ? "dependent" : "independent")
151 << "\n";
Andreas Bolkab88ee912009-06-28 00:16:08 +0000152}
153
154void LoopDependenceAnalysis::print(raw_ostream &OS, const Module*) const {
Andreas Bolka158c5902009-06-28 00:35:22 +0000155 // TODO: doc why const_cast is safe
156 PrintLoopInfo(OS, const_cast<LoopDependenceAnalysis*>(this), this->L);
Andreas Bolkab88ee912009-06-28 00:16:08 +0000157}
158
159void LoopDependenceAnalysis::print(std::ostream &OS, const Module *M) const {
160 raw_os_ostream os(OS);
161 print(os, M);
Andreas Bolka306b5b22009-06-24 21:29:13 +0000162}