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-exception 6 // 7 //===----------------------------------------------------------------------===// 8 // 9 // This file contains test passes for constructing and testing alias analysis 10 // results. 11 // 12 //===----------------------------------------------------------------------===// 13 14 #include "mlir/Analysis/AliasAnalysis.h" 15 #include "mlir/Pass/Pass.h" 16 17 using namespace mlir; 18 19 /// Print a value that is used as an operand of an alias query. 20 static void printAliasOperand(Operation *op) { 21 llvm::errs() << op->getAttrOfType<StringAttr>("test.ptr").getValue(); 22 } 23 static void printAliasOperand(Value value) { 24 if (BlockArgument arg = value.dyn_cast<BlockArgument>()) { 25 Region *region = arg.getParentRegion(); 26 unsigned parentBlockNumber = 27 std::distance(region->begin(), arg.getOwner()->getIterator()); 28 llvm::errs() << region->getParentOp() 29 ->getAttrOfType<StringAttr>("test.ptr") 30 .getValue() 31 << ".region" << region->getRegionNumber(); 32 if (parentBlockNumber != 0) 33 llvm::errs() << ".block" << parentBlockNumber; 34 llvm::errs() << "#" << arg.getArgNumber(); 35 return; 36 } 37 OpResult result = value.cast<OpResult>(); 38 printAliasOperand(result.getOwner()); 39 llvm::errs() << "#" << result.getResultNumber(); 40 } 41 42 //===----------------------------------------------------------------------===// 43 // Testing AliasResult 44 //===----------------------------------------------------------------------===// 45 46 namespace { 47 struct TestAliasAnalysisPass 48 : public PassWrapper<TestAliasAnalysisPass, OperationPass<>> { 49 StringRef getArgument() const final { return "test-alias-analysis"; } 50 StringRef getDescription() const final { 51 return "Test alias analysis results."; 52 } 53 void runOnOperation() override { 54 llvm::errs() << "Testing : " << getOperation()->getAttr("sym_name") << "\n"; 55 56 // Collect all of the values to check for aliasing behavior. 57 AliasAnalysis &aliasAnalysis = getAnalysis<AliasAnalysis>(); 58 SmallVector<Value, 32> valsToCheck; 59 getOperation()->walk([&](Operation *op) { 60 if (!op->getAttr("test.ptr")) 61 return; 62 valsToCheck.append(op->result_begin(), op->result_end()); 63 for (Region ®ion : op->getRegions()) 64 for (Block &block : region) 65 valsToCheck.append(block.args_begin(), block.args_end()); 66 }); 67 68 // Check for aliasing behavior between each of the values. 69 for (auto it = valsToCheck.begin(), e = valsToCheck.end(); it != e; ++it) 70 for (auto innerIt = valsToCheck.begin(); innerIt != it; ++innerIt) 71 printAliasResult(aliasAnalysis.alias(*innerIt, *it), *innerIt, *it); 72 } 73 74 /// Print the result of an alias query. 75 void printAliasResult(AliasResult result, Value lhs, Value rhs) { 76 printAliasOperand(lhs); 77 llvm::errs() << " <-> "; 78 printAliasOperand(rhs); 79 llvm::errs() << ": " << result << "\n"; 80 } 81 }; 82 } // end anonymous namespace 83 84 //===----------------------------------------------------------------------===// 85 // Testing ModRefResult 86 //===----------------------------------------------------------------------===// 87 88 namespace { 89 struct TestAliasAnalysisModRefPass 90 : public PassWrapper<TestAliasAnalysisModRefPass, OperationPass<>> { 91 StringRef getArgument() const final { return "test-alias-analysis-modref"; } 92 StringRef getDescription() const final { 93 return "Test alias analysis ModRef results."; 94 } 95 void runOnOperation() override { 96 llvm::errs() << "Testing : " << getOperation()->getAttr("sym_name") << "\n"; 97 98 // Collect all of the values to check for aliasing behavior. 99 AliasAnalysis &aliasAnalysis = getAnalysis<AliasAnalysis>(); 100 SmallVector<Value, 32> valsToCheck; 101 getOperation()->walk([&](Operation *op) { 102 if (!op->getAttr("test.ptr")) 103 return; 104 valsToCheck.append(op->result_begin(), op->result_end()); 105 for (Region ®ion : op->getRegions()) 106 for (Block &block : region) 107 valsToCheck.append(block.args_begin(), block.args_end()); 108 }); 109 110 // Check for aliasing behavior between each of the values. 111 for (auto it = valsToCheck.begin(), e = valsToCheck.end(); it != e; ++it) { 112 getOperation()->walk([&](Operation *op) { 113 if (!op->getAttr("test.ptr")) 114 return; 115 printModRefResult(aliasAnalysis.getModRef(op, *it), op, *it); 116 }); 117 } 118 } 119 120 /// Print the result of an alias query. 121 void printModRefResult(ModRefResult result, Operation *op, Value location) { 122 printAliasOperand(op); 123 llvm::errs() << " -> "; 124 printAliasOperand(location); 125 llvm::errs() << ": " << result << "\n"; 126 } 127 }; 128 } // end anonymous namespace 129 130 //===----------------------------------------------------------------------===// 131 // Pass Registration 132 //===----------------------------------------------------------------------===// 133 134 namespace mlir { 135 namespace test { 136 void registerTestAliasAnalysisPass() { 137 PassRegistration<TestAliasAnalysisPass>(); 138 PassRegistration<TestAliasAnalysisModRefPass>(); 139 } 140 } // namespace test 141 } // namespace mlir 142