CodeQL / Analyze (actions) (push) Canceled after 0s
CodeQL / Analyze (python) (push) Canceled after 0s
pre-commit / pre-commit (push) Canceled after 0s
Multi-Arch CI / setup (push) Canceled after 0s
Publish build_manylinux_x86_64 images / publish_build_manylinux_x86_64 (push) Canceled after 0s
Setup (Multi-Arch) / setup (push) Canceled after 0s
Multi-Arch CI / Linux::${{ fromJSON(needs.setup.outputs.linux_build_config || '{}').build_variant_label || 'skip' }} (push) Canceled after 0s
Publish TheRock Docker image / build-and-push-image (push) Canceled after 0s
Publish no_rocm_image_ubi10 image / publish_no_rocm_image_ubi10 (push) Canceled after 0s
Multi-Arch CI / Windows::${{ fromJSON(needs.setup.outputs.windows_build_config || '{}').build_variant_label || 'skip' }} (push) Canceled after 0s
Publish TheRock Docker image / build-and-push-image (push) Canceled after 0s
Multi-Arch CI / Manifest Diff (push) Canceled after 0s
TheRock Manifest Diff Report / Generate Manifest Diff Report (push) Canceled after 0s
Multi-Arch CI / CI Summary (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04 images / publish_no_rocm_image_ubuntu24_04 (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04_ocl_rt images / publish_no_rocm_image_ubuntu24_04_ocl_rt (push) Canceled after 0s
Publish TheRock Docker image / build-and-push-image (push) Canceled after 0s
Publish TheRock Docker image / build-and-push-image (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04 images / publish_no_rocm_image_ubuntu24_04_rocgdb (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04_rocgdb images / publish_no_rocm_image_ubuntu24_04_rocgdb (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04 images / publish_no_rocm_image_ubuntu24_04_ocl_rt (push) Canceled after 0s
Publish TheRock Docker image / build-and-push-image (push) Canceled after 0s
Unit Tests / Unit Tests :: ubuntu-24.04 (push) Canceled after 0s
Unit Tests / Unit Tests :: windows-2022 (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04 images / publish_no_rocm_image_ubuntu24_04_media (push) Canceled after 0s
Unit Tests / Unit Tests Summary (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04 images / publish_no_rocm_image_ubuntu24_04_openmpi (push) Canceled after 0s
226 lines
7.8 KiB
C++
226 lines
7.8 KiB
C++
//===- TestAliasAnalysis.cpp - Test alias analysis results ----------------===//
|
|
//
|
|
// 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
|
|
//
|
|
//===----------------------------------------------------------------------===//
|
|
//
|
|
// This file contains test passes for constructing and testing alias analysis
|
|
// results.
|
|
//
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
#include "TestAliasAnalysis.h"
|
|
#include "mlir/Analysis/AliasAnalysis.h"
|
|
#include "mlir/Analysis/AliasAnalysis/LocalAliasAnalysis.h"
|
|
#include "mlir/Interfaces/FunctionInterfaces.h"
|
|
#include "mlir/Pass/Pass.h"
|
|
|
|
using namespace mlir;
|
|
|
|
/// Print a value that is used as an operand of an alias query.
|
|
static void printAliasOperand(Operation *op) {
|
|
llvm::errs() << op->getAttrOfType<StringAttr>("test.ptr").getValue();
|
|
}
|
|
static void printAliasOperand(Value value) {
|
|
if (BlockArgument arg = dyn_cast<BlockArgument>(value)) {
|
|
Region *region = arg.getParentRegion();
|
|
unsigned parentBlockNumber = arg.getOwner()->computeBlockNumber();
|
|
llvm::errs() << region->getParentOp()
|
|
->getAttrOfType<StringAttr>("test.ptr")
|
|
.getValue()
|
|
<< ".region" << region->getRegionNumber();
|
|
if (parentBlockNumber != 0)
|
|
llvm::errs() << ".block" << parentBlockNumber;
|
|
llvm::errs() << "#" << arg.getArgNumber();
|
|
return;
|
|
}
|
|
OpResult result = cast<OpResult>(value);
|
|
printAliasOperand(result.getOwner());
|
|
llvm::errs() << "#" << result.getResultNumber();
|
|
}
|
|
|
|
namespace mlir {
|
|
namespace test {
|
|
void printAliasResult(AliasResult result, Value lhs, Value rhs) {
|
|
printAliasOperand(lhs);
|
|
llvm::errs() << " <-> ";
|
|
printAliasOperand(rhs);
|
|
llvm::errs() << ": " << result << "\n";
|
|
}
|
|
|
|
/// Print the result of an alias query.
|
|
void printModRefResult(ModRefResult result, Operation *op, Value location) {
|
|
printAliasOperand(op);
|
|
llvm::errs() << " -> ";
|
|
printAliasOperand(location);
|
|
llvm::errs() << ": " << result << "\n";
|
|
}
|
|
|
|
void TestAliasAnalysisBase::runAliasAnalysisOnOperation(
|
|
Operation *op, AliasAnalysis &aliasAnalysis) {
|
|
llvm::errs() << "Testing : " << *op->getInherentAttr("sym_name") << "\n";
|
|
|
|
// Collect all of the values to check for aliasing behavior.
|
|
SmallVector<Value, 32> valsToCheck;
|
|
op->walk([&](Operation *op) {
|
|
if (!op->getDiscardableAttr("test.ptr"))
|
|
return;
|
|
valsToCheck.append(op->result_begin(), op->result_end());
|
|
for (Region ®ion : op->getRegions())
|
|
for (Block &block : region)
|
|
valsToCheck.append(block.args_begin(), block.args_end());
|
|
});
|
|
|
|
// Check for aliasing behavior between each of the values.
|
|
for (auto it = valsToCheck.begin(), e = valsToCheck.end(); it != e; ++it)
|
|
for (auto *innerIt = valsToCheck.begin(); innerIt != it; ++innerIt)
|
|
printAliasResult(aliasAnalysis.alias(*innerIt, *it), *innerIt, *it);
|
|
}
|
|
|
|
void TestAliasAnalysisModRefBase::runAliasAnalysisOnOperation(
|
|
Operation *op, AliasAnalysis &aliasAnalysis) {
|
|
llvm::errs() << "Testing : " << *op->getInherentAttr("sym_name") << "\n";
|
|
|
|
// Collect all of the values to check for aliasing behavior.
|
|
SmallVector<Value, 32> valsToCheck;
|
|
op->walk([&](Operation *op) {
|
|
if (!op->getDiscardableAttr("test.ptr"))
|
|
return;
|
|
valsToCheck.append(op->result_begin(), op->result_end());
|
|
for (Region ®ion : op->getRegions())
|
|
for (Block &block : region)
|
|
valsToCheck.append(block.args_begin(), block.args_end());
|
|
});
|
|
|
|
// Check for aliasing behavior between each of the values.
|
|
for (auto &it : valsToCheck) {
|
|
op->walk([&](Operation *op) {
|
|
if (!op->getDiscardableAttr("test.ptr"))
|
|
return;
|
|
printModRefResult(aliasAnalysis.getModRef(op, it), op, it);
|
|
});
|
|
}
|
|
}
|
|
|
|
} // namespace test
|
|
} // namespace mlir
|
|
|
|
//===----------------------------------------------------------------------===//
|
|
// Testing AliasResult
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
namespace {
|
|
struct TestAliasAnalysisPass
|
|
: public test::TestAliasAnalysisBase,
|
|
PassWrapper<TestAliasAnalysisPass, OperationPass<>> {
|
|
MLIR_DEFINE_EXPLICIT_INTERNAL_INLINE_TYPE_ID(TestAliasAnalysisPass)
|
|
|
|
StringRef getArgument() const final { return "test-alias-analysis"; }
|
|
StringRef getDescription() const final {
|
|
return "Test alias analysis results.";
|
|
}
|
|
void runOnOperation() override {
|
|
AliasAnalysis &aliasAnalysis = getAnalysis<AliasAnalysis>();
|
|
runAliasAnalysisOnOperation(getOperation(), aliasAnalysis);
|
|
}
|
|
};
|
|
} // namespace
|
|
|
|
//===----------------------------------------------------------------------===//
|
|
// Testing ModRefResult
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
namespace {
|
|
struct TestAliasAnalysisModRefPass
|
|
: public test::TestAliasAnalysisModRefBase,
|
|
PassWrapper<TestAliasAnalysisModRefPass, OperationPass<>> {
|
|
MLIR_DEFINE_EXPLICIT_INTERNAL_INLINE_TYPE_ID(TestAliasAnalysisModRefPass)
|
|
|
|
StringRef getArgument() const final { return "test-alias-analysis-modref"; }
|
|
StringRef getDescription() const final {
|
|
return "Test alias analysis ModRef results.";
|
|
}
|
|
void runOnOperation() override {
|
|
AliasAnalysis &aliasAnalysis = getAnalysis<AliasAnalysis>();
|
|
runAliasAnalysisOnOperation(getOperation(), aliasAnalysis);
|
|
}
|
|
};
|
|
} // namespace
|
|
|
|
//===----------------------------------------------------------------------===//
|
|
// Testing LocalAliasAnalysis extending
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
/// Check if value is function argument.
|
|
static bool isFuncArg(Value val) {
|
|
auto blockArg = dyn_cast<BlockArgument>(val);
|
|
if (!blockArg)
|
|
return false;
|
|
|
|
return mlir::isa_and_nonnull<FunctionOpInterface>(
|
|
blockArg.getOwner()->getParentOp());
|
|
}
|
|
|
|
/// Check if value has "restrict" attribute. Value must be a function argument.
|
|
static bool isRestrict(Value val) {
|
|
auto blockArg = cast<BlockArgument>(val);
|
|
auto func =
|
|
mlir::cast<FunctionOpInterface>(blockArg.getOwner()->getParentOp());
|
|
return !!func.getArgAttr(blockArg.getArgNumber(),
|
|
"local_alias_analysis.restrict");
|
|
}
|
|
|
|
namespace {
|
|
/// LocalAliasAnalysis extended to support "restrict" attreibute.
|
|
class LocalAliasAnalysisRestrict : public LocalAliasAnalysis {
|
|
protected:
|
|
AliasResult aliasImpl(Value lhs, Value rhs) override {
|
|
if (lhs == rhs)
|
|
return AliasResult::MustAlias;
|
|
|
|
// Assume no aliasing if both values are function arguments and any of them
|
|
// have restrict attr.
|
|
if (isFuncArg(lhs) && isFuncArg(rhs))
|
|
if (isRestrict(lhs) || isRestrict(rhs))
|
|
return AliasResult::NoAlias;
|
|
|
|
return LocalAliasAnalysis::aliasImpl(lhs, rhs);
|
|
}
|
|
};
|
|
|
|
/// This pass tests adding additional analysis impls to the AliasAnalysis.
|
|
struct TestAliasAnalysisExtendingPass
|
|
: public test::TestAliasAnalysisBase,
|
|
PassWrapper<TestAliasAnalysisExtendingPass, OperationPass<>> {
|
|
MLIR_DEFINE_EXPLICIT_INTERNAL_INLINE_TYPE_ID(TestAliasAnalysisExtendingPass)
|
|
|
|
StringRef getArgument() const final {
|
|
return "test-alias-analysis-extending";
|
|
}
|
|
StringRef getDescription() const final {
|
|
return "Test alias analysis extending.";
|
|
}
|
|
void runOnOperation() override {
|
|
AliasAnalysis aliasAnalysis(getOperation());
|
|
aliasAnalysis.addAnalysisImplementation(LocalAliasAnalysisRestrict());
|
|
runAliasAnalysisOnOperation(getOperation(), aliasAnalysis);
|
|
}
|
|
};
|
|
} // namespace
|
|
|
|
//===----------------------------------------------------------------------===//
|
|
// Pass Registration
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
namespace mlir {
|
|
namespace test {
|
|
void registerTestAliasAnalysisPass() {
|
|
PassRegistration<TestAliasAnalysisExtendingPass>();
|
|
PassRegistration<TestAliasAnalysisModRefPass>();
|
|
PassRegistration<TestAliasAnalysisPass>();
|
|
}
|
|
} // namespace test
|
|
} // namespace mlir
|