1 //===- AliasAnalysis.cpp - Alias Analysis for MLIR ------------------------===//
2 //
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 //
7 //===----------------------------------------------------------------------===//
8 
9 #include "mlir/Analysis/AliasAnalysis.h"
10 #include "mlir/Analysis/AliasAnalysis/LocalAliasAnalysis.h"
11 
12 using namespace mlir;
13 
14 //===----------------------------------------------------------------------===//
15 // AliasResult
16 //===----------------------------------------------------------------------===//
17 
18 /// Merge this alias result with `other` and return a new result that
19 /// represents the conservative merge of both results.
merge(AliasResult other) const20 AliasResult AliasResult::merge(AliasResult other) const {
21   if (kind == other.kind)
22     return *this;
23   // A mix of PartialAlias and MustAlias is PartialAlias.
24   if ((isPartial() && other.isMust()) || (other.isPartial() && isMust()))
25     return PartialAlias;
26   // Otherwise, don't assume anything.
27   return MayAlias;
28 }
29 
print(raw_ostream & os) const30 void AliasResult::print(raw_ostream &os) const {
31   switch (kind) {
32   case Kind::NoAlias:
33     os << "NoAlias";
34     break;
35   case Kind::MayAlias:
36     os << "MayAlias";
37     break;
38   case Kind::PartialAlias:
39     os << "PartialAlias";
40     break;
41   case Kind::MustAlias:
42     os << "MustAlias";
43     break;
44   }
45 }
46 
47 //===----------------------------------------------------------------------===//
48 // ModRefResult
49 //===----------------------------------------------------------------------===//
50 
print(raw_ostream & os) const51 void ModRefResult::print(raw_ostream &os) const {
52   switch (kind) {
53   case Kind::NoModRef:
54     os << "NoModRef";
55     break;
56   case Kind::Ref:
57     os << "Ref";
58     break;
59   case Kind::Mod:
60     os << "Mod";
61     break;
62   case Kind::ModRef:
63     os << "ModRef";
64     break;
65   }
66 }
67 
68 //===----------------------------------------------------------------------===//
69 // AliasAnalysis
70 //===----------------------------------------------------------------------===//
71 
AliasAnalysis(Operation * op)72 AliasAnalysis::AliasAnalysis(Operation *op) {
73   addAnalysisImplementation(LocalAliasAnalysis());
74 }
75 
alias(Value lhs,Value rhs)76 AliasResult AliasAnalysis::alias(Value lhs, Value rhs) {
77   // Check each of the alias analysis implemenations for an alias result.
78   for (const std::unique_ptr<Concept> &aliasImpl : aliasImpls) {
79     AliasResult result = aliasImpl->alias(lhs, rhs);
80     if (!result.isMay())
81       return result;
82   }
83   return AliasResult::MayAlias;
84 }
85 
getModRef(Operation * op,Value location)86 ModRefResult AliasAnalysis::getModRef(Operation *op, Value location) {
87   // Compute the mod-ref behavior by refining a top `ModRef` result with each of
88   // the alias analysis implementations. We early exit at the point where we
89   // refine down to a `NoModRef`.
90   ModRefResult result = ModRefResult::getModAndRef();
91   for (const std::unique_ptr<Concept> &aliasImpl : aliasImpls) {
92     result = result.intersect(aliasImpl->getModRef(op, location));
93     if (result.isNoModRef())
94       return result;
95   }
96   return result;
97 }
98