MLIR-AIE 1.4.5.dev
AIENormalizeAddressSpaces.cpp
Go to the documentation of this file.
1//===- AIENormalizeAddressSpaces.cpp ----------------------------*- C++ -*-===//
2//
3// Copyright (C) 2021-2022 Xilinx, Inc.
4// Copyright (C) 2022-2026 Advanced Micro Devices, Inc.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8
11
12#include "mlir/Dialect/Ptr/IR/PtrOps.h"
13#include "mlir/IR/Attributes.h"
14#include "mlir/IR/PatternMatch.h"
15#include "mlir/Pass/Pass.h"
16#include "mlir/Transforms/DialectConversion.h"
17
18#define DEBUG_TYPE "aie-normalize-address-spaces"
19
20using namespace mlir;
21using namespace xilinx;
22using namespace xilinx::AIE;
23
24static Type memRefToDefaultAddressSpace(Type t) {
25 if (auto memRefType = llvm::dyn_cast<MemRefType>(t);
26 memRefType && memRefType.getMemorySpace() != nullptr) {
27 // Preserve ptr::GenericSpaceAttr - it's needed for ptr dialect
28 // transformations
29 if (llvm::isa<ptr::GenericSpaceAttr>(memRefType.getMemorySpace()))
30 return t; // Keep as-is
31
32 // Remove other memory spaces
33 return MemRefType::get(memRefType.getShape(), memRefType.getElementType(),
34 memRefType.getLayout(), nullptr /* Address Space */);
35 }
36 return t;
37}
38
39#include "aie/Dialect/AIE/Transforms/AIENormalizeAddressSpaces.inc"
40
41namespace xilinx::AIE {
42#define GEN_PASS_DEF_AIENORMALIZEADDRESSSPACES
43#include "aie/Dialect/AIE/Transforms/AIEPasses.h.inc"
44} // namespace xilinx::AIE
45
48 AIENormalizeAddressSpacesPass> {
49 void getDependentDialects(DialectRegistry &registry) const override {
50 registry.insert<func::FuncDialect>();
51 }
52 void runOnOperation() override {
53 DeviceOp device = getOperation();
54
55 TypeConverter converter;
56 converter.addConversion([&](Type type) -> std::optional<Type> {
57 return memRefToDefaultAddressSpace(type);
58 });
59
60 ConversionTarget target(getContext());
61 target.addDynamicallyLegalOp<memref::GlobalOp>([](memref::GlobalOp op) {
62 return op.getType().getMemorySpace() == nullptr;
63 });
64
65 target.addDynamicallyLegalOp<func::FuncOp>([&](func::FuncOp op) {
66 return converter.isSignatureLegal(op.getFunctionType());
67 });
68
69 RewritePatternSet patterns(&getContext());
70 populateWithGenerated(patterns);
71 populateFunctionOpInterfaceTypeConversionPattern<func::FuncOp>(patterns,
72 converter);
73
74 if (failed(applyPartialConversion(device, target, std::move(patterns))))
75 signalPassFailure();
76
77 // Convert any output types to have the default address space
78 device.walk([&](Operation *op) {
79 for (Value r : op->getResults())
80 r.setType(memRefToDefaultAddressSpace(r.getType()));
81 });
82 }
83};
84
85std::unique_ptr<OperationPass<DeviceOp>>
87 return std::make_unique<AIENormalizeAddressSpacesPass>();
88}
std::unique_ptr< mlir::OperationPass< DeviceOp > > createAIENormalizeAddressSpacesPass()
void getDependentDialects(DialectRegistry &registry) const override