1*c59ce1f6SAlex Zinenko //===- DataLayoutAnalysis.cpp ---------------------------------------------===//
2*c59ce1f6SAlex Zinenko //
3*c59ce1f6SAlex Zinenko // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4*c59ce1f6SAlex Zinenko // See https://llvm.org/LICENSE.txt for license information.
5*c59ce1f6SAlex Zinenko // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6*c59ce1f6SAlex Zinenko //
7*c59ce1f6SAlex Zinenko //===----------------------------------------------------------------------===//
8*c59ce1f6SAlex Zinenko 
9*c59ce1f6SAlex Zinenko #include "mlir/Analysis/DataLayoutAnalysis.h"
10*c59ce1f6SAlex Zinenko #include "mlir/IR/BuiltinOps.h"
11*c59ce1f6SAlex Zinenko #include "mlir/IR/Operation.h"
12*c59ce1f6SAlex Zinenko #include "mlir/Interfaces/DataLayoutInterfaces.h"
13*c59ce1f6SAlex Zinenko 
14*c59ce1f6SAlex Zinenko using namespace mlir;
15*c59ce1f6SAlex Zinenko 
DataLayoutAnalysis(Operation * root)16*c59ce1f6SAlex Zinenko DataLayoutAnalysis::DataLayoutAnalysis(Operation *root)
17*c59ce1f6SAlex Zinenko     : defaultLayout(std::make_unique<DataLayout>(DataLayoutOpInterface())) {
18*c59ce1f6SAlex Zinenko   // Construct a DataLayout if possible from the op.
19*c59ce1f6SAlex Zinenko   auto computeLayout = [this](Operation *op) {
20*c59ce1f6SAlex Zinenko     if (auto iface = dyn_cast<DataLayoutOpInterface>(op))
21*c59ce1f6SAlex Zinenko       layouts[op] = std::make_unique<DataLayout>(iface);
22*c59ce1f6SAlex Zinenko     if (auto module = dyn_cast<ModuleOp>(op))
23*c59ce1f6SAlex Zinenko       layouts[op] = std::make_unique<DataLayout>(module);
24*c59ce1f6SAlex Zinenko   };
25*c59ce1f6SAlex Zinenko 
26*c59ce1f6SAlex Zinenko   // Compute layouts for both ancestors and descendants.
27*c59ce1f6SAlex Zinenko   root->walk(computeLayout);
28*c59ce1f6SAlex Zinenko   for (Operation *ancestor = root->getParentOp(); ancestor != nullptr;
29*c59ce1f6SAlex Zinenko        ancestor = ancestor->getParentOp()) {
30*c59ce1f6SAlex Zinenko     computeLayout(ancestor);
31*c59ce1f6SAlex Zinenko   }
32*c59ce1f6SAlex Zinenko }
33*c59ce1f6SAlex Zinenko 
getAbove(Operation * operation) const34*c59ce1f6SAlex Zinenko const DataLayout &DataLayoutAnalysis::getAbove(Operation *operation) const {
35*c59ce1f6SAlex Zinenko   for (Operation *ancestor = operation->getParentOp(); ancestor != nullptr;
36*c59ce1f6SAlex Zinenko        ancestor = ancestor->getParentOp()) {
37*c59ce1f6SAlex Zinenko     auto it = layouts.find(ancestor);
38*c59ce1f6SAlex Zinenko     if (it != layouts.end())
39*c59ce1f6SAlex Zinenko       return *it->getSecond();
40*c59ce1f6SAlex Zinenko   }
41*c59ce1f6SAlex Zinenko 
42*c59ce1f6SAlex Zinenko   // Fallback to the default layout.
43*c59ce1f6SAlex Zinenko   return *defaultLayout;
44*c59ce1f6SAlex Zinenko }
45*c59ce1f6SAlex Zinenko 
getAtOrAbove(Operation * operation) const46*c59ce1f6SAlex Zinenko const DataLayout &DataLayoutAnalysis::getAtOrAbove(Operation *operation) const {
47*c59ce1f6SAlex Zinenko   auto it = layouts.find(operation);
48*c59ce1f6SAlex Zinenko   if (it != layouts.end())
49*c59ce1f6SAlex Zinenko     return *it->getSecond();
50*c59ce1f6SAlex Zinenko   return getAbove(operation);
51*c59ce1f6SAlex Zinenko }
52