MLIR-AIE
AIELocalizeLocks.cpp
Go to the documentation of this file.
1//===- AIELocalizeLocks.cpp ---------------------------------------*- C++
2//-*-===//
3//
4// This file is licensed under the Apache License v2.0 with LLVM Exceptions.
5// See https://llvm.org/LICENSE.txt for license information.
6// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
7//
8// (c) Copyright 2019 Xilinx Inc.
9//
10//===----------------------------------------------------------------------===//
11
14
15#include "mlir/Dialect/Arith/IR/Arith.h"
16#include "mlir/Pass/Pass.h"
17
18namespace xilinx::AIE {
19#define GEN_PASS_DEF_AIELOCALIZELOCKS
20#include "aie/Dialect/AIE/Transforms/AIEPasses.h.inc"
21} // namespace xilinx::AIE
22
23#define DEBUG_TYPE "aie-localize-locks"
24
25using namespace mlir;
26using namespace xilinx;
27using namespace xilinx::AIE;
28
30 : xilinx::AIE::impl::AIELocalizeLocksBase<AIELocalizeLocksPass> {
31 void getDependentDialects(DialectRegistry &registry) const override {
32 registry.insert<arith::ArithDialect>();
33 }
34 void runOnOperation() override {
35
36 DeviceOp deviceOp = getOperation();
37
38 for (auto coreOp : deviceOp.getOps<CoreOp>()) {
39 // Collect the locks used in this core.
40 const auto &targetModel = getTargetModel(coreOp);
41
42 auto thisTile = dyn_cast<TileOp>(coreOp.getTile().getDefiningOp());
43 int col = thisTile.colIndex();
44 int row = thisTile.rowIndex();
45
46 // Find the neighboring tiles
47 SmallVector<TileOp, 4> accessibleTiles;
48 for (auto tile : deviceOp.getOps<TileOp>())
49 if (int dstRow = tile.rowIndex();
50 targetModel.isLegalMemAffinity(col, row, tile.colIndex(), dstRow))
51 accessibleTiles.push_back(tile);
52
53 for (auto tile : accessibleTiles) {
54 int dstCol = tile.colIndex();
55 int dstRow = tile.rowIndex();
56
57 const auto &targetModel = getTargetModel(tile);
58 for (auto user : tile.getResult().getUsers())
59 if (auto lock = dyn_cast<LockOp>(user)) {
60 // At this point, we are iterating over all locks that are
61 // accessible from within the current core coreOp. We only need to
62 // localize the current lock if it is used within the core. Note
63 // that this pass is to be applied after the scf-to-cf lowering, so
64 // it suffices to check if the parent of a UseLockOp is coreOp.
65 if (llvm::none_of(lock.getResult().getUsers(),
66 [&](Operation *user) {
67 return user->getParentOp() == coreOp;
68 }))
69 continue;
70
71 auto lockIndexOffset =
72 targetModel.getLockLocalBaseIndex(col, row, dstCol, dstRow);
73 if (!lockIndexOffset)
74 llvm_unreachable("Found illegal lock user!");
75
76 int localLockIndex =
77 lockIndexOffset.value() + lock.getLockIDValue();
78
79 OpBuilder builder =
80 OpBuilder::atBlockBegin(&coreOp.getBody().front());
81
82 Value coreLockIDValue = arith::ConstantIndexOp::create(
83 builder, builder.getUnknownLoc(), localLockIndex);
84 lock.getResult().replaceUsesWithIf(
85 coreLockIDValue, [&](OpOperand &opOperand) {
86 return opOperand.getOwner()->getParentOp() == coreOp;
87 });
88 }
89 }
90 }
91 }
92};
93
94std::unique_ptr<OperationPass<DeviceOp>> AIE::createAIELocalizeLocksPass() {
95 return std::make_unique<AIELocalizeLocksPass>();
96}
Include the generated interface declarations.
const AIETargetModel & getTargetModel(mlir::Operation *op)
std::unique_ptr< mlir::OperationPass< DeviceOp > > createAIELocalizeLocksPass()
void runOnOperation() override
void getDependentDialects(DialectRegistry &registry) const override