brintos

brintos / llvm-project-archived public Read only

0
0
Text · 7.9 KiB · 65e3490 Raw
227 lines · cpp
1//===- TestAliasAnalysis.cpp - Test alias analysis results ----------------===//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-exception6//7//===----------------------------------------------------------------------===//8//9// This file contains test passes for constructing and testing alias analysis10// results.11//12//===----------------------------------------------------------------------===//13 14#include "TestAliasAnalysis.h"15#include "mlir/Analysis/AliasAnalysis.h"16#include "mlir/Analysis/AliasAnalysis/LocalAliasAnalysis.h"17#include "mlir/Interfaces/FunctionInterfaces.h"18#include "mlir/Pass/Pass.h"19 20using namespace mlir;21 22/// Print a value that is used as an operand of an alias query.23static void printAliasOperand(Operation *op) {24  llvm::errs() << op->getAttrOfType<StringAttr>("test.ptr").getValue();25}26static void printAliasOperand(Value value) {27  if (BlockArgument arg = dyn_cast<BlockArgument>(value)) {28    Region *region = arg.getParentRegion();29    unsigned parentBlockNumber =30        std::distance(region->begin(), arg.getOwner()->getIterator());31    llvm::errs() << region->getParentOp()32                        ->getAttrOfType<StringAttr>("test.ptr")33                        .getValue()34                 << ".region" << region->getRegionNumber();35    if (parentBlockNumber != 0)36      llvm::errs() << ".block" << parentBlockNumber;37    llvm::errs() << "#" << arg.getArgNumber();38    return;39  }40  OpResult result = cast<OpResult>(value);41  printAliasOperand(result.getOwner());42  llvm::errs() << "#" << result.getResultNumber();43}44 45namespace mlir {46namespace test {47void printAliasResult(AliasResult result, Value lhs, Value rhs) {48  printAliasOperand(lhs);49  llvm::errs() << " <-> ";50  printAliasOperand(rhs);51  llvm::errs() << ": " << result << "\n";52}53 54/// Print the result of an alias query.55void printModRefResult(ModRefResult result, Operation *op, Value location) {56  printAliasOperand(op);57  llvm::errs() << " -> ";58  printAliasOperand(location);59  llvm::errs() << ": " << result << "\n";60}61 62void TestAliasAnalysisBase::runAliasAnalysisOnOperation(63    Operation *op, AliasAnalysis &aliasAnalysis) {64  llvm::errs() << "Testing : " << *op->getInherentAttr("sym_name") << "\n";65 66  // Collect all of the values to check for aliasing behavior.67  SmallVector<Value, 32> valsToCheck;68  op->walk([&](Operation *op) {69    if (!op->getDiscardableAttr("test.ptr"))70      return;71    valsToCheck.append(op->result_begin(), op->result_end());72    for (Region &region : op->getRegions())73      for (Block &block : region)74        valsToCheck.append(block.args_begin(), block.args_end());75  });76 77  // Check for aliasing behavior between each of the values.78  for (auto it = valsToCheck.begin(), e = valsToCheck.end(); it != e; ++it)79    for (auto *innerIt = valsToCheck.begin(); innerIt != it; ++innerIt)80      printAliasResult(aliasAnalysis.alias(*innerIt, *it), *innerIt, *it);81}82 83void TestAliasAnalysisModRefBase::runAliasAnalysisOnOperation(84    Operation *op, AliasAnalysis &aliasAnalysis) {85  llvm::errs() << "Testing : " << *op->getInherentAttr("sym_name") << "\n";86 87  // Collect all of the values to check for aliasing behavior.88  SmallVector<Value, 32> valsToCheck;89  op->walk([&](Operation *op) {90    if (!op->getDiscardableAttr("test.ptr"))91      return;92    valsToCheck.append(op->result_begin(), op->result_end());93    for (Region &region : op->getRegions())94      for (Block &block : region)95        valsToCheck.append(block.args_begin(), block.args_end());96  });97 98  // Check for aliasing behavior between each of the values.99  for (auto &it : valsToCheck) {100    op->walk([&](Operation *op) {101      if (!op->getDiscardableAttr("test.ptr"))102        return;103      printModRefResult(aliasAnalysis.getModRef(op, it), op, it);104    });105  }106}107 108} // namespace test109} // namespace mlir110 111//===----------------------------------------------------------------------===//112// Testing AliasResult113//===----------------------------------------------------------------------===//114 115namespace {116struct TestAliasAnalysisPass117    : public test::TestAliasAnalysisBase,118      PassWrapper<TestAliasAnalysisPass, OperationPass<>> {119  MLIR_DEFINE_EXPLICIT_INTERNAL_INLINE_TYPE_ID(TestAliasAnalysisPass)120 121  StringRef getArgument() const final { return "test-alias-analysis"; }122  StringRef getDescription() const final {123    return "Test alias analysis results.";124  }125  void runOnOperation() override {126    AliasAnalysis &aliasAnalysis = getAnalysis<AliasAnalysis>();127    runAliasAnalysisOnOperation(getOperation(), aliasAnalysis);128  }129};130} // namespace131 132//===----------------------------------------------------------------------===//133// Testing ModRefResult134//===----------------------------------------------------------------------===//135 136namespace {137struct TestAliasAnalysisModRefPass138    : public test::TestAliasAnalysisModRefBase,139      PassWrapper<TestAliasAnalysisModRefPass, OperationPass<>> {140  MLIR_DEFINE_EXPLICIT_INTERNAL_INLINE_TYPE_ID(TestAliasAnalysisModRefPass)141 142  StringRef getArgument() const final { return "test-alias-analysis-modref"; }143  StringRef getDescription() const final {144    return "Test alias analysis ModRef results.";145  }146  void runOnOperation() override {147    AliasAnalysis &aliasAnalysis = getAnalysis<AliasAnalysis>();148    runAliasAnalysisOnOperation(getOperation(), aliasAnalysis);149  }150};151} // namespace152 153//===----------------------------------------------------------------------===//154// Testing LocalAliasAnalysis extending155//===----------------------------------------------------------------------===//156 157/// Check if value is function argument.158static bool isFuncArg(Value val) {159  auto blockArg = dyn_cast<BlockArgument>(val);160  if (!blockArg)161    return false;162 163  return mlir::isa_and_nonnull<FunctionOpInterface>(164      blockArg.getOwner()->getParentOp());165}166 167/// Check if value has "restrict" attribute. Value must be a function argument.168static bool isRestrict(Value val) {169  auto blockArg = cast<BlockArgument>(val);170  auto func =171      mlir::cast<FunctionOpInterface>(blockArg.getOwner()->getParentOp());172  return !!func.getArgAttr(blockArg.getArgNumber(),173                           "local_alias_analysis.restrict");174}175 176namespace {177/// LocalAliasAnalysis extended to support "restrict" attreibute.178class LocalAliasAnalysisRestrict : public LocalAliasAnalysis {179protected:180  AliasResult aliasImpl(Value lhs, Value rhs) override {181    if (lhs == rhs)182      return AliasResult::MustAlias;183 184    // Assume no aliasing if both values are function arguments and any of them185    // have restrict attr.186    if (isFuncArg(lhs) && isFuncArg(rhs))187      if (isRestrict(lhs) || isRestrict(rhs))188        return AliasResult::NoAlias;189 190    return LocalAliasAnalysis::aliasImpl(lhs, rhs);191  }192};193 194/// This pass tests adding additional analysis impls to the AliasAnalysis.195struct TestAliasAnalysisExtendingPass196    : public test::TestAliasAnalysisBase,197      PassWrapper<TestAliasAnalysisExtendingPass, OperationPass<>> {198  MLIR_DEFINE_EXPLICIT_INTERNAL_INLINE_TYPE_ID(TestAliasAnalysisExtendingPass)199 200  StringRef getArgument() const final {201    return "test-alias-analysis-extending";202  }203  StringRef getDescription() const final {204    return "Test alias analysis extending.";205  }206  void runOnOperation() override {207    AliasAnalysis aliasAnalysis(getOperation());208    aliasAnalysis.addAnalysisImplementation(LocalAliasAnalysisRestrict());209    runAliasAnalysisOnOperation(getOperation(), aliasAnalysis);210  }211};212} // namespace213 214//===----------------------------------------------------------------------===//215// Pass Registration216//===----------------------------------------------------------------------===//217 218namespace mlir {219namespace test {220void registerTestAliasAnalysisPass() {221  PassRegistration<TestAliasAnalysisExtendingPass>();222  PassRegistration<TestAliasAnalysisModRefPass>();223  PassRegistration<TestAliasAnalysisPass>();224}225} // namespace test226} // namespace mlir227