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