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 RiddleAliasResult 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 Riddlevoid 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 Riddlevoid 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 RiddleAliasAnalysis::AliasAnalysis(Operation *op) { 77b9c876bdSRiver Riddle addAnalysisImplementation(LocalAliasAnalysis()); 78b9c876bdSRiver Riddle } 79b9c876bdSRiver Riddle alias(Value lhs,Value rhs)80b9c876bdSRiver RiddleAliasResult 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 RiddleModRefResult 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