| //===- AliasAnalysis.cpp - Alias Analysis for MLIR ------------------------===// | 
 | // | 
 | // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. | 
 | // See https://llvm.org/LICENSE.txt for license information. | 
 | // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception | 
 | // | 
 | //===----------------------------------------------------------------------===// | 
 |  | 
 | #include "mlir/Analysis/AliasAnalysis.h" | 
 | #include "mlir/Analysis/AliasAnalysis/LocalAliasAnalysis.h" | 
 |  | 
 | using namespace mlir; | 
 |  | 
 | //===----------------------------------------------------------------------===// | 
 | // AliasResult | 
 | //===----------------------------------------------------------------------===// | 
 |  | 
 | /// Merge this alias result with `other` and return a new result that | 
 | /// represents the conservative merge of both results. | 
 | AliasResult AliasResult::merge(AliasResult other) const { | 
 |   if (kind == other.kind) | 
 |     return *this; | 
 |   // A mix of PartialAlias and MustAlias is PartialAlias. | 
 |   if ((isPartial() && other.isMust()) || (other.isPartial() && isMust())) | 
 |     return PartialAlias; | 
 |   // Otherwise, don't assume anything. | 
 |   return MayAlias; | 
 | } | 
 |  | 
 | void AliasResult::print(raw_ostream &os) const { | 
 |   switch (kind) { | 
 |   case Kind::NoAlias: | 
 |     os << "NoAlias"; | 
 |     break; | 
 |   case Kind::MayAlias: | 
 |     os << "MayAlias"; | 
 |     break; | 
 |   case Kind::PartialAlias: | 
 |     os << "PartialAlias"; | 
 |     break; | 
 |   case Kind::MustAlias: | 
 |     os << "MustAlias"; | 
 |     break; | 
 |   } | 
 | } | 
 |  | 
 | //===----------------------------------------------------------------------===// | 
 | // ModRefResult | 
 | //===----------------------------------------------------------------------===// | 
 |  | 
 | void ModRefResult::print(raw_ostream &os) const { | 
 |   switch (kind) { | 
 |   case Kind::NoModRef: | 
 |     os << "NoModRef"; | 
 |     break; | 
 |   case Kind::Ref: | 
 |     os << "Ref"; | 
 |     break; | 
 |   case Kind::Mod: | 
 |     os << "Mod"; | 
 |     break; | 
 |   case Kind::ModRef: | 
 |     os << "ModRef"; | 
 |     break; | 
 |   } | 
 | } | 
 |  | 
 | //===----------------------------------------------------------------------===// | 
 | // AliasAnalysis | 
 | //===----------------------------------------------------------------------===// | 
 |  | 
 | AliasAnalysis::AliasAnalysis(Operation *op) { | 
 |   addAnalysisImplementation(LocalAliasAnalysis()); | 
 | } | 
 |  | 
 | AliasResult AliasAnalysis::alias(Value lhs, Value rhs) { | 
 |   // Check each of the alias analysis implemenations for an alias result. | 
 |   for (const std::unique_ptr<Concept> &aliasImpl : aliasImpls) { | 
 |     AliasResult result = aliasImpl->alias(lhs, rhs); | 
 |     if (!result.isMay()) | 
 |       return result; | 
 |   } | 
 |   return AliasResult::MayAlias; | 
 | } | 
 |  | 
 | ModRefResult AliasAnalysis::getModRef(Operation *op, Value location) { | 
 |   // Compute the mod-ref behavior by refining a top `ModRef` result with each of | 
 |   // the alias analysis implementations. We early exit at the point where we | 
 |   // refine down to a `NoModRef`. | 
 |   ModRefResult result = ModRefResult::getModAndRef(); | 
 |   for (const std::unique_ptr<Concept> &aliasImpl : aliasImpls) { | 
 |     result = result.intersect(aliasImpl->getModRef(op, location)); | 
 |     if (result.isNoModRef()) | 
 |       return result; | 
 |   } | 
 |   return result; | 
 | } |