Files
clang-p2996/mlir/lib/Analysis/DataLayoutAnalysis.cpp
Alex Zinenko c59ce1f625 [mlir] support memref of memref in standard-to-llvm conversion
Now that memref supports arbitrary element types, add support for memref of
memref and make sure it is properly converted to the LLVM dialect. The type
support itself avoids adding the interface to the memref type itself similarly
to other built-in types. This allows the shape, and therefore byte size, of the
memref descriptor to remain a lowering aspect that is easier to customize and
evolve as opposed to sanctifying it in the data layout specification for the
memref type itself.

Factor out the code previously in a testing pass to live in a dedicated data
layout analysis and use that analysis in the conversion to compute the
allocation size for memref of memref. Other conversions will be ported
separately.

Depends On D103827

Reviewed By: rriddle

Differential Revision: https://reviews.llvm.org/D103828
2021-06-08 11:11:31 +02:00

52 lines
1.8 KiB
C++

//===- DataLayoutAnalysis.cpp ---------------------------------------------===//
//
// 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
//
//===----------------------------------------------------------------------===//
#include "mlir/Analysis/DataLayoutAnalysis.h"
#include "mlir/IR/BuiltinOps.h"
#include "mlir/IR/Operation.h"
#include "mlir/Interfaces/DataLayoutInterfaces.h"
using namespace mlir;
DataLayoutAnalysis::DataLayoutAnalysis(Operation *root)
: defaultLayout(std::make_unique<DataLayout>(DataLayoutOpInterface())) {
// Construct a DataLayout if possible from the op.
auto computeLayout = [this](Operation *op) {
if (auto iface = dyn_cast<DataLayoutOpInterface>(op))
layouts[op] = std::make_unique<DataLayout>(iface);
if (auto module = dyn_cast<ModuleOp>(op))
layouts[op] = std::make_unique<DataLayout>(module);
};
// Compute layouts for both ancestors and descendants.
root->walk(computeLayout);
for (Operation *ancestor = root->getParentOp(); ancestor != nullptr;
ancestor = ancestor->getParentOp()) {
computeLayout(ancestor);
}
}
const DataLayout &DataLayoutAnalysis::getAbove(Operation *operation) const {
for (Operation *ancestor = operation->getParentOp(); ancestor != nullptr;
ancestor = ancestor->getParentOp()) {
auto it = layouts.find(ancestor);
if (it != layouts.end())
return *it->getSecond();
}
// Fallback to the default layout.
return *defaultLayout;
}
const DataLayout &DataLayoutAnalysis::getAtOrAbove(Operation *operation) const {
auto it = layouts.find(operation);
if (it != layouts.end())
return *it->getSecond();
return getAbove(operation);
}