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 #include "mlir/IR/Operation.h" 12 #include "mlir/IR/Value.h" 13 #include "mlir/Support/LLVM.h" 14 #include <memory> 15 16 using namespace mlir; 17 18 //===----------------------------------------------------------------------===// 19 // AliasResult 20 //===----------------------------------------------------------------------===// 21 22 /// Merge this alias result with `other` and return a new result that 23 /// represents the conservative merge of both results. merge(AliasResult other) const24AliasResult AliasResult::merge(AliasResult other) const { 25 if (kind == other.kind) 26 return *this; 27 // A mix of PartialAlias and MustAlias is PartialAlias. 28 if ((isPartial() && other.isMust()) || (other.isPartial() && isMust())) 29 return PartialAlias; 30 // Otherwise, don't assume anything. 31 return MayAlias; 32 } 33 print(raw_ostream & os) const34void AliasResult::print(raw_ostream &os) const { 35 switch (kind) { 36 case Kind::NoAlias: 37 os << "NoAlias"; 38 break; 39 case Kind::MayAlias: 40 os << "MayAlias"; 41 break; 42 case Kind::PartialAlias: 43 os << "PartialAlias"; 44 break; 45 case Kind::MustAlias: 46 os << "MustAlias"; 47 break; 48 } 49 } 50 51 //===----------------------------------------------------------------------===// 52 // ModRefResult 53 //===----------------------------------------------------------------------===// 54 print(raw_ostream & os) const55void ModRefResult::print(raw_ostream &os) const { 56 switch (kind) { 57 case Kind::NoModRef: 58 os << "NoModRef"; 59 break; 60 case Kind::Ref: 61 os << "Ref"; 62 break; 63 case Kind::Mod: 64 os << "Mod"; 65 break; 66 case Kind::ModRef: 67 os << "ModRef"; 68 break; 69 } 70 } 71 72 //===----------------------------------------------------------------------===// 73 // AliasAnalysis 74 //===----------------------------------------------------------------------===// 75 AliasAnalysis(Operation * op)76AliasAnalysis::AliasAnalysis(Operation *op) { 77 addAnalysisImplementation(LocalAliasAnalysis()); 78 } 79 alias(Value lhs,Value rhs)80AliasResult AliasAnalysis::alias(Value lhs, Value rhs) { 81 // Check each of the alias analysis implemenations for an alias result. 82 for (const std::unique_ptr<Concept> &aliasImpl : aliasImpls) { 83 AliasResult result = aliasImpl->alias(lhs, rhs); 84 if (!result.isMay()) 85 return result; 86 } 87 return AliasResult::MayAlias; 88 } 89 getModRef(Operation * op,Value location)90ModRefResult AliasAnalysis::getModRef(Operation *op, Value location) { 91 // Compute the mod-ref behavior by refining a top `ModRef` result with each of 92 // the alias analysis implementations. We early exit at the point where we 93 // refine down to a `NoModRef`. 94 ModRefResult result = ModRefResult::getModAndRef(); 95 for (const std::unique_ptr<Concept> &aliasImpl : aliasImpls) { 96 result = result.intersect(aliasImpl->getModRef(op, location)); 97 if (result.isNoModRef()) 98 return result; 99 } 100 return result; 101 } 102