blob: 156642a1f6962d43dd910939fc62e4095ab4e6e8 [file] [log] [blame]
Andreas Bolkacb210102009-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 Bolkafecbc592009-07-01 21:45:23 +000021#include "llvm/Analysis/AliasAnalysis.h"
Andreas Bolkacb210102009-06-24 21:29:13 +000022#include "llvm/Analysis/LoopDependenceAnalysis.h"
23#include "llvm/Analysis/LoopPass.h"
24#include "llvm/Analysis/ScalarEvolution.h"
Andreas Bolkaf35626d2009-06-28 00:21:21 +000025#include "llvm/Instructions.h"
Andreas Bolkae9722fc2009-06-30 02:12:10 +000026#include "llvm/Support/Debug.h"
Torok Edwinc25e7582009-07-11 20:10:48 +000027#include "llvm/Support/ErrorHandling.h"
Andreas Bolkafecbc592009-07-01 21:45:23 +000028#include "llvm/Target/TargetData.h"
Andreas Bolkacb210102009-06-24 21:29:13 +000029using namespace llvm;
30
31LoopPass *llvm::createLoopDependenceAnalysisPass() {
32 return new LoopDependenceAnalysis();
33}
34
35static RegisterPass<LoopDependenceAnalysis>
36R("lda", "Loop Dependence Analysis", false, true);
37char LoopDependenceAnalysis::ID = 0;
38
39//===----------------------------------------------------------------------===//
Andreas Bolkaf35626d2009-06-28 00:21:21 +000040// Utility Functions
41//===----------------------------------------------------------------------===//
42
Andreas Bolka2fbb7702009-06-29 18:51:11 +000043static inline bool IsMemRefInstr(const Value *V) {
44 const Instruction *I = dyn_cast<const Instruction>(V);
45 return I && (I->mayReadFromMemory() || I->mayWriteToMemory());
Andreas Bolkaf35626d2009-06-28 00:21:21 +000046}
47
Andreas Bolkaacd6f8d2009-06-29 00:50:26 +000048static void GetMemRefInstrs(
Andreas Bolkac6a30302009-06-28 00:35:22 +000049 const Loop *L, SmallVectorImpl<Instruction*> &memrefs) {
50 for (Loop::block_iterator b = L->block_begin(), be = L->block_end();
51 b != be; ++b)
52 for (BasicBlock::iterator i = (*b)->begin(), ie = (*b)->end();
53 i != ie; ++i)
Andreas Bolkaacd6f8d2009-06-29 00:50:26 +000054 if (IsMemRefInstr(i))
Andreas Bolkac6a30302009-06-28 00:35:22 +000055 memrefs.push_back(i);
56}
57
Andreas Bolkae9722fc2009-06-30 02:12:10 +000058static bool IsLoadOrStoreInst(Value *I) {
59 return isa<LoadInst>(I) || isa<StoreInst>(I);
60}
61
62static Value *GetPointerOperand(Value *I) {
63 if (LoadInst *i = dyn_cast<LoadInst>(I))
64 return i->getPointerOperand();
65 if (StoreInst *i = dyn_cast<StoreInst>(I))
66 return i->getPointerOperand();
Torok Edwinc23197a2009-07-14 16:55:14 +000067 llvm_unreachable("Value is no load or store instruction!");
Andreas Bolkae9722fc2009-06-30 02:12:10 +000068 // Never reached.
69 return 0;
70}
71
Andreas Bolkaf35626d2009-06-28 00:21:21 +000072//===----------------------------------------------------------------------===//
73// Dependence Testing
74//===----------------------------------------------------------------------===//
75
76bool LoopDependenceAnalysis::isDependencePair(const Value *x,
77 const Value *y) const {
Andreas Bolka2fbb7702009-06-29 18:51:11 +000078 return IsMemRefInstr(x) &&
79 IsMemRefInstr(y) &&
80 (cast<const Instruction>(x)->mayWriteToMemory() ||
81 cast<const Instruction>(y)->mayWriteToMemory());
Andreas Bolkaf35626d2009-06-28 00:21:21 +000082}
83
84bool LoopDependenceAnalysis::depends(Value *src, Value *dst) {
85 assert(isDependencePair(src, dst) && "Values form no dependence pair!");
Andreas Bolkae9722fc2009-06-30 02:12:10 +000086 DOUT << "== LDA test ==\n" << *src << *dst;
87
88 // We only analyse loads and stores; for possible memory accesses by e.g.
89 // free, call, or invoke instructions we conservatively assume dependence.
90 if (!IsLoadOrStoreInst(src) || !IsLoadOrStoreInst(dst))
91 return true;
92
93 Value *srcPtr = GetPointerOperand(src);
94 Value *dstPtr = GetPointerOperand(dst);
95 const Value *srcObj = srcPtr->getUnderlyingObject();
96 const Value *dstObj = dstPtr->getUnderlyingObject();
Andreas Bolkafecbc592009-07-01 21:45:23 +000097 AliasAnalysis::AliasResult alias = AA->alias(
98 srcObj, AA->getTargetData().getTypeStoreSize(srcObj->getType()),
99 dstObj, AA->getTargetData().getTypeStoreSize(dstObj->getType()));
Andreas Bolkae9722fc2009-06-30 02:12:10 +0000100
Andreas Bolkafecbc592009-07-01 21:45:23 +0000101 // If we don't know whether or not the two objects alias, assume dependence.
102 if (alias == AliasAnalysis::MayAlias)
Andreas Bolkae9722fc2009-06-30 02:12:10 +0000103 return true;
104
Andreas Bolkafecbc592009-07-01 21:45:23 +0000105 // If the objects noalias, they are distinct, accesses are independent.
106 if (alias == AliasAnalysis::NoAlias)
Andreas Bolkae9722fc2009-06-30 02:12:10 +0000107 return false;
108
Andreas Bolkafecbc592009-07-01 21:45:23 +0000109 // TODO: the underlying objects MustAlias, test for dependence
110
Andreas Bolkae9722fc2009-06-30 02:12:10 +0000111 // We couldn't establish a more precise result, so we have to conservatively
112 // assume full dependence.
Andreas Bolkaf35626d2009-06-28 00:21:21 +0000113 return true;
114}
115
116//===----------------------------------------------------------------------===//
Andreas Bolkacb210102009-06-24 21:29:13 +0000117// LoopDependenceAnalysis Implementation
118//===----------------------------------------------------------------------===//
119
120bool LoopDependenceAnalysis::runOnLoop(Loop *L, LPPassManager &) {
121 this->L = L;
Andreas Bolkafecbc592009-07-01 21:45:23 +0000122 AA = &getAnalysis<AliasAnalysis>();
Andreas Bolkacb210102009-06-24 21:29:13 +0000123 SE = &getAnalysis<ScalarEvolution>();
124 return false;
125}
126
127void LoopDependenceAnalysis::getAnalysisUsage(AnalysisUsage &AU) const {
128 AU.setPreservesAll();
Andreas Bolkafecbc592009-07-01 21:45:23 +0000129 AU.addRequiredTransitive<AliasAnalysis>();
Andreas Bolka707207a2009-06-28 00:16:08 +0000130 AU.addRequiredTransitive<ScalarEvolution>();
131}
132
133static void PrintLoopInfo(
Andreas Bolkac6a30302009-06-28 00:35:22 +0000134 raw_ostream &OS, LoopDependenceAnalysis *LDA, const Loop *L) {
Andreas Bolka707207a2009-06-28 00:16:08 +0000135 if (!L->empty()) return; // ignore non-innermost loops
136
Andreas Bolka292aef32009-07-03 01:42:52 +0000137 SmallVector<Instruction*, 8> memrefs;
138 GetMemRefInstrs(L, memrefs);
139
Andreas Bolka707207a2009-06-28 00:16:08 +0000140 OS << "Loop at depth " << L->getLoopDepth() << ", header block: ";
141 WriteAsOperand(OS, L->getHeader(), false);
142 OS << "\n";
Andreas Bolkac6a30302009-06-28 00:35:22 +0000143
Andreas Bolkac6a30302009-06-28 00:35:22 +0000144 OS << " Load/store instructions: " << memrefs.size() << "\n";
Andreas Bolka292aef32009-07-03 01:42:52 +0000145 for (SmallVector<Instruction*, 8>::const_iterator x = memrefs.begin(),
146 end = memrefs.end(); x != end; ++x)
147 OS << "\t" << (x - memrefs.begin()) << ": " << **x;
148
Andreas Bolkac6a30302009-06-28 00:35:22 +0000149 OS << " Pairwise dependence results:\n";
150 for (SmallVector<Instruction*, 8>::const_iterator x = memrefs.begin(),
151 end = memrefs.end(); x != end; ++x)
152 for (SmallVector<Instruction*, 8>::const_iterator y = x + 1;
153 y != end; ++y)
154 if (LDA->isDependencePair(*x, *y))
155 OS << "\t" << (x - memrefs.begin()) << "," << (y - memrefs.begin())
156 << ": " << (LDA->depends(*x, *y) ? "dependent" : "independent")
157 << "\n";
Andreas Bolka707207a2009-06-28 00:16:08 +0000158}
159
160void LoopDependenceAnalysis::print(raw_ostream &OS, const Module*) const {
Andreas Bolkac6a30302009-06-28 00:35:22 +0000161 // TODO: doc why const_cast is safe
162 PrintLoopInfo(OS, const_cast<LoopDependenceAnalysis*>(this), this->L);
Andreas Bolka707207a2009-06-28 00:16:08 +0000163}
164
165void LoopDependenceAnalysis::print(std::ostream &OS, const Module *M) const {
166 raw_os_ostream os(OS);
167 print(os, M);
Andreas Bolkacb210102009-06-24 21:29:13 +0000168}