summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--llvm/lib/Analysis/DependenceAnalysis.cpp17
-rw-r--r--llvm/test/Analysis/DependenceAnalysis/Dump.ll50
2 files changed, 57 insertions, 10 deletions
diff --git a/llvm/lib/Analysis/DependenceAnalysis.cpp b/llvm/lib/Analysis/DependenceAnalysis.cpp
index a3c8bc8ad2f..c343867e09f 100644
--- a/llvm/lib/Analysis/DependenceAnalysis.cpp
+++ b/llvm/lib/Analysis/DependenceAnalysis.cpp
@@ -170,25 +170,25 @@ void DependenceAnalysisWrapperPass::getAnalysisUsage(AnalysisUsage &AU) const {
AU.addRequiredTransitive<LoopInfoWrapperPass>();
}
-
// Used to test the dependence analyzer.
-// Looks through the function, noting loads and stores.
+// Looks through the function, noting instructions that may access memory.
// Calls depends() on every possible pair and prints out the result.
// Ignores all other instructions.
static void dumpExampleDependence(raw_ostream &OS, DependenceInfo *DA) {
auto *F = DA->getFunction();
for (inst_iterator SrcI = inst_begin(F), SrcE = inst_end(F); SrcI != SrcE;
++SrcI) {
- if (isa<StoreInst>(*SrcI) || isa<LoadInst>(*SrcI)) {
+ if (SrcI->mayReadOrWriteMemory()) {
for (inst_iterator DstI = SrcI, DstE = inst_end(F);
DstI != DstE; ++DstI) {
- if (isa<StoreInst>(*DstI) || isa<LoadInst>(*DstI)) {
- OS << "da analyze - ";
+ if (DstI->mayReadOrWriteMemory()) {
+ OS << "Src:" << *SrcI << " --> Dst:" << *DstI << "\n";
+ OS << " da analyze - ";
if (auto D = DA->depends(&*SrcI, &*DstI, true)) {
D->dump(OS);
for (unsigned Level = 1; Level <= D->getLevels(); Level++) {
if (D->isSplitable(Level)) {
- OS << "da analyze - split level = " << Level;
+ OS << " da analyze - split level = " << Level;
OS << ", iteration = " << *DA->getSplitIteration(*D, Level);
OS << "!\n";
}
@@ -3413,8 +3413,7 @@ DependenceInfo::depends(Instruction *Src, Instruction *Dst,
if (Src == Dst)
PossiblyLoopIndependent = false;
- if ((!Src->mayReadFromMemory() && !Src->mayWriteToMemory()) ||
- (!Dst->mayReadFromMemory() && !Dst->mayWriteToMemory()))
+ if (!(Src->mayReadOrWriteMemory() && Dst->mayReadOrWriteMemory()))
// if both instructions don't reference memory, there's no dependence
return nullptr;
@@ -3786,8 +3785,6 @@ DependenceInfo::depends(Instruction *Src, Instruction *Dst,
return std::make_unique<FullDependence>(std::move(Result));
}
-
-
//===----------------------------------------------------------------------===//
// getSplitIteration -
// Rather than spend rarely-used space recording the splitting iteration
diff --git a/llvm/test/Analysis/DependenceAnalysis/Dump.ll b/llvm/test/Analysis/DependenceAnalysis/Dump.ll
new file mode 100644
index 00000000000..d86221d852a
--- /dev/null
+++ b/llvm/test/Analysis/DependenceAnalysis/Dump.ll
@@ -0,0 +1,50 @@
+; RUN: opt < %s -disable-output "-passes=print<da>" -aa-pipeline=basic-aa 2>&1 \
+; RUN: | FileCheck %s
+
+;; Test to make sure the dump shows the src and dst
+;; instructions (including call instructions).
+;;
+;; void bar(float * restrict A);
+;; void foo(float * restrict A, int n) {
+;; for (int i = 0; i < n; i++) {
+;; A[i] = i;
+;; bar(A);
+;; }
+;; }
+
+; CHECK-LABEL: foo
+
+; CHECK: Src: store float %conv, float* %arrayidx, align 4 --> Dst: store float %conv, float* %arrayidx, align 4
+; CHECK-NEXT: da analyze - none!
+; CHECK-NEXT: Src: store float %conv, float* %arrayidx, align 4 --> Dst: call void @bar(float* %A)
+; CHECK-NEXT: da analyze - confused!
+; CHECK-NEXT: Src: call void @bar(float* %A) --> Dst: call void @bar(float* %A)
+; CHECK-NEXT: da analyze - confused!
+
+define void @foo(float* noalias %A, i32 signext %n) {
+entry:
+ %cmp1 = icmp slt i32 0, %n
+ br i1 %cmp1, label %for.body.lr.ph, label %for.end
+
+for.body.lr.ph: ; preds = %entry
+ br label %for.body
+
+for.body: ; preds = %for.body.lr.ph, %for.body
+ %i.02 = phi i32 [ 0, %for.body.lr.ph ], [ %inc, %for.body ]
+ %conv = sitofp i32 %i.02 to float
+ %idxprom = zext i32 %i.02 to i64
+ %arrayidx = getelementptr inbounds float, float* %A, i64 %idxprom
+ store float %conv, float* %arrayidx, align 4
+ call void @bar(float* %A) #3
+ %inc = add nuw nsw i32 %i.02, 1
+ %cmp = icmp slt i32 %inc, %n
+ br i1 %cmp, label %for.body, label %for.cond.for.end_crit_edge
+
+for.cond.for.end_crit_edge: ; preds = %for.body
+ br label %for.end
+
+for.end: ; preds = %for.cond.for.end_crit_edge, %entry
+ ret void
+}
+
+declare void @bar(float*)
OpenPOWER on IntegriCloud